blob: 6bb6e2bacc6f0e6df1ece261a4c6b6e10731a641 [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 */
27#include <wlan_hdd_includes.h>
28#include <cds_api.h>
29#include <cds_sched.h>
Arun Khandavallifae92942016-08-01 13:31:08 +053030#include <linux/cpu.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080031#include <linux/etherdevice.h>
32#include <linux/firmware.h>
33#include <wlan_hdd_tx_rx.h>
34#include <wni_api.h>
35#include <wlan_hdd_cfg.h>
36#include <wlan_ptt_sock_svc.h>
37#include <dbglog_host.h>
38#include <wlan_logging_sock_svc.h>
39#include <wlan_hdd_wowl.h>
40#include <wlan_hdd_misc.h>
41#include <wlan_hdd_wext.h>
42#include "wlan_hdd_trace.h"
43#include "wlan_hdd_ioctl.h"
44#include "wlan_hdd_ftm.h"
45#include "wlan_hdd_power.h"
46#include "wlan_hdd_stats.h"
Prashanth Bhatta527fd752016-04-28 12:35:23 -070047#include "wlan_hdd_scan.h"
Jeff Johnsonce0032c2017-01-20 07:18:27 -080048#include "wlan_hdd_request_manager.h"
Naveen Rawate02f8f52018-04-05 11:58:04 -070049#include <wlan_osif_request_manager.h>
Dustin Brown26b3d042017-12-21 11:13:27 -080050#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4bc0a622017-12-06 15:56:50 -080051#include "qdf_debug_domain.h"
Dustin Brown26b3d042017-12-21 11:13:27 -080052#endif
Dustin Brownd4241942018-02-26 12:51:37 -080053#include "qdf_str.h"
54#include "qdf_trace.h"
55#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070056#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080057#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070058#include <cdp_txrx_stats.h>
bings0e03a982018-05-09 08:40:59 +080059#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060
61#include <net/addrconf.h>
62#include <linux/wireless.h>
63#include <net/cfg80211.h>
64#include <linux/inetdevice.h>
65#include <net/addrconf.h>
66#include "wlan_hdd_cfg80211.h"
67#include "wlan_hdd_ext_scan.h"
68#include "wlan_hdd_p2p.h"
69#include <linux/rtnetlink.h>
70#include "sap_api.h"
71#include <linux/semaphore.h>
72#include <linux/ctype.h>
73#include <linux/compat.h>
Arunk Khandavalli830c9692018-03-22 12:17:40 +053074#include <linux/reboot.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076#include <soc/qcom/subsystem_restart.h>
77#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078#include <wlan_hdd_hostapd.h>
79#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070080#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081#include "cfg_api.h"
82#include "qwlan_version.h"
83#include "wma_types.h"
84#include "wlan_hdd_tdls.h"
85#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053086#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070088#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070089#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080090#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091#include "wlan_hdd_nan.h"
92#include "wlan_hdd_debugfs.h"
93#include "wlan_hdd_driver_ops.h"
94#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +053095#include "wlan_hdd_data_stall_detection.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096
97#include <wlan_hdd_ipa.h>
98#include "hif.h"
99#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800100#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700101#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530102#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700103#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700104#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530105#include "nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700106#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530107#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800108#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800109#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530110#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800111#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800112#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530113#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530114#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800115#include "os_if_wifi_pos.h"
116#include "wifi_pos_api.h"
117#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800118#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700119#include "os_if_nan.h"
120#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700121#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800122#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700123#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530124#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530125#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700126#include <cdp_txrx_cmn_struct.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800127#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530128#include "wlan_disa_ucfg_api.h"
Wu Gao52084c12018-05-17 20:47:11 +0800129#include "wlan_disa_obj_mgmt_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530130#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530131#include <target_if.h>
Alok Kumarb64650c2018-03-23 17:05:11 +0530132#include "wlan_hdd_nud_tracking.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530133
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530134#ifdef CNSS_GENL
135#include <net/cnss_nl.h>
136#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800137#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800138#include "wlan_ocb_ucfg_api.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530139
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800140#include <wlan_hdd_spectralscan.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141#ifdef MODULE
142#define WLAN_MODULE_NAME module_name(THIS_MODULE)
143#else
144#define WLAN_MODULE_NAME "wlan"
145#endif
146
147#ifdef TIMER_MANAGER
148#define TIMER_MANAGER_STR " +TIMER_MANAGER"
149#else
150#define TIMER_MANAGER_STR ""
151#endif
152
153#ifdef MEMORY_DEBUG
154#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
155#else
156#define MEMORY_DEBUG_STR ""
157#endif
158
Dustin Brownc1034df2018-02-07 14:51:32 -0800159#ifdef PANIC_ON_BUG
160#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
161#else
162#define PANIC_ON_BUG_STR ""
163#endif
164
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530165bool g_is_system_reboot_triggered;
Sachin Ahujadddd2632017-03-07 19:07:24 +0530166int wlan_start_ret_val;
167static DECLARE_COMPLETION(wlan_start_comp);
168static unsigned int dev_num = 1;
169static struct cdev wlan_hdd_state_cdev;
170static struct class *class;
171static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530172#ifndef MODULE
173static struct gwlan_loader *wlan_loader;
174static ssize_t wlan_boot_cb(struct kobject *kobj,
175 struct kobj_attribute *attr,
176 const char *buf, size_t count);
177struct gwlan_loader {
178 bool loaded_state;
179 struct kobject *boot_wlan_obj;
180 struct attribute_group *attr_group;
181};
182
183static struct kobj_attribute wlan_boot_attribute =
184 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
185
186static struct attribute *attrs[] = {
187 &wlan_boot_attribute.attr,
188 NULL,
189};
190
191#define MODULE_INITIALIZED 1
192#endif
193
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530194#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
195#define MAX_OPS_NAME_STRING_SIZE 20
Rajeev Kumar6d0b2ea2017-12-26 17:55:33 -0800196#define RATE_LIMIT_ERROR_LOG (256)
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530197
198static qdf_timer_t hdd_drv_ops_inactivity_timer;
Dustin Brown45ed4bb2017-12-18 12:00:13 -0800199static struct task_struct *hdd_drv_ops_task;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530200static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
201
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202/* the Android framework expects this param even though we don't use it */
203#define BUF_LEN 20
204static char fwpath_buffer[BUF_LEN];
205static struct kparam_string fwpath = {
206 .string = fwpath_buffer,
207 .maxlen = BUF_LEN,
208};
209
210static char *country_code;
211static int enable_11d = -1;
212static int enable_dfs_chan_scan = -1;
213
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214/*
215 * spinlock for synchronizing asynchronous request/response
216 * (full description of use in wlan_hdd_main.h)
217 */
218DEFINE_SPINLOCK(hdd_context_lock);
Arunk Khandavalli16d84252017-06-21 15:26:29 +0530219DEFINE_MUTEX(hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800221#define WLAN_NLINK_CESIUM 30
222
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530223static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224
225#define WOW_MAX_FILTER_LISTS 1
226#define WOW_MAX_FILTERS_PER_LIST 4
227#define WOW_MIN_PATTERN_SIZE 6
228#define WOW_MAX_PATTERN_SIZE 64
229
230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
231static const struct wiphy_wowlan_support wowlan_support_reg_init = {
232 .flags = WIPHY_WOWLAN_ANY |
233 WIPHY_WOWLAN_MAGIC_PKT |
234 WIPHY_WOWLAN_DISCONNECT |
235 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
236 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
237 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
238 WIPHY_WOWLAN_4WAY_HANDSHAKE |
239 WIPHY_WOWLAN_RFKILL_RELEASE,
240 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
241 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
242 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
243};
244#endif
245
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700246static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
247 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
248 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
249 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
250 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
251 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
252 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
253 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
254 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
255 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
256 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
257 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
258 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
259 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
260 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
261 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
262 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
263 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
264 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
265 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
266 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
267 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
268 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
269 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
270 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
271 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
272 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
273 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
274 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
275 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
276 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
277 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
278 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
279 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
280 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700281 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700282 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700283 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530284 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800285 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530286 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700287};
288
Ganesh Kondabattini35739572017-06-21 16:26:39 +0530289int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
290 { HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
291 { HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
292 { HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
293 { HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
294};
295
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530296struct notifier_block hdd_netdev_notifier;
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530297struct notifier_block system_reboot_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298
299struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800300#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700301static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302#endif
303
Sachin Ahujadddd2632017-03-07 19:07:24 +0530304void hdd_start_complete(int ret)
305{
306 wlan_start_ret_val = ret;
307
308 complete(&wlan_start_comp);
309}
310
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530312 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700313 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530314 *
315 * Return: none
316 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700317static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530318{
Jeff Johnson9d295242017-08-29 14:39:48 -0700319 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530320
Dustin Brown920397d2017-12-13 16:27:50 -0800321 hdd_for_each_adapter(hdd_ctx, adapter)
322 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530323}
324
325/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
327 * @vdev_id: vdev_id
328 * @action: action type
329 * @reason: reason type
330 *
331 * Return: none
332 */
333void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
334 enum netif_action_type action, enum netif_reason_type reason)
335{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700336 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700337 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800338
339 if (!hdd_ctx) {
340 hdd_err("hdd ctx is NULL");
341 return;
342 }
343 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
344
345 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346}
347
348/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700349 * Store WLAN driver version and timestamp info in global variables such that
350 * crash debugger can extract them from driver debug symbol and crashdump for
351 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800353#ifdef BUILD_TAG
354uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR "; " BUILD_TAG;
355#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;
Naveen Rawat93836252017-06-20 16:30:59 -0700357#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358
359/**
360 * hdd_device_mode_to_string() - return string conversion of device mode
361 * @device_mode: device mode
362 *
363 * This utility function helps log string conversion of device mode.
364 *
365 * Return: string conversion of device mode, if match found;
366 * "Unknown" otherwise.
367 */
368const char *hdd_device_mode_to_string(uint8_t device_mode)
369{
370 switch (device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -0800371 CASE_RETURN_STRING(QDF_STA_MODE);
372 CASE_RETURN_STRING(QDF_SAP_MODE);
373 CASE_RETURN_STRING(QDF_P2P_CLIENT_MODE);
374 CASE_RETURN_STRING(QDF_P2P_GO_MODE);
375 CASE_RETURN_STRING(QDF_FTM_MODE);
376 CASE_RETURN_STRING(QDF_IBSS_MODE);
377 CASE_RETURN_STRING(QDF_P2P_DEVICE_MODE);
378 CASE_RETURN_STRING(QDF_OCB_MODE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700379 CASE_RETURN_STRING(QDF_NDI_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 default:
381 return "Unknown";
382 }
383}
384
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530385/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500386 * hdd_get_valid_chan() - return current chan list from regulatory.
387 * @hdd_ctx: HDD context
388 * @chan_list: buf hold returned chan list
389 * @chan_num: input buf size and output returned chan num
390 *
391 * This function helps get current available chan list from regulatory
392 * module. It excludes the "disabled" and "invalid" channels.
393 *
394 * Return: 0 for success.
395 */
396static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
397 uint8_t *chan_list,
398 uint32_t *chan_num)
399{
400 int i = 0, j = 0;
401 struct regulatory_channel *cur_chan_list;
402 struct wlan_objmgr_pdev *pdev;
403
404 if (!hdd_ctx || !hdd_ctx->hdd_pdev || !chan_list || !chan_num)
405 return -EINVAL;
406
407 pdev = hdd_ctx->hdd_pdev;
408 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
409 sizeof(struct regulatory_channel));
410 if (!cur_chan_list)
411 return -ENOMEM;
412
413 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
414 QDF_STATUS_SUCCESS) {
415 qdf_mem_free(cur_chan_list);
416 return -EINVAL;
417 }
418
419 for (i = 0; i < NUM_CHANNELS; i++) {
420 uint32_t ch = cur_chan_list[i].chan_num;
421 enum channel_state state = wlan_reg_get_channel_state(pdev,
422 ch);
423
424 if (state != CHANNEL_STATE_DISABLE &&
425 state != CHANNEL_STATE_INVALID &&
426 j < *chan_num) {
427 chan_list[j] = (uint8_t)ch;
428 j++;
429 }
430 }
431 *chan_num = j;
432 qdf_mem_free(cur_chan_list);
433 return 0;
434}
435
436/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530437 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
438 * @adapter: HDD adapter
439 * @chan_number: Channel number
440 * @chan_bw: Bandwidth
441 *
442 * Checks if the given bandwidth is valid for the given channel number.
443 *
444 * Return: 0 for success, non-zero for failure
445 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700446int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530447 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800448 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530449{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500450 uint8_t chan[NUM_CHANNELS];
451 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530452 bool found = false;
453 tHalHandle hal;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500454 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530455
456 hal = WLAN_HDD_GET_HAL_CTX(adapter);
457 if (!hal) {
458 hdd_err("Invalid HAL context");
459 return -EINVAL;
460 }
461
Liangwei Dong17bf2662018-01-05 02:02:05 -0500462 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
463 &len);
464 if (ret) {
465 hdd_err("error %d in getting valid channel list", ret);
466 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530467 }
468
469 for (i = 0; i < len; i++) {
470 if (chan[i] == chan_number) {
471 found = true;
472 break;
473 }
474 }
475
476 if (found == false) {
477 hdd_err("Channel not in driver's valid channel list");
478 return -EOPNOTSUPP;
479 }
480
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700481 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
482 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530483 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
484 return -EINVAL;
485 }
486
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700487 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530488 if (chan_bw == CH_WIDTH_80MHZ) {
489 hdd_err("BW80 not possible in 2.4GHz band");
490 return -EINVAL;
491 }
492 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
493 (chan_bw != CH_WIDTH_MAX)) {
494 hdd_err("Only BW20 possible on channel 14");
495 return -EINVAL;
496 }
497 }
498
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700499 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530500 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
501 (chan_bw != CH_WIDTH_MAX)) {
502 hdd_err("Only BW20 possible on channel 165");
503 return -EINVAL;
504 }
505 }
506
507 return 0;
508}
509
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530510/**
511 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
512 *
513 * Block the unloading of the driver (or) interface up until the
514 * cds recovery is completed
515 *
516 * Return: true for recovery completion else false
517 */
518static bool hdd_wait_for_recovery_completion(void)
519{
520 int retry = 0;
521
522 /* Wait for recovery to complete */
523 while (cds_is_driver_recovering()) {
524 if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
525 hdd_err("Recovery in progress; wait here!!!");
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530526
527 if (g_is_system_reboot_triggered) {
528 hdd_info("System Reboot happening ignore unload!!");
529 return false;
530 }
531
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530532 msleep(1000);
533 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
534 hdd_err("SSR never completed, error");
535 /*
536 * Trigger the bug_on in the internal builds, in the
537 * customer builds self-recovery will be enabled
538 * in those cases just return error.
539 */
540 if (cds_is_self_recovery_enabled())
541 return false;
542 QDF_BUG(0);
543 }
544 }
545
546 hdd_info("Recovery completed successfully!");
547 return true;
548}
549
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530550
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551static int __hdd_netdev_notifier_call(struct notifier_block *nb,
552 unsigned long state, void *data)
553{
554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
555 struct netdev_notifier_info *dev_notif_info = data;
556 struct net_device *dev = dev_notif_info->dev;
557#else
558 struct net_device *dev = data;
559#endif
Jeff Johnson9d295242017-08-29 14:39:48 -0700560 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700561 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562
Dustin Brownfdf17c12018-03-14 12:55:34 -0700563 hdd_enter_dev(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800564
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565 /* Make sure that this callback corresponds to our device. */
566 if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
567 return NOTIFY_DONE;
568
Samuel Ahnc9c48ca2016-09-19 15:46:36 +0530569 if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 (adapter->dev != dev)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700571 hdd_err("device adapter is not matching!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 return NOTIFY_DONE;
573 }
574
575 if (!dev->ieee80211_ptr) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700576 hdd_err("ieee80211_ptr is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 return NOTIFY_DONE;
578 }
579
580 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
581 if (NULL == hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800582 hdd_err("HDD Context Null Pointer");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530583 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 return NOTIFY_DONE;
585 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800586
587 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
588 hdd_err("%s: Driver module is closed", __func__);
589 return NOTIFY_DONE;
590 }
591
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530592 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state())
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 return NOTIFY_DONE;
594
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800595 hdd_debug("%s New Net Device State = %lu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 dev->name, state);
597
598 switch (state) {
599 case NETDEV_REGISTER:
600 break;
601
602 case NETDEV_UNREGISTER:
603 break;
604
605 case NETDEV_UP:
606 sme_ch_avoid_update_req(hdd_ctx->hHal);
607 break;
608
609 case NETDEV_DOWN:
610 break;
611
612 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700613 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 complete(&adapter->linkup_event_var);
615 break;
616
617 case NETDEV_GOING_DOWN:
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700618 if (ucfg_scan_get_vdev_status(adapter->hdd_vdev) !=
619 SCAN_NOT_IN_PROGRESS) {
Abhishek Singh69ccb512017-04-25 11:58:16 +0530620 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -0700621 adapter->session_id, INVALID_SCAN_ID, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800622 } else {
hqueaa33ee2017-05-04 17:56:35 +0800623 cds_flush_work(&adapter->scan_block_work);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800624 hdd_debug("Scan is not Pending from user");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800625 }
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530626 /*
627 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
628 * of return status of hdd_stop call, kernel resets the IFF_UP
629 * flag after which driver does not send the cfg80211_scan_done.
630 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
631 */
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +0530632 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633 break;
634
635 default:
636 break;
637 }
638
639 return NOTIFY_DONE;
640}
641
642/**
643 * hdd_netdev_notifier_call() - netdev notifier callback function
644 * @nb: pointer to notifier block
645 * @state: state
646 * @ndev: ndev pointer
647 *
648 * Return: 0 on success, error number otherwise.
649 */
650static int hdd_netdev_notifier_call(struct notifier_block *nb,
651 unsigned long state,
652 void *ndev)
653{
654 int ret;
655
656 cds_ssr_protect(__func__);
657 ret = __hdd_netdev_notifier_call(nb, state, ndev);
658 cds_ssr_unprotect(__func__);
659
660 return ret;
661}
662
663struct notifier_block hdd_netdev_notifier = {
664 .notifier_call = hdd_netdev_notifier_call,
665};
666
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530667static int system_reboot_notifier_call(struct notifier_block *nb,
668 unsigned long msg_type, void *_unused)
669{
670 switch (msg_type) {
671 case SYS_DOWN:
672 case SYS_HALT:
673 case SYS_POWER_OFF:
674 g_is_system_reboot_triggered = true;
675 hdd_info("reboot, reason: %ld", msg_type);
676 break;
677 default:
678 break;
679 }
680
681 return NOTIFY_OK;
682}
683
684struct notifier_block system_reboot_notifier = {
685 .notifier_call = system_reboot_notifier_call,
686};
687
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688/* variable to hold the insmod parameters */
689static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800690
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530691static int con_mode_ftm;
Ravi Joshia307f632017-07-17 23:41:41 -0700692int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530693
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800694/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530697/**
698 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
699 * @ch_width: NL channel width
700 *
701 * Converts the NL channel width to the driver's internal representation
702 *
703 * Return: Converted channel width. In case of non matching NL channel width,
704 * CH_WIDTH_MAX will be returned.
705 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800706enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530707{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800708 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700709
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800710 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530711 switch (ch_width) {
712 case NL80211_CHAN_WIDTH_20_NOHT:
713 case NL80211_CHAN_WIDTH_20:
714 return CH_WIDTH_20MHZ;
715 case NL80211_CHAN_WIDTH_40:
716 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530717 case NL80211_CHAN_WIDTH_80:
718 return CH_WIDTH_80MHZ;
719 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800720 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
721 return CH_WIDTH_80P80MHZ;
722 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
723 return CH_WIDTH_160MHZ;
724 else
725 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530726 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800727 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
728 return CH_WIDTH_160MHZ;
729 else
730 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530731 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800732 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530733 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800734 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530735 default:
736 hdd_err("Invalid channel width %d, setting to default",
737 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800738 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530739 }
740}
741
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530742/* wlan_hdd_find_opclass() - Find operating class for a channel
743 * @hal: handler to HAL
744 * @channel: channel id
745 * @bw_offset: bandwidth offset
746 *
747 * Function invokes sme api to find the operating class
748 *
749 * Return: operating class
750 */
751uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
752 uint8_t bw_offset)
753{
754 uint8_t opclass = 0;
755
756 sme_get_opclass(hal, channel, bw_offset, &opclass);
757 return opclass;
758}
759
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800760/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530761 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530762 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763 * @bitmask: Bitmask of log levels to be enabled
764 *
765 * Called immediately after the cfg.ini is read in order to configure
766 * the desired trace levels.
767 *
768 * Return: None
769 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530770int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530772 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530773 int qdf_print_idx = -1;
774 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 /*
776 * if the bitmask is the default value, then a bitmask was not
777 * specified in cfg.ini, so leave the logging level alone (it
778 * will remain at the "compiled in" default value)
779 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700780 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530781 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800782
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530783 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530785 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530786 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530787 QDF_TRACE_LEVEL_NONE, 0);
788
789 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530790 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800791 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +0530792 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793 while (0 != bitmask) {
794 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530795 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530796 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530797 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530798 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 level++;
802 bitmask >>= 1;
803 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530804 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805}
806
807/**
Chris Guo1751acf2017-07-03 14:09:01 +0800808 * wlan_hdd_validate_context_in_loading() - check the HDD context in loading
809 * @hdd_ctx: HDD context pointer
810 *
811 * Return: 0 if the context is valid. Error code otherwise
812 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700813int wlan_hdd_validate_context_in_loading(struct hdd_context *hdd_ctx)
Chris Guo1751acf2017-07-03 14:09:01 +0800814{
815 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
816 hdd_info("%pS HDD context is Null", (void *)_RET_IP_);
817 return -ENODEV;
818 }
819
820 if (cds_is_driver_recovering()) {
821 hdd_info("%pS Recovery in Progress. State: 0x%x Ignore!!!",
822 (void *)_RET_IP_, cds_get_driver_state());
823 return -EAGAIN;
824 }
825
826 if (hdd_ctx->start_modules_in_progress ||
827 hdd_ctx->stop_modules_in_progress) {
828 hdd_info("%pS Start/Stop Modules in progress. Ignore!!!",
829 (void *)_RET_IP_);
830 return -EAGAIN;
831 }
832
833 return 0;
834}
835
836
837/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 * wlan_hdd_validate_context() - check the HDD context
839 * @hdd_ctx: HDD context pointer
840 *
841 * Return: 0 if the context is valid. Error code otherwise
842 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700843int wlan_hdd_validate_context(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800844{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530846 hdd_err("%pS HDD context is Null", (void *)_RET_IP_);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847 return -ENODEV;
848 }
849
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800850 if (cds_is_driver_recovering()) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800851 hdd_debug("%pS Recovery in Progress. State: 0x%x Ignore!!!",
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530852 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853 return -EAGAIN;
854 }
855
Yue Ma9f275d92017-09-14 16:58:41 -0700856 if (cds_is_load_or_unload_in_progress()) {
857 hdd_debug("%pS Load or unload in progress, state: 0x%x, ignore!",
858 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -0700860 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530861
862 if (hdd_ctx->start_modules_in_progress ||
863 hdd_ctx->stop_modules_in_progress) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800864 hdd_debug("%pS Start/Stop Modules in progress. Ignore!!!",
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530865 (void *)_RET_IP_);
866 return -EAGAIN;
867 }
868
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530869 if (cds_is_driver_in_bad_state()) {
870 hdd_debug("%pS driver in bad State: 0x%x Ignore!!!",
871 (void *)_RET_IP_, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +0530872 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530873 }
874
Arunk Khandavalli2859fa12018-02-14 10:46:26 +0530875 if (cds_is_fw_down()) {
876 hdd_debug("%pS FW is down: 0x%x Ignore!!!",
877 (void *)_RET_IP_, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +0530878 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +0530879 }
880
Liangwei Dong858feb12018-05-21 01:52:46 -0400881 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
882 hdd_debug("con_mode_handler is in progress Ignore!!!");
883 return -EAGAIN;
884 }
885
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 return 0;
887}
888
Jeff Johnson9d295242017-08-29 14:39:48 -0700889int hdd_validate_adapter(struct hdd_adapter *adapter)
Dustin Brownf13b8c32017-05-19 17:23:08 -0700890{
891 if (!adapter) {
892 hdd_err("adapter is null");
893 return -EINVAL;
894 }
895
896 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
897 hdd_err("bad adapter magic: 0x%x (should be 0x%x)",
898 adapter->magic, WLAN_HDD_ADAPTER_MAGIC);
899 return -EINVAL;
900 }
901
902 if (!adapter->dev) {
903 hdd_err("adapter net_device is null");
904 return -EINVAL;
905 }
906
907 if (!(adapter->dev->flags & IFF_UP)) {
908 hdd_info("adapter net_device is not up");
909 return -EAGAIN;
910 }
911
Jeff Johnson1b780e42017-10-31 14:11:45 -0700912 if (wlan_hdd_validate_session_id(adapter->session_id)) {
Dustin Brownf13b8c32017-05-19 17:23:08 -0700913 hdd_info("adapter session is not open");
914 return -EAGAIN;
915 }
916
Jeff Johnson1b780e42017-10-31 14:11:45 -0700917 if (adapter->session_id >= MAX_NUMBER_OF_ADAPTERS) {
918 hdd_err("bad adapter session Id: %u", adapter->session_id);
Dustin Brownf13b8c32017-05-19 17:23:08 -0700919 return -EINVAL;
920 }
921
922 return 0;
923}
924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925/**
Arun Khandavallica892f62017-05-26 14:25:50 +0530926 * wlan_hdd_validate_modules_state() - Check modules status
927 * @hdd_ctx: HDD context pointer
928 *
929 * Check's the driver module's state and returns true if the
930 * modules are enabled returns false if modules are closed.
931 *
932 * Return: True if modules are enabled or false.
933 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700934bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +0530935{
936 mutex_lock(&hdd_ctx->iface_change_lock);
937 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
938 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown5e89ef82018-03-14 11:50:23 -0700939 hdd_info("Modules not enabled, Present status: %d",
940 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +0530941 return false;
942 }
943 mutex_unlock(&hdd_ctx->iface_change_lock);
944 return true;
945}
946
947/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -0700949 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 *
951 * This function sets the IBSS power save config parameters to WMA
952 * which will send it to firmware if FW supports IBSS power save
953 * before vdev start.
954 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530955 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800956 * on failure.
957 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700958QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959{
960 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700961 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800962
963 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700964 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530965 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 }
967
Jeff Johnson1b780e42017-10-31 14:11:45 -0700968 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
970 hdd_ctx->config->ibssATIMWinSize,
971 VDEV_CMD);
972 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700973 hdd_err("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530974 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800975 }
976
Jeff Johnson1b780e42017-10-31 14:11:45 -0700977 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
979 hdd_ctx->config->isIbssPowerSaveAllowed,
980 VDEV_CMD);
981 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700982 hdd_err("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d",
983 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530984 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985 }
986
Jeff Johnson1b780e42017-10-31 14:11:45 -0700987 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
989 hdd_ctx->config->
990 isIbssPowerCollapseAllowed, VDEV_CMD);
991 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700992 hdd_err("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d",
993 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530994 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 }
996
Jeff Johnson1b780e42017-10-31 14:11:45 -0700997 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800998 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
999 hdd_ctx->config->isIbssAwakeOnTxRx,
1000 VDEV_CMD);
1001 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001002 hdd_err("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301003 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 }
1005
Jeff Johnson1b780e42017-10-31 14:11:45 -07001006 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
1008 hdd_ctx->config->ibssInactivityCount,
1009 VDEV_CMD);
1010 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001011 hdd_err("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301012 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 }
1014
Jeff Johnson1b780e42017-10-31 14:11:45 -07001015 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
1017 hdd_ctx->config->ibssTxSpEndInactivityTime,
1018 VDEV_CMD);
1019 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001020 hdd_err("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d",
1021 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301022 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023 }
1024
Jeff Johnson1b780e42017-10-31 14:11:45 -07001025 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001026 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
1027 hdd_ctx->config->ibssPsWarmupTime,
1028 VDEV_CMD);
1029 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001030 hdd_err("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d",
1031 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301032 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033 }
1034
Jeff Johnson1b780e42017-10-31 14:11:45 -07001035 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
1037 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
1038 VDEV_CMD);
1039 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001040 hdd_err("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d",
1041 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301042 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 }
1044
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301045 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046}
1047
Yue Macd359b72017-10-03 15:21:00 -07001048#ifdef FEATURE_RUNTIME_PM
1049/**
1050 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1051 * @hdd_ctx: HDD context
1052 *
1053 * Return: None
1054 */
1055static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1056{
1057 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1058
Yue Macd359b72017-10-03 15:21:00 -07001059 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001060 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001061
1062 wlan_scan_runtime_pm_init(hdd_ctx->hdd_pdev);
1063}
1064
1065/**
1066 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1067 * @hdd_ctx: HDD Context
1068 *
1069 * Return: None
1070 */
1071static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1072{
1073 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1074
Yue Macd359b72017-10-03 15:21:00 -07001075 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001076 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001077
1078 wlan_scan_runtime_pm_deinit(hdd_ctx->hdd_pdev);
1079}
1080
Yue Macd359b72017-10-03 15:21:00 -07001081#else /* FEATURE_RUNTIME_PM */
1082static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1083static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001084#endif /* FEATURE_RUNTIME_PM */
1085
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001086#define INTF_MACADDR_MASK 0x7
1087
1088/**
1089 * hdd_update_macaddr() - update mac address
1090 * @config: hdd configuration
1091 * @hw_macaddr: mac address
1092 *
1093 * Mac address for multiple virtual interface is found as following
1094 * i) The mac address of the first interface is just the actual hw mac address.
1095 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
1096 * define the mac address for the remaining interfaces and locally
1097 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
1098 * supported virtual interfaces, right now this is 0x07 (meaning 8
1099 * interface).
1100 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
1101 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
1102 *
1103 * Return: None
1104 */
1105void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301106 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001107{
1108 int8_t i;
1109 uint8_t macaddr_b3, tmp_br3;
1110
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301111 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301112 QDF_MAC_ADDR_SIZE);
1113 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301114 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301115 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116 macaddr_b3 = config->intfMacAddr[i].bytes[3];
1117 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1118 INTF_MACADDR_MASK;
1119 macaddr_b3 += tmp_br3;
1120
1121 /* XOR-ing bit-24 of the mac address. This will give enough
1122 * mac address range before collision
1123 */
1124 macaddr_b3 ^= (1 << 7);
1125
1126 /* Set locally administered bit */
1127 config->intfMacAddr[i].bytes[0] |= 0x02;
1128 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001129 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001130 MAC_ADDRESS_STR, i,
1131 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
1132 }
1133}
1134
Kabilan Kannan44a58372017-12-06 18:16:11 -08001135static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1136{
1137 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
1138 struct tdls_start_params tdls_cfg;
1139 struct tdls_user_config *config = &tdls_cfg.config;
1140 struct hdd_config *cfg = hdd_ctx->config;
1141 QDF_STATUS status;
1142
1143 config->tdls_tx_states_period = cfg->fTDLSTxStatsPeriod;
1144 config->tdls_tx_pkt_threshold = cfg->fTDLSTxPacketThreshold;
1145 config->tdls_rx_pkt_threshold = cfg->fTDLSRxFrameThreshold;
1146 config->tdls_max_discovery_attempt = cfg->fTDLSMaxDiscoveryAttempt;
1147 config->tdls_idle_timeout = cfg->tdls_idle_timeout;
1148 config->tdls_idle_pkt_threshold = cfg->fTDLSIdlePacketThreshold;
1149 config->tdls_rssi_trigger_threshold = cfg->fTDLSRSSITriggerThreshold;
1150 config->tdls_rssi_teardown_threshold = cfg->fTDLSRSSITeardownThreshold;
1151 config->tdls_rssi_delta = cfg->fTDLSRSSIDelta;
1152 config->tdls_uapsd_mask = cfg->fTDLSUapsdMask;
1153 config->tdls_uapsd_inactivity_time = cfg->fTDLSPuapsdInactivityTimer;
1154 config->tdls_uapsd_pti_window = cfg->fTDLSPuapsdPTIWindow;
1155 config->tdls_uapsd_ptr_timeout = cfg->fTDLSPuapsdPTRTimeout;
1156 config->tdls_pre_off_chan_num = cfg->fTDLSPrefOffChanNum;
1157 config->tdls_pre_off_chan_bw = cfg->fTDLSPrefOffChanBandwidth;
1158 config->tdls_peer_kickout_threshold = cfg->tdls_peer_kickout_threshold;
1159 config->delayed_trig_framint = cfg->DelayedTriggerFrmInt;
1160 config->tdls_feature_flags = ((cfg->fEnableTDLSOffChannel ?
1161 1 << TDLS_FEATURE_OFF_CHANNEL : 0) |
1162 (cfg->fEnableTDLSWmmMode ? 1 << TDLS_FEATURE_WMM : 0) |
1163 (cfg->fEnableTDLSBufferSta ? 1 << TDLS_FEATURE_BUFFER_STA : 0) |
1164 (cfg->fEnableTDLSSleepSta ? 1 << TDLS_FEATURE_SLEEP_STA : 0) |
1165 (cfg->enable_tdls_scan ? 1 << TDLS_FEATURE_SCAN : 0) |
1166 (cfg->fEnableTDLSSupport ? 1 << TDLS_FEATURE_ENABLE : 0) |
1167 (cfg->fEnableTDLSImplicitTrigger ?
1168 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) |
1169 (cfg->fTDLSExternalControl ?
1170 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0));
1171 config->tdls_vdev_nss_2g = CFG_TDLS_NSS(cfg->vdev_type_nss_2g);
1172 config->tdls_vdev_nss_5g = CFG_TDLS_NSS(cfg->vdev_type_nss_5g);
1173
1174 tdls_cfg.tdls_send_mgmt_req = eWNI_SME_TDLS_SEND_MGMT_REQ;
1175 tdls_cfg.tdls_add_sta_req = eWNI_SME_TDLS_ADD_STA_REQ;
1176 tdls_cfg.tdls_del_sta_req = eWNI_SME_TDLS_DEL_STA_REQ;
1177 tdls_cfg.tdls_update_peer_state = WMA_UPDATE_TDLS_PEER_STATE;
1178 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1179 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1180 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1181 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001182 tdls_cfg.tdls_peer_context = hdd_ctx;
1183 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1184 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001185 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1186 tdls_cfg.tdls_wmm_cb_data = psoc;
1187 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1188 tdls_cfg.tdls_rx_cb_data = psoc;
1189 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1190
1191 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1192 if (status != QDF_STATUS_SUCCESS) {
1193 hdd_err("failed pmo psoc configuration");
1194 return -EINVAL;
1195 }
1196
1197 hdd_ctx->tdls_umac_comp_active = true;
1198 /* enable napier specific tdls data path */
1199 hdd_ctx->tdls_nap_active = true;
1200
1201 return 0;
1202}
1203
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001204static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 struct wma_tgt_services *cfg)
1206{
1207 struct hdd_config *config = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208
1209 /* Set up UAPSD */
1210 config->apUapsdEnabled &= cfg->uapsd;
1211
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001212 /* 11AX mode support */
1213 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1214 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1215 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1216
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 /* 11AC mode support */
1218 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1219 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1220 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221
1222 /* ARP offload: override user setting if invalid */
1223 config->fhostArpOffload &= cfg->arp_offload;
1224
1225#ifdef FEATURE_WLAN_SCAN_PNO
1226 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001227 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001228 if (cfg->pno_offload)
1229 config->PnoOffload = true;
1230#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231#ifdef FEATURE_WLAN_TDLS
1232 config->fEnableTDLSSupport &= cfg->en_tdls;
Manjeet Singhfdd2ac72016-09-02 18:11:43 +05301233 config->fEnableTDLSOffChannel = config->fEnableTDLSOffChannel &&
1234 cfg->en_tdls_offchan;
1235 config->fEnableTDLSBufferSta = config->fEnableTDLSBufferSta &&
1236 cfg->en_tdls_uapsd_buf_sta;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001237 if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238 config->fEnableTDLSSleepSta = true;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001239 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 config->fEnableTDLSSleepSta = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001242#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1243 config->isRoamOffloadEnabled &= cfg->en_roam_offload;
1244#endif
Will Huang496b36c2017-07-11 16:38:50 +08001245 config->sap_get_peer_info &= cfg->get_peer_info_enabled;
Varun Reddy Yeturu62c32652017-10-26 15:32:35 -07001246 config->MAWCEnabled &= cfg->is_fw_mawc_capable;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001247 hdd_update_tdls_config(hdd_ctx);
Krishna Kumaar Natarajan052c6e62015-09-28 15:32:55 -07001248 sme_update_tgt_services(hdd_ctx->hHal, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001249
1250}
1251
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001252/**
1253 * hdd_update_vdev_nss() - sets the vdev nss
1254 * @hdd_ctx: HDD context
1255 *
1256 * Sets the Nss per vdev type based on INI
1257 *
1258 * Return: None
1259 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001260static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001261{
1262 struct hdd_config *cfg_ini = hdd_ctx->config;
1263 uint8_t max_supp_nss = 1;
1264
Naveen Rawat10b1c152017-01-18 11:16:06 -08001265 if (cfg_ini->enable2x2 && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001266 max_supp_nss = 2;
Liangwei Dong22810e82018-03-15 03:42:12 -04001267 hdd_debug("max nss %d vdev_type_nss_2g %x vdev_type_nss_5g %x",
1268 max_supp_nss, cfg_ini->vdev_type_nss_2g,
1269 cfg_ini->vdev_type_nss_5g);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001270
1271 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001272 cfg_ini->vdev_type_nss_2g, BAND_2G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001273
1274 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001275 cfg_ini->vdev_type_nss_5g, BAND_5G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001276}
1277
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301278/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301279 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1280 * @hdd_ctx: HDD context
1281 *
1282 * Updates wiphy vhtcap fields
1283 *
1284 * Return: None
1285 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001286static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301287{
1288 struct ieee80211_supported_band *band_5g =
1289 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
1290 uint32_t val;
1291
1292 if (!band_5g) {
1293 hdd_debug("5GHz band disabled, skipping capability population");
1294 return;
1295 }
1296
1297 val = hdd_ctx->config->txBFCsnValue;
1298 band_5g->vht_cap.cap |= (val << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
1299
1300 val = NUM_OF_SOUNDING_DIMENSIONS;
1301 band_5g->vht_cap.cap |=
1302 (val << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
1303
1304 hdd_info("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
1305 band_5g->vht_cap.cap, hdd_ctx->config->txBFCsnValue, val);
1306}
1307
1308/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301309 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
1310 * @hdd_ctx: HDD context
1311 *
1312 * Sets the DBS capability as per INI and firmware capability
1313 *
1314 * Return: None
1315 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001316static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301317{
1318 struct hdd_config *cfg_ini = hdd_ctx->config;
1319 uint8_t hw_dbs_capable = 0;
1320
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07001321 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc) &&
1322 ((cfg_ini->dual_mac_feature_disable ==
1323 ENABLE_DBS_CXN_AND_SCAN) ||
1324 (cfg_ini->dual_mac_feature_disable ==
1325 ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF)))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301326 hw_dbs_capable = 1;
1327
1328 sme_update_hw_dbs_capable(hdd_ctx->hHal, hw_dbs_capable);
1329}
1330
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001331static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001332 struct wma_tgt_ht_cap *cfg)
1333{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301334 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335 uint32_t value, val32;
1336 uint16_t val16;
1337 struct hdd_config *pconfig = hdd_ctx->config;
1338 tSirMacHTCapabilityInfo *phtCapInfo;
1339 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
1340 uint8_t enable_tx_stbc;
1341
1342 /* check and update RX STBC */
1343 if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
1344 pconfig->enableRxSTBC = cfg->ht_rx_stbc;
1345
1346 /* get the MPDU density */
1347 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);
1348
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301349 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001350 hdd_err("could not get MPDU DENSITY");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351 value = 0;
1352 }
1353
1354 /*
1355 * MPDU density:
1356 * override user's setting if value is larger
1357 * than the one supported by target
1358 */
1359 if (value > cfg->mpdu_density) {
1360 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
1361 cfg->mpdu_density);
1362
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301363 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001364 hdd_err("could not set MPDU DENSITY to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001365 }
1366
1367 /* get the HT capability info */
1368 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301369 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001370 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001371 return;
1372 }
1373 val16 = (uint16_t) val32;
1374 phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;
1375
1376 /* Set the LDPC capability */
1377 phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;
1378
1379 if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
1380 pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;
1381
1382 if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
1383 pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;
1384
1385 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1386 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1387
1388 enable_tx_stbc = pconfig->enableTxSTBC;
1389
1390 if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
1391 pconfig->enable2x2 = 1;
1392 } else {
1393 pconfig->enable2x2 = 0;
1394 enable_tx_stbc = 0;
1395
1396 /* 1x1 */
1397 /* Update Rx Highest Long GI data Rate */
1398 if (sme_cfg_set_int(hdd_ctx->hHal,
1399 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001400 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301401 == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001402 hdd_err("Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001403 }
1404
1405 /* Update Tx Highest Long GI data Rate */
1406 if (sme_cfg_set_int
1407 (hdd_ctx->hHal,
1408 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001409 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301410 QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001411 hdd_err("VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001412 }
1413 }
1414 if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
1415 enable_tx_stbc = 0;
1416 phtCapInfo->txSTBC = enable_tx_stbc;
1417
1418 val32 = val16;
1419 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301420 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001421 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
1423 value = SIZE_OF_SUPPORTED_MCS_SET;
1424 if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301425 &value) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001426 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301427 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1428 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 if (pconfig->enable2x2) {
1430 for (value = 0; value < cfg->num_rf_chains; value++)
1431 mcs_set[value] =
1432 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1433
1434 status =
1435 sme_cfg_set_str(hdd_ctx->hHal,
1436 WNI_CFG_SUPPORTED_MCS_SET,
1437 mcs_set,
1438 SIZE_OF_SUPPORTED_MCS_SET);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301439 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001440 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 }
1442 }
1443#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1444}
1445
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001446static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447 struct wma_tgt_vht_cap *cfg)
1448{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301449 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 uint32_t value = 0;
1451 struct hdd_config *pconfig = hdd_ctx->config;
1452 struct wiphy *wiphy = hdd_ctx->wiphy;
1453 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001454 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001455 uint32_t temp = 0;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001456 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
jiad4a7a33c2017-08-08 15:32:24 +08001457 uint32_t hw_rx_ldpc_enabled;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001458 struct wma_caps_per_phy caps_per_phy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459
Dustin Brown5e06bd32016-10-04 12:49:10 -07001460 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001461 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001462 return;
1463 }
1464
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 /* Get the current MPDU length */
1466 status =
1467 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
1468 &value);
1469
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301470 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001471 hdd_err("could not get MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001472 value = 0;
1473 }
1474
1475 /*
1476 * VHT max MPDU length:
1477 * override if user configured value is too high
1478 * that the target cannot support
1479 */
1480 if (value > cfg->vht_max_mpdu) {
1481 status = sme_cfg_set_int(hdd_ctx->hHal,
1482 WNI_CFG_VHT_MAX_MPDU_LENGTH,
1483 cfg->vht_max_mpdu);
1484
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001485 if (status == QDF_STATUS_E_FAILURE)
1486 hdd_err("could not set VHT MAX MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487 }
1488
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001489 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
1490 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1491
1492 if (pconfig->enable2x2)
1493 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1494
1495 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) ==
1496 QDF_STATUS_E_FAILURE) {
1497 hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM");
1498 }
1499
1500 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
1501 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1502 if (pconfig->enable2x2)
1503 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1504
1505 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) ==
1506 QDF_STATUS_E_FAILURE) {
1507 hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM");
1508 }
1509
1510 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
1511 temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
1512 if (pconfig->enable2x2)
1513 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
1514
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001515 hdd_debug("vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001516 pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
1517
1518 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) ==
1519 QDF_STATUS_E_FAILURE) {
1520 hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM");
1521 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522 /* Get the current RX LDPC setting */
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001523 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 &value);
1525
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301526 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001527 hdd_err("could not get VHT LDPC CODING CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 value = 0;
1529 }
1530
jiad4a7a33c2017-08-08 15:32:24 +08001531 /* Set HW RX LDPC capability */
1532 hw_rx_ldpc_enabled = !!cfg->vht_rx_ldpc;
1533 if (hw_rx_ldpc_enabled != value) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 status = sme_cfg_set_int(hdd_ctx->hHal,
1535 WNI_CFG_VHT_LDPC_CODING_CAP,
jiad4a7a33c2017-08-08 15:32:24 +08001536 hw_rx_ldpc_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001538 if (status == QDF_STATUS_E_FAILURE)
1539 hdd_err("could not set VHT LDPC CODING CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001540 }
1541
1542 /* Get current GI 80 value */
1543 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
1544 &value);
1545
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301546 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001547 hdd_err("could not get SHORT GI 80MHZ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 value = 0;
1549 }
1550
1551 /* set the Guard interval 80MHz */
1552 if (value && !cfg->vht_short_gi_80) {
1553 status = sme_cfg_set_int(hdd_ctx->hHal,
1554 WNI_CFG_VHT_SHORT_GI_80MHZ,
1555 cfg->vht_short_gi_80);
1556
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001557 if (status == QDF_STATUS_E_FAILURE)
1558 hdd_err("could not set SHORT GI 80MHZ to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 }
1560
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561 /* Get VHT TX STBC cap */
1562 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);
1563
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301564 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001565 hdd_err("could not get VHT TX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 value = 0;
1567 }
1568
1569 /* VHT TX STBC cap */
1570 if (value && !cfg->vht_tx_stbc) {
1571 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
1572 cfg->vht_tx_stbc);
1573
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001574 if (status == QDF_STATUS_E_FAILURE)
1575 hdd_err("could not set the VHT TX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576 }
1577
1578 /* Get VHT RX STBC cap */
1579 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);
1580
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301581 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001582 hdd_err("could not get VHT RX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 value = 0;
1584 }
1585
1586 /* VHT RX STBC cap */
1587 if (value && !cfg->vht_rx_stbc) {
1588 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
1589 cfg->vht_rx_stbc);
1590
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001591 if (status == QDF_STATUS_E_FAILURE)
1592 hdd_err("could not set the VHT RX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 }
1594
1595 /* Get VHT SU Beamformer cap */
1596 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1597 &value);
1598
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301599 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001600 hdd_err("could not get VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601 value = 0;
1602 }
1603
1604 /* set VHT SU Beamformer cap */
1605 if (value && !cfg->vht_su_bformer) {
1606 status = sme_cfg_set_int(hdd_ctx->hHal,
1607 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1608 cfg->vht_su_bformer);
1609
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001610 if (status == QDF_STATUS_E_FAILURE)
1611 hdd_err("could not set VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 }
1613
1614 /* check and update SU BEAMFORMEE capabality */
1615 if (pconfig->enableTxBF && !cfg->vht_su_bformee)
1616 pconfig->enableTxBF = cfg->vht_su_bformee;
1617
1618 status = sme_cfg_set_int(hdd_ctx->hHal,
1619 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1620 pconfig->enableTxBF);
1621
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001622 if (status == QDF_STATUS_E_FAILURE)
1623 hdd_err("could not set VHT SU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624
1625 /* Get VHT MU Beamformer cap */
1626 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1627 &value);
1628
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301629 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001630 hdd_err("could not get VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 value = 0;
1632 }
1633
1634 /* set VHT MU Beamformer cap */
1635 if (value && !cfg->vht_mu_bformer) {
1636 status = sme_cfg_set_int(hdd_ctx->hHal,
1637 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1638 cfg->vht_mu_bformer);
1639
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001640 if (status == QDF_STATUS_E_FAILURE)
1641 hdd_err("could not set the VHT MU BEAMFORMER CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 }
1643
1644 /* Get VHT MU Beamformee cap */
1645 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1646 &value);
1647
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301648 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001649 hdd_err("could not get VHT MU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 value = 0;
1651 }
1652
1653 /* set VHT MU Beamformee cap */
1654 if (value && !cfg->vht_mu_bformee) {
1655 status = sme_cfg_set_int(hdd_ctx->hHal,
1656 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1657 cfg->vht_mu_bformee);
1658
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001659 if (status == QDF_STATUS_E_FAILURE)
1660 hdd_err("could not set VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 }
1662
1663 /* Get VHT MAX AMPDU Len exp */
1664 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1665 &value);
1666
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301667 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001668 hdd_err("could not get VHT AMPDU LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 value = 0;
1670 }
1671
1672 /*
1673 * VHT max AMPDU len exp:
1674 * override if user configured value is too high
1675 * that the target cannot support.
1676 * Even though Rome publish ampdu_len=7, it can
1677 * only support 4 because of some h/w bug.
1678 */
1679
1680 if (value > cfg->vht_max_ampdu_len_exp) {
1681 status = sme_cfg_set_int(hdd_ctx->hHal,
1682 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1683 cfg->vht_max_ampdu_len_exp);
1684
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001685 if (status == QDF_STATUS_E_FAILURE)
1686 hdd_err("could not set the VHT AMPDU LEN EXP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001687 }
1688
1689 /* Get VHT TXOP PS CAP */
1690 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);
1691
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301692 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001693 hdd_err("could not get VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001694 value = 0;
1695 }
1696
1697 /* set VHT TXOP PS cap */
1698 if (value && !cfg->vht_txop_ps) {
1699 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
1700 cfg->vht_txop_ps);
1701
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001702 if (status == QDF_STATUS_E_FAILURE)
1703 hdd_err("could not set the VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704 }
1705
1706 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1707 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1708 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1709 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1710 else
1711 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1712
1713
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001714 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
1715 status = sme_cfg_set_int(hdd_ctx->hHal,
1716 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1717 VHT_CAP_160_AND_80P80_SUPP);
1718 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001719 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 band_5g->vht_cap.cap |=
1721 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001722 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1723 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
1724 status = sme_cfg_set_int(hdd_ctx->hHal,
1725 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1726 VHT_CAP_160_SUPP);
1727 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001728 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729 band_5g->vht_cap.cap |=
1730 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001731 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1732 }
1733 pconfig->vhtChannelWidth = QDF_MIN(pconfig->vhtChannelWidth,
1734 ch_width);
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301735 /* Get the current GI 160 value */
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001736 status = sme_cfg_get_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301737 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001738 &value);
1739 if (status != QDF_STATUS_SUCCESS) {
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301740 hdd_err("could not get GI 80 & 160");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001741 value = 0;
1742 }
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301743 /* set the Guard interval 160MHz */
1744 if (value && !cfg->vht_short_gi_160) {
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001745 status = sme_cfg_set_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301746 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
1747 cfg->vht_short_gi_160);
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001748
1749 if (status == QDF_STATUS_E_FAILURE)
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301750 hdd_err("failed to set SHORT GI 160MHZ");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001751 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001753 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001755 hdd_debug("VHT RxLDPC capability is set");
1756 } else {
1757 /*
1758 * Get the RX LDPC capability for the NON DBS
1759 * hardware mode for 5G band
1760 */
1761 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1762 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1763 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1764 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1765 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1766 hdd_debug("VHT RX LDPC capability is set");
1767 }
1768 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001769
1770 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1771 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1772 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1773 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1774
1775 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1776 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1777
1778 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1779 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1780 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1781 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1782 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1783 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1784
1785 band_5g->vht_cap.cap |=
1786 (cfg->vht_max_ampdu_len_exp <<
1787 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1788
1789 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1790 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1791 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1792 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1793 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1794 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1795 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1796 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1797
1798 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1799 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1800
1801}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001803/**
1804 * hdd_generate_macaddr_auto() - Auto-generate mac address
1805 * @hdd_ctx: Pointer to the HDD context
1806 *
1807 * Auto-generate mac address using device serial number.
1808 * Keep the first 3 bytes of OUI as before and replace
1809 * the last 3 bytes with the lower 3 bytes of serial number.
1810 *
1811 * Return: 0 for success
1812 * Non zero failure code for errors
1813 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001814static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001815{
1816 unsigned int serialno = 0;
1817 struct qdf_mac_addr mac_addr = {
1818 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1819 };
1820
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001821 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001822 if (serialno == 0)
1823 return -EINVAL;
1824
1825 serialno &= 0x00ffffff;
1826
1827 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1828 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1829 mac_addr.bytes[5] = serialno & 0xff;
1830
1831 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1832 return 0;
1833}
1834
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301835/**
1836 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1837 * configuration to cfg_ini in HDD
1838 * @hdd_ctx: Pointer to hdd_ctx
1839 * @cfg: target configuration
1840 *
1841 * Return: None
1842 */
1843#ifdef FEATURE_WLAN_RA_FILTERING
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001844static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301845 struct wma_tgt_cfg *cfg)
1846{
1847 hdd_ctx->config->IsRArateLimitEnabled = cfg->is_ra_rate_limit_enabled;
1848}
1849#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001850static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301851 struct wma_tgt_cfg *cfg)
1852{
1853}
1854#endif
1855
Jeff Johnson8abc5932018-06-02 22:51:37 -07001856void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001858 int ret;
Jeff Johnson8abc5932018-06-02 22:51:37 -07001859 struct hdd_context *hdd_ctx = (struct hdd_context *)hdd_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 uint8_t temp_band_cap;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001861 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301862 uint8_t antenna_mode;
Arif Hussainee10f902017-12-27 16:30:17 -08001863 QDF_STATUS status;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301864
Dustin Brownbd68fe12017-11-21 15:28:52 -08001865 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1866 if (ret) {
1867 hdd_err("Failed to create pdev; errno:%d", ret);
1868 QDF_BUG(0);
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07001869 } else {
Dustin Brownbd68fe12017-11-21 15:28:52 -08001870 hdd_debug("New pdev has been created with pdev_id = %u",
Arif Hussainee10f902017-12-27 16:30:17 -08001871 hdd_ctx->hdd_pdev->pdev_objmgr.wlan_pdev_id);
Amar Singhal410675c2018-01-10 12:14:21 -08001872 if (dispatcher_pdev_open(hdd_ctx->hdd_pdev)) {
1873 hdd_err("dispatcher pdev open failed");
1874 QDF_BUG(0);
1875 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301876 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001877
Jeff Johnsone8846ab2018-03-31 11:54:45 -07001878 ret = hdd_green_ap_update_config(hdd_ctx);
Himanshu Agarwalb229a142017-12-21 10:16:45 +05301879
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301880 ucfg_ipa_set_dp_handle(hdd_ctx->hdd_psoc,
1881 cds_get_context(QDF_MODULE_ID_SOC));
1882 ucfg_ipa_set_txrx_handle(hdd_ctx->hdd_psoc,
1883 cds_get_context(QDF_MODULE_ID_TXRX));
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301884 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->hdd_pdev,
1885 hdd_softap_hard_start_xmit);
1886 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->hdd_pdev,
1887 hdd_ipa_send_skb_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301888
Naveen Rawat64e477e2016-05-20 10:34:56 -07001889 if (cds_cfg) {
1890 if (hdd_ctx->config->enable_sub_20_channel_width !=
1891 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
1892 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1893 cds_cfg->sub_20_channel_width =
1894 WLAN_SUB_20_CH_WIDTH_NONE;
1895 } else {
1896 cds_cfg->sub_20_channel_width =
1897 hdd_ctx->config->enable_sub_20_channel_width;
1898 }
1899 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001900
1901 /* first store the INI band capability */
1902 temp_band_cap = hdd_ctx->config->nBandCapability;
1903
1904 hdd_ctx->config->nBandCapability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301905 hdd_ctx->is_fils_roaming_supported =
1906 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05301908 hdd_ctx->config->is_11k_offload_supported =
1909 cfg->services.is_11k_offload_supported;
1910
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001911 /*
1912 * now overwrite the target band capability with INI
1913 * setting if INI setting is a subset
1914 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001915
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001916 if ((hdd_ctx->config->nBandCapability == BAND_ALL) &&
1917 (temp_band_cap != BAND_ALL))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918 hdd_ctx->config->nBandCapability = temp_band_cap;
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001919 else if ((hdd_ctx->config->nBandCapability != BAND_ALL) &&
1920 (temp_band_cap != BAND_ALL) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001921 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001922 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923 }
1924
Amar Singhal58b45ef2017-08-01 13:43:54 -07001925 hdd_ctx->curr_band = hdd_ctx->config->nBandCapability;
1926
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301927 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928 hdd_ctx->reg.reg_domain = cfg->reg_domain;
1929 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
1930 }
1931
1932 /* This can be extended to other configurations like ht, vht cap... */
1933
Anurag Chouhanc5548422016-02-24 18:33:27 +05301934 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001936 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001937 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001938 static struct qdf_mac_addr default_mac_addr = {
1939 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
1940 };
1941 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
1942 &default_mac_addr)) {
1943 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
1944 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
1945 MAC_ADDRESS_STR,
1946 MAC_ADDR_ARRAY(hdd_ctx->config->
1947 intfMacAddr[0].bytes));
1948 } else {
1949 hdd_err("Invalid MAC passed from target, using MAC from ini file "
1950 MAC_ADDRESS_STR,
1951 MAC_ADDR_ARRAY(hdd_ctx->config->
1952 intfMacAddr[0].bytes));
1953 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001954 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955 }
1956
1957 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07001958 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001959
Ryan Hsuc6918552018-05-16 13:29:59 -07001960 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
1961 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
1962 sizeof(cfg->hw_bd_info));
1963
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 hdd_ctx->max_intf_count = cfg->max_intf_count;
1965
Jeff Johnsonc875e242016-09-23 18:12:34 -07001966 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001967
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
1969 hdd_update_tgt_services(hdd_ctx, &cfg->services);
1970
1971 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
1972
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07001974 if (cfg->services.en_11ax) {
1975 hdd_info("11AX: 11ax is enabled - update HDD config");
1976 hdd_update_tgt_he_cap(hdd_ctx, cfg);
1977 }
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07001978
1979 hdd_update_vdev_nss(hdd_ctx);
1980
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301981 hdd_update_hw_dbs_capable(hdd_ctx);
1982
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08001983 hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
Krunal Sonie3531942016-04-12 17:43:53 -07001984 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001985 hdd_debug("fine_time_meas_cap: 0x%x",
Arif Hussainee10f902017-12-27 16:30:17 -08001986 hdd_ctx->config->fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001987
Nitesh Shahe50711f2017-04-26 16:30:45 +05301988 antenna_mode = (hdd_ctx->config->enable2x2 == 0x01) ?
1989 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
1990 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001991 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08001992 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001993
Rajeev Kumardd3bc602016-08-16 14:21:05 -07001994 hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
1995 hdd_ctx->config->bpf_packet_filter_enable);
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05301996 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301997 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301998
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05301999 if ((hdd_ctx->config->txBFCsnValue >
Arif Hussainee10f902017-12-27 16:30:17 -08002000 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
2001 !cfg->tx_bfee_8ss_enabled)
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302002 hdd_ctx->config->txBFCsnValue =
2003 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF;
2004
Arif Hussainee10f902017-12-27 16:30:17 -08002005 status = sme_cfg_set_int(hdd_ctx->hHal,
2006 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
2007 hdd_ctx->config->txBFCsnValue);
2008 if (QDF_IS_STATUS_ERROR(status))
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302009 hdd_err("fw update WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED to CFG fails");
2010
2011
2012 hdd_debug("Target BPF %d Host BPF %d 8ss fw support %d txBFCsnValue %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002013 cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable,
2014 cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302015
2016 /*
2017 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2018 */
2019 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302020
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302021 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2022
Yue Macd359b72017-10-03 15:21:00 -07002023 /*
2024 * This needs to be done after HDD pdev is created and stored since
2025 * it will access the HDD pdev object lock.
2026 */
2027 hdd_runtime_suspend_context_init(hdd_ctx);
2028
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002029 /* Configure NAN datapath features */
2030 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07002031 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002032 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Arif Hussainee10f902017-12-27 16:30:17 -08002033 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_OBSS_DETECTION_OFFLOAD,
2034 cfg->obss_detection_offloaded);
2035 if (QDF_IS_STATUS_ERROR(status))
2036 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002037
2038 status = sme_cfg_set_int(hdd_ctx->hHal,
2039 WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
2040 cfg->obss_color_collision_offloaded);
2041 if (QDF_IS_STATUS_ERROR(status))
2042 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043}
2044
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002045bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046{
Jeff Johnson9d295242017-08-29 14:39:48 -07002047 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002048 struct hdd_ap_ctx *ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002049
Jiachao Wuf610d912018-01-23 17:47:32 +08002050 if (!hdd_ctx) {
2051 hdd_info("Couldn't get hdd_ctx");
2052 return true;
2053 }
2054
2055 if (hdd_ctx->config->disableDFSChSwitch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002056 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussaincd151632017-02-11 16:57:19 -08002057 hdd_ctx, hdd_ctx->config->disableDFSChSwitch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302058 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002059 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060
Dustin Brown920397d2017-12-13 16:27:50 -08002061 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002062 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2063
2064 if ((QDF_SAP_MODE == adapter->device_mode ||
2065 QDF_P2P_GO_MODE == adapter->device_mode) &&
bings0e03a982018-05-09 08:40:59 +08002066 (wlan_reg_is_passive_or_disable_ch(hdd_ctx->hdd_pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002067 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002068 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2069 true;
2070 hdd_info("tx blocked for session: %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07002071 adapter->session_id);
bings0e03a982018-05-09 08:40:59 +08002072 cdp_fc_vdev_flush(cds_get_context(QDF_MODULE_ID_SOC),
2073 adapter->txrx_vdev);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302074 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002075 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302076
2077 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002078}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002079
2080/**
2081 * hdd_is_valid_mac_address() - validate MAC address
2082 * @pMacAddr: Pointer to the input MAC address
2083 *
2084 * This function validates whether the given MAC address is valid or not
2085 * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
2086 * where X is the hexa decimal digit character and separated by ':'
2087 * This algorithm works even if MAC address is not separated by ':'
2088 *
2089 * This code checks given input string mac contains exactly 12 hexadecimal
2090 * digits and a separator colon : appears in the input string only after
2091 * an even number of hex digits.
2092 *
2093 * Return: 1 for valid and 0 for invalid
2094 */
2095bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
2096{
2097 int xdigit = 0;
2098 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002099
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 while (*pMacAddr) {
2101 if (isxdigit(*pMacAddr)) {
2102 xdigit++;
2103 } else if (':' == *pMacAddr) {
2104 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2105 break;
2106
2107 ++separator;
2108 } else {
2109 /* Invalid MAC found */
2110 return 0;
2111 }
2112 ++pMacAddr;
2113 }
2114 return xdigit == 12 && (separator == 5 || separator == 0);
2115}
2116
2117/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302118 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2119 * @dev: Handle to struct net_device to be updated.
2120 *
2121 * Return: None
2122 */
2123static void hdd_mon_mode_ether_setup(struct net_device *dev)
2124{
2125 dev->header_ops = NULL;
2126 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2127 dev->hard_header_len = ETH_HLEN;
2128 dev->mtu = ETH_DATA_LEN;
2129 dev->addr_len = ETH_ALEN;
2130 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2131 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2132 dev->priv_flags |= IFF_TX_SKB_SHARING;
2133
2134 memset(dev->broadcast, 0xFF, ETH_ALEN);
2135}
2136
2137/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002138 * __hdd__mon_open() - HDD Open function
2139 * @dev: Pointer to net_device structure
2140 *
2141 * This is called in response to ifconfig up
2142 *
2143 * Return: 0 for success; non-zero for failure
2144 */
2145static int __hdd_mon_open(struct net_device *dev)
2146{
2147 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002148 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2149 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002150
Dustin Brownfdf17c12018-03-14 12:55:34 -07002151 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002152
2153 ret = wlan_hdd_validate_context(hdd_ctx);
2154 if (ret)
2155 return ret;
2156
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302157 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002158
2159 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Browne7e71d32018-05-11 16:00:08 -07002160 ret = hdd_wlan_start_modules(hdd_ctx, false);
Ravi Joshia307f632017-07-17 23:41:41 -07002161 if (ret) {
2162 hdd_err("Failed to start WLAN modules return");
2163 return ret;
2164 }
2165 hdd_err("hdd_wlan_start_modules() successful !");
2166
2167 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2168 ret = hdd_start_adapter(adapter);
2169 if (ret) {
2170 hdd_err("Failed to start adapter :%d",
2171 adapter->device_mode);
2172 return ret;
2173 }
2174 hdd_err("hdd_start_adapters() successful !");
2175 }
2176 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2177 }
2178
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002179 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002180
2181 if (!ret)
2182 ret = hdd_enable_monitor_mode(dev);
2183
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002184 return ret;
2185}
2186
2187/**
2188 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2189 * @dev: Pointer to net_device structure
2190 *
2191 * This is called in response to ifconfig up
2192 *
2193 * Return: 0 for success; non-zero for failure
2194 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002195static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002196{
2197 int ret;
2198
2199 cds_ssr_protect(__func__);
2200 ret = __hdd_mon_open(dev);
2201 cds_ssr_unprotect(__func__);
2202
2203 return ret;
2204}
2205
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002206static QDF_STATUS
2207wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2208{
2209 struct policy_mgr_dual_mac_config cfg = {0};
2210 QDF_STATUS status;
2211 uint32_t channel_select_logic_conc;
2212 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2213
2214 if (!hdd_ctx) {
2215 hdd_err("HDD context is NULL");
2216 return QDF_STATUS_E_FAILURE;
2217 }
2218
2219
2220 if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc))
2221 return QDF_STATUS_SUCCESS;
2222
2223 cfg.scan_config = 0;
2224 cfg.fw_mode_config = 0;
2225 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
2226
2227 channel_select_logic_conc = hdd_ctx->config->
2228 channel_select_logic_conc;
2229
2230 if (hdd_ctx->config->dual_mac_feature_disable !=
2231 DISABLE_DBS_CXN_AND_SCAN) {
2232 status = policy_mgr_get_updated_scan_and_fw_mode_config(
2233 hdd_ctx->hdd_psoc, &cfg.scan_config,
2234 &cfg.fw_mode_config,
2235 hdd_ctx->config->dual_mac_feature_disable,
2236 channel_select_logic_conc);
2237
2238 if (status != QDF_STATUS_SUCCESS) {
2239 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2240 status);
2241 return status;
2242 }
2243 }
2244
2245 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2246 cfg.scan_config, cfg.fw_mode_config);
2247
2248 status = sme_soc_set_dual_mac_config(cfg);
2249 if (status != QDF_STATUS_SUCCESS) {
2250 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2251 return status;
2252 }
2253
2254 return QDF_STATUS_SUCCESS;
2255}
2256
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002257/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302258 * hdd_start_adapter() - Wrapper function for device specific adapter
2259 * @adapter: pointer to HDD adapter
2260 *
2261 * This function is called to start the device specific adapter for
2262 * the mode passed in the adapter's device_mode.
2263 *
2264 * Return: 0 for success; non-zero for failure
2265 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002266int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302267{
2268
2269 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002270 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302271
Dustin Brownfdf17c12018-03-14 12:55:34 -07002272 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002273 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302274
2275 switch (device_mode) {
2276 case QDF_P2P_CLIENT_MODE:
2277 case QDF_P2P_DEVICE_MODE:
2278 case QDF_OCB_MODE:
2279 case QDF_STA_MODE:
2280 case QDF_MONITOR_MODE:
2281 ret = hdd_start_station_adapter(adapter);
2282 if (ret)
2283 goto err_start_adapter;
2284 break;
2285 case QDF_P2P_GO_MODE:
2286 case QDF_SAP_MODE:
2287 ret = hdd_start_ap_adapter(adapter);
2288 if (ret)
2289 goto err_start_adapter;
2290 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302291 case QDF_IBSS_MODE:
2292 /*
2293 * For IBSS interface is initialized as part of
2294 * hdd_init_station_mode()
2295 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002296 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302297 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002298 /* vdevs are dynamically managed by firmware in FTM */
2299 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302300 default:
2301 hdd_err("Invalid session type %d", device_mode);
2302 QDF_ASSERT(0);
2303 goto err_start_adapter;
2304 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002305
Arun Khandavallifae92942016-08-01 13:31:08 +05302306 if (hdd_set_fw_params(adapter))
2307 hdd_err("Failed to set the FW params for the adapter!");
2308
Dustin Browne7e71d32018-05-11 16:00:08 -07002309 if (adapter->session_id != HDD_SESSION_ID_INVALID) {
2310 ret = wlan_hdd_cfg80211_register_frames(adapter);
2311 if (ret < 0) {
2312 hdd_err("Failed to register frames - ret %d", ret);
2313 goto err_start_adapter;
2314 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302315 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002316
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002317 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302318
Dustin Browndb2a8be2017-12-20 11:49:56 -08002319exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002320 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002321
Arun Khandavallifae92942016-08-01 13:31:08 +05302322 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002323
Arun Khandavallifae92942016-08-01 13:31:08 +05302324err_start_adapter:
2325 return -EINVAL;
2326}
2327
2328/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302329 * hdd_enable_power_management() - API to Enable Power Management
2330 *
2331 * API invokes Bus Interface Layer power management functionality
2332 *
2333 * Return: None
2334 */
2335static void hdd_enable_power_management(void)
2336{
2337 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2338
2339 if (!hif_ctx) {
2340 hdd_err("Bus Interface Context is Invalid");
2341 return;
2342 }
2343
2344 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2345}
2346
2347/**
2348 * hdd_disable_power_management() - API to disable Power Management
2349 *
2350 * API disable Bus Interface Layer Power management functionality
2351 *
2352 * Return: None
2353 */
2354static void hdd_disable_power_management(void)
2355{
2356 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2357
2358 if (!hif_ctx) {
2359 hdd_err("Bus Interface Context is Invalid");
2360 return;
2361 }
2362
2363 hif_disable_power_management(hif_ctx);
2364}
2365
Ryan Hsuaadba072018-04-20 13:01:53 -07002366void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302367{
2368 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002369 size_t target_hw_name_len;
2370 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002371 uint8_t *buf;
2372 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302373
2374 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2375 if (!hif_sc) {
2376 hdd_err("HIF context is NULL");
2377 return;
2378 }
2379
Ryan Hsuaadba072018-04-20 13:01:53 -07002380 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302381 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002382 &target_hw_name);
2383
2384 if (hdd_ctx->target_hw_name)
2385 qdf_mem_free(hdd_ctx->target_hw_name);
2386
2387 target_hw_name_len = strlen(target_hw_name) + 1;
2388 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2389 if (hdd_ctx->target_hw_name)
2390 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2391 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302392
Ryan Hsuaadba072018-04-20 13:01:53 -07002393 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2394 if (buf) {
2395 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2396 hdd_info("%s", buf);
2397 qdf_mem_free(buf);
2398 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302399}
2400
2401/**
gbian62edd7e2017-03-07 13:12:13 +08002402 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2403 * @hdd_ctx: Pointer to hdd context
2404 *
2405 * Return: none
2406 */
2407static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002408hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002409{
2410 uint8_t num_entries = 0;
2411 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
2412 uint8_t *tx_sched_wrr_ac;
2413 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002414 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002415
2416 if (NULL == hdd_ctx)
2417 return;
2418
2419 if (NULL == hdd_ctx->config) {
2420 /* Do nothing if hdd_ctx is invalid */
2421 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2422 return;
2423 }
2424
2425 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2426
2427 if (!cds_ctx) {
2428 hdd_err("Invalid CDS Context");
2429 return;
2430 }
2431
2432 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
2433 switch (i) {
2434 case OL_TX_WMM_AC_BE:
2435 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_be;
2436 break;
2437 case OL_TX_WMM_AC_BK:
2438 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_bk;
2439 break;
2440 case OL_TX_WMM_AC_VI:
2441 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vi;
2442 break;
2443 case OL_TX_WMM_AC_VO:
2444 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vo;
2445 break;
2446 default:
2447 tx_sched_wrr_ac = NULL;
2448 break;
2449 }
2450
2451 hdd_string_to_u8_array(tx_sched_wrr_ac,
2452 tx_sched_wrr_param,
2453 &num_entries,
2454 sizeof(tx_sched_wrr_param));
2455
2456 if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
2457 cds_ctx->ac_specs[i].wrr_skip_weight =
2458 tx_sched_wrr_param[0];
2459 cds_ctx->ac_specs[i].credit_threshold =
2460 tx_sched_wrr_param[1];
2461 cds_ctx->ac_specs[i].send_limit =
2462 tx_sched_wrr_param[2];
2463 cds_ctx->ac_specs[i].credit_reserve =
2464 tx_sched_wrr_param[3];
2465 cds_ctx->ac_specs[i].discard_weight =
2466 tx_sched_wrr_param[4];
2467 }
2468
2469 num_entries = 0;
2470 }
2471}
2472
Ryan Hsuaadba072018-04-20 13:01:53 -07002473uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2474 const size_t version_len, uint8_t *version)
2475{
2476 uint32_t size;
2477 uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0, sub_id = 0;
2478
2479 if (!hdd_ctx) {
2480 hdd_err("Invalid context, HDD context is null");
2481 return 0;
2482 }
2483
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302484 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002485 hdd_err("Invalid buffer pointr or buffer len\n");
2486 return 0;
2487 }
2488
2489 msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
2490 mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
2491 siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
2492 crmid = hdd_ctx->target_fw_version & 0x7fff;
2493 sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
2494
2495 size = scnprintf(version, version_len,
Ryan Hsuc6918552018-05-16 13:29:59 -07002496 "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 -07002497 QWLAN_VERSIONSTR,
2498 msp_id, mspid, siid, crmid, sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002499 hdd_ctx->target_hw_name,
2500 hdd_ctx->hw_bd_info.bdf_version,
2501 hdd_ctx->hw_bd_info.ref_design_id,
2502 hdd_ctx->hw_bd_info.customer_id,
2503 hdd_ctx->hw_bd_info.project_id,
2504 hdd_ctx->hw_bd_info.board_data_rev);
Ryan Hsuaadba072018-04-20 13:01:53 -07002505
2506 return size;
2507}
2508
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302509#ifdef IPA_OFFLOAD
2510/**
2511 * hdd_update_ipa_component_config() - update ipa config
2512 * @hdd_ctx: Pointer to hdd context
2513 *
2514 * Return: none
2515 */
2516static void hdd_update_ipa_component_config(struct hdd_context *hdd_ctx)
2517{
2518 struct hdd_config *cfg = hdd_ctx->config;
2519 struct wlan_ipa_config ipa_cfg;
2520
2521 ipa_cfg.ipa_config = cfg->IpaConfig;
2522 ipa_cfg.desc_size = cfg->IpaDescSize;
2523 ipa_cfg.txbuf_count = cfg->IpaUcTxBufCount;
2524 ipa_cfg.bus_bw_high = cfg->busBandwidthHighThreshold;
2525 ipa_cfg.bus_bw_medium = cfg->busBandwidthMediumThreshold;
2526 ipa_cfg.bus_bw_low = cfg->busBandwidthLowThreshold;
2527 ipa_cfg.ipa_bw_high = cfg->IpaHighBandwidthMbps;
2528 ipa_cfg.ipa_bw_medium = cfg->IpaMediumBandwidthMbps;
2529 ipa_cfg.ipa_bw_low = cfg->IpaLowBandwidthMbps;
2530
2531 ucfg_ipa_update_config(&ipa_cfg);
2532}
2533#else
2534static void hdd_update_ipa_component_config(struct hdd_context *hdd_ctx)
2535{
2536}
2537#endif
2538
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002539#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002540static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2541 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2542{
Jeff Johnson9d295242017-08-29 14:39:48 -07002543 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002544 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002545
2546 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2547 if (!adapter) {
2548 hdd_err("Adapter is NULL");
2549 return PM_MAX_NUM_OF_MODE;
2550 }
2551
2552 return policy_mgr_convert_device_mode_to_qdf_type(
2553 adapter->device_mode);
2554}
2555
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002556static void hdd_register_policy_manager_callback(
2557 struct wlan_objmgr_psoc *psoc)
2558{
2559 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002560
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002561 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002562 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002563 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2564 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002565 hdd_cbacks.get_mode_for_non_connected_vdev =
2566 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302567 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002568
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002569 if (QDF_STATUS_SUCCESS !=
2570 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2571 hdd_err("HDD callback registration with policy manager failed");
2572 }
2573}
2574#else
2575static void hdd_register_policy_manager_callback(
2576 struct wlan_objmgr_psoc *psoc)
2577{
2578}
2579#endif
2580
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002581static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002582{
2583 struct nan_callbacks cb_obj = {0};
2584
2585 cb_obj.ndi_open = hdd_ndi_open;
2586 cb_obj.ndi_close = hdd_ndi_close;
2587 cb_obj.ndi_start = hdd_ndi_start;
2588 cb_obj.ndi_delete = hdd_ndi_delete;
2589 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2590 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2591
Naveen Rawat37f62c82017-03-26 22:24:43 -07002592 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2593 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002594 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002595
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002596 os_if_nan_register_hdd_callbacks(hdd_ctx->hdd_psoc, &cb_obj);
2597}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002598
Dustin Brown26b3d042017-12-21 11:13:27 -08002599#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002600/**
2601 * hdd_check_for_leaks() - Perform runtime memory leak checks
2602 *
2603 * This API triggers runtime memory leak detection. This feature enforces the
2604 * policy that any memory allocated at runtime must also be released at runtime.
2605 *
2606 * Allocating memory at runtime and releasing it at unload is effectively a
2607 * memory leak for configurations which never unload (e.g. LONU, statically
2608 * compiled driver). Such memory leaks are NOT false positives, and must be
2609 * fixed.
2610 *
2611 * Return: None
2612 */
Dustin Brown4bc0a622017-12-06 15:56:50 -08002613static void hdd_check_for_leaks(void)
2614{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002615 /* DO NOT REMOVE these checks; for false positives, read above first */
2616
Dustin Brown677e0862017-10-10 16:30:09 -07002617 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08002618 qdf_nbuf_map_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08002619 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002620}
2621
Dustin Brown26b3d042017-12-21 11:13:27 -08002622#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
2623#else
2624static inline void hdd_check_for_leaks(void) {}
2625
2626#define hdd_debug_domain_set(domain)
2627#endif /* CONFIG_LEAK_DETECTION */
2628
gbian62edd7e2017-03-07 13:12:13 +08002629/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08002630 * hdd_update_country_code - Update country code
2631 * @hdd_ctx: HDD context
2632 *
2633 * Update country code based on module parameter country_code
2634 *
2635 * Return: 0 on success and errno on failure
2636 */
2637static int hdd_update_country_code(struct hdd_context *hdd_ctx)
2638{
2639 if (!country_code)
2640 return 0;
2641
2642 return hdd_reg_set_country(hdd_ctx, country_code);
2643}
2644
2645/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302646 * hdd_wlan_start_modules() - Single driver state machine for starting modules
2647 * @hdd_ctx: HDD context
Arun Khandavallifae92942016-08-01 13:31:08 +05302648 * @reinit: flag to indicate from SSR or normal path
2649 *
2650 * This function maintains the driver state machine it will be invoked from
2651 * startup, reinit and change interface. Depending on the driver state shall
2652 * perform the opening of the modules.
2653 *
2654 * Return: 0 for success; non-zero for failure
2655 */
Dustin Browne7e71d32018-05-11 16:00:08 -07002656int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05302657{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002658 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302659 qdf_device_t qdf_dev;
2660 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302661 bool unint = false;
2662 void *hif_ctx;
Jingxiang Ge95912f82018-04-19 12:01:26 +08002663 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +05302664
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002665 hdd_debug("state:%d reinit:%d", hdd_ctx->driver_status, reinit);
Arun Khandavallifae92942016-08-01 13:31:08 +05302666
2667 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2668 if (!qdf_dev) {
2669 hdd_err("QDF Device Context is Invalid return");
2670 return -EINVAL;
2671 }
2672
Dustin Brown6f427922017-09-19 12:19:00 -07002673 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Arun Khandavallifae92942016-08-01 13:31:08 +05302674
Dustin Brown1fe30a82017-10-03 16:13:36 -07002675 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302676 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
2677 mutex_unlock(&hdd_ctx->iface_change_lock);
2678 hdd_info("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07002679 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302680 return 0;
2681 }
2682
Dustin Brown1fe30a82017-10-03 16:13:36 -07002683 hdd_ctx->start_modules_in_progress = true;
2684
Arun Khandavallifae92942016-08-01 13:31:08 +05302685 switch (hdd_ctx->driver_status) {
2686 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002687 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302688 unint = true;
2689 /* Fall through dont add break here */
2690 case DRIVER_MODULES_CLOSED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002691 hdd_info("Wlan transitioning (CLOSED -> OPENED)");
2692
Dustin Brown26b3d042017-12-21 11:13:27 -08002693 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002694
Arun Khandavallifae92942016-08-01 13:31:08 +05302695 if (!reinit && !unint) {
2696 ret = pld_power_on(qdf_dev->dev);
2697 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002698 hdd_err("Failed to Powerup the device; errno: %d",
2699 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302700 goto release_lock;
2701 }
2702 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002703
2704 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2705 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05302706 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2707 qdf_dev->bus_type,
2708 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2709 HIF_ENABLE_TYPE_PROBE);
2710 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002711 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302712 goto power_down;
2713 }
2714
2715 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302716 if (!hif_ctx) {
2717 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002718 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302719 goto power_down;
2720 }
2721
Arun Khandavallifae92942016-08-01 13:31:08 +05302722 status = ol_cds_init(qdf_dev, hif_ctx);
2723 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002724 hdd_err("No Memory to Create BMI Context; status: %d",
2725 status);
2726 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302727 goto hif_close;
2728 }
2729
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302730 hdd_update_ipa_component_config(hdd_ctx);
2731
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002732 ret = hdd_update_config(hdd_ctx);
2733 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002734 hdd_err("Failed to update configuration; errno: %d",
2735 ret);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002736 goto cds_free;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002737 }
2738
gbian62edd7e2017-03-07 13:12:13 +08002739 hdd_update_cds_ac_specs_params(hdd_ctx);
2740
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302741 status = cds_open(hdd_ctx->hdd_psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002742 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002743 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002744 ret = qdf_status_to_os_return(status);
2745 goto deinit_config;
Arun Khandavallifae92942016-08-01 13:31:08 +05302746 }
2747
Jeff Johnson79e36882018-05-06 17:15:33 -07002748 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05302749 ret = hdd_update_components_config(hdd_ctx);
2750 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002751 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302752 ret);
2753 goto close;
2754 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002755 status = cds_dp_open(hdd_ctx->hdd_psoc);
2756 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002757 hdd_err("Failed to Open cds post open; status: %d",
2758 status);
2759 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002760 goto close;
2761 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302762
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002763 /*
2764 * NAN compoenet requires certian operations like, open adapter,
2765 * close adapter, etc. to be initiated by HDD, for those
2766 * register HDD callbacks with UMAC's NAN componenet.
2767 */
2768 hdd_nan_register_callbacks(hdd_ctx);
2769
Arun Khandavallifae92942016-08-01 13:31:08 +05302770 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
2771
Jeff Johnson3a280122017-09-13 07:42:00 -07002772 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302773 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002774 hdd_err("Failed to pre-enable CDS; status: %d", status);
2775 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002776 goto cds_txrx_free;
Arun Khandavallifae92942016-08-01 13:31:08 +05302777 }
2778
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002779 hdd_register_policy_manager_callback(
2780 hdd_ctx->hdd_psoc);
2781
Amar Singhal0928b192017-12-01 10:50:54 -08002782 hdd_sysfs_create_version_interface(hdd_ctx->hdd_psoc);
2783
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302784 hdd_update_hw_sw_info(hdd_ctx);
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05302785 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002786 hdd_info("Wlan transitioned (now OPENED)");
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302787
Arun Khandavallifae92942016-08-01 13:31:08 +05302788 if (unint) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002789 hdd_debug("In phase-1 initialization don't enable modules");
Arun Khandavallifae92942016-08-01 13:31:08 +05302790 break;
2791 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302792
Arun Khandavallifae92942016-08-01 13:31:08 +05302793 /* Fall through dont add break here */
2794 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002795 hdd_info("Wlan transitioning (OPENED -> ENABLED)");
2796
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302797 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2798 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002799 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302800 break;
2801 }
Dustin Browndca39692017-11-09 15:30:25 -08002802
Dustin Browne7e71d32018-05-11 16:00:08 -07002803 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08002804 if (ret) {
2805 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002806 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302807 }
Dustin Browndca39692017-11-09 15:30:25 -08002808
Komal Seelamf2136bb2016-09-28 18:30:44 +05302809 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08002810
Arun Khandavallifae92942016-08-01 13:31:08 +05302811 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002812 hdd_info("Wlan transitioned (now ENABLED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302813 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08002814
Arun Khandavallifae92942016-08-01 13:31:08 +05302815 default:
2816 hdd_err("WLAN start invoked in wrong state! :%d\n",
2817 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08002818 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05302819 goto release_lock;
2820 }
Dustin Brown550f6d22017-12-14 15:44:01 -08002821
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302822 hdd_ctx->start_modules_in_progress = false;
Paul Zhange03cf4c2018-01-19 18:33:22 +08002823 if (DRIVER_MODULES_ENABLED == hdd_ctx->driver_status) {
2824 ret = hdd_update_country_code(hdd_ctx);
2825 if (ret)
2826 hdd_err("Failed to update command line country code!");
2827 }
Arun Khandavallifae92942016-08-01 13:31:08 +05302828 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown550f6d22017-12-14 15:44:01 -08002829
Dustin Browne74003f2018-03-14 12:51:58 -07002830 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08002831
Arun Khandavallifae92942016-08-01 13:31:08 +05302832 return 0;
2833
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002834post_disable:
Rajeev Kumarbe021242017-02-16 16:12:23 -08002835 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002836
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002837cds_txrx_free:
Jingxiang Ge95912f82018-04-19 12:01:26 +08002838 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->hdd_psoc);
2839
2840 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) {
2841 hdd_runtime_suspend_context_deinit(hdd_ctx);
2842 dispatcher_pdev_close(hdd_ctx->hdd_pdev);
2843 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
2844 }
2845
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002846 cds_dp_close(hdd_ctx->hdd_psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08002847
Arun Khandavallifae92942016-08-01 13:31:08 +05302848close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002849 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002850 hdd_info("Wlan transition aborted (now CLOSED)");
2851
Jeff Johnsone4b14592017-09-13 14:23:33 -07002852 cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05302853
Dustin Brown28b17892017-10-10 13:29:38 -07002854deinit_config:
2855 cds_deinit_ini_config();
2856
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002857cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05302858 ol_cds_free();
2859
2860hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002861 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2862 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302863power_down:
2864 if (!reinit && !unint)
2865 pld_power_off(qdf_dev->dev);
2866release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302867 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302868 mutex_unlock(&hdd_ctx->iface_change_lock);
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05302869 if (hdd_ctx->target_hw_name) {
2870 qdf_mem_free(hdd_ctx->target_hw_name);
2871 hdd_ctx->target_hw_name = NULL;
2872 }
Dustin Brown4bc0a622017-12-06 15:56:50 -08002873 /* many adapter resources are not freed by design in SSR case */
2874 if (!reinit)
2875 hdd_check_for_leaks();
Dustin Brown26b3d042017-12-21 11:13:27 -08002876 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002877
Dustin Browne74003f2018-03-14 12:51:58 -07002878 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002879
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002880 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05302881}
2882
Naveen Rawat910726a2017-03-06 11:42:51 -08002883#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002884static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002885{
2886 int ret = os_if_wifi_pos_register_nl();
2887
2888 if (ret)
2889 hdd_err("os_if_wifi_pos_register_nl failed");
2890
2891 return ret;
2892}
2893
2894static int hdd_deactivate_wifi_pos(void)
2895{
2896 int ret = os_if_wifi_pos_deregister_nl();
2897
2898 if (ret)
2899 hdd_err("os_if_wifi_pos_deregister_nl failed");
2900
2901 return ret;
2902}
2903
2904/**
2905 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
2906 * @hdd_ctx: hdd context
2907 *
2908 * Return: status of operation
2909 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002910static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002911{
2912 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
2913 struct hdd_config *cfg = hdd_ctx->config;
2914
2915 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
2916 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
2917 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
2918 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
2919 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
2920 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
2921 wifi_pos_set_dwell_time_min(psoc, cfg->nNeighborScanMinChanTime);
2922 wifi_pos_set_dwell_time_max(psoc, cfg->nNeighborScanMaxChanTime);
2923}
2924#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002925static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002926{
2927 return oem_activate_service(hdd_ctx);
2928}
2929
2930static int hdd_deactivate_wifi_pos(void)
2931{
2932 return 0;
2933}
2934
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002935static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002936{
2937}
2938#endif
2939
Arun Khandavallifae92942016-08-01 13:31:08 +05302940/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002941 * __hdd_open() - HDD Open function
2942 * @dev: Pointer to net_device structure
2943 *
2944 * This is called in response to ifconfig up
2945 *
2946 * Return: 0 for success; non-zero for failure
2947 */
2948static int __hdd_open(struct net_device *dev)
2949{
Jeff Johnson9d295242017-08-29 14:39:48 -07002950 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002951 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002952 int ret;
2953
Dustin Brownfdf17c12018-03-14 12:55:34 -07002954 hdd_enter_dev(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302955 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002956 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05302958 /* Nothing to be done if device is unloading */
2959 if (cds_is_driver_unloading()) {
2960 hdd_err("Driver is unloading can not open the hdd");
2961 return -EBUSY;
2962 }
2963
Dustin Brown01847752017-10-25 13:56:27 -07002964 if (cds_is_driver_recovering()) {
2965 hdd_err("WLAN is currently recovering; Please try again.");
2966 return -EBUSY;
2967 }
2968
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05302969 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
2970 hdd_err("con_mode_handler is in progress; Please try again.");
2971 return -EBUSY;
2972 }
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302973
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05302974 mutex_lock(&hdd_init_deinit_lock);
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05302975 hdd_start_driver_ops_timer(eHDD_DRV_OP_IFF_UP);
2976
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302977 /*
2978 * This scenario can be hit in cases where in the wlan driver after
2979 * registering the netdevices and there is a failure in driver
2980 * initialization. So return error gracefully because the netdevices
2981 * will be de-registered as part of the load failure.
2982 */
2983
2984 if (!cds_is_driver_loaded()) {
2985 hdd_err("Failed to start the wlan driver!!");
2986 ret = -EIO;
2987 goto err_hdd_hdd_init_deinit_lock;
2988 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302989
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002990
Dustin Browne7e71d32018-05-11 16:00:08 -07002991 ret = hdd_wlan_start_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05302992 if (ret) {
2993 hdd_err("Failed to start WLAN modules return");
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302994 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05302995 }
2996
2997
2998 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2999 ret = hdd_start_adapter(adapter);
3000 if (ret) {
3001 hdd_err("Failed to start adapter :%d",
3002 adapter->device_mode);
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303003 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303004 }
3005 }
3006
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003007 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3008 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003009 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003010 /* Enable TX queues only when we are connected */
3011 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303012 WLAN_START_ALL_NETIF_QUEUE,
3013 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003014 }
3015
Naveen Rawat286def52016-09-23 15:38:02 -07003016 /* Enable carrier and transmit queues for NDI */
3017 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003018 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003019 wlan_hdd_netif_queue_control(adapter,
3020 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3021 WLAN_CONTROL_PATH);
3022 }
3023
Naveen Rawat910726a2017-03-06 11:42:51 -08003024 hdd_populate_wifi_pos_cfg(hdd_ctx);
3025
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303026err_hdd_hdd_init_deinit_lock:
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303027 hdd_stop_driver_ops_timer();
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303028 mutex_unlock(&hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003029 return ret;
3030}
3031
Arun Khandavallifae92942016-08-01 13:31:08 +05303032
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003033/**
3034 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
3035 * @dev: Pointer to net_device structure
3036 *
3037 * This is called in response to ifconfig up
3038 *
3039 * Return: 0 for success; non-zero for failure
3040 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003041static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003042{
3043 int ret;
3044
3045 cds_ssr_protect(__func__);
3046 ret = __hdd_open(dev);
3047 cds_ssr_unprotect(__func__);
3048
3049 return ret;
3050}
3051
3052/**
3053 * __hdd_stop() - HDD stop function
3054 * @dev: Pointer to net_device structure
3055 *
3056 * This is called in response to ifconfig down
3057 *
3058 * Return: 0 for success; non-zero for failure
3059 */
3060static int __hdd_stop(struct net_device *dev)
3061{
Jeff Johnson9d295242017-08-29 14:39:48 -07003062 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003063 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003064 int ret;
3065
Dustin Brownfdf17c12018-03-14 12:55:34 -07003066 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303068 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003069 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003070
3071 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303072 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003073 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003074
3075 /* Nothing to be done if the interface is not opened */
3076 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003077 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003078 return -ENODEV;
3079 }
3080
3081 /* Make sure the interface is marked as closed */
3082 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303083
3084 hdd_debug("Disabling Auto Power save timer");
3085 sme_ps_disable_auto_ps_timer(
3086 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07003087 adapter->session_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303088
3089 /*
3090 * Disable TX on the interface, after this hard_start_xmit() will not
3091 * be called on that interface
3092 */
Dustin Brown5e89ef82018-03-14 11:50:23 -07003093 hdd_info("Disabling queues, adapter device mode: %s(%d)",
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003094 hdd_device_mode_to_string(adapter->device_mode),
3095 adapter->device_mode);
3096
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303097 wlan_hdd_netif_queue_control(adapter,
3098 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3099 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100
3101 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003102 * NAN data interface is different in some sense. The traffic on NDI is
3103 * bursty in nature and depends on the need to transfer. The service
3104 * layer may down the interface after the usage and up again when
3105 * required. In some sense, the NDI is expected to be available
3106 * (like SAP) iface until NDI delete request is issued by the service
3107 * layer. Skip BSS termination and adapter deletion for NAN Data
3108 * interface (NDI).
3109 */
3110 if (WLAN_HDD_IS_NDI(adapter))
3111 return 0;
3112
3113 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003114 * The interface is marked as down for outside world (aka kernel)
3115 * But the driver is pretty much alive inside. The driver needs to
3116 * tear down the existing connection on the netdev (session)
3117 * cleanup the data pipes and wait until the control plane is stabilized
3118 * for this interface. The call also needs to wait until the above
3119 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003120 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003121 * That is intentional to be able to scan if it is a STA/P2P interface
3122 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003123 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003124
3125 /* DeInit the adapter. This ensures datapath cleanup as well */
3126 hdd_deinit_adapter(hdd_ctx, adapter, true);
3127
Arun Khandavallifae92942016-08-01 13:31:08 +05303128
3129 /*
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +05303130 * Upon wifi turn off, DUT has to flush the scan results so if
3131 * this is the last cli iface, flush the scan database.
3132 */
3133 if (!hdd_is_cli_iface_up(hdd_ctx))
3134 sme_scan_flush_result(hdd_ctx->hHal);
3135
3136 /*
Arun Khandavallifae92942016-08-01 13:31:08 +05303137 * Find if any iface is up. If any iface is up then can't put device to
3138 * sleep/power save mode
3139 */
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05303140 if (hdd_check_for_opened_interfaces(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003141 hdd_debug("Closing all modules from the hdd_stop");
Dustin Brown6f427922017-09-19 12:19:00 -07003142 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
3143 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +05303144 hdd_prevent_suspend_timeout(
3145 hdd_ctx->config->iface_change_wait_time,
3146 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Arun Khandavallifae92942016-08-01 13:31:08 +05303147 }
3148
Dustin Browne74003f2018-03-14 12:51:58 -07003149 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003150 return 0;
3151}
3152
3153/**
3154 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3155 * @dev: pointer to net_device structure
3156 *
3157 * This is called in response to ifconfig down
3158 *
3159 * Return: 0 for success and error number for failure
3160 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003161static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003162{
3163 int ret;
3164
3165 cds_ssr_protect(__func__);
3166 ret = __hdd_stop(dev);
3167 cds_ssr_unprotect(__func__);
3168
3169 return ret;
3170}
3171
3172/**
3173 * __hdd_uninit() - HDD uninit function
3174 * @dev: Pointer to net_device structure
3175 *
3176 * This is called during the netdev unregister to uninitialize all data
3177 * associated with the device
3178 *
3179 * Return: None
3180 */
3181static void __hdd_uninit(struct net_device *dev)
3182{
Jeff Johnson9d295242017-08-29 14:39:48 -07003183 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003184 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185
Dustin Brownfdf17c12018-03-14 12:55:34 -07003186 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003187
3188 do {
3189 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003190 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191 break;
3192 }
3193
Jeff Johnson399c6272017-08-30 10:51:00 -07003194 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3195 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003196 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003197 break;
3198 }
3199
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003200 if (dev != adapter->dev)
3201 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003202
Jeff Johnson399c6272017-08-30 10:51:00 -07003203 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003204
3205 /* after uninit our adapter structure will no longer be valid */
3206 adapter->dev = NULL;
3207 adapter->magic = 0;
3208 } while (0);
3209
Dustin Browne74003f2018-03-14 12:51:58 -07003210 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003211}
3212
3213/**
3214 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
3215 * @dev: pointer to net_device structure
3216 *
3217 * This is called during the netdev unregister to uninitialize all data
3218 * associated with the device
3219 *
3220 * Return: none
3221 */
3222static void hdd_uninit(struct net_device *dev)
3223{
3224 cds_ssr_protect(__func__);
3225 __hdd_uninit(dev);
3226 cds_ssr_unprotect(__func__);
3227}
3228
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003229static int hdd_open_cesium_nl_sock(void)
3230{
3231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3232 struct netlink_kernel_cfg cfg = {
3233 .groups = WLAN_NLINK_MCAST_GRP_ID,
3234 .input = NULL
3235 };
3236#endif
3237 int ret = 0;
3238
3239#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3240 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3241#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3242 THIS_MODULE,
3243#endif
3244 &cfg);
3245#else
3246 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3247 WLAN_NLINK_MCAST_GRP_ID,
3248 NULL, NULL, THIS_MODULE);
3249#endif
3250
3251 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003252 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003253 ret = -ECONNREFUSED;
3254 }
3255
3256 return ret;
3257}
3258
3259static void hdd_close_cesium_nl_sock(void)
3260{
3261 if (NULL != cesium_nl_srv_sock) {
3262 netlink_kernel_release(cesium_nl_srv_sock);
3263 cesium_nl_srv_sock = NULL;
3264 }
3265}
3266
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267/**
3268 * __hdd_set_mac_address() - set the user specified mac address
3269 * @dev: Pointer to the net device.
3270 * @addr: Pointer to the sockaddr.
3271 *
3272 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003273 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274 *
3275 * Return: 0 for success, non zero for failure
3276 */
3277static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3278{
Jeff Johnson9d295242017-08-29 14:39:48 -07003279 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003280 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303282 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303284 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003285
Dustin Brownfdf17c12018-03-14 12:55:34 -07003286 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003287
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303288 if (netif_running(dev)) {
3289 hdd_err("On iface up, set mac address change isn't supported");
3290 return -EBUSY;
3291 }
3292
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003293 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3294 ret = wlan_hdd_validate_context(hdd_ctx);
3295 if (0 != ret)
3296 return ret;
3297
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303298 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
3299
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303300 if (hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes)) {
3301 hdd_err("adapter exist with same mac address " MAC_ADDRESS_STR,
3302 MAC_ADDR_ARRAY(mac_addr.bytes));
3303 return -EINVAL;
3304 }
3305
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303306 if (qdf_is_macaddr_zero(&mac_addr)) {
3307 hdd_err("MAC is all zero");
3308 return -EINVAL;
3309 }
3310
3311 if (qdf_is_macaddr_broadcast(&mac_addr)) {
3312 hdd_err("MAC is Broadcast");
3313 return -EINVAL;
3314 }
3315
3316 if (ETHER_IS_MULTICAST(psta_mac_addr->sa_data)) {
3317 hdd_err("MAC is Multicast");
3318 return -EINVAL;
3319 }
Ashish Kumar Dhanotiya8bfef122018-04-18 16:48:27 +05303320 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of the interface %s ",
3321 MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303322
Jeff Johnson1e851a12017-10-28 14:36:12 -07003323 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003324 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3325
Dustin Browne74003f2018-03-14 12:51:58 -07003326 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303327 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003328}
3329
3330/**
3331 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
3332 * function from SSR
3333 * @dev: pointer to net_device structure
3334 * @addr: Pointer to the sockaddr
3335 *
3336 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003337 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003338 *
3339 * Return: 0 for success.
3340 */
3341static int hdd_set_mac_address(struct net_device *dev, void *addr)
3342{
3343 int ret;
3344
3345 cds_ssr_protect(__func__);
3346 ret = __hdd_set_mac_address(dev, addr);
3347 cds_ssr_unprotect(__func__);
3348
3349 return ret;
3350}
3351
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003352uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353{
3354 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003355
Anurag Chouhan6d760662016-02-20 16:05:43 +05303356 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003357 if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
3358 break;
3359 }
3360
Anurag Chouhan6d760662016-02-20 16:05:43 +05303361 if (QDF_MAX_CONCURRENCY_PERSONA == i)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003362 return NULL;
3363
3364 hdd_ctx->config->intfAddrMask |= (1 << i);
3365 return &hdd_ctx->config->intfMacAddr[i].bytes[0];
3366}
3367
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003368void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3369 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370{
3371 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003372
Anurag Chouhan6d760662016-02-20 16:05:43 +05303373 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003374 if (!memcmp(releaseAddr,
3375 &hdd_ctx->config->intfMacAddr[i].bytes[0],
3376 6)) {
3377 hdd_ctx->config->intfAddrMask &= ~(1 << i);
3378 break;
3379 }
3380 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003381}
3382
3383#ifdef WLAN_FEATURE_PACKET_FILTERING
3384/**
3385 * __hdd_set_multicast_list() - set the multicast address list
3386 * @dev: Pointer to the WLAN device.
3387 * @skb: Pointer to OS packet (sk_buff).
3388 *
3389 * This funciton sets the multicast address list.
3390 *
3391 * Return: None
3392 */
3393static void __hdd_set_multicast_list(struct net_device *dev)
3394{
Jeff Johnson9d295242017-08-29 14:39:48 -07003395 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396 int i = 0, status;
3397 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003398 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303399 struct pmo_mc_addr_list_params *mc_list_request = NULL;
3400 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
3401 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003402
Dustin Brownfdf17c12018-03-14 12:55:34 -07003403 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303404 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303405 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303406
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303408 if (0 != status)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303409 goto out;
3410
Dustin Brownc788acb2017-08-01 17:43:51 -07003411 status = hdd_validate_adapter(adapter);
3412 if (status)
3413 goto out;
3414
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303415 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3416 hdd_err("%s: Driver module is closed", __func__);
3417 return;
3418 }
3419
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303420 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
3421 if (!mc_list_request) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003422 hdd_err("Cannot allocate mc_list_request");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303423 goto out;
3424 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003425
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303426 /* Delete already configured multicast address list */
3427 if (adapter->mc_addr_list.mc_cnt > 0) {
3428 hdd_info("clear previously configured MC address list");
3429 hdd_disable_and_flush_mc_addr_list(adapter,
3430 pmo_mc_list_change_notify);
3431 }
3432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003433 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003434 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303435 hdd_disable_and_flush_mc_addr_list(adapter,
3436 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003437 } else {
3438 mc_count = netdev_mc_count(dev);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303439 if (mc_count > pmo_ucfg_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003440 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303441 pmo_ucfg_max_mc_addr_supported(psoc));
3442 hdd_disable_and_flush_mc_addr_list(adapter,
3443 pmo_mc_list_change_notify);
3444 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003446 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003447 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303448 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003449 if (i == mc_count)
3450 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303451 memset(&(mc_list_request->mc_addr[i].bytes),
3452 0, ETH_ALEN);
3453 memcpy(&(mc_list_request->mc_addr[i].bytes),
3454 ha->addr, ETH_ALEN);
3455 hdd_info("mlist[%d] = %pM", i,
3456 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457 i++;
3458 }
3459 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303460
3461 mc_list_request->psoc = psoc;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003462 mc_list_request->vdev_id = adapter->session_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303463 mc_list_request->count = mc_count;
3464 status = hdd_cache_mc_addr_list(mc_list_request);
3465 if (status == 0) {
3466 hdd_enable_mc_addr_filtering(adapter,
3467 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003468 } else {
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303469 hdd_err("error while caching mc list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003470 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303471out:
3472 if (mc_list_request)
3473 qdf_mem_free(mc_list_request);
Dustin Browne74003f2018-03-14 12:51:58 -07003474 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003475}
3476
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303477
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003478/**
3479 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
3480 * @dev: pointer to net_device
3481 *
3482 * Return: none
3483 */
3484static void hdd_set_multicast_list(struct net_device *dev)
3485{
3486 cds_ssr_protect(__func__);
3487 __hdd_set_multicast_list(dev);
3488 cds_ssr_unprotect(__func__);
3489}
3490#endif
3491
3492/**
3493 * hdd_select_queue() - used by Linux OS to decide which queue to use first
3494 * @dev: Pointer to the WLAN device.
3495 * @skb: Pointer to OS packet (sk_buff).
3496 *
3497 * This function is registered with the Linux OS for network
3498 * core to decide which queue to use first.
3499 *
3500 * Return: ac, Queue Index/access category corresponding to UP in IP header
3501 */
3502static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
3503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
3504 , void *accel_priv
3505#endif
3506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3507 , select_queue_fallback_t fallback
3508#endif
3509)
3510{
3511 return hdd_wmm_select_queue(dev, skb);
3512}
3513
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003514static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003515 .ndo_open = hdd_open,
3516 .ndo_stop = hdd_stop,
3517 .ndo_uninit = hdd_uninit,
3518 .ndo_start_xmit = hdd_hard_start_xmit,
3519 .ndo_tx_timeout = hdd_tx_timeout,
3520 .ndo_get_stats = hdd_get_stats,
3521 .ndo_do_ioctl = hdd_ioctl,
3522 .ndo_set_mac_address = hdd_set_mac_address,
3523 .ndo_select_queue = hdd_select_queue,
3524#ifdef WLAN_FEATURE_PACKET_FILTERING
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003525 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003526#endif
3527};
3528
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003529/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003530static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003531 .ndo_open = hdd_mon_open,
3532 .ndo_stop = hdd_stop,
3533 .ndo_get_stats = hdd_get_stats,
3534};
3535
3536/**
3537 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003538 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003539 * Return: None
3540 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003541void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003542{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003543 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
Jeff Johnson5505db82017-11-02 21:19:23 -07003544 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003545 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003546 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003547}
3548
3549/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003550 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3551 * @hdd_ctx: global hdd context
3552 * @macAddr: mac address to assign to the interface
3553 * @name: User-visible name of the interface
3554 *
3555 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07003556 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08003557 *
3558 * Return: the pointer to hdd adapter, otherwise NULL
3559 */
Jeff Johnson9d295242017-08-29 14:39:48 -07003560static struct hdd_adapter *hdd_alloc_station_adapter(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003561 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003562 unsigned char name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003563 const char *name)
3564{
Jeff Johnson5505db82017-11-02 21:19:23 -07003565 struct net_device *dev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07003566 struct hdd_adapter *adapter = NULL;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003567 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303568 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003569 /*
3570 * cfg80211 initialization and registration....
3571 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003572 dev = alloc_netdev_mq(sizeof(struct hdd_adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003573#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
3574 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003575#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003576 (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
3577 hdd_mon_mode_ether_setup : ether_setup),
3578 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003579
Jeff Johnson5505db82017-11-02 21:19:23 -07003580 if (dev != NULL) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003581
3582 /* Save the pointer to the net_device in the HDD adapter */
Jeff Johnson5505db82017-11-02 21:19:23 -07003583 adapter = (struct hdd_adapter *) netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003584
Jeff Johnson9d295242017-08-29 14:39:48 -07003585 qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
Jeff Johnsonb9424862017-10-30 08:49:35 -07003586 sta_ctx = &adapter->session.station;
Hanumanth Reddy Pothula18553ae2017-04-28 15:03:10 +05303587 qdf_mem_set(sta_ctx->conn_info.staId,
3588 sizeof(sta_ctx->conn_info.staId),
3589 HDD_WLAN_INVALID_STA_ID);
Jeff Johnson5505db82017-11-02 21:19:23 -07003590 adapter->dev = dev;
Jeff Johnsondba0db62017-08-30 11:12:39 -07003591 adapter->hdd_ctx = hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003592 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003593 adapter->session_id = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303595 qdf_status = qdf_event_create(
3596 &adapter->qdf_session_open_event);
3597 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3598 hdd_err("Session open QDF event init failed!");
3599 free_netdev(adapter->dev);
3600 return NULL;
3601 }
3602
3603 qdf_status = qdf_event_create(
3604 &adapter->qdf_session_close_event);
3605 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3606 hdd_err("Session close QDF event init failed!");
3607 free_netdev(adapter->dev);
3608 return NULL;
3609 }
3610
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003611 init_completion(&adapter->disconnect_comp_var);
Abhishek Singh533c9da2017-05-04 10:23:34 +05303612 init_completion(&adapter->roaming_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003613 init_completion(&adapter->linkup_event_var);
3614 init_completion(&adapter->cancel_rem_on_chan_var);
3615 init_completion(&adapter->rem_on_chan_ready_event);
3616 init_completion(&adapter->sta_authorized_event);
3617 init_completion(&adapter->offchannel_tx_event);
3618 init_completion(&adapter->tx_action_cnf_event);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003619 init_completion(&adapter->ibss_peer_info_comp);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05303620 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003621
3622 adapter->offloads_configured = false;
Jeff Johnsonc72c5732017-10-28 12:49:37 -07003623 adapter->is_link_up_service_needed = false;
Alok Kumarb64650c2018-03-23 17:05:11 +05303624 adapter->disconnection_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003625 /* Init the net_device structure */
Jeff Johnson5505db82017-11-02 21:19:23 -07003626 strlcpy(dev->name, name, IFNAMSIZ);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003627
Jeff Johnson5505db82017-11-02 21:19:23 -07003628 qdf_mem_copy(dev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003629 sizeof(tSirMacAddr));
Jeff Johnson1e851a12017-10-28 14:36:12 -07003630 qdf_mem_copy(adapter->mac_addr.bytes, macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003631 sizeof(tSirMacAddr));
Jeff Johnson5505db82017-11-02 21:19:23 -07003632 dev->watchdog_timeo = HDD_TX_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003633
3634 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
Jeff Johnson5505db82017-11-02 21:19:23 -07003635 dev->features |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003636 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
Jeff Johnson5505db82017-11-02 21:19:23 -07003637 dev->features |= NETIF_F_RXCSUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003638
Jeff Johnson5505db82017-11-02 21:19:23 -07003639 hdd_set_tso_flags(hdd_ctx, dev);
Dhanashri Atre83d373d2015-07-28 16:45:59 -07003640
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003641 hdd_set_station_ops(adapter->dev);
3642
Jeff Johnson5505db82017-11-02 21:19:23 -07003643 hdd_dev_setup_destructor(dev);
3644 dev->ieee80211_ptr = &adapter->wdev;
3645 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003646 adapter->wdev.wiphy = hdd_ctx->wiphy;
Jeff Johnson5505db82017-11-02 21:19:23 -07003647 adapter->wdev.netdev = dev;
3648 /* set dev's parent to underlying device */
3649 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003650 hdd_wmm_init(adapter);
3651 spin_lock_init(&adapter->pause_map_lock);
Nirav Shah617cff92016-04-25 10:24:24 +05303652 adapter->start_time = adapter->last_time = qdf_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003653 }
3654
3655 return adapter;
3656}
3657
Jeff Johnson9d295242017-08-29 14:39:48 -07003658static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003659{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003660 struct net_device *dev = adapter->dev;
3661 int ret;
3662
Dustin Brown491d54b2018-03-14 12:39:11 -07003663 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003664
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003665 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003666 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3667
3668 ret = dev_alloc_name(dev, dev->name);
3669 if (ret < 0) {
3670 hdd_err(
3671 "unable to get dev name: %s, err = 0x%x",
3672 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303673 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003674 }
3675 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003676
3677 ret = register_netdevice(dev);
3678 if (ret) {
3679 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3680 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303681 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003682 }
3683 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003684 ret = register_netdev(dev);
3685 if (ret) {
3686 hdd_err("register_netdev(%s) failed, err = 0x%x",
3687 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303688 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003689 }
3690 }
3691 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3692
Dustin Browne74003f2018-03-14 12:51:58 -07003693 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003694
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303695 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003696}
3697
Krunal Sonib51eec72017-11-20 21:53:01 -08003698QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003699{
Krunal Sonib51eec72017-11-20 21:53:01 -08003700 struct hdd_adapter *adapter;
3701 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003702
Krunal Sonib51eec72017-11-20 21:53:01 -08003703 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3704 if (!hdd_ctx) {
3705 hdd_err("Invalid HDD_CTX");
3706 return QDF_STATUS_E_FAILURE;
3707 }
3708
3709 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
3710 if (NULL == adapter) {
3711 hdd_err("NULL adapter");
3712 return QDF_STATUS_E_INVAL;
3713 }
3714 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303715 qdf_event_set(&adapter->qdf_session_open_event);
Krunal Sonib51eec72017-11-20 21:53:01 -08003716 hdd_debug("session %d opened", adapter->session_id);
3717
3718 return QDF_STATUS_SUCCESS;
3719}
3720
3721QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
3722{
3723 struct hdd_adapter *adapter;
3724 struct hdd_context *hdd_ctx;
3725
3726 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3727 if (!hdd_ctx) {
3728 hdd_err("Invalid HDD_CTX");
3729 return QDF_STATUS_E_FAILURE;
3730 }
3731
3732 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003733 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003734 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303735 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736 }
3737
3738 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003739 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303740 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 }
3742
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003743 /*
3744 * For NAN Data interface, the close session results in the final
3745 * indication to the userspace
3746 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003747 if (adapter->device_mode == QDF_NDI_MODE)
3748 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003749
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003750 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3751
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003752 /*
3753 * We can be blocked while waiting for scheduled work to be
3754 * flushed, and the adapter structure can potentially be freed, in
3755 * which case the magic will have been reset. So make sure the
3756 * magic is still good, and hence the adapter structure is still
3757 * valid, before signaling completion
3758 */
3759 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303760 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003761
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303762 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763}
3764
Jeff Johnson9d295242017-08-29 14:39:48 -07003765int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003766{
Dustin Brownd28772b2017-03-17 14:16:07 -07003767 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003768
Dustin Brownd28772b2017-03-17 14:16:07 -07003769 status = pmo_vdev_ready(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003770 if (QDF_IS_STATUS_ERROR(status))
3771 return qdf_status_to_os_return(status);
3772
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003773 status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003774 if (QDF_IS_STATUS_ERROR(status))
3775 return qdf_status_to_os_return(status);
3776
3777 if (wma_capability_enhanced_mcast_filter())
3778 status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev);
3779 else
3780 status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07003781
3782 return qdf_status_to_os_return(status);
3783}
3784
Jeff Johnson9d295242017-08-29 14:39:48 -07003785int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07003786{
3787 QDF_STATUS status;
Jiachao Wu2c42c222018-01-15 18:13:19 +08003788 int errno = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003789 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003790 uint8_t vdev_id;
Dustin Brownd28772b2017-03-17 14:16:07 -07003791
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003792 vdev_id = adapter->session_id;
3793 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003794
3795 /* vdev created sanity check */
3796 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07003797 hdd_err("vdev for Id %d does not exist", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003798 return -EINVAL;
3799 }
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003800 status = ucfg_reg_11d_vdev_delete_update(adapter->hdd_vdev);
Yue Maf9782842017-05-08 12:49:49 -07003801
Dustin Brownd28772b2017-03-17 14:16:07 -07003802 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303803 qdf_event_reset(&adapter->qdf_session_close_event);
Dustin Brownd28772b2017-03-17 14:16:07 -07003804 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08003805 status = sme_close_session(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003806 if (QDF_IS_STATUS_ERROR(status)) {
3807 hdd_err("failed to close sme session: %d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003808 errno = qdf_status_to_os_return(status);
3809 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07003810 }
3811
3812 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303813 status = qdf_wait_for_event_completion(
3814 &adapter->qdf_session_close_event,
3815 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3816 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003817 if (adapter->device_mode == QDF_NDI_MODE)
3818 hdd_ndp_session_end_handler(adapter);
3819 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303820 adapter->session_id = HDD_SESSION_ID_INVALID;
3821 if (QDF_STATUS_E_TIMEOUT != status) {
3822 hdd_err("timed out waiting for close sme session: %u", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003823 errno = -ETIMEDOUT;
3824 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303825 } else if (adapter->qdf_session_close_event.force_set) {
3826 hdd_err("Session close evt focefully set, SSR/PDR has occurred");
Jiachao Wu2c42c222018-01-15 18:13:19 +08003827 errno = -EINVAL;
3828 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303829 } else {
3830 hdd_err("Failed to close sme session (%u)", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003831 errno = -EINVAL;
3832 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303833 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003834 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08003835
Yue Maf9782842017-05-08 12:49:49 -07003836release_vdev:
Frank Liuc66d4bf2018-01-26 16:18:18 +08003837 /*
3838 * In SSR or driver unloading case, directly exit may cause objects
3839 * leak, if sme_close_session failed. Free objects anyway.
Jiachao Wu2c42c222018-01-15 18:13:19 +08003840 */
Kabilan Kannanb867c312018-02-15 17:43:21 -08003841 if (errno && !cds_is_driver_recovering() && !cds_is_driver_unloading())
Jiachao Wu2c42c222018-01-15 18:13:19 +08003842 return errno;
3843
Sandeep Puligillaef415362017-08-30 16:37:13 -07003844 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08003845 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07003846 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08003847 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07003848 return errno;
3849 }
3850
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003851 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003852
3853 return 0;
3854}
3855
Krunal Sonib51eec72017-11-20 21:53:01 -08003856static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
3857 struct sme_session_params *session_param,
3858 csr_roam_completeCallback callback,
3859 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07003860{
Dustin Brownd28772b2017-03-17 14:16:07 -07003861 uint32_t type;
3862 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08003863 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07003864
3865 /* determine vdev (sub)type */
3866 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303867 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003868 hdd_err("failed to get vdev type: %d", status);
3869 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003870 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003871 session_param->sme_session_id = adapter->session_id;
3872 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
3873 session_param->type_of_persona = type;
3874 session_param->subtype_of_persona = sub_type;
3875 session_param->session_open_cb = hdd_sme_open_session_callback;
3876 session_param->session_close_cb = hdd_sme_close_session_callback;
3877 session_param->callback = callback;
3878 session_param->callback_ctx = callback_ctx;
3879
3880 return 0;
3881}
3882
3883int hdd_vdev_create(struct hdd_adapter *adapter,
3884 csr_roam_completeCallback callback, void *ctx)
3885{
3886 QDF_STATUS status;
3887 int errno;
3888 struct hdd_context *hdd_ctx;
3889 struct sme_session_params sme_session_params = {0};
Krunal Sonib51eec72017-11-20 21:53:01 -08003890
3891 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07003892
3893 /* do vdev create via objmgr */
3894 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown7d043f62017-03-27 12:07:36 -07003895 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07003896 if (errno) {
3897 hdd_err("failed to create objmgr vdev: %d", errno);
3898 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003899 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003900
3901 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303902 status = qdf_event_reset(&adapter->qdf_session_open_event);
3903 if (QDF_STATUS_SUCCESS != status) {
3904 hdd_err("failed to reinit session open event");
3905 return -EINVAL;
3906 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003907 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
3908 callback, ctx);
3909 if (errno) {
3910 hdd_err("failed to populating SME params");
3911 goto objmgr_vdev_destroy_procedure;
3912 }
3913
3914 status = sme_open_session(hdd_ctx->hHal, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07003915 if (QDF_IS_STATUS_ERROR(status)) {
3916 hdd_err("failed to open sme session: %d", status);
3917 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07003918 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003919 }
3920
3921 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303922 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
3923 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3924 if (QDF_STATUS_SUCCESS != status) {
3925 if (adapter->qdf_session_open_event.force_set) {
3926 /*
3927 * SSR/PDR has caused shutdown, which has forcefully
3928 * set the event. Return without the closing session.
3929 */
3930 adapter->session_id = HDD_SESSION_ID_INVALID;
3931 hdd_err("Session open event forcefully set");
3932 return -EINVAL;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303933 }
Jeff Johnsonc66d3102018-02-28 11:58:26 -08003934
3935 if (QDF_STATUS_E_TIMEOUT == status)
3936 hdd_err("Session failed to open within timeout period");
3937 else
3938 hdd_err("Failed to wait for session open event(status-%d)",
3939 status);
3940 errno = -ETIMEDOUT;
3941 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3942 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003943 }
3944
3945 /* firmware ready for component communication, raise vdev_ready event */
3946 errno = hdd_vdev_ready(adapter);
3947 if (errno) {
3948 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07003949 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003950 }
3951
Naveen Rawat2b430892018-03-13 13:58:18 -07003952 if (adapter->device_mode == QDF_STA_MODE) {
3953 hdd_debug("setting RTT mac randomization param: %d",
3954 hdd_ctx->config->enable_rtt_mac_randomization);
3955 errno = sme_cli_set_command(adapter->session_id,
3956 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
3957 hdd_ctx->config->enable_rtt_mac_randomization,
3958 VDEV_CMD);
3959 if (0 != errno)
3960 hdd_err("RTT mac randomization param set failed %d",
3961 errno);
3962 }
3963
Jeff Johnson1b780e42017-10-31 14:11:45 -07003964 hdd_info("vdev %d created successfully", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003965
3966 return 0;
3967
3968 /*
3969 * Due to legacy constraints, we need to destroy in the same order as
3970 * create. So, split error handling into 2 cases to accommodate.
3971 */
3972
Krunal Soni4a020c72017-10-30 20:58:40 -07003973objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07003974 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07003975
3976 return errno;
3977
Krunal Soni4a020c72017-10-30 20:58:40 -07003978hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07003979 QDF_BUG(!hdd_vdev_destroy(adapter));
3980
3981 return errno;
3982}
3983
Jeff Johnson9d295242017-08-29 14:39:48 -07003984QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07003985{
Jeff Johnsonb9424862017-10-30 08:49:35 -07003986 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003987 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07003988 QDF_STATUS status;
3989 int ret_val;
3990
Dustin Brownd28772b2017-03-17 14:16:07 -07003991 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3992 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
3993 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Jeff Johnson1b780e42017-10-31 14:11:45 -07003994 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003995
Jeff Johnson7f2c5912018-03-23 11:42:28 -07003996 hdd_roam_profile_init(adapter);
3997 hdd_register_wext(adapter->dev);
3998
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07003999 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004000
Jeff Johnsond377dce2017-10-04 10:32:42 -07004001 qdf_mem_set(sta_ctx->conn_info.staId,
4002 sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304003
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004004 /* set fast roaming capability in sme session */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004005 status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->session_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304006 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004007 /* Set the default operation channel */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004008 sta_ctx->conn_info.operationChannel =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004009 hdd_ctx->config->OperatingChannel;
4010
4011 /* Make the default Auth Type as OPEN */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004012 sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004013
4014 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304015 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004016 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004017 status, status);
4018 goto error_init_txrx;
4019 }
4020
4021 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4022
4023 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304024 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004025 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004026 status, status);
4027 goto error_wmm_init;
4028 }
4029
4030 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4031
Jeff Johnson1b780e42017-10-31 14:11:45 -07004032 ret_val = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004033 WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +05304034 HDD_ENABLE_SIFS_BURST_DEFAULT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004035 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004036 if (ret_val)
4037 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304039 /*
4040 * In case of USB tethering, LRO is disabled. If SSR happened
4041 * during that time, then as part of SSR init, do not enable
4042 * the LRO again. Keep the LRO state same as before SSR.
4043 */
4044 if (!(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004045 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304046
4047 /* rcpi info initialization */
4048 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4049
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304050 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004052error_wmm_init:
4053 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4054 hdd_deinit_tx_rx(adapter);
4055error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004056 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004057 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004058
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004059 return status;
4060}
4061
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304062/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004063 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304064 * @hdd_ctx: global hdd context
4065 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004066 * @rtnl_held: Used to indicate whether or not the caller is holding
4067 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304068 *
4069 * This function De-initializes the STA/P2P/OCB adapter.
4070 *
4071 * Return: None.
4072 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004073static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004074 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004075 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304076{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004077 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304078
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304079 if (adapter->dev) {
4080 if (rtnl_held)
4081 adapter->dev->wireless_handlers = NULL;
4082 else {
4083 rtnl_lock();
4084 adapter->dev->wireless_handlers = NULL;
4085 rtnl_unlock();
4086 }
4087 }
4088
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304089 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4090 hdd_deinit_tx_rx(adapter);
4091 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4092 }
4093
4094 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4095 hdd_wmm_adapter_close(adapter);
4096 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4097 }
4098
Krunal Sonib51eec72017-11-20 21:53:01 -08004099
Dustin Browne74003f2018-03-14 12:51:58 -07004100 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304101}
4102
Krunal Sonib51eec72017-11-20 21:53:01 -08004103void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4104 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004105 bool rtnl_held)
4106{
Dustin Brown491d54b2018-03-14 12:39:11 -07004107 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304108
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004109 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004110 case QDF_STA_MODE:
4111 case QDF_P2P_CLIENT_MODE:
4112 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004113 case QDF_IBSS_MODE:
4114 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004115 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004116 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004117 break;
4118 }
4119
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004120 case QDF_SAP_MODE:
4121 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004123 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004124 break;
4125 }
4126
4127 default:
4128 break;
4129 }
4130
Dustin Browne74003f2018-03-14 12:51:58 -07004131 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004132}
4133
Jeff Johnson9d295242017-08-29 14:39:48 -07004134static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004135 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004136{
Jeff Johnson5505db82017-11-02 21:19:23 -07004137 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138
4139 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004140 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004142 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 return;
4144 }
4145
Alok Kumarb64650c2018-03-23 17:05:11 +05304146 hdd_nud_deinit_tracking(adapter);
4147 qdf_mutex_destroy(&adapter->disconnection_status_lock);
4148
Rajeev Kumardca5f812016-02-04 17:28:06 -08004149 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304150
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004151 /*
4152 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4153 * the driver is almost closed and cannot handle either control
4154 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004155 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4156 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004157 * is not right. Setting this flag helps hdd_stop() to recognize that
4158 * the interface is closed and restricts any operations on that
4159 */
4160 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4161
4162 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004163 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004164 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004165 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004166 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004167 /*
4168 * Note that the adapter is no longer valid at this point
4169 * since the memory has been reclaimed
4170 */
4171 }
4172}
4173
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004174static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07004175 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004176{
Jeff Johnson9d295242017-08-29 14:39:48 -07004177 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004178
Dustin Brown920397d2017-12-13 16:27:50 -08004179 hdd_for_each_adapter(hdd_ctx, adapter) {
4180 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
4181 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304182 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004183 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 }
Dustin Brown920397d2017-12-13 16:27:50 -08004185
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304186 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004188
Arun Khandavalli2358d522016-05-16 18:05:37 +05304189#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4190/**
4191 * hdd_set_fw_log_params() - Set log parameters to FW
4192 * @hdd_ctx: HDD Context
4193 * @adapter: HDD Adapter
4194 *
4195 * This function set the FW Debug log level based on the INI.
4196 *
4197 * Return: None
4198 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004199static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004200 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304201{
4202 uint8_t count = 0, numentries = 0,
4203 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
4204 uint32_t value = 0;
4205 int ret;
4206
Arun Khandavallifae92942016-08-01 13:31:08 +05304207 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4208 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004209 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304210 return;
4211 }
4212
Arun Khandavallifae92942016-08-01 13:31:08 +05304213 /* Enable FW logs based on INI configuration */
Arun Khandavalli2358d522016-05-16 18:05:37 +05304214 hdd_ctx->fw_log_settings.dl_type =
4215 hdd_ctx->config->enableFwLogType;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004216 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304217 WMI_DBGLOG_TYPE,
4218 hdd_ctx->config->enableFwLogType,
4219 DBG_CMD);
4220 if (ret != 0)
4221 hdd_err("Failed to enable FW log type ret %d",
4222 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304223
4224 hdd_ctx->fw_log_settings.dl_loglevel =
Arun Khandavallifae92942016-08-01 13:31:08 +05304225 hdd_ctx->config->enableFwLogLevel;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004226 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304227 WMI_DBGLOG_LOG_LEVEL,
4228 hdd_ctx->config->enableFwLogLevel,
4229 DBG_CMD);
4230 if (ret != 0)
4231 hdd_err("Failed to enable FW log level ret %d",
4232 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304233
4234 hdd_string_to_u8_array(
4235 hdd_ctx->config->enableFwModuleLogLevel,
4236 moduleloglevel,
4237 &numentries,
4238 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
4239
4240 while (count < numentries) {
4241 /*
4242 * FW module log level input string looks like
4243 * below:
4244 * gFwDebugModuleLoglevel=<FW Module ID>,
4245 * <Log Level>,...
4246 * For example:
4247 * gFwDebugModuleLoglevel=
4248 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
4249 * Above input string means :
4250 * For FW module ID 1 enable log level 0
4251 * For FW module ID 2 enable log level 1
4252 * For FW module ID 3 enable log level 2
4253 * For FW module ID 4 enable log level 3
4254 * For FW module ID 5 enable log level 4
4255 * For FW module ID 6 enable log level 5
4256 * For FW module ID 7 enable log level 6
4257 */
4258
Nishank Aggarwale239d962017-03-03 12:26:02 +05304259 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
4260 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
4261 hdd_err("Module id %d and dbglog level %d input length is more than max",
4262 moduleloglevel[count],
4263 moduleloglevel[count + 1]);
4264 return;
4265 }
4266
4267 value = moduleloglevel[count] << 16;
4268 value |= moduleloglevel[count + 1];
Jeff Johnson1b780e42017-10-31 14:11:45 -07004269 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304270 WMI_DBGLOG_MOD_LOG_LEVEL,
4271 value, DBG_CMD);
4272 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304273 hdd_err("Failed to enable FW module log level %d ret %d",
4274 value, ret);
4275
4276 count += 2;
4277 }
Arun Khandavallifae92942016-08-01 13:31:08 +05304278
Arun Khandavalli2358d522016-05-16 18:05:37 +05304279}
4280#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004281static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004282 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304283{
4284}
4285
4286#endif
4287
4288/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004289 * hdd_configure_chain_mask() - programs chain mask to firmware
4290 * @adapter: HDD adapter
4291 *
4292 * Return: 0 on success or errno on failure
4293 */
4294static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4295{
4296 int ret_val;
Naveen Rawat98322472018-03-06 10:29:42 -08004297 QDF_STATUS status;
4298 struct wma_caps_per_phy non_dbs_phy_cap;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004299 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4300
4301 hdd_debug("enable2x2: %d, lte_coex: %d, ChainMask1x1: tx: %d rx: %d",
4302 hdd_ctx->config->enable2x2, hdd_ctx->lte_coex_ant_share,
4303 hdd_ctx->config->txchainmask1x1,
4304 hdd_ctx->config->rxchainmask1x1);
4305 hdd_debug("disable_DBS: %d, tx_chain_mask_2g: %d, rx_chain_mask_2g: %d",
4306 hdd_ctx->config->dual_mac_feature_disable,
4307 hdd_ctx->config->tx_chain_mask_2g,
4308 hdd_ctx->config->rx_chain_mask_2g);
4309 hdd_debug("tx_chain_mask_5g: %d, rx_chain_mask_5g: %d",
4310 hdd_ctx->config->tx_chain_mask_5g,
4311 hdd_ctx->config->rx_chain_mask_5g);
Liangwei Dong22810e82018-03-15 03:42:12 -04004312 hdd_debug("enable_bt_chain_separation %d",
4313 hdd_ctx->config->enable_bt_chain_separation);
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004314
Naveen Rawat98322472018-03-06 10:29:42 -08004315 status = wma_get_caps_for_phyidx_hwmode(&non_dbs_phy_cap,
4316 HW_MODE_DBS_NONE,
4317 CDS_BAND_ALL);
4318 if (QDF_IS_STATUS_ERROR(status)) {
4319 hdd_err("couldn't get phy caps. skip chain mask programming");
4320 return qdf_status_to_os_return(status);
4321 }
4322
4323 if (non_dbs_phy_cap.tx_chain_mask_2G < 3 ||
4324 non_dbs_phy_cap.rx_chain_mask_2G < 3 ||
4325 non_dbs_phy_cap.tx_chain_mask_5G < 3 ||
4326 non_dbs_phy_cap.rx_chain_mask_5G < 3) {
4327 hdd_info("firmware not capable. skip chain mask programming");
4328 return 0;
4329 }
4330
Liangwei Dong22810e82018-03-15 03:42:12 -04004331 if (hdd_ctx->config->enable2x2 &&
4332 !hdd_ctx->config->enable_bt_chain_separation) {
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004333 hdd_info("2x2 enabled. skip chain mask programming");
4334 return 0;
4335 }
4336
Naveen Rawatb54c72b2018-02-05 10:39:06 -08004337 if (hdd_ctx->config->dual_mac_feature_disable !=
4338 DISABLE_DBS_CXN_AND_SCAN) {
4339 hdd_info("DBS enabled(%d). skip chain mask programming",
4340 hdd_ctx->config->dual_mac_feature_disable);
4341 return 0;
4342 }
4343
Naveen Rawatdacb5032018-02-08 15:23:24 -08004344 if (hdd_ctx->lte_coex_ant_share) {
4345 hdd_info("lte ant sharing enabled. skip chainmask programming");
4346 return 0;
4347 }
4348
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004349 if (hdd_ctx->config->txchainmask1x1) {
4350 ret_val = sme_cli_set_command(adapter->session_id,
4351 WMI_PDEV_PARAM_TX_CHAIN_MASK,
4352 hdd_ctx->config->txchainmask1x1,
4353 PDEV_CMD);
4354 if (ret_val)
4355 goto error;
4356 }
4357
4358 if (hdd_ctx->config->rxchainmask1x1) {
4359 ret_val = sme_cli_set_command(adapter->session_id,
4360 WMI_PDEV_PARAM_RX_CHAIN_MASK,
4361 hdd_ctx->config->rxchainmask1x1,
4362 PDEV_CMD);
4363 if (ret_val)
4364 goto error;
4365 }
4366
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004367 if (hdd_ctx->config->txchainmask1x1 ||
4368 hdd_ctx->config->rxchainmask1x1) {
4369 hdd_info("band agnostic tx/rx chain mask set. skip per band chain mask");
4370 return 0;
4371 }
4372
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004373 if (hdd_ctx->config->tx_chain_mask_2g) {
4374 ret_val = sme_cli_set_command(adapter->session_id,
4375 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
4376 hdd_ctx->config->tx_chain_mask_2g, PDEV_CMD);
4377 if (0 != ret_val)
4378 goto error;
4379 }
4380
4381 if (hdd_ctx->config->rx_chain_mask_2g) {
4382 ret_val = sme_cli_set_command(adapter->session_id,
4383 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
4384 hdd_ctx->config->rx_chain_mask_2g, PDEV_CMD);
4385 if (0 != ret_val)
4386 goto error;
4387 }
4388
4389 if (hdd_ctx->config->tx_chain_mask_5g) {
4390 ret_val = sme_cli_set_command(adapter->session_id,
4391 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
4392 hdd_ctx->config->tx_chain_mask_5g, PDEV_CMD);
4393 if (0 != ret_val)
4394 goto error;
4395 }
4396
4397 if (hdd_ctx->config->rx_chain_mask_5g) {
4398 ret_val = sme_cli_set_command(adapter->session_id,
4399 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
4400 hdd_ctx->config->rx_chain_mask_5g, PDEV_CMD);
4401 if (0 != ret_val)
4402 goto error;
4403 }
4404
4405 return 0;
4406
4407error:
4408 hdd_err("WMI PDEV set param failed %d", ret_val);
4409 return -EINVAL;
4410}
4411
4412/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304413 * hdd_set_fw_params() - Set parameters to firmware
4414 * @adapter: HDD adapter
4415 *
4416 * This function Sets various parameters to fw once the
4417 * adapter is started.
4418 *
4419 * Return: 0 on success or errno on failure
4420 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004421int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304422{
4423 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004424 struct hdd_context *hdd_ctx;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304425
Dustin Brownfdf17c12018-03-14 12:55:34 -07004426 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304427
4428 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4429 if (!hdd_ctx)
4430 return -EINVAL;
4431
Dustin Brown732ab9c2017-06-15 13:24:09 -07004432 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4433 hdd_debug("FTM Mode is active; nothing to do");
4434 return 0;
4435 }
4436
Jeff Johnson1b780e42017-10-31 14:11:45 -07004437 ret = sme_cli_set_command(adapter->session_id,
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304438 WMI_PDEV_PARAM_DTIM_SYNTH,
4439 hdd_ctx->config->enable_lprx, PDEV_CMD);
4440 if (ret) {
4441 hdd_err("Failed to set LPRx");
4442 goto error;
4443 }
4444
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304445
4446 ret = sme_cli_set_command(
4447 adapter->session_id,
4448 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
4449 hdd_ctx->config->enable_dtim_selection_diversity,
4450 PDEV_CMD);
4451 if (ret) {
4452 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
4453 goto error;
4454 }
4455
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05304456 ret = sme_cli_set_command(
4457 adapter->session_id,
4458 WMI_PDEV_PARAM_TX_SCH_DELAY,
4459 hdd_ctx->config->enable_tx_sch_delay,
4460 PDEV_CMD);
4461 if (ret) {
4462 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
4463 goto error;
4464 }
4465
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05304466 ret = sme_cli_set_command(
4467 adapter->session_id,
4468 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
4469 hdd_ctx->config->enable_secondary_rate,
4470 PDEV_CMD);
4471 if (ret) {
4472 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
4473 goto error;
4474 }
4475
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304476 if (adapter->device_mode == QDF_STA_MODE) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07004477 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304478 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
4479 hdd_ctx->config->upper_brssi_thresh);
4480
Jeff Johnson1b780e42017-10-31 14:11:45 -07004481 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304482 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
4483 hdd_ctx->config->lower_brssi_thresh);
4484
Jeff Johnson1b780e42017-10-31 14:11:45 -07004485 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304486 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
4487 hdd_ctx->config->enable_dtim_1chrx);
4488 }
4489
Dustin Brown732ab9c2017-06-15 13:24:09 -07004490 if (hdd_ctx->config->enable2x2) {
4491 hdd_debug("configuring 2x2 mode fw params");
4492
Jeff Johnson1b780e42017-10-31 14:11:45 -07004493 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004494 WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE,
4495 hdd_ctx->config->enable_cck_tx_fir_override,
4496 PDEV_CMD);
4497 if (ret) {
4498 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
4499 ret);
4500 goto error;
4501 }
Liangwei Dong22810e82018-03-15 03:42:12 -04004502
4503 if (hdd_configure_chain_mask(adapter))
4504 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07004505 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304506#define HDD_DTIM_1CHAIN_RX_ID 0x5
4507#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004508 hdd_debug("configuring 1x1 mode fw params");
4509
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004510 /*
4511 * Disable DTIM 1 chain Rx when in 1x1,
4512 * we are passing two value
4513 * as param_id << 29 | param_value.
4514 * Below param_value = 0(disable)
4515 */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004516 ret = sme_cli_set_command(adapter->session_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004517 WMI_STA_SMPS_PARAM_CMDID,
4518 HDD_DTIM_1CHAIN_RX_ID <<
4519 HDD_SMPS_PARAM_VALUE_S,
4520 VDEV_CMD);
4521 if (ret) {
4522 hdd_err("DTIM 1 chain set failed %d", ret);
4523 goto error;
4524 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304525
Arun Khandavalli2358d522016-05-16 18:05:37 +05304526#undef HDD_DTIM_1CHAIN_RX_ID
4527#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004528
4529 if (hdd_configure_chain_mask(adapter))
4530 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004531 }
4532
Jeff Johnson1b780e42017-10-31 14:11:45 -07004533 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004534 WMI_PDEV_PARAM_HYST_EN,
4535 hdd_ctx->config->enableMemDeepSleep,
4536 PDEV_CMD);
4537 if (ret) {
4538 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4539 goto error;
4540 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304541
Jeff Johnson1b780e42017-10-31 14:11:45 -07004542 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004543 WMI_VDEV_PARAM_ENABLE_RTSCTS,
4544 hdd_ctx->config->rts_profile,
4545 VDEV_CMD);
4546 if (ret) {
4547 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4548 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304549 }
4550
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004551 hdd_debug("SET AMSDU num %d", hdd_ctx->config->max_amsdu_num);
4552
Jeff Johnson1b780e42017-10-31 14:11:45 -07004553 ret = wma_cli_set_command(adapter->session_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004554 GEN_VDEV_PARAM_AMSDU,
4555 hdd_ctx->config->max_amsdu_num,
4556 GEN_CMD);
4557 if (ret != 0) {
4558 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4559 goto error;
4560 }
4561
Arun Khandavalli2358d522016-05-16 18:05:37 +05304562 hdd_set_fw_log_params(hdd_ctx, adapter);
Dustin Browne74003f2018-03-14 12:51:58 -07004563 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004564
Arun Khandavalli2358d522016-05-16 18:05:37 +05304565 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304566
Arun Khandavalli2358d522016-05-16 18:05:37 +05304567error:
4568 return -EINVAL;
4569}
4570
Ryan Hsu07495ea2016-01-21 15:25:39 -08004571/**
4572 * hdd_open_adapter() - open and setup the hdd adatper
4573 * @hdd_ctx: global hdd context
4574 * @session_type: type of the interface to be created
4575 * @iface_name: User-visible name of the interface
4576 * @macAddr: MAC address to assign to the interface
4577 * @name_assign_type: the name of assign type of the netdev
4578 * @rtnl_held: the rtnl lock hold flag
4579 *
4580 * This function open and setup the hdd adpater according to the device
4581 * type request, assign the name, the mac address assigned, and then prepared
4582 * the hdd related parameters, queue, lock and ready to start.
4583 *
4584 * Return: the pointer of hdd adapter, otherwise NULL.
4585 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004586struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004587 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08004588 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004589 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004590{
Jeff Johnson9d295242017-08-29 14:39:48 -07004591 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304592 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004593
4594 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
4595 /*
4596 * Max limit reached on the number of vdevs configured by the
4597 * host. Return error
4598 */
Arun Khandavallifae92942016-08-01 13:31:08 +05304599 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
4600 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004601 return NULL;
4602 }
4603
4604 if (macAddr == NULL) {
4605 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05304606 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004607 return NULL;
4608 }
4609 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304610 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304611 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
4612 " already exists",
4613 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004614 return NULL;
4615 }
4616
4617 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004618 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004619 /* Reset locally administered bit if the device mode is STA */
4620 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
Arunk Khandavalli794fdfc2017-09-13 18:00:40 +05304621 hdd_info("locally administered bit reset in sta mode: "
4622 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004623 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004624 case QDF_P2P_CLIENT_MODE:
4625 case QDF_P2P_DEVICE_MODE:
4626 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07004627 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304628 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004629 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4630 name_assign_type,
4631 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004632
4633 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304634 hdd_err("failed to allocate adapter for session %d",
4635 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004636 return NULL;
4637 }
4638
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004639 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004640 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004641 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004642 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304643 else if (QDF_MONITOR_MODE == session_type)
4644 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004645 else
4646 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4647
4648 adapter->device_mode = session_type;
4649
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004650
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004651 /*
4652 * Workqueue which gets scheduled in IPv4 notification
4653 * callback
4654 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004655 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004656 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004657
4658#ifdef WLAN_NS_OFFLOAD
4659 /*
4660 * Workqueue which gets scheduled in IPv6
4661 * notification callback.
4662 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004663 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004664 hdd_ipv6_notifier_work_queue);
4665#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004666 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004667 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004668 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004669
4670 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004671 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004672 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304673 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4674 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05304675
Ravi Joshi1a292562017-05-18 16:28:54 -07004676 /* Initialize NAN Data Interface */
4677 if (QDF_NDI_MODE == session_type) {
4678 status = hdd_init_nan_data_mode(adapter);
4679 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004680 goto err_free_netdev;
Ravi Joshi1a292562017-05-18 16:28:54 -07004681 }
4682
Alok Kumarb64650c2018-03-23 17:05:11 +05304683 hdd_nud_init_tracking(adapter);
4684
4685 qdf_mutex_create(&adapter->disconnection_status_lock);
4686
Ravi Joshi1a292562017-05-18 16:28:54 -07004687 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004688
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004689 case QDF_P2P_GO_MODE:
4690 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004691 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
4692 name_assign_type,
4693 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004694 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004695 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05304696 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004697 return NULL;
4698 }
4699
4700 adapter->wdev.iftype =
4701 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004702 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004703 NL80211_IFTYPE_P2P_GO;
4704 adapter->device_mode = session_type;
4705
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004706 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004707 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004708 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004709
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004710 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004711 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304712 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4713 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304714
4715 /*
4716 * Workqueue which gets scheduled in IPv4 notification
4717 * callback
4718 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004719 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304720 hdd_ipv4_notifier_work_queue);
4721
4722#ifdef WLAN_NS_OFFLOAD
4723 /*
4724 * Workqueue which gets scheduled in IPv6
4725 * notification callback.
4726 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004727 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304728 hdd_ipv6_notifier_work_queue);
4729#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004730 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304731 case QDF_FTM_MODE:
4732 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4733 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08004734 iface_name);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304735 if (NULL == adapter) {
4736 hdd_err("Failed to allocate adapter for FTM mode");
4737 return NULL;
4738 }
4739 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4740 adapter->device_mode = session_type;
4741 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004742 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004743 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004744
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304745 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004746 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304747 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304748 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4749 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304750 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004751 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004752 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304753 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004754 return NULL;
4755 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004756
hqueaa33ee2017-05-04 17:56:35 +08004757 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
4758
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304759 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004760 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08004761 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004762 }
4763
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304764 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004765 if (NULL != adapter) {
4766 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4767 adapter = NULL;
4768 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004770 return NULL;
4771 }
4772
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304773 if (QDF_STATUS_SUCCESS == status) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004774 policy_mgr_set_concurrency_mode(hdd_ctx->hdd_psoc,
4775 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004776
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004777 /* Adapter successfully added. Increment the vdev count */
4778 hdd_ctx->current_intf_count++;
4779
Jeff Johnson5880d792016-08-15 13:32:30 -07004780 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004781 hdd_ctx->current_intf_count);
4782
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004783 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004784 }
4785
Rajeev Kumardca5f812016-02-04 17:28:06 -08004786 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07004787 hdd_err("Interface %s wow debug_fs init failed",
4788 netdev_name(adapter->dev));
4789
4790 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
4791 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004792
4793 return adapter;
4794
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004795err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07004796 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05304797 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004798
4799 return NULL;
4800}
4801
Nirav Shaheb017be2018-02-15 11:20:58 +05304802#ifdef MSM_PLATFORM
4803static inline
4804void hdd_cancel_bus_bw_work(struct hdd_context *hdd_ctx)
4805{
4806 cancel_work_sync(&hdd_ctx->bus_bw_work);
4807}
4808#else
4809static inline
4810void hdd_cancel_bus_bw_work(struct hdd_context *hdd_ctx)
4811{
4812}
4813#endif
4814
Jeff Johnson9d295242017-08-29 14:39:48 -07004815QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004816 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004817{
Dustin Brown920397d2017-12-13 16:27:50 -08004818 /*
4819 * Here we are stopping global bus_bw timer & work per adapter.
4820 *
4821 * The reason is to fix one race condition between
4822 * bus bandwidth work and cleaning up an adapter.
4823 * Under some conditions, it is possible for the bus bandwidth
4824 * work to access a particularly destroyed adapter, leading to
4825 * use-after-free.
4826 */
4827 hdd_debug("wait for bus bw work to flush");
4828 hdd_bus_bw_compute_timer_stop(hdd_ctx);
4829 hdd_bus_bw_cancel_work(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004830
Dustin Brown920397d2017-12-13 16:27:50 -08004831 /* cleanup adapter */
4832 policy_mgr_clear_concurrency_mode(hdd_ctx->hdd_psoc,
4833 adapter->device_mode);
Dustin Brown920397d2017-12-13 16:27:50 -08004834 hdd_remove_adapter(hdd_ctx, adapter);
Liangwei Dongad89c762018-06-01 01:56:23 -04004835 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004836
Dustin Brown920397d2017-12-13 16:27:50 -08004837 /* conditionally restart the bw timer */
4838 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004839
Dustin Brown920397d2017-12-13 16:27:50 -08004840 /* Adapter removed. Decrement vdev count */
4841 if (hdd_ctx->current_intf_count != 0)
4842 hdd_ctx->current_intf_count--;
Dustin Brown5ec6b552017-03-31 12:11:40 -07004843
Dustin Brown920397d2017-12-13 16:27:50 -08004844 /* Fw will take care incase of concurrency */
4845 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004846}
4847
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004848/**
4849 * hdd_close_all_adapters - Close all open adapters
4850 * @hdd_ctx: Hdd context
4851 * rtnl_held: True if RTNL lock held
4852 *
4853 * Close all open adapters.
4854 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304855 * Return: QDF status code
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004856 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004857QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004858{
Dustin Brown920397d2017-12-13 16:27:50 -08004859 struct hdd_adapter *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304860 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004861
Dustin Brown491d54b2018-03-14 12:39:11 -07004862 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004863
4864 do {
Dustin Brown920397d2017-12-13 16:27:50 -08004865 status = hdd_remove_front_adapter(hdd_ctx, &adapter);
4866 if (QDF_IS_STATUS_SUCCESS(status)) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304867 wlan_hdd_release_intf_addr(hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08004868 adapter->mac_addr.bytes);
4869 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4870
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304871 /* Adapter removed. Decrement vdev count */
4872 if (hdd_ctx->current_intf_count != 0)
4873 hdd_ctx->current_intf_count--;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004874 }
Dustin Brown920397d2017-12-13 16:27:50 -08004875 } while (QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004876
Dustin Browne74003f2018-03-14 12:51:58 -07004877 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304879 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004880}
4881
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004882void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883{
Anurag Chouhan6d760662016-02-20 16:05:43 +05304884 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004885 tSirUpdateIE updateIE;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004886
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004887 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004888 case QDF_STA_MODE:
4889 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004890 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07004891 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004892 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -07004893 bssid = &sta_ctx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004894 break;
4895 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004896 case QDF_SAP_MODE:
4897 case QDF_P2P_GO_MODE:
4898 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004899 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07004900 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004901 break;
4902 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004903 case QDF_FTM_MODE:
4904 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004905 default:
4906 /*
4907 * wlan_hdd_reset_prob_rspies should not have been called
4908 * for these kind of devices
4909 */
Jeff Johnson5880d792016-08-15 13:32:30 -07004910 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004911 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004912 return;
4913 }
4914
Anurag Chouhanc5548422016-02-24 18:33:27 +05304915 qdf_copy_macaddr(&updateIE.bssid, bssid);
Jeff Johnson1b780e42017-10-31 14:11:45 -07004916 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004917 updateIE.ieBufferlength = 0;
4918 updateIE.pAdditionIEBuffer = NULL;
4919 updateIE.append = true;
4920 updateIE.notify = false;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004921 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004922 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304923 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004924 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004925 }
4926}
4927
Dustin Browndb2a8be2017-12-20 11:49:56 -08004928QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
4929 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004930{
Liangwei Dongad89c762018-06-01 01:56:23 -04004931 return hdd_stop_adapter_ext(hdd_ctx, adapter, 0);
4932}
4933
4934QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
4935 struct hdd_adapter *adapter,
4936 enum hdd_adapter_stop_flag_t flag)
4937{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304938 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Jeff Johnson025618c2018-03-18 14:41:00 -07004939 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004940 union iwreq_data wrqu;
4941 tSirUpdateIE updateIE;
4942 unsigned long rc;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07004943 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004944
Dustin Brown491d54b2018-03-14 12:39:11 -07004945 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004946
Dustin Browne7e71d32018-05-11 16:00:08 -07004947 if (adapter->session_id != HDD_SESSION_ID_INVALID)
4948 wlan_hdd_cfg80211_deregister_frames(adapter);
4949
Alok Kumarb64650c2018-03-23 17:05:11 +05304950 hdd_nud_ignore_tracking(adapter, true);
4951 hdd_nud_reset_tracking(adapter);
4952
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004953 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304954 wlan_hdd_netif_queue_control(adapter,
4955 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4956 WLAN_CONTROL_PATH);
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08004957 /*
4958 * if this is the last active connection check & stop the
4959 * opportunistic timer first
4960 */
4961 if (((policy_mgr_get_connection_count(hdd_ctx->hdd_psoc) == 1) &&
4962 (policy_mgr_mode_specific_connection_count(hdd_ctx->hdd_psoc,
4963 policy_mgr_convert_device_mode_to_qdf_type(
4964 adapter->device_mode), NULL) == 1)) ||
4965 !policy_mgr_get_connection_count(hdd_ctx->hdd_psoc))
4966 policy_mgr_check_and_stop_opportunistic_timer(
4967 hdd_ctx->hdd_psoc, adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004968 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004969 case QDF_STA_MODE:
4970 case QDF_P2P_CLIENT_MODE:
4971 case QDF_IBSS_MODE:
4972 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004973 case QDF_NDI_MODE:
4974 if ((QDF_NDI_MODE == adapter->device_mode) ||
4975 hdd_conn_is_connected(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004976 WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
4977 hdd_is_connecting(
4978 WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004979 INIT_COMPLETION(adapter->disconnect_comp_var);
Jeff Johnson025618c2018-03-18 14:41:00 -07004980 roam_profile = hdd_roam_profile(adapter);
4981 /* For NDI do not use roam_profile */
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004982 if (QDF_NDI_MODE == adapter->device_mode)
4983 qdf_ret_status = sme_roam_disconnect(
4984 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004985 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004986 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07004987 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004988 eCSR_BSS_TYPE_START_IBSS)
4989 qdf_ret_status = sme_roam_disconnect(
4990 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004991 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004992 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004993 else if (QDF_STA_MODE == adapter->device_mode) {
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004994 qdf_ret_status =
4995 wlan_hdd_try_disconnect(adapter);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004996 hdd_debug("Send disconnected event to userspace");
4997 wlan_hdd_cfg80211_indicate_disconnect(
4998 adapter->dev, true,
4999 WLAN_REASON_UNSPECIFIED);
Jeff Johnson109e79d2018-02-27 15:10:04 -08005000 } else
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005001 qdf_ret_status = sme_roam_disconnect(
5002 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005003 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005004 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005005 /* success implies disconnect command got
5006 * queued up successfully
5007 */
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005008 if (qdf_ret_status == QDF_STATUS_SUCCESS &&
5009 QDF_STA_MODE != adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005010 rc = wait_for_completion_timeout(
5011 &adapter->disconnect_comp_var,
5012 msecs_to_jiffies
5013 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005014 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005015 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005016 }
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005017 if (qdf_ret_status != QDF_STATUS_SUCCESS)
5018 hdd_warn("failed to post disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005019 memset(&wrqu, '\0', sizeof(wrqu));
5020 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5021 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5022 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5023 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305024 }
Wu Gaoaceec6c2017-08-30 16:08:21 +08005025 wlan_hdd_scan_abort(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005026
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305027 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305028 hdd_clear_fils_connection_info(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005029
5030#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005031 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005032#endif
5033
5034 hdd_deregister_tx_flow_control(adapter);
5035
5036#ifdef WLAN_NS_OFFLOAD
5037#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005038 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005039#endif
5040#endif
5041
Hanumanth Reddy Pothula05860142017-07-26 18:45:27 +05305042 if (adapter->device_mode == QDF_STA_MODE)
5043 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
5044 adapter->dev);
Dustin Browndb2a8be2017-12-20 11:49:56 -08005045
5046 if (wlan_hdd_try_disconnect(adapter)) {
5047 hdd_err("Error: Can't disconnect adapter");
5048 return QDF_STATUS_E_FAILURE;
Krunal Soni985b8132017-02-10 18:49:08 -08005049 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005050
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305051 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005052 break;
5053
Rajeev Kumar3b906202018-02-01 10:55:14 -08005054 case QDF_MONITOR_MODE:
5055 wlan_hdd_scan_abort(adapter);
5056 hdd_deregister_tx_flow_control(adapter);
5057 hdd_vdev_destroy(adapter);
5058 break;
5059
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005060 case QDF_SAP_MODE:
wadesongf9b15ed2017-12-14 14:12:32 +08005061 wlan_hdd_scan_abort(adapter);
Govind Singh1dab23b2017-08-12 13:31:00 +05305062 /* Flush IPA exception path packets */
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305063 sap_config = &adapter->session.ap.sap_config;
5064 if (sap_config)
5065 wlansap_reset_sap_config_add_ie(sap_config,
5066 eUPDATE_IE_ALL);
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +05305067 ucfg_ipa_flush(hdd_ctx->hdd_pdev);
Liangwei Dongad89c762018-06-01 01:56:23 -04005068 if (!(flag & HDD_IN_CAC_WORK_TH_CONTEXT))
5069 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Jeff Johnson46807cd2018-04-29 21:32:22 -07005070 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005071
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005072 case QDF_P2P_GO_MODE:
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07005073 if (QDF_SAP_MODE == adapter->device_mode) {
5074 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5075 cds_flush_delayed_work(
5076 &adapter->acs_pending_work);
5077 clear_bit(ACS_PENDING, &adapter->event_flags);
5078 }
5079 }
Krunal Soni22208392017-09-29 18:10:34 -07005080 cds_flush_work(&adapter->sap_stop_bss_work);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005081
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005082 /* Any softap specific cleanup here... */
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305083 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005084 wlan_hdd_undo_acs(adapter);
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005085 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5087
5088 hdd_deregister_tx_flow_control(adapter);
5089
Kapil Guptac1224bf2017-06-22 21:22:40 +05305090 hdd_destroy_acs_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091 mutex_lock(&hdd_ctx->sap_lock);
5092 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305093 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305094 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005095
5096 /* Stop Bss. */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097 status = wlansap_stop_bss(
5098 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005099
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305100 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005101 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005102 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305103 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305104 qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305105 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +05305106 qdf_wait_for_event_completion(
5107 &hostapd_state->qdf_stop_bss_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -08005108 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005109
Anurag Chouhance0dc992016-02-16 18:18:03 +05305110 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005111 hdd_err("failure waiting for wlansap_stop_bss %d",
5112 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005113 }
5114 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005115 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005116 }
5117 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005118 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
5119 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005120 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005121 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305122 adapter->device_mode,
5123 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124
Anurag Chouhanc5548422016-02-24 18:33:27 +05305125 qdf_copy_macaddr(&updateIE.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005126 &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005127 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005128 updateIE.ieBufferlength = 0;
5129 updateIE.pAdditionIEBuffer = NULL;
5130 updateIE.append = false;
5131 updateIE.notify = false;
5132 /* Probe bcn reset */
5133 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
5134 &updateIE, eUPDATE_IE_PROBE_BCN)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305135 == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005136 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005137 }
5138 /* Assoc resp reset */
5139 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
5140 &updateIE,
5141 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305142 QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005143 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005144 }
5145 /* Reset WNI_CFG_PROBE_RSP Flags */
5146 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005148 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005149 qdf_mem_free(adapter->session.ap.beacon);
5150 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005151
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305152 /*
5153 * If Do_Not_Break_Stream was enabled clear avoid channel list.
5154 */
5155 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev))
5156 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
5157
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305158#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005159 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305160#endif
5161
5162#ifdef WLAN_NS_OFFLOAD
5163#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005164 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305165#endif
5166#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08005167
5168 hdd_vdev_destroy(adapter);
5169
Krunal Sonib51eec72017-11-20 21:53:01 -08005170 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005171 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005172 case QDF_OCB_MODE:
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08005173 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005174 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
Leo Changfdb45c32016-10-28 11:09:23 -07005175 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.staId[0]);
Zhang Qian79d0d132018-02-05 13:40:16 +08005176 hdd_deregister_tx_flow_control(adapter);
5177 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005178 break;
5179 default:
5180 break;
5181 }
5182
Dustin Brown04348372017-12-14 16:13:39 -08005183 if (adapter->scan_info.default_scan_ies) {
5184 qdf_mem_free(adapter->scan_info.default_scan_ies);
5185 adapter->scan_info.default_scan_ies = NULL;
5186 }
5187
Dustin Browne74003f2018-03-14 12:51:58 -07005188 hdd_exit();
Dustin Brown04348372017-12-14 16:13:39 -08005189
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305190 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005191}
5192
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305193/**
5194 * hdd_deinit_all_adapters - deinit all adapters
5195 * @hdd_ctx: HDD context
5196 * @rtnl_held: True if RTNL lock held
5197 *
5198 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005199void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305200{
Jeff Johnson9d295242017-08-29 14:39:48 -07005201 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305202
Dustin Brown491d54b2018-03-14 12:39:11 -07005203 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305204
Dustin Brown920397d2017-12-13 16:27:50 -08005205 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305206 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305207
Dustin Browne74003f2018-03-14 12:51:58 -07005208 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305209}
5210
Dustin Browndb2a8be2017-12-20 11:49:56 -08005211QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212{
Jeff Johnson9d295242017-08-29 14:39:48 -07005213 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005214
Dustin Brown491d54b2018-03-14 12:39:11 -07005215 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005216
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305217 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5218
Dustin Brown920397d2017-12-13 16:27:50 -08005219 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08005220 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005221
Dustin Browne74003f2018-03-14 12:51:58 -07005222 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005223
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305224 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005225}
5226
Paul Zhang84fa9382017-11-10 21:18:21 +08005227static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
5228 struct hdd_adapter *adapter)
5229{
5230 switch (adapter->device_mode) {
5231 case QDF_STA_MODE:
5232 case QDF_P2P_CLIENT_MODE:
5233 case QDF_IBSS_MODE:
5234 case QDF_P2P_DEVICE_MODE:
5235 case QDF_NDI_MODE:
5236 wlan_hdd_scan_abort(adapter);
5237 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5238 if (adapter->device_mode == QDF_STA_MODE)
5239 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
5240 adapter->dev);
5241 break;
5242 case QDF_P2P_GO_MODE:
5243 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5244 break;
5245 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305246 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08005247 wlan_hdd_undo_acs(adapter);
5248 break;
5249 default:
5250 break;
5251 }
5252}
5253
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005254QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005255{
Jeff Johnson9d295242017-08-29 14:39:48 -07005256 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07005257 struct hdd_station_ctx *sta_ctx;
Yue Mad5b4b9f2017-05-26 16:23:40 -07005258 struct qdf_mac_addr peerMacAddr;
Yue Ma42654682018-01-11 16:55:24 -08005259 int sta_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005260
Dustin Brown491d54b2018-03-14 12:39:11 -07005261 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005262
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305263 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5264
Dustin Brown920397d2017-12-13 16:27:50 -08005265 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07005266 hdd_info("[SSR] reset adapter with device mode %s(%d)",
5267 hdd_device_mode_to_string(adapter->device_mode),
5268 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305269
5270 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08005271 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305272 /* Stop tdls timers */
Kabilan Kannan00d20412017-06-04 14:20:32 -07005273 hdd_notify_tdls_reset_adapter(adapter->hdd_vdev);
Paul Zhang679025e2018-03-08 22:39:44 +08005274 adapter->session.station.hdd_reassoc_scenario = false;
5275 }
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305276
Arun Khandavallicc544b32017-01-30 19:52:16 +05305277 if (hdd_ctx->config->sap_internal_restart &&
5278 adapter->device_mode == QDF_SAP_MODE) {
5279 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305280 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305281 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005282 if (test_bit(SOFTAP_BSS_STARTED,
Krunal Sonib51eec72017-11-20 21:53:01 -08005283 &adapter->event_flags))
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005284 hdd_sap_indicate_disconnect_for_sta(adapter);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005285 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
5286 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05305287 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305288 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005289 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005290 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005291
Paul Zhang84fa9382017-11-10 21:18:21 +08005292 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005293
5294 hdd_deinit_tx_rx(adapter);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005295 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005296 adapter->device_mode, adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005297 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305298 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005299 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
5300 hdd_wmm_adapter_close(adapter);
5301 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
5302 }
5303
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05305304 if (adapter->device_mode == QDF_STA_MODE)
5305 hdd_clear_fils_connection_info(adapter);
5306
Wu Gao3545e642017-07-14 19:24:41 +08005307 if (adapter->device_mode == QDF_SAP_MODE) {
5308 /*
5309 * If adapter is SAP, set session ID to invalid
5310 * since SAP session will be cleanup during SSR.
5311 */
Wu Gao36717432016-11-21 15:09:48 +08005312 wlansap_set_invalid_session(
5313 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
5314
Wu Gao3545e642017-07-14 19:24:41 +08005315 wlansap_cleanup_cac_timer(
5316 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
5317 }
5318
Yue Ma42654682018-01-11 16:55:24 -08005319 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07005320 if (adapter->device_mode == QDF_STA_MODE ||
5321 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005322 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005323 qdf_copy_macaddr(&peerMacAddr,
Jeff Johnsond377dce2017-10-04 10:32:42 -07005324 &sta_ctx->conn_info.bssId);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005325
5326 hdd_objmgr_remove_peer_object(adapter->hdd_vdev,
5327 peerMacAddr.bytes);
Yue Ma42654682018-01-11 16:55:24 -08005328 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Wu Gao6b81fc52018-05-24 19:27:27 +08005329 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Yue Ma42654682018-01-11 16:55:24 -08005330 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
5331 if (adapter->sta_info[sta_id].in_use) {
5332 hdd_debug("[SSR] deregister STA with ID %d",
5333 sta_id);
5334 hdd_softap_deregister_sta(adapter,
5335 sta_id);
5336 adapter->sta_info[sta_id].in_use = 0;
5337 }
5338 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07005339 }
5340
Alok Kumarb64650c2018-03-23 17:05:11 +05305341 hdd_nud_reset_tracking(adapter);
5342 hdd_nud_ignore_tracking(adapter, true);
5343 hdd_set_disconnect_status(adapter, false);
5344
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005345 hdd_softap_deinit_tx_rx(adapter);
5346
Yue Maf9782842017-05-08 12:49:49 -07005347 /* Destroy vdev which will be recreated during reinit. */
5348 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005349 }
5350
Dustin Browne74003f2018-03-14 12:51:58 -07005351 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005352
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305353 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005354}
5355
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005356bool hdd_check_for_opened_interfaces(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305357{
Dustin Brown920397d2017-12-13 16:27:50 -08005358 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305359 bool close_modules = true;
5360
Arun Khandavalliba479c42017-07-26 21:29:40 +05305361 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
5362 hdd_info("FTM mode, don't close the module");
5363 return false;
5364 }
5365
Dustin Brown920397d2017-12-13 16:27:50 -08005366 hdd_for_each_adapter(hdd_ctx, adapter) {
5367 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
5368 test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005369 hdd_debug("Still other ifaces are up cannot close modules");
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305370 close_modules = false;
5371 break;
5372 }
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305373 }
5374
5375 return close_modules;
5376}
5377
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05305378bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05305379{
5380 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
5381 return true;
5382 else
5383 return false;
5384}
5385
Anurag Chouhanc4092922016-09-08 15:56:11 +05305386#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08005387 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305388struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5389 struct ieee80211_channel *channel,
5390 const u8 *bssid, const u8 *ssid,
5391 size_t ssid_len)
5392{
5393 return cfg80211_get_bss(wiphy, channel, bssid,
5394 ssid, ssid_len,
5395 WLAN_CAPABILITY_ESS,
5396 WLAN_CAPABILITY_ESS);
5397}
5398#else
5399struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5400 struct ieee80211_channel *channel,
5401 const u8 *bssid, const u8 *ssid,
5402 size_t ssid_len)
5403{
5404 return cfg80211_get_bss(wiphy, channel, bssid,
5405 ssid, ssid_len,
5406 IEEE80211_BSS_TYPE_ESS,
5407 IEEE80211_PRIVACY_ANY);
5408}
5409#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305410
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305411#if defined CFG80211_CONNECT_BSS || \
5412 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305413#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305414 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305415/**
5416 * hdd_convert_timeout_reason() - Convert to kernel specific enum
5417 * @timeout_reason: reason for connect timeout
5418 *
5419 * This function is used to convert host timeout
5420 * reason enum to kernel specific enum.
5421 *
5422 * Return: nl timeout enum
5423 */
5424static enum nl80211_timeout_reason hdd_convert_timeout_reason(
5425 tSirResultCodes timeout_reason)
5426{
5427 switch (timeout_reason) {
5428 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5429 return NL80211_TIMEOUT_SCAN;
5430 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5431 return NL80211_TIMEOUT_AUTH;
5432 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5433 return NL80211_TIMEOUT_ASSOC;
5434 default:
5435 return NL80211_TIMEOUT_UNSPECIFIED;
5436 }
5437}
5438
5439/**
5440 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5441 * @dev: network device
5442 * @bssid: bssid to which we want to associate
5443 * @timeout_reason: reason for connect timeout
5444 *
5445 * This API is used to send connection timeout reason to supplicant
5446 *
5447 * Return: void
5448 */
5449static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5450 const u8 *bssid,
5451 tSirResultCodes timeout_reason)
5452{
5453 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005454
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305455 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5456
5457 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
5458 nl_timeout_reason);
5459}
5460
5461/**
5462 * __hdd_connect_bss() - API to send connection status to supplicant
5463 * @dev: network device
5464 * @bssid: bssid to which we want to associate
5465 * @req_ie: Request Information Element
5466 * @req_ie_len: len of the req IE
5467 * @resp_ie: Response IE
5468 * @resp_ie_len: len of ht response IE
5469 * @status: status
5470 * @gfp: Kernel Flag
5471 * @timeout_reason: reason for connect timeout
5472 *
5473 * Return: void
5474 */
5475static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5476 struct cfg80211_bss *bss, const u8 *req_ie,
5477 size_t req_ie_len, const u8 *resp_ie,
5478 size_t resp_ie_len, int status, gfp_t gfp,
5479 tSirResultCodes timeout_reason)
5480{
5481 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005482
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305483 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5484
5485 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5486 resp_ie, resp_ie_len, status, gfp,
5487 nl_timeout_reason);
5488}
5489#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305490#if defined CFG80211_CONNECT_TIMEOUT || \
5491 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305492static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5493 const u8 *bssid,
5494 tSirResultCodes timeout_reason)
5495{
5496 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
5497}
5498#endif
5499
5500static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5501 struct cfg80211_bss *bss, const u8 *req_ie,
5502 size_t req_ie_len, const u8 *resp_ie,
5503 size_t resp_ie_len, int status, gfp_t gfp,
5504 tSirResultCodes timeout_reason)
5505{
5506 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5507 resp_ie, resp_ie_len, status, gfp);
5508}
5509#endif
5510
Abhishek Singha84d3952016-09-13 13:45:05 +05305511/**
5512 * hdd_connect_bss() - API to send connection status to supplicant
5513 * @dev: network device
5514 * @bssid: bssid to which we want to associate
5515 * @req_ie: Request Information Element
5516 * @req_ie_len: len of the req IE
5517 * @resp_ie: Response IE
5518 * @resp_ie_len: len of ht response IE
5519 * @status: status
5520 * @gfp: Kernel Flag
5521 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305522 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05305523 *
5524 * The API is a wrapper to send connection status to supplicant
5525 *
5526 * Return: Void
5527 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305528#if defined CFG80211_CONNECT_TIMEOUT || \
5529 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05305530static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5531 struct cfg80211_bss *bss, const u8 *req_ie,
5532 size_t req_ie_len, const u8 *resp_ie,
5533 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305534 bool connect_timeout,
5535 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305536{
5537 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305538 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305539 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305540 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5541 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305542}
5543#else
5544static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5545 struct cfg80211_bss *bss, const u8 *req_ie,
5546 size_t req_ie_len, const u8 *resp_ie,
5547 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305548 bool connect_timeout,
5549 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305550{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305551 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5552 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305553}
5554#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305555
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305556#if defined(WLAN_FEATURE_FILS_SK)
5557#if defined(CFG80211_CONNECT_DONE) || \
5558 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
5559#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
5560 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305561/**
5562 * hdd_populate_fils_params() - Populate FILS keys to connect response
5563 * @fils_params: connect response to supplicant
5564 * @fils_kek: FILS kek
5565 * @fils_kek_len: FILS kek length
5566 * @pmk: FILS PMK
5567 * @pmk_len: FILS PMK length
5568 * @pmkid: PMKID
5569 * @fils_seq_num: FILS Seq number
5570 *
5571 * Return: None
5572 */
5573static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5574 *fils_params, const uint8_t *fils_kek,
5575 size_t fils_kek_len, const uint8_t *pmk,
5576 size_t pmk_len, const uint8_t *pmkid,
5577 uint16_t fils_seq_num)
5578{
5579 /* Increament seq number to be used for next FILS */
5580 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
5581 fils_params->update_erp_next_seq_num = true;
5582 fils_params->fils_kek = fils_kek;
5583 fils_params->fils_kek_len = fils_kek_len;
5584 fils_params->pmk = pmk;
5585 fils_params->pmk_len = pmk_len;
5586 fils_params->pmkid = pmkid;
5587}
5588#else
5589static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5590 *fils_params, const uint8_t
5591 *fils_kek, size_t fils_kek_len,
5592 const uint8_t *pmk, size_t pmk_len,
5593 const uint8_t *pmkid,
5594 uint16_t fils_seq_num)
5595{ }
5596#endif
5597
Jeff Johnson172237b2017-11-07 15:32:59 -08005598void hdd_update_hlp_info(struct net_device *dev,
5599 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305600{
5601 struct sk_buff *skb;
5602 uint16_t skb_len;
5603 struct llc_snap_hdr_t *llc_hdr;
5604 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305605 uint8_t *hlp_data;
5606 uint16_t hlp_data_len;
5607 struct fils_join_rsp_params *roam_fils_params
5608 = roam_info->fils_join_rsp;
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305609 struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
5610
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305611 if (!roam_fils_params) {
5612 hdd_err("FILS Roam Param NULL");
5613 return;
5614 }
5615
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08005616 if (!roam_fils_params->hlp_data_len) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305617 hdd_err("FILS HLP Data NULL, len %d",
5618 roam_fils_params->hlp_data_len);
5619 return;
5620 }
5621
5622 hlp_data = roam_fils_params->hlp_data;
5623 hlp_data_len = roam_fils_params->hlp_data_len;
5624
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305625 /* Calculate skb length */
5626 skb_len = (2 * ETH_ALEN) + hlp_data_len;
5627 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
5628 if (skb == NULL) {
5629 hdd_err("HLP packet nbuf alloc fails");
5630 return;
5631 }
5632
5633 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
5634 QDF_MAC_ADDR_SIZE);
5635 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
5636 QDF_MAC_ADDR_SIZE);
5637
5638 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
5639 if (IS_SNAP(llc_hdr)) {
5640 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5641 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5642 }
5643
5644 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
5645
5646 /*
5647 * This HLP packet is formed from HLP info encapsulated
5648 * in assoc response frame which is AEAD encrypted.
5649 * Hence, this checksum validation can be set unnecessary.
5650 * i.e. network layer need not worry about checksum.
5651 */
5652 skb->ip_summed = CHECKSUM_UNNECESSARY;
5653
5654 status = hdd_rx_packet_cbk(padapter, skb);
5655 if (QDF_IS_STATUS_ERROR(status)) {
5656 hdd_err("Sending HLP packet fails");
5657 return;
5658 }
5659 hdd_debug("send HLP packet to netif successfully");
5660}
5661
5662/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305663 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
5664 * @dev: network device
5665 * @bssid: bssid to which we want to associate
5666 * @bss: cfg80211 bss info
5667 * @roam_info: information about connected bss
5668 * @req_ie: Request Information Element
5669 * @req_ie_len: len of the req IE
5670 * @resp_ie: Response IE
5671 * @resp_ie_len: len of ht response IE
5672 * @status: status
5673 * @gfp: allocation flags
5674 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5675 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305676 *
5677 * This API is used as wrapper to send FILS key/sequence number
5678 * params etc. to supplicant in case of FILS connection
5679 *
5680 * Return: None
5681 */
5682static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005683 struct cfg80211_bss *bss,
5684 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305685 const u8 *req_ie, size_t req_ie_len,
5686 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005687 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305688 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305689{
5690 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305691 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5692 struct fils_join_rsp_params *roam_fils_params =
5693 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005694
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305695 qdf_mem_zero(&fils_params, sizeof(fils_params));
5696
5697 if (!roam_fils_params) {
5698 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
5699 } else {
5700 fils_params.status = status;
5701 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08005702 fils_params.timeout_reason =
5703 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305704 fils_params.req_ie = req_ie;
5705 fils_params.req_ie_len = req_ie_len;
5706 fils_params.resp_ie = resp_ie;
5707 fils_params.resp_ie_len = resp_ie_len;
5708 fils_params.bss = bss;
5709 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
5710 roam_fils_params->kek_len,
5711 roam_fils_params->fils_pmk,
5712 roam_fils_params->fils_pmk_len,
5713 roam_fils_params->fils_pmkid,
5714 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05305715 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305716 }
5717 hdd_debug("FILS indicate connect status %d seq no %d",
5718 fils_params.status,
5719 fils_params.fils_erp_next_seq_num);
5720
5721 cfg80211_connect_done(dev, &fils_params, gfp);
5722
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305723 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305724 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305725
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305726 /* Clear all the FILS key info */
5727 if (roam_fils_params && roam_fils_params->fils_pmk)
5728 qdf_mem_free(roam_fils_params->fils_pmk);
5729 if (roam_fils_params)
5730 qdf_mem_free(roam_fils_params);
5731 roam_info->fils_join_rsp = NULL;
5732}
5733#else
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005734static inline void
5735hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005736 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005737 const u8 *req_ie, size_t req_ie_len,
5738 const u8 *resp_ie, size_t resp_ie_len, u16 status,
5739 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305740 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305741{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305742#endif
5743#endif
5744
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305745#if defined(WLAN_FEATURE_FILS_SK) && \
5746 (defined(CFG80211_CONNECT_DONE) || \
5747 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305748/**
5749 * hdd_fils_update_connect_results() - API to send fils connection status to
5750 * supplicant.
5751 * @dev: network device
5752 * @bssid: bssid to which we want to associate
5753 * @bss: cfg80211 bss info
5754 * @roam_info: information about connected bss
5755 * @req_ie: Request Information Element
5756 * @req_ie_len: len of the req IE
5757 * @resp_ie: Response IE
5758 * @resp_ie_len: len of ht response IE
5759 * @status: status
5760 * @gfp: allocation flags
5761 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5762 * @timeout_reason: reason for connect timeout
5763 *
5764 * The API is a wrapper to send connection status to supplicant
5765 *
5766 * Return: 0 if success else failure
5767 */
5768static int hdd_fils_update_connect_results(struct net_device *dev,
5769 const u8 *bssid,
5770 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005771 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305772 size_t req_ie_len, const u8 *resp_ie,
5773 size_t resp_ie_len, u16 status, gfp_t gfp,
5774 bool connect_timeout,
5775 tSirResultCodes timeout_reason)
5776{
Dustin Brown491d54b2018-03-14 12:39:11 -07005777 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305778 if (!roam_info || !roam_info->is_fils_connection)
5779 return -EINVAL;
5780
5781 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
5782 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305783 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305784 return 0;
5785}
5786#else
5787static inline int hdd_fils_update_connect_results(struct net_device *dev,
5788 const u8 *bssid,
5789 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005790 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305791 size_t req_ie_len, const u8 *resp_ie,
5792 size_t resp_ie_len, u16 status, gfp_t gfp,
5793 bool connect_timeout,
5794 tSirResultCodes timeout_reason)
5795{
5796 return -EINVAL;
5797}
5798#endif
5799
Anurag Chouhanc4092922016-09-08 15:56:11 +05305800/**
5801 * hdd_connect_result() - API to send connection status to supplicant
5802 * @dev: network device
5803 * @bssid: bssid to which we want to associate
5804 * @roam_info: information about connected bss
5805 * @req_ie: Request Information Element
5806 * @req_ie_len: len of the req IE
5807 * @resp_ie: Response IE
5808 * @resp_ie_len: len of ht response IE
5809 * @status: status
5810 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05305811 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305812 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05305813 *
5814 * The API is a wrapper to send connection status to supplicant
5815 * and allow runtime suspend
5816 *
5817 * Return: Void
5818 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05305819void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005820 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305821 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305822 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305823 bool connect_timeout,
5824 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305825{
Jeff Johnson9d295242017-08-29 14:39:48 -07005826 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305827 struct cfg80211_bss *bss = NULL;
Jingxiang Ge929c7932018-01-24 14:01:12 +08005828 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305829
5830 if (WLAN_STATUS_SUCCESS == status) {
5831 struct ieee80211_channel *chan;
5832 int freq;
5833 int chan_no = roam_info->pBssDesc->channelId;
5834
5835 if (chan_no <= 14)
5836 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005837 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305838 else
5839 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005840 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305841
5842 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
5843 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
5844 roam_info->u.pConnectedProfile->SSID.ssId,
5845 roam_info->u.pConnectedProfile->SSID.length);
5846 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305847
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305848 if (hdd_fils_update_connect_results(dev, bssid, bss,
5849 roam_info, req_ie, req_ie_len, resp_ie,
5850 resp_ie_len, status, gfp, connect_timeout,
5851 timeout_reason) != 0) {
5852 hdd_connect_bss(dev, bssid, bss, req_ie,
5853 req_ie_len, resp_ie, resp_ie_len,
5854 status, gfp, connect_timeout, timeout_reason);
5855 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305856
Jingxiang Geb49aa302018-01-17 20:54:15 +08005857 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005858 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305859}
5860#else
5861void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005862 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305863 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305864 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305865 bool connect_timeout,
5866 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305867{
Jeff Johnson9d295242017-08-29 14:39:48 -07005868 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Jingxiang Ge929c7932018-01-24 14:01:12 +08005869 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05305870
Anurag Chouhanc4092922016-09-08 15:56:11 +05305871 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
5872 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08005873
Jingxiang Geb49aa302018-01-17 20:54:15 +08005874 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005875 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305876}
5877#endif
5878
Jeff Johnsond9952752018-04-18 12:15:35 -07005879int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
5880 uint32_t bandwidth)
5881{
5882 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5883 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5884 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
5885 QDF_STATUS status;
5886 tHalHandle hal_hdl = hdd_ctx->hHal;
5887 struct qdf_mac_addr bssid;
5888 struct csr_roam_profile roam_profile;
5889 struct ch_params ch_params;
5890
5891 if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) {
5892 hdd_err("Not supported, device is not in monitor mode");
5893 return -EINVAL;
5894 }
5895
Visweswara Tanuku006313a2018-04-12 12:26:34 +05305896 /* Validate Channel */
5897 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
5898 hdd_err("Channel %d Not supported", chan);
5899 return -EINVAL;
5900 }
5901
5902 if (WLAN_REG_IS_24GHZ_CH(chan)) {
5903 if (bandwidth == CH_WIDTH_80MHZ) {
5904 hdd_err("BW80 not possible in 2.4GHz band");
5905 return -EINVAL;
5906 }
5907 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
5908 (bandwidth != CH_WIDTH_MAX)) {
5909 hdd_err("Only BW20 possible on channel 14");
5910 return -EINVAL;
5911 }
5912 }
5913
5914 if (WLAN_REG_IS_5GHZ_CH(chan)) {
5915 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
5916 (bandwidth != CH_WIDTH_MAX)) {
5917 hdd_err("Only BW20 possible on channel 165");
5918 return -EINVAL;
5919 }
5920 }
5921
Jeff Johnsond9952752018-04-18 12:15:35 -07005922 hdd_debug("Set monitor mode Channel %d", chan);
5923 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
5924 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
5925 roam_profile.ChannelInfo.numOfChannels = 1;
5926 roam_profile.phyMode = ch_info->phy_mode;
5927 roam_profile.ch_params.ch_width = bandwidth;
5928 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
5929
5930 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
5931 QDF_MAC_ADDR_SIZE);
5932
5933 ch_params.ch_width = bandwidth;
5934 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, chan, 0, &ch_params);
5935 if (ch_params.ch_width == CH_WIDTH_INVALID) {
5936 hdd_err("Invalid capture channel or bandwidth for a country");
5937 return -EINVAL;
5938 }
5939 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
5940 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
5941 hdd_err("Failed to change hw mode");
5942 return -EINVAL;
5943 }
5944
5945 status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
5946 &roam_profile);
5947 if (status) {
5948 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
5949 status);
5950 }
5951
5952 adapter->mon_chan = chan;
5953 adapter->mon_bandwidth = bandwidth;
5954 return qdf_status_to_os_return(status);
5955}
Anurag Chouhanc4092922016-09-08 15:56:11 +05305956
Wu Gaodf929f12018-05-25 18:12:25 +08005957#ifdef MSM_PLATFORM
5958/**
5959 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
5960 * @adapter: pointer to adapter
5961 *
5962 * This function calls cfg80211 API to stop P2P GO
5963 *
5964 * Return: None
5965 */
5966static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
5967{
5968 hdd_debug("[SSR] send stop ap to supplicant");
5969 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
5970}
5971
5972static inline void hdd_delete_sta(struct hdd_adapter *adapter)
5973{
5974}
5975#else
5976static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
5977{
5978}
5979
5980/**
5981 * hdd_delete_sta() - call cfg80211 API to delete STA
5982 * @adapter: pointer to adapter
5983 *
5984 * This function calls cfg80211 API to delete STA
5985 *
5986 * Return: None
5987 */
5988static void hdd_delete_sta(struct hdd_adapter *adapter)
5989{
5990 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
5991
5992 hdd_debug("[SSR] send restart supplicant");
5993 /* event supplicant to restart */
5994 cfg80211_del_sta(adapter->dev,
5995 (const u8 *)&bcast_mac.bytes[0],
5996 GFP_KERNEL);
5997}
5998#endif
5999
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006000QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006001{
Jeff Johnson9d295242017-08-29 14:39:48 -07006002 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006003 eConnectionState connState;
6004
Dustin Brown491d54b2018-03-14 12:39:11 -07006005 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006006
Dustin Brown920397d2017-12-13 16:27:50 -08006007 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306008 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006009 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306010
Yue Ma42654682018-01-11 16:55:24 -08006011 hdd_debug("[SSR] start adapter with device mode %s(%d)",
6012 hdd_device_mode_to_string(adapter->device_mode),
6013 adapter->device_mode);
6014
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006015 hdd_wmm_init(adapter);
6016
6017 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006018 case QDF_STA_MODE:
6019 case QDF_P2P_CLIENT_MODE:
6020 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006021
6022 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6023 ->conn_info.connState;
6024
Krunal Sonib51eec72017-11-20 21:53:01 -08006025 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006026 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006027 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006028
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006029 /* Indicate disconnect event to supplicant
6030 * if associated previously
6031 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006032 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07006033 eConnectionState_IbssConnected == connState ||
6034 eConnectionState_NotConnected == connState ||
6035 eConnectionState_IbssDisconnected == connState ||
6036 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006037 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006038
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006039 memset(&wrqu, '\0', sizeof(wrqu));
6040 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6041 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
6042 wireless_send_event(adapter->dev, SIOCGIWAP,
6043 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006044 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07006045 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006046
6047 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05306048 wlan_hdd_cfg80211_indicate_disconnect(
6049 adapter->dev, false,
6050 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006051 } else if (eConnectionState_Connecting == connState) {
6052 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006053 * Indicate connect failure to supplicant if we
6054 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006055 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306056 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306057 NULL, 0, NULL, 0,
6058 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006059 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006060 }
6061
6062 hdd_register_tx_flow_control(adapter,
6063 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08006064 hdd_tx_resume_cb,
6065 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006066
Alok Kumarb64650c2018-03-23 17:05:11 +05306067 hdd_nud_ignore_tracking(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006068 break;
6069
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006070 case QDF_SAP_MODE:
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006071 if (hdd_ctx->config->sap_internal_restart)
Krunal Sonib51eec72017-11-20 21:53:01 -08006072 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05306073
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006074 break;
6075
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006076 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08006077 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006078 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306079 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08006080 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306081 hdd_set_mon_rx_cb(adapter->dev);
6082 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
6083 adapter->mon_bandwidth);
6084 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006085 default:
6086 break;
6087 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07006088 /*
6089 * Action frame registered in one adapter which will
6090 * applicable to all interfaces
6091 */
6092 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006093 }
6094
Wu Gaodf929f12018-05-25 18:12:25 +08006095 hdd_for_each_adapter(hdd_ctx, adapter) {
6096 if (!hdd_is_interface_up(adapter))
6097 continue;
6098
6099 if (adapter->device_mode == QDF_P2P_GO_MODE)
6100 hdd_stop_p2p_go(adapter);
6101 }
6102
Dustin Browne74003f2018-03-14 12:51:58 -07006103 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006104
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306105 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006106}
6107
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006108QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006109 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006110{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306111 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006112 qdf_list_node_t *node;
6113
6114 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006115
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006116 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006117 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006118 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006119
6120 if (QDF_IS_STATUS_ERROR(status))
6121 return status;
6122
6123 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6124
6125 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006126}
6127
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006128QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006129 struct hdd_adapter *current_adapter,
6130 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006131{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306132 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006133 qdf_list_node_t *node;
6134
6135 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006136
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006137 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006138 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08006139 &current_adapter->node,
6140 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006141 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006142
6143 if (QDF_IS_STATUS_ERROR(status))
6144 return status;
6145
6146 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6147
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006148 return status;
6149}
6150
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006151QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006152 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006153{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306154 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006155
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006156 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006157 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006158 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006159
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006160 return status;
6161}
6162
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006163QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006164 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006165{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306166 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006167 qdf_list_node_t *node;
6168
6169 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006170
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006171 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006172 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006173 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006174
6175 if (QDF_IS_STATUS_ERROR(status))
6176 return status;
6177
6178 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6179
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006180 return status;
6181}
6182
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006183QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006184 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006185{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306186 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006187
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006188 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006189 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006190 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006191
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006192 return status;
6193}
6194
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006195QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006196 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006197{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306198 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006199
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006200 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006201 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006202 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006203
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006204 return status;
6205}
6206
Jeff Johnson9d295242017-08-29 14:39:48 -07006207struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006208 tSirMacAddr macAddr)
6209{
Jeff Johnson9d295242017-08-29 14:39:48 -07006210 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006211
Dustin Brown920397d2017-12-13 16:27:50 -08006212 hdd_for_each_adapter(hdd_ctx, adapter) {
6213 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
6214 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006215 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006216 }
6217
6218 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006219}
6220
Jeff Johnson9d295242017-08-29 14:39:48 -07006221struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006222 uint32_t vdev_id)
6223{
Jeff Johnson9d295242017-08-29 14:39:48 -07006224 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006225
Dustin Brown920397d2017-12-13 16:27:50 -08006226 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07006227 if (adapter->session_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006228 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006229 }
6230
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006231 return NULL;
6232}
6233
Abhishek Singh7996eb72015-12-30 17:24:02 +05306234/**
6235 * hdd_get_adapter_by_sme_session_id() - Return adapter with
6236 * the sessionid
6237 * @hdd_ctx: hdd context.
6238 * @sme_session_id: sme session is for the adapter to get.
6239 *
6240 * This function is used to get the adapter with provided session id
6241 *
6242 * Return: adapter pointer if found
6243 *
6244 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07006245struct hdd_adapter *
6246hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
6247 uint32_t sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306248{
Jeff Johnson9d295242017-08-29 14:39:48 -07006249 struct hdd_adapter *adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306250
Dustin Brown920397d2017-12-13 16:27:50 -08006251 hdd_for_each_adapter(hdd_ctx, adapter) {
6252 if (adapter->session_id == sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306253 return adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306254 }
Dustin Brown920397d2017-12-13 16:27:50 -08006255
Abhishek Singh7996eb72015-12-30 17:24:02 +05306256 return NULL;
6257}
6258
Jeff Johnson9d295242017-08-29 14:39:48 -07006259struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07006260 const char *iface_name)
6261{
Jeff Johnson9d295242017-08-29 14:39:48 -07006262 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006263
Dustin Brown920397d2017-12-13 16:27:50 -08006264 hdd_for_each_adapter(hdd_ctx, adapter) {
6265 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07006266 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006267 }
Dustin Brown920397d2017-12-13 16:27:50 -08006268
Naveen Rawat4edb6822017-04-12 10:09:17 -07006269 return NULL;
6270}
6271
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006272/**
6273 * hdd_get_adapter() - to get adapter matching the mode
6274 * @hdd_ctx: hdd context
6275 * @mode: adapter mode
6276 *
6277 * This routine will return the pointer to adapter matching
6278 * with the passed mode.
6279 *
6280 * Return: pointer to adapter or null
6281 */
Jeff Johnson9d295242017-08-29 14:39:48 -07006282struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006283 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006284{
Jeff Johnson9d295242017-08-29 14:39:48 -07006285 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006286
Dustin Brown920397d2017-12-13 16:27:50 -08006287 hdd_for_each_adapter(hdd_ctx, adapter) {
6288 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006289 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006290 }
6291
6292 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293}
6294
Jeff Johnson36a0abf2018-05-20 11:24:25 -07006295enum QDF_OPMODE hdd_get_device_mode(uint32_t session_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306296{
6297 struct hdd_context *hdd_ctx;
6298 struct hdd_adapter *adapter;
6299
6300 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6301 if (!hdd_ctx) {
6302 hdd_err("Invalid HDD context");
6303 return QDF_MAX_NO_OF_MODE;
6304 }
6305
6306 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
6307 if (!adapter) {
6308 hdd_err("Invalid HDD adapter");
6309 return QDF_MAX_NO_OF_MODE;
6310 }
6311
6312 return adapter->device_mode;
6313}
6314
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006315/**
6316 * hdd_get_operating_channel() - return operating channel of the device mode
6317 * @hdd_ctx: Pointer to the HDD context.
6318 * @mode: Device mode for which operating channel is required.
Jeff Johnson77f89bb2018-05-06 16:21:36 -07006319 * Supported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006320 * QDF_STA_MODE,
6321 * QDF_P2P_CLIENT_MODE,
6322 * QDF_SAP_MODE,
6323 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006324 *
6325 * This API returns the operating channel of the requested device mode
6326 *
6327 * Return: channel number. "0" id the requested device is not found OR it is
6328 * not connected.
6329 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006330uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006331 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006332{
Jeff Johnson9d295242017-08-29 14:39:48 -07006333 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006334 uint8_t operatingChannel = 0;
6335
Dustin Brown920397d2017-12-13 16:27:50 -08006336 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006337 if (mode == adapter->device_mode) {
6338 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006339 case QDF_STA_MODE:
6340 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006341 if (hdd_conn_is_connected
6342 (WLAN_HDD_GET_STATION_CTX_PTR
6343 (adapter))) {
6344 operatingChannel =
6345 (WLAN_HDD_GET_STATION_CTX_PTR
6346 (adapter))->conn_info.
6347 operationChannel;
6348 }
6349 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006350 case QDF_SAP_MODE:
6351 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006352 /* softap connection info */
6353 if (test_bit
6354 (SOFTAP_BSS_STARTED,
6355 &adapter->event_flags))
6356 operatingChannel =
6357 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07006358 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006359 break;
6360 default:
6361 break;
6362 }
6363
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006364 /* Found the device of interest. break the loop */
6365 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006366 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006367 }
Dustin Brown920397d2017-12-13 16:27:50 -08006368
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006369 return operatingChannel;
6370}
6371
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006372static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006373 hdd_ctx)
6374{
Jeff Johnson9d295242017-08-29 14:39:48 -07006375 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006376
Dustin Brown491d54b2018-03-14 12:39:11 -07006377 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006378
Dustin Brown920397d2017-12-13 16:27:50 -08006379 hdd_for_each_adapter(hdd_ctx, adapter) {
6380 if (adapter->device_mode == QDF_STA_MODE ||
6381 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6382 adapter->device_mode == QDF_IBSS_MODE ||
6383 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6384 adapter->device_mode == QDF_SAP_MODE ||
6385 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006386 hdd_unregister_wext(adapter->dev);
6387 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006388 }
6389
Dustin Browne74003f2018-03-14 12:51:58 -07006390 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006391
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306392 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006393}
6394
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006395QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006396{
Jeff Johnson9d295242017-08-29 14:39:48 -07006397 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006398
Dustin Brown491d54b2018-03-14 12:39:11 -07006399 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006400
Dustin Brown920397d2017-12-13 16:27:50 -08006401 hdd_for_each_adapter(hdd_ctx, adapter) {
6402 if (adapter->device_mode == QDF_STA_MODE ||
6403 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6404 adapter->device_mode == QDF_IBSS_MODE ||
6405 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6406 adapter->device_mode == QDF_SAP_MODE ||
6407 adapter->device_mode == QDF_P2P_GO_MODE) {
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07006408 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006409 adapter->session_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05306410 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006411 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006412 }
6413
Dustin Browne74003f2018-03-14 12:51:58 -07006414 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006415
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306416 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006417}
6418
Dustin Brownf27bce82016-11-03 12:52:27 -07006419/**
6420 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
6421 * adapters
6422 * @hdd_ctx: The HDD context containing the adapters to operate on
6423 *
6424 * return: QDF_STATUS_SUCCESS
6425 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006426static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07006427{
Jeff Johnson9d295242017-08-29 14:39:48 -07006428 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07006429 int err;
6430
Dustin Brown491d54b2018-03-14 12:39:11 -07006431 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07006432
Dustin Brown920397d2017-12-13 16:27:50 -08006433 hdd_for_each_adapter(hdd_ctx, adapter) {
6434 if (adapter->device_mode == QDF_STA_MODE ||
6435 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6436 adapter->device_mode == QDF_IBSS_MODE ||
6437 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6438 adapter->device_mode == QDF_SAP_MODE ||
6439 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07006440 err = wlan_hdd_sched_scan_stop(adapter->dev);
6441 if (err)
6442 hdd_err("Unable to stop scheduled scan");
6443 }
Dustin Brownf27bce82016-11-03 12:52:27 -07006444 }
6445
Dustin Browne74003f2018-03-14 12:51:58 -07006446 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07006447
6448 return QDF_STATUS_SUCCESS;
6449}
6450
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006451#ifdef WLAN_NS_OFFLOAD
6452/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006453 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006454 * @hdd_ctx: Pointer to hdd context
6455 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006456 * Unregister for IPv6 address change notifications.
6457 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006458 * Return: None
6459 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006460static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006461{
6462 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006463}
6464
6465/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006466 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006467 * @hdd_ctx: Pointer to hdd context
6468 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006469 * Register for IPv6 address change notifications.
6470 *
6471 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006472 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006473static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006474{
6475 int ret;
6476
6477 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6478 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006479 if (ret) {
6480 hdd_err("Failed to register IPv6 notifier: %d", ret);
6481 goto out;
6482 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006483
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006484 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006485out:
6486 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006487}
6488#else
6489/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006490 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006491 * @hdd_ctx: Pointer to hdd context
6492 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006493 * Unregister for IPv6 address change notifications.
6494 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006495 * Return: None
6496 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006497static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006498{
6499}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006500
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006501/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006502 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006503 * @hdd_ctx: Pointer to hdd context
6504 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006505 * Register for IPv6 address change notifications.
6506 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006507 * Return: None
6508 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006509static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006510{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006511 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006512}
6513#endif
6514
Alok Kumarb64650c2018-03-23 17:05:11 +05306515void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
6516{
6517 qdf_mutex_acquire(&adapter->disconnection_status_lock);
6518 adapter->disconnection_in_progress = status;
6519 qdf_mutex_release(&adapter->disconnection_status_lock);
6520 hdd_debug("setting disconnection status: %d", status);
6521}
6522
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006523/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006524 * hdd_register_notifiers - Register netdev notifiers.
6525 * @hdd_ctx: HDD context
6526 *
6527 * Register netdev notifiers like IPv4 and IPv6.
6528 *
6529 * Return: 0 on success and errno on failure
6530 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006531static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006532{
6533 int ret;
6534
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006535 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
6536 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05306537 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006538
6539 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
6540 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
6541 if (ret) {
6542 hdd_err("Failed to register IPv4 notifier: %d", ret);
6543 goto unregister_ip6_notifier;
6544 }
6545
Alok Kumarb64650c2018-03-23 17:05:11 +05306546 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
6547 if (ret) {
6548 hdd_err("Failed to register netevent notifier: %d",
6549 ret);
6550 goto unregister_inetaddr_notifier;
6551 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006552 return 0;
6553
Alok Kumarb64650c2018-03-23 17:05:11 +05306554unregister_inetaddr_notifier:
6555 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006556unregister_ip6_notifier:
6557 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006558out:
6559 return ret;
6560
6561}
6562
6563/**
6564 * hdd_unregister_notifiers - Unregister netdev notifiers.
6565 * @hdd_ctx: HDD context
6566 *
6567 * Unregister netdev notifiers like IPv4 and IPv6.
6568 *
6569 * Return: None.
6570 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006571void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006572{
Alok Kumarb64650c2018-03-23 17:05:11 +05306573 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006574 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
6575
6576 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006577}
6578
6579/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006580 * hdd_exit_netlink_services - Exit netlink services
6581 * @hdd_ctx: HDD context
6582 *
6583 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
6584 * nl service.
6585 *
6586 * Return: None.
6587 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006588static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006589{
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006590 hdd_close_cesium_nl_sock();
Naveen Rawat910726a2017-03-06 11:42:51 -08006591 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006592 ptt_sock_deactivate_svc();
6593
6594 nl_srv_exit();
6595}
6596
6597/**
6598 * hdd_init_netlink_services- Init netlink services
6599 * @hdd_ctx: HDD context
6600 *
6601 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
6602 * nl service.
6603 *
6604 * Return: 0 on success and errno on failure.
6605 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006606static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006607{
6608 int ret;
6609
Ryan Hsuceddceb2016-04-28 10:20:14 -07006610 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006611 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006612 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006613 goto out;
6614 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07006615 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006616
Naveen Rawat910726a2017-03-06 11:42:51 -08006617 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006618 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006619 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006620 goto err_nl_srv;
6621 }
6622
6623 ret = ptt_sock_activate_svc();
6624 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006625 hdd_err("ptt_sock_activate_svc failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006626 goto err_nl_srv;
6627 }
6628
6629 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07006630 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006631 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006632
6633 ret = cnss_diag_activate_service();
6634 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006635 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006636 goto err_close_cesium;
6637 }
6638
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08006639 ret = spectral_scan_activate_service();
6640 if (ret) {
6641 hdd_alert("spectral_scan_activate_service failed: %d", ret);
6642 goto err_close_cesium;
6643 }
6644
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006645 return 0;
6646
6647err_close_cesium:
6648 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006649 ptt_sock_deactivate_svc();
6650err_nl_srv:
6651 nl_srv_exit();
6652out:
6653 return ret;
6654}
6655
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006656/**
6657 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
6658 * @hdd_ctx: HDD context.
6659 *
6660 * Destroy RX wakelock.
6661 *
6662 * Return: None.
6663 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006664static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006665{
6666 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
6667}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006668
6669/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006670 * hdd_rx_wake_lock_create() - Create RX wakelock
6671 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006672 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006673 * Create RX wakelock.
6674 *
6675 * Return: None.
6676 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006677static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006678{
6679 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
6680}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006681
6682/**
Houston Hoffman160db392016-10-10 17:37:51 -07006683 * hdd_context_deinit() - Deinitialize HDD context
6684 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006685 *
Houston Hoffman160db392016-10-10 17:37:51 -07006686 * Deinitialize HDD context along with all the feature specific contexts but
6687 * do not free hdd context itself. Caller of this API is supposed to free
6688 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006689 *
Houston Hoffman160db392016-10-10 17:37:51 -07006690 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006691 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006692static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006693{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306694 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
6695
Houston Hoffman160db392016-10-10 17:37:51 -07006696 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006697
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006698 hdd_sap_context_destroy(hdd_ctx);
6699
6700 hdd_rx_wake_lock_destroy(hdd_ctx);
6701
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006702 hdd_scan_context_destroy(hdd_ctx);
6703
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006704 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006705
Houston Hoffman160db392016-10-10 17:37:51 -07006706 return 0;
6707}
6708
6709/**
6710 * hdd_context_destroy() - Destroy HDD context
6711 * @hdd_ctx: HDD context to be destroyed.
6712 *
6713 * Free config and HDD context as well as destroy all the resources.
6714 *
6715 * Return: None
6716 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006717static void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07006718{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07006719 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05306720
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05306721 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
6722
Houston Hoffman160db392016-10-10 17:37:51 -07006723 hdd_context_deinit(hdd_ctx);
6724
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306725 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006726 hdd_ctx->config = NULL;
6727
6728 wiphy_free(hdd_ctx->wiphy);
6729}
6730
6731/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05306732 * wlan_destroy_bug_report_lock() - Destroy bug report lock
6733 *
6734 * This function is used to destroy bug report lock
6735 *
6736 * Return: None
6737 */
6738static void wlan_destroy_bug_report_lock(void)
6739{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07006740 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05306741
6742 p_cds_context = cds_get_global_context();
6743 if (!p_cds_context) {
6744 hdd_err("cds context is NULL");
6745 return;
6746 }
6747
6748 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
6749}
6750
6751/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006752 * hdd_wlan_exit() - HDD WLAN exit function
6753 * @hdd_ctx: Pointer to the HDD Context
6754 *
6755 * This is the driver exit point (invoked during rmmod)
6756 *
6757 * Return: None
6758 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006759static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006760{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006761 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05306762 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006763
Dustin Brown491d54b2018-03-14 12:39:11 -07006764 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006765
Arun Khandavallifae92942016-08-01 13:31:08 +05306766 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006767
Prashanth Bhattaab004382016-10-11 16:08:11 -07006768 hdd_bus_bandwidth_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006769
6770#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05306771 if (QDF_TIMER_STATE_RUNNING ==
6772 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
6773 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006774 }
6775
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306776 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05306777 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07006778 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006779 }
Liangwei Dongaef84342016-10-21 05:28:00 -04006780 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6781 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6782 hdd_ctx->last_acs_channel_list = NULL;
6783 hdd_ctx->num_of_channels = 0;
6784 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006785#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006786
Arun Khandavallifae92942016-08-01 13:31:08 +05306787 mutex_lock(&hdd_ctx->iface_change_lock);
6788 driver_status = hdd_ctx->driver_status;
6789 mutex_unlock(&hdd_ctx->iface_change_lock);
6790
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006791 /*
6792 * Powersave Offload Case
6793 * Disable Idle Power Save Mode
6794 */
6795 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07006796 /* clear the scan queue in all the scenarios */
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +05306797 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006798
Arun Khandavallifae92942016-08-01 13:31:08 +05306799 if (driver_status != DRIVER_MODULES_CLOSED) {
6800 hdd_unregister_wext_all_adapters(hdd_ctx);
6801 /*
6802 * Cancel any outstanding scan requests. We are about to close
6803 * all of our adapters, but an adapter structure is what SME
6804 * passes back to our callback function. Hence if there
6805 * are any outstanding scan requests then there is a
6806 * race condition between when the adapter is closed and
6807 * when the callback is invoked. We try to resolve that
6808 * race condition here by canceling any outstanding scans
6809 * before we close the adapters.
6810 * Note that the scans may be cancelled in an asynchronous
6811 * manner, so ideally there needs to be some kind of
6812 * synchronization. Rather than introduce a new
6813 * synchronization here, we will utilize the fact that we are
6814 * about to Request Full Power, and since that is synchronized,
6815 * the expectation is that by the time Request Full Power has
6816 * completed, all scans will be cancelled
6817 */
6818 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07006819 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08006820 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08006821 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006822 }
6823
Arunk Khandavalli830c9692018-03-22 12:17:40 +05306824 unregister_reboot_notifier(&system_reboot_notifier);
Arun Khandavalli08479ba2017-08-07 19:56:23 +05306825 unregister_netdevice_notifier(&hdd_netdev_notifier);
6826
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07006827 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05306828
Dustin Brown021cecd2017-12-11 13:56:43 -08006829 hdd_driver_memdump_deinit();
6830
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05306831 qdf_nbuf_deinit_replenish_timer();
6832
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306833 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
6834 hdd_info("Release wakelock for monitor mode!");
6835 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
6836 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
6837 }
6838
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05306839 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
6840 qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
6841 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
6842
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006843 /*
6844 * Close CDS
6845 * This frees pMac(HAL) context. There should not be any call
6846 * that requires pMac access after this.
6847 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006848
Jeff Johnsonce0032c2017-01-20 07:18:27 -08006849 hdd_request_manager_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -07006850 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006851
Dustin Brownd005ad82018-01-19 10:32:13 -08006852 hdd_close_all_adapters(hdd_ctx, false);
6853
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05306854 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306855 /*
6856 * If there is re_init failure wiphy would have already de-registered
6857 * check the wiphy status before un-registering again
6858 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05306859 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306860 wiphy_unregister(wiphy);
6861 wlan_hdd_cfg80211_deinit(wiphy);
6862 hdd_lpass_notify_stop(hdd_ctx);
6863 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07006864
Arun Khandavallifae92942016-08-01 13:31:08 +05306865 hdd_exit_netlink_services(hdd_ctx);
6866 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05306867#ifdef FEATURE_WLAN_CH_AVOID
6868 mutex_destroy(&hdd_ctx->avoid_freq_lock);
6869#endif
Abhishek Singhe9068f12017-03-31 14:14:52 +05306870
Abhishek Singhe9068f12017-03-31 14:14:52 +05306871 driver_status = hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
6872 if (driver_status)
6873 hdd_err("Psoc delete failed");
Dustin Brown6f17a022017-07-19 13:40:55 -07006874
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006875 hdd_context_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006876}
6877
6878void __hdd_wlan_exit(void)
6879{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006880 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006881
Dustin Brown491d54b2018-03-14 12:39:11 -07006882 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006883
Anurag Chouhan6d760662016-02-20 16:05:43 +05306884 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006885 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006886 hdd_err("Invalid HDD Context");
Dustin Browne74003f2018-03-14 12:51:58 -07006887 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006888 return;
6889 }
6890
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006891 /* Do all the cleanup before deregistering the driver */
6892 hdd_wlan_exit(hdd_ctx);
Mohit Khannaebf8a862016-04-28 17:53:59 -07006893
Dustin Browne74003f2018-03-14 12:51:58 -07006894 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006895}
6896
6897#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04006898/**
6899 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006900 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04006901 *
6902 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
6903 * Then new ACS request will do a fresh scan without reusing the cached
6904 * scan information.
6905 *
6906 * Return: void
6907 */
Tang Yingying523322d2017-01-17 23:28:43 +08006908static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006909{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006910 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006911
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006912 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006913 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04006914 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6915 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6916 hdd_ctx->last_acs_channel_list = NULL;
6917 hdd_ctx->num_of_channels = 0;
6918 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006919
6920 if (!hdd_ctx->hHal)
6921 return;
6922 sme_scan_flush_result(hdd_ctx->hHal);
6923}
6924#endif
6925
6926#ifdef QCA_HT_2040_COEX
Jeff Johnsone7672e72017-10-21 15:10:04 -07006927int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
6928 struct qdf_mac_addr sta_mac, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006929{
6930 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306931 QDF_STATUS qdf_status;
Jeff Johnsone7672e72017-10-21 15:10:04 -07006932 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006933
6934 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6935
6936 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306937 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006938 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306939
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006940 if (!hdd_ctx->hHal)
6941 return -EINVAL;
6942
Jeff Johnsone7672e72017-10-21 15:10:04 -07006943 qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, sta_id, sta_mac,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006944 adapter->session_id, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306945 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006946 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006947 return -EINVAL;
6948 }
6949
6950 return 0;
6951}
6952#endif
6953
6954/**
6955 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
6956 * @state: state
6957 *
6958 * This function notifies FW with modem power status
6959 *
6960 * Return: 0 if successful, error number otherwise
6961 */
6962int hdd_wlan_notify_modem_power_state(int state)
6963{
6964 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306965 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006966 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006967
Anurag Chouhan6d760662016-02-20 16:05:43 +05306968 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006969 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306970 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006971 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306972
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006973 if (!hdd_ctx->hHal)
6974 return -EINVAL;
6975
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306976 qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
6977 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006978 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006979 state);
6980 return -EINVAL;
6981 }
6982 return 0;
6983}
6984
6985/**
6986 *
6987 * hdd_post_cds_enable_config() - HDD post cds start config helper
6988 * @adapter - Pointer to the HDD
6989 *
6990 * Return: None
6991 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006992QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006993{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306994 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006995
6996 /*
6997 * Send ready indication to the HDD. This will kick off the MAC
6998 * into a 'running' state and should kick off an initial scan.
6999 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307000 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
7001 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007002 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7003 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307004 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007005 }
7006
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307007 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007008}
7009
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307010struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7011{
7012 struct hdd_adapter *adapter;
7013
7014 hdd_for_each_adapter(hdd_ctx, adapter) {
7015 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7016 return adapter;
7017 }
7018
7019 return NULL;
7020}
7021
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007022/* wake lock APIs for HDD */
7023void hdd_prevent_suspend(uint32_t reason)
7024{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307025 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007026}
7027
7028void hdd_allow_suspend(uint32_t reason)
7029{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307030 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007031}
7032
7033void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
7034{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05307035 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
7036 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007037}
7038
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007039/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007040QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007041{
Amar Singhal5cccafe2017-02-15 12:42:58 -08007042
Amar Singhal6f8592b2017-04-26 14:31:58 -07007043 return sme_init_chan_list(hdd_ctx->hHal,
7044 hdd_ctx->reg.alpha2,
7045 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007046}
7047
7048/**
7049 * hdd_is_5g_supported() - check if hardware supports 5GHz
7050 * @hdd_ctx: Pointer to the hdd context
7051 *
7052 * HDD function to know if hardware supports 5GHz
7053 *
7054 * Return: true if hardware supports 5GHz
7055 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007056bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007057{
Amar Singhal58b45ef2017-08-01 13:43:54 -07007058 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08007059 return true;
7060
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08007061 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08007062 return true;
7063 else
7064 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007065}
7066
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007067static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007068{
7069 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07007070 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007071
7072 wiphy = hdd_ctx->wiphy;
7073
7074 /*
7075 * The channel information in
7076 * wiphy needs to be initialized before wiphy registration
7077 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007078 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
7079 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007080 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07007081 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007082 }
7083
7084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7085 wiphy->wowlan = &wowlan_support_reg_init;
7086#else
7087 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
7088 WIPHY_WOWLAN_MAGIC_PKT |
7089 WIPHY_WOWLAN_DISCONNECT |
7090 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
7091 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
7092 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
7093 WIPHY_WOWLAN_4WAY_HANDSHAKE |
7094 WIPHY_WOWLAN_RFKILL_RELEASE;
7095
7096 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
7097 WOW_MAX_FILTERS_PER_LIST);
7098 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
7099 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
7100#endif
7101
7102 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007103 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307104 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07007105 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307106 return ret_val;
7107 }
7108
Amar Singhal2d812012018-02-03 15:06:47 +08007109 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007110
Amar Singhale4f28ee2015-10-21 14:36:56 -07007111 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007112}
7113
Mohit Khannaca4173b2017-09-12 21:52:19 -07007114#ifdef MSM_PLATFORM
7115/**
7116 * hdd_display_periodic_stats() - Function to display periodic stats
7117 * @hdd_ctx - handle to hdd context
7118 * @bool data_in_interval - true, if data detected in bw time interval
7119 *
7120 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
7121 * Stats show up in wlan driver logs.
7122 *
7123 * Returns: None
7124 */
7125static inline
7126void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
7127 bool data_in_interval)
7128{
7129 static u32 counter;
7130 static bool data_in_time_period;
7131 ol_txrx_pdev_handle pdev;
7132
7133 if (hdd_ctx->config->periodic_stats_disp_time == 0)
7134 return;
7135
7136 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
7137 if (!pdev) {
7138 hdd_err("pdev is NULL");
7139 return;
7140 }
7141
7142 counter++;
7143 if (data_in_interval)
7144 data_in_time_period = data_in_interval;
7145
7146 if (counter * hdd_ctx->config->busBandwidthComputeInterval >=
7147 hdd_ctx->config->periodic_stats_disp_time * 1000) {
7148 if (data_in_time_period) {
7149 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
7150 CDP_TXRX_PATH_STATS,
7151 QDF_STATS_VERBOSITY_LEVEL_LOW);
7152 wlan_hdd_display_netif_queue_history
7153 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
7154 qdf_dp_trace_dump_stats();
7155 }
7156 counter = 0;
7157 data_in_time_period = false;
7158 }
7159}
7160
Ravi Joshie2331e82015-07-01 18:18:54 -07007161/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007162 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
7163 * @hdd_ctx: pointer to struct hdd_context
7164 *
7165 * Return: none
7166 */
7167static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
7168{
7169 struct hdd_adapter *adapter;
7170
7171 hdd_for_each_adapter(hdd_ctx, adapter)
7172 hdd_send_rps_disable_ind(adapter);
7173}
7174
7175/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07007176 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07007177 * @hdd_ctx - handle to hdd context
7178 * @tx_packets - transmit packet count
7179 * @rx_packets - receive packet count
7180 *
7181 * The function controls the bus bandwidth and dynamic control of
7182 * tcp delayed ack configuration
7183 *
7184 * Returns: None
7185 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007186
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007187static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07007188 const uint64_t tx_packets,
7189 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007190{
Mohit Khannaca4173b2017-09-12 21:52:19 -07007191 u64 total_pkts = tx_packets + rx_packets;
Mohit Khannae71e2262015-11-10 09:37:24 -08007192 uint64_t temp_rx = 0;
7193 uint64_t temp_tx = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007194 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08007195 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08007196 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007197 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007198 uint16_t index = 0;
7199 bool vote_level_change = false;
7200 bool rx_level_change = false;
7201 bool tx_level_change = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007202
Mohit Khannaca4173b2017-09-12 21:52:19 -07007203 if (total_pkts > hdd_ctx->config->busBandwidthHighThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007204 next_vote_level = PLD_BUS_WIDTH_HIGH;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007205 else if (total_pkts > hdd_ctx->config->busBandwidthMediumThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007206 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007207 else if (total_pkts > hdd_ctx->config->busBandwidthLowThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007208 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07007209 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07007210 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007211
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007212 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07007213 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
7214 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007215 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007216 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007217 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007218 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
7219 (next_vote_level == PLD_BUS_WIDTH_NONE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05307220 if (hdd_ctx->hbw_requested) {
7221 pld_remove_pm_qos(hdd_ctx->parent_dev);
7222 hdd_ctx->hbw_requested = false;
7223 }
Nirav Shah3bbfa512016-05-12 16:43:49 +05307224 if (cds_sched_handle_throughput_req(false))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007225 hdd_warn("low bandwidth set rx affinity fail");
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007226
7227 if (hdd_ctx->dynamic_rps)
7228 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007229 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05307230 if (!hdd_ctx->hbw_requested) {
7231 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
7232 hdd_ctx->hbw_requested = true;
7233 }
7234
Nirav Shah3bbfa512016-05-12 16:43:49 +05307235 if (cds_sched_handle_throughput_req(true))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007236 hdd_warn("high bandwidth set rx affinity fail");
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007237
7238 if (hdd_ctx->dynamic_rps)
7239 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007240 }
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -07007241 hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007242 }
Mohit Khannae71e2262015-11-10 09:37:24 -08007243
Mohit Khannaf8f96822017-05-17 17:11:59 -07007244 qdf_dp_trace_throttle_live_mode(
7245 (next_vote_level > PLD_BUS_WIDTH_NONE) ? true : false);
7246
Mohit Khannae71e2262015-11-10 09:37:24 -08007247 /* fine-tuning parameters for RX Flows */
7248 temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
7249
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007250 hdd_ctx->prev_rx = rx_packets;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08007251
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307252 if (temp_rx < hdd_ctx->config->busBandwidthLowThreshold)
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07007253 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307254 else
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07007255 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307256
Ravi Joshifed83572016-10-07 16:20:37 -07007257 if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) {
7258 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
7259 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
7260 next_rx_level = WLAN_SVC_TP_HIGH;
7261 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07007262 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07007263 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08007264 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007265 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007266
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007267 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007268 struct wlan_rx_tp_data rx_tp_data = {0};
7269
Ravi Joshie2331e82015-07-01 18:18:54 -07007270 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007271 next_rx_level, temp_rx);
7272 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007273 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07007274 /* Send throughput indication only if it is enabled.
7275 * Disabling tcp_del_ack will revert the tcp stack behavior
7276 * to default delayed ack. Note that this will disable the
7277 * dynamic delayed ack mechanism across the system
7278 */
Manjunathappa Prakashbfd12762018-04-29 22:44:52 -07007279 if (hdd_ctx->en_tcp_delack_no_lro)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007280 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
7281
Mohit Khanna6272fb682017-04-13 09:34:36 -07007282 if (hdd_ctx->config->enable_tcp_adv_win_scale)
7283 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
7284
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007285 rx_tp_data.level = next_rx_level;
7286 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7287 WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
7288 sizeof(rx_tp_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007289 }
7290
Mohit Khannae71e2262015-11-10 09:37:24 -08007291 /* fine-tuning parameters for TX Flows */
7292 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
7293 hdd_ctx->prev_tx = tx_packets;
7294 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
7295 next_tx_level = WLAN_SVC_TP_HIGH;
7296 else
7297 next_tx_level = WLAN_SVC_TP_LOW;
7298
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08007299 if ((hdd_ctx->config->enable_tcp_limit_output) &&
7300 (hdd_ctx->cur_tx_level != next_tx_level)) {
Mohit Khannae71e2262015-11-10 09:37:24 -08007301 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
7302 next_tx_level, temp_tx);
7303 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007304 tx_level_change = true;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05307305 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7306 WLAN_SVC_WLAN_TP_TX_IND,
Mohit Khannae71e2262015-11-10 09:37:24 -08007307 &next_tx_level,
7308 sizeof(next_tx_level));
7309 }
7310
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007311 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007312 if (vote_level_change || tx_level_change || rx_level_change) {
7313 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
7314 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
7315 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
7316 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
7317 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
7318 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
7319 hdd_ctx->hdd_txrx_hist_idx++;
7320 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
7321 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07007322
7323 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007324}
7325
7326#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307327static void hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007328{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007329 struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307330 bus_bw_work);
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307331 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307332 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05307333 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
7334 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007335 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307336 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007337 bool connected = false;
7338 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
7339
Prashanth Bhattaab004382016-10-11 16:08:11 -07007340 if (wlan_hdd_validate_context(hdd_ctx))
7341 return;
7342
Jeff Johnson214671b2017-10-30 19:45:23 -07007343 if (hdd_ctx->is_wiphy_suspended)
Jingxiang Gec64e1932017-08-22 14:38:59 +08007344 goto restart_timer;
7345
Dustin Brown920397d2017-12-13 16:27:50 -08007346 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05307347 /*
7348 * Validate magic so we don't end up accessing
7349 * an invalid adapter.
7350 */
7351 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
7352 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007353
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007354 if ((adapter->device_mode == QDF_STA_MODE ||
7355 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007356 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
7357 != eConnectionState_Associated) {
7358
7359 continue;
7360 }
7361
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007362 if ((adapter->device_mode == QDF_SAP_MODE ||
7363 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07007364 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007365
7366 continue;
7367 }
7368
7369 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
7370 adapter->prev_tx_packets);
7371 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
7372 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307373
7374 if (adapter->device_mode == QDF_SAP_MODE ||
7375 adapter->device_mode == QDF_P2P_GO_MODE ||
7376 adapter->device_mode == QDF_IBSS_MODE) {
7377
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08007378 ret = cdp_get_intra_bss_fwd_pkts_count(
7379 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07007380 adapter->session_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307381 &fwd_tx_packets, &fwd_rx_packets);
7382 if (ret == A_OK) {
7383 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
7384 fwd_tx_packets,
7385 adapter->prev_fwd_tx_packets);
7386 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
7387 fwd_tx_packets,
7388 adapter->prev_fwd_rx_packets);
7389 }
7390 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007391
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307392 if (adapter->device_mode == QDF_SAP_MODE)
7393 con_sap_adapter = adapter;
7394
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007395 total_rx += adapter->stats.rx_packets;
7396 total_tx += adapter->stats.tx_packets;
7397
7398 spin_lock_bh(&hdd_ctx->bus_bw_lock);
7399 adapter->prev_tx_packets = adapter->stats.tx_packets;
7400 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307401 adapter->prev_fwd_tx_packets = fwd_tx_packets;
7402 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007403 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
7404 connected = true;
7405 }
7406
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007407 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007408 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007409 return;
7410 }
7411
Yun Parka29974a2018-04-09 12:05:49 -07007412 /* add intra bss forwarded tx and rx packets */
7413 tx_packets += fwd_tx_packets_diff;
7414 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007415
Yun Parka29974a2018-04-09 12:05:49 -07007416 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->hdd_pdev)) {
7417 ucfg_ipa_uc_stat_query(hdd_ctx->hdd_pdev, &ipa_tx_packets,
7418 &ipa_rx_packets);
7419 tx_packets += (uint64_t)ipa_tx_packets;
7420 rx_packets += (uint64_t)ipa_rx_packets;
7421
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307422 if (con_sap_adapter) {
7423 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
7424 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
7425 }
7426
Yun Parka29974a2018-04-09 12:05:49 -07007427 ucfg_ipa_set_perf_level(hdd_ctx->hdd_pdev, tx_packets, rx_packets);
7428 ucfg_ipa_uc_stat_request(hdd_ctx->hdd_pdev, 2);
7429 }
7430
7431 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007432
Jingxiang Gec64e1932017-08-22 14:38:59 +08007433restart_timer:
Dustin Brown2ed60362017-01-18 12:25:50 -08007434 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08007435 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08007436 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05307437 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
Dustin Brownfce08d12017-01-17 16:29:38 -08007438 hdd_ctx->config->busBandwidthComputeInterval);
Dustin Brownfce08d12017-01-17 16:29:38 -08007439 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007440}
Prashanth Bhattaab004382016-10-11 16:08:11 -07007441
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307442/**
7443 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
7444 * @arg: Argument of timer function
7445 *
7446 * Schedule a workqueue in this function where all the processing is done.
7447 *
7448 * Return: None.
7449 */
7450static void __hdd_bus_bw_cbk(void *arg)
7451{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007452 struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307453
7454 if (wlan_hdd_validate_context(hdd_ctx))
7455 return;
7456
7457 schedule_work(&hdd_ctx->bus_bw_work);
7458}
7459
7460/**
7461 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
7462 * @arg: Argument of timer function
7463 *
7464 * Return: None.
7465 */
7466static void hdd_bus_bw_cbk(void *arg)
7467{
7468 cds_ssr_protect(__func__);
7469 __hdd_bus_bw_cbk(arg);
7470 cds_ssr_unprotect(__func__);
7471}
7472
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007473int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007474{
7475 spin_lock_init(&hdd_ctx->bus_bw_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307476 INIT_WORK(&hdd_ctx->bus_bw_work,
7477 hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08007478 hdd_ctx->bus_bw_timer_running = false;
7479 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307480 qdf_timer_init(NULL,
7481 &hdd_ctx->bus_bw_timer,
7482 hdd_bus_bw_cbk, (void *)hdd_ctx,
7483 QDF_TIMER_TYPE_SW);
Prashanth Bhattaab004382016-10-11 16:08:11 -07007484
7485 return 0;
7486}
7487
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007488void hdd_bus_bandwidth_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007489{
Dustin Brownfce08d12017-01-17 16:29:38 -08007490 if (hdd_ctx->bus_bw_timer_running)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007491 hdd_reset_tcp_delack(hdd_ctx);
7492
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007493 hdd_debug("wait for bus bw work to flush");
Nirav Shaheb017be2018-02-15 11:20:58 +05307494 hdd_cancel_bus_bw_work(hdd_ctx);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307495 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08007496 hdd_ctx->bus_bw_timer_running = false;
7497 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Prashanth Bhattaab004382016-10-11 16:08:11 -07007498}
Lin Baic5c06882017-09-21 13:58:43 +08007499
7500void hdd_bus_bw_cancel_work(struct hdd_context *hdd_ctx)
7501{
7502 if (hdd_ctx)
7503 cancel_work_sync(&hdd_ctx->bus_bw_work);
7504}
jiadcdaf9bd2017-10-26 12:20:21 +08007505
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007506#endif
7507
7508/**
Nirav Shahed34b212016-04-25 10:59:16 +05307509 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
7510 * @hdd_ctx: hdd context
7511 *
7512 * Return: 0 for success or error code
7513 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007514static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05307515{
7516 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
7517 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
7518 if (hdd_ctx->hdd_txrx_hist == NULL) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007519 hdd_err("Failed malloc for hdd_txrx_hist");
Nirav Shahed34b212016-04-25 10:59:16 +05307520 return -ENOMEM;
7521 }
7522 return 0;
7523}
7524
7525/**
7526 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
7527 * @hdd_ctx: hdd context
7528 *
7529 * Return: none
7530 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007531void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05307532{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307533 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
7534 return;
7535
7536 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
7537 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05307538}
7539
Nirav Shahda008342016-05-17 18:50:40 +05307540static uint8_t *convert_level_to_string(uint32_t level)
7541{
7542 switch (level) {
7543 /* initialize the wlan sub system */
7544 case WLAN_SVC_TP_NONE:
7545 return "NONE";
7546 case WLAN_SVC_TP_LOW:
7547 return "LOW";
7548 case WLAN_SVC_TP_MEDIUM:
7549 return "MED";
7550 case WLAN_SVC_TP_HIGH:
7551 return "HIGH";
7552 default:
7553 return "INVAL";
7554 }
7555}
7556
Nirav Shahed34b212016-04-25 10:59:16 +05307557
7558/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007559 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
7560 * @hdd_ctx: hdd context
7561 *
7562 * Return: none
7563 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007564void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007565{
7566 int i;
7567
7568#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007569 hdd_debug("BW compute Interval: %dms",
Nirav Shahda008342016-05-17 18:50:40 +05307570 hdd_ctx->config->busBandwidthComputeInterval);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007571 hdd_debug("BW High TH: %d BW Med TH: %d BW Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007572 hdd_ctx->config->busBandwidthHighThreshold,
7573 hdd_ctx->config->busBandwidthMediumThreshold,
7574 hdd_ctx->config->busBandwidthLowThreshold);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007575 hdd_debug("Enable TCP DEL ACK: %d",
Manjunathappa Prakashbfd12762018-04-29 22:44:52 -07007576 hdd_ctx->en_tcp_delack_no_lro);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007577 hdd_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007578 hdd_ctx->config->tcpDelackThresholdHigh,
7579 hdd_ctx->config->tcpDelackThresholdLow);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007580 hdd_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
Nirav Shahda008342016-05-17 18:50:40 +05307581 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007582#endif
7583
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007584 hdd_debug("Total entries: %d Current index: %d",
Nirav Shahda008342016-05-17 18:50:40 +05307585 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
7586
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007587 hdd_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007588
7589 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007590 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007591 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Dustin Brown632af712018-03-14 15:03:55 -07007592 hdd_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
7593 i, hdd_ctx->hdd_txrx_hist[i].qtime,
7594 hdd_ctx->hdd_txrx_hist[i].interval_rx,
7595 hdd_ctx->hdd_txrx_hist[i].interval_tx,
7596 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007597 hdd_ctx->hdd_txrx_hist[i].
7598 next_vote_level),
Dustin Brown632af712018-03-14 15:03:55 -07007599 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007600 hdd_ctx->hdd_txrx_hist[i].
7601 next_rx_level),
Dustin Brown632af712018-03-14 15:03:55 -07007602 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007603 hdd_ctx->hdd_txrx_hist[i].
7604 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007605 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007606}
7607
7608/**
7609 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
7610 * @hdd_ctx: hdd context
7611 *
7612 * Return: none
7613 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007614void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007615{
7616 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05307617 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
7618 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007619}
7620
Mohit Khannaca4173b2017-09-12 21:52:19 -07007621/* length of the netif queue log needed per adapter */
7622#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
7623
7624/**
7625 *
7626 * hdd_display_netif_queue_history_compact() - display compact netifq history
7627 * @hdd_ctx: hdd context
7628 *
7629 * Return: none
7630 */
7631static void
7632hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
7633{
7634 int adapter_num = 0;
7635 int i;
7636 int bytes_written;
7637 u32 tbytes;
7638 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007639 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08007640 char *comb_log_str;
7641 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007642 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007643
jiadbdefb252018-01-03 14:27:06 +08007644 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * MAX_NUMBER_OF_ADAPTERS) + 1;
7645 comb_log_str = qdf_mem_malloc(comb_log_str_size);
7646 if (!comb_log_str) {
7647 hdd_err("failed to alloc comb_log_str");
7648 return;
7649 }
7650
Mohit Khannaca4173b2017-09-12 21:52:19 -07007651 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007652
Dustin Brown920397d2017-12-13 16:27:50 -08007653 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07007654 curr_time = qdf_system_ticks();
7655 total = curr_time - adapter->start_time;
7656 delta = curr_time - adapter->last_time;
7657
7658 if (adapter->pause_map) {
7659 pause = adapter->total_pause_time + delta;
7660 unpause = adapter->total_unpause_time;
7661 } else {
7662 unpause = adapter->total_unpause_time + delta;
7663 pause = adapter->total_pause_time;
7664 }
7665
7666 tbytes = 0;
7667 qdf_mem_set(temp_str, 0, sizeof(temp_str));
7668 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7669 if (adapter->queue_oper_stats[i].pause_count == 0)
7670 continue;
7671 tbytes +=
7672 snprintf(
7673 &temp_str[tbytes],
7674 (tbytes >= sizeof(temp_str) ?
7675 0 : sizeof(temp_str) - tbytes),
7676 "%d(%d,%d) ",
7677 i,
7678 adapter->queue_oper_stats[i].
7679 pause_count,
7680 adapter->queue_oper_stats[i].
7681 unpause_count);
7682 }
7683 if (tbytes >= sizeof(temp_str))
7684 hdd_warn("log truncated");
7685
7686 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08007687 bytes_written >= comb_log_str_size ? 0 :
7688 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07007689 "[%d %d] (%d) %u/%ums %s|",
7690 adapter->session_id, adapter->device_mode,
7691 adapter->pause_map,
7692 qdf_system_ticks_to_msecs(pause),
7693 qdf_system_ticks_to_msecs(total),
7694 temp_str);
7695
Mohit Khannaca4173b2017-09-12 21:52:19 -07007696 adapter_num++;
7697 }
7698
7699 /* using QDF_TRACE to avoid printing function name */
7700 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
7701 "STATS |%s", comb_log_str);
7702
jiadbdefb252018-01-03 14:27:06 +08007703 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007704 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08007705
7706 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07007707}
7708
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007709/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007710 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07007711 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007712 *
7713 * Return: none
7714 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007715void
7716wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
7717 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007718{
7719
Jeff Johnson9d295242017-08-29 14:39:48 -07007720 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007721 int i;
Nirav Shahda008342016-05-17 18:50:40 +05307722 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007723
Mohit Khannaca4173b2017-09-12 21:52:19 -07007724 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
7725 hdd_display_netif_queue_history_compact(hdd_ctx);
7726 return;
7727 }
7728
Dustin Brown920397d2017-12-13 16:27:50 -08007729 hdd_for_each_adapter(hdd_ctx, adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007730 hdd_debug("Netif queue operation statistics:");
7731 hdd_debug("Session_id %d device mode %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07007732 adapter->session_id, adapter->device_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007733 hdd_debug("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05307734 curr_time = qdf_system_ticks();
7735 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05307736 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05307737 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05307738 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307739 unpause = adapter->total_unpause_time;
7740 } else {
Nirav Shahda008342016-05-17 18:50:40 +05307741 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307742 pause = adapter->total_pause_time;
7743 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007744 hdd_debug("Total: %ums Pause: %ums Unpause: %ums",
Nirav Shah617cff92016-04-25 10:24:24 +05307745 qdf_system_ticks_to_msecs(total),
7746 qdf_system_ticks_to_msecs(pause),
7747 qdf_system_ticks_to_msecs(unpause));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007748 hdd_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007749
Nirav Shahda008342016-05-17 18:50:40 +05307750 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7751 qdf_time_t pause_delta = 0;
7752
7753 if (adapter->pause_map & (1 << i))
7754 pause_delta = delta;
7755
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007756 /* using hdd_log to avoid printing function name */
Dustin Brown632af712018-03-14 15:03:55 -07007757 hdd_debug("%s: %d: %d: %ums",
7758 hdd_reason_type_to_string(i),
7759 adapter->queue_oper_stats[i].pause_count,
7760 adapter->queue_oper_stats[i].unpause_count,
7761 qdf_system_ticks_to_msecs(
7762 adapter->queue_oper_stats[i].total_pause_time +
7763 pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007764 }
7765
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007766 hdd_debug("Netif queue operation history:");
7767 hdd_debug("Total entries: %d current index %d",
Nirav Shahda008342016-05-17 18:50:40 +05307768 WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index);
7769
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007770 hdd_debug("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007771
7772 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007773 /* using hdd_log to avoid printing function name */
7774 if (adapter->queue_oper_history[i].time == 0)
7775 continue;
Dustin Brown632af712018-03-14 15:03:55 -07007776 hdd_debug("%d: %u: %s: %s: %x",
7777 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007778 adapter->queue_oper_history[i].time),
Dustin Brown632af712018-03-14 15:03:55 -07007779 hdd_action_type_to_string(
7780 adapter->queue_oper_history[i].netif_action),
7781 hdd_reason_type_to_string(
7782 adapter->queue_oper_history[i].netif_reason),
7783 adapter->queue_oper_history[i].pause_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007784 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007785 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007786}
7787
7788/**
7789 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
7790 * @hdd_ctx: hdd context
7791 *
7792 * Return: none
7793 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007794void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007795{
Jeff Johnson9d295242017-08-29 14:39:48 -07007796 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007797
Dustin Brown920397d2017-12-13 16:27:50 -08007798 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307799 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007800 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307801 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007802 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05307803 adapter->history_index = 0;
7804 adapter->start_time = adapter->last_time = qdf_system_ticks();
7805 adapter->total_pause_time = 0;
7806 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007807 }
7808}
7809
7810/**
7811 * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
7812 * @halHandle: Hal handle
7813 * @pContext: Pointer to the context
7814 * @sessionId: Session ID
7815 * @scanId: Scan ID
7816 * @status: Status
7817 *
7818 * This is the callback to be executed when 11d scan is completed to flush out
7819 * the scan results
7820 *
7821 * 11d scan is done during driver load and is a passive scan on all
7822 * channels supported by the device, 11d scans may find some APs on
7823 * frequencies which are forbidden to be used in the regulatory domain
7824 * the device is operating in. If these APs are notified to the supplicant
7825 * it may try to connect to these APs, thus flush out all the scan results
7826 * which are present in SME after 11d scan is done.
7827 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307828 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007829 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307830static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007831 uint8_t sessionId, uint32_t scanId,
7832 eCsrScanStatus status)
7833{
Dustin Brown491d54b2018-03-14 12:39:11 -07007834 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007835
7836 sme_scan_flush_result(halHandle);
7837
Dustin Browne74003f2018-03-14 12:51:58 -07007838 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307840 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007841}
7842
7843#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7844/**
7845 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
7846 * @hdd_ctx: hdd global context
7847 *
7848 * Return: none
7849 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007850static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007851{
7852 uint8_t i;
7853
7854 mutex_init(&hdd_ctx->op_ctx.op_lock);
7855 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
7856 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
7857 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
7858 }
7859}
7860#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007861static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007862{
7863}
7864#endif
7865
Yingying Tang95409972016-10-20 15:16:15 +08007866#ifdef WLAN_FEATURE_WOW_PULSE
7867/**
7868 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007869 * @phddctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08007870 * @enable: enable or disable this behaviour
7871 *
7872 * Return: int
7873 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007874static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007875{
7876 struct hdd_config *pcfg_ini = phddctx->config;
7877 struct wow_pulse_mode wow_pulse_set_info;
7878 QDF_STATUS status;
7879
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007880 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08007881
7882 if (false == phddctx->config->wow_pulse_support)
7883 return 0;
7884
7885 /* prepare the request to send to SME */
7886 if (enable == true) {
7887 wow_pulse_set_info.wow_pulse_enable = true;
7888 wow_pulse_set_info.wow_pulse_pin =
7889 pcfg_ini->wow_pulse_pin;
7890 wow_pulse_set_info.wow_pulse_interval_low =
7891 pcfg_ini->wow_pulse_interval_low;
7892 wow_pulse_set_info.wow_pulse_interval_high =
7893 pcfg_ini->wow_pulse_interval_high;
7894 } else {
7895 wow_pulse_set_info.wow_pulse_enable = false;
7896 wow_pulse_set_info.wow_pulse_pin = 0;
7897 wow_pulse_set_info.wow_pulse_interval_low = 0;
7898 wow_pulse_set_info.wow_pulse_interval_high = 0;
7899 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007900 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08007901 wow_pulse_set_info.wow_pulse_enable,
7902 wow_pulse_set_info.wow_pulse_pin,
7903 wow_pulse_set_info.wow_pulse_interval_low,
7904 wow_pulse_set_info.wow_pulse_interval_high);
7905
7906 status = sme_set_wow_pulse(&wow_pulse_set_info);
7907 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007908 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08007909 return -EIO;
7910 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007911 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08007912 return 0;
7913}
7914#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007915static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007916{
7917 return 0;
7918}
7919#endif
7920
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007921#ifdef WLAN_FEATURE_FASTPATH
7922/**
7923 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
7924 * @hdd_cfg: hdd config
7925 * @context: lower layer context
7926 *
7927 * Return: none
7928 */
Arun Khandavallifae92942016-08-01 13:31:08 +05307929void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007930 void *context)
7931{
7932 if (hdd_cfg->fastpath_enable)
7933 hif_enable_fastpath(context);
7934}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007935#endif
7936
Yuanyuan Liu13738502016-04-06 17:41:37 -07007937#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007938/**
7939 * hdd_set_thermal_level_cb() - set thermal level callback function
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007940 * @context: hdd context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007941 * @level: thermal level
7942 *
7943 * Change IPA data path to SW path when the thermal throttle level greater
7944 * than 0, and restore the original data path when throttle level is 0
7945 *
7946 * Return: none
7947 */
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007948static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007949{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007950 struct hdd_context *hdd_ctx = context;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007951
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007952 /* Change IPA to SW path when throttle level greater than 0 */
7953 if (level > THROTTLE_LEVEL_0)
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05307954 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007955 else
7956 /* restore original concurrency mode */
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05307957 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007958}
7959
7960/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307961 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
7962 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05307963 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007964 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307965 * Get a safe channel to restart SAP. PCL already takes into account the
7966 * unsafe channels. So, the PCL is validated with the ACS range to provide
7967 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007968 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307969 * Return: Channel number to restart SAP in case of success. In case of any
7970 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007971 */
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307972static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range(
Jeff Johnson9d295242017-08-29 14:39:48 -07007973 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007974{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307975 struct sir_pcl_list pcl;
7976 QDF_STATUS status;
7977 uint32_t i, j;
Jeff Johnson796b9a72018-06-01 17:12:32 -07007978 tHalHandle hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007979 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307980 bool found = false;
Liangwei Dong17bf2662018-01-05 02:02:05 -05007981 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007982
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307983 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7984 if (!hdd_ctx) {
7985 hdd_err("invalid HDD context");
7986 return INVALID_CHANNEL_ID;
7987 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007988
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05307989 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
7990 if (!hal_handle) {
7991 hdd_err("invalid HAL handle");
7992 return INVALID_CHANNEL_ID;
7993 }
7994
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007995 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->hdd_psoc,
7996 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08007997 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
7998 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307999 if (QDF_IS_STATUS_ERROR(status)) {
8000 hdd_err("Get PCL failed");
8001 return INVALID_CHANNEL_ID;
8002 }
8003
Frank Liudc2cefb2017-06-21 15:38:18 +08008004 /*
8005 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
8006 * channel is unsafe channel, the pcl may be empty, instead of return,
8007 * try to choose a safe channel from acs range.
8008 */
8009 if (!pcl.pcl_len)
8010 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308011
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008012 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07008013 adapter->session.ap.sap_config.acs_cfg.start_ch,
8014 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308015
8016 /* PCL already takes unsafe channel into account */
8017 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008018 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308019 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008020 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308021 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008022 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008023 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308024 return pcl.pcl_list[i];
8025 }
8026 }
8027
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008028 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308029
8030 /* Try for safe channel from all valid channel */
8031 pcl.pcl_len = MAX_NUM_CHAN;
Liangwei Dong17bf2662018-01-05 02:02:05 -05008032 ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
8033 &pcl.pcl_len);
8034 if (ret) {
8035 hdd_err("error %d in getting valid channel list", ret);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308036 return INVALID_CHANNEL_ID;
8037 }
8038
8039 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008040 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308041 found = false;
8042 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
Krunal Soni15f0db12016-10-11 18:53:37 -07008043 if (pcl.pcl_list[i] ==
8044 hdd_ctx->unsafe_channel_list[j]) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008045 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308046 found = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008047 break;
8048 }
8049 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308050
8051 if (found)
8052 continue;
8053
8054 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008055 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308056 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008057 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008058 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308059 return pcl.pcl_list[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008060 }
8061 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308062
8063 return INVALID_CHANNEL_ID;
8064}
Nirav Shaheb017be2018-02-15 11:20:58 +05308065#endif
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308066
8067/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008068 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308069 * @adapter: AP adapter
8070 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08008071 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308072 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008073 * Moves the SAP interface by invoking the function which
8074 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308075 *
8076 * Return: None
8077 */
Min Liu2fef5792018-01-19 17:59:42 +08008078void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
8079 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308080{
Jeff Johnson87251032017-08-29 13:31:11 -07008081 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnson796b9a72018-06-01 17:12:32 -07008082 tHalHandle hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008083 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308084
8085 if (!adapter) {
8086 hdd_err("invalid adapter");
8087 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008088 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308089
8090 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
8091
8092 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
8093 if (!hal_handle) {
8094 hdd_err("invalid HAL handle");
8095 return;
8096 }
8097
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008098 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8099
Jeff Johnson91df29d2017-10-27 19:29:50 -07008100 hdd_ap_ctx->sap_config.channel = channel;
8101 hdd_ap_ctx->sap_config.ch_params.ch_width =
8102 hdd_ap_ctx->sap_config.ch_width_orig;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308103
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008104 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07008105 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308106
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07008107 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
Jeff Johnson91df29d2017-10-27 19:29:50 -07008108 hdd_ap_ctx->sap_config.channel,
8109 hdd_ap_ctx->sap_config.sec_ch,
8110 &hdd_ap_ctx->sap_config.ch_params);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308111
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008112 policy_mgr_change_sap_channel_with_csa(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07008113 adapter->session_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08008114 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008115}
Kapil Gupta8878ad92017-02-13 11:56:04 +05308116
Jeff Johnson9d295242017-08-29 14:39:48 -07008117int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05308118{
8119 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308120 int status;
8121 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308122
8123 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8124
8125 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07008126 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05308127 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07008128 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308129 }
8130 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07008131 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308132 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308133 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07008134 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308135 WLAN_VENDOR_ACS_WAIT_TIME);
8136 if (qdf_status != QDF_STATUS_SUCCESS) {
8137 hdd_err("failed to start external acs timer");
8138 return -ENOSPC;
8139 }
8140 /* Update config to application */
8141 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07008142 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308143
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308144 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308145}
8146
Nirav Shaheb017be2018-02-15 11:20:58 +05308147#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308148/**
8149 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
8150 * @hdd_ctx: hdd context pointer
8151 *
8152 * hdd_unsafe_channel_restart_sap check all unsafe channel list
8153 * and if ACS is enabled, driver will ask userspace to restart the
8154 * sap. User space on LTE coex indication restart driver.
8155 *
8156 * Return - none
8157 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008158void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308159{
Dustin Brown920397d2017-12-13 16:27:50 -08008160 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308161 uint32_t i;
8162 bool found = false;
8163 uint8_t restart_chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008164
Dustin Brown920397d2017-12-13 16:27:50 -08008165 hdd_for_each_adapter(hdd_ctxt, adapter) {
8166 if (!(adapter->device_mode == QDF_SAP_MODE &&
8167 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008168 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08008169 adapter->device_mode,
8170 adapter->session.ap.sap_config.
8171 acs_cfg.acs_mode);
8172 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308173 }
8174
8175 found = false;
8176 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
Dustin Brown920397d2017-12-13 16:27:50 -08008177 if (adapter->session.ap.operating_channel ==
Agrawal Ashish467dde42016-09-08 18:44:22 +05308178 hdd_ctxt->unsafe_channel_list[i]) {
8179 found = true;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008180 hdd_debug("operating ch:%d is unsafe",
Dustin Brown920397d2017-12-13 16:27:50 -08008181 adapter->session.ap.operating_channel);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308182 break;
8183 }
8184 }
8185
8186 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008187 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08008188 adapter->session.ap.operating_channel);
8189 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308190 }
8191
Kapil Gupta8878ad92017-02-13 11:56:04 +05308192 if (hdd_ctxt->config->vendor_acs_support &&
8193 hdd_ctxt->config->acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08008194 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05308195 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08008196 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308197 } else
8198 restart_chan =
8199 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08008200 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308201 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008202 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308203 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008204 /*
8205 * SAP restart due to unsafe channel. While
8206 * restarting the SAP, make sure to clear
8207 * acs_channel, channel to reset to
8208 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308209 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008210 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308211 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown920397d2017-12-13 16:27:50 -08008212 adapter->session.ap.sap_config.channel =
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308213 AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008214 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308215 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
8216 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Liangwei Dong6663d162017-07-10 03:29:36 -04008217 hdd_debug("driver to start sap: %d",
8218 hdd_ctxt->config->sap_internal_restart);
8219 if (hdd_ctxt->config->sap_internal_restart)
Min Liu2fef5792018-01-19 17:59:42 +08008220 hdd_switch_sap_channel(adapter, restart_chan,
8221 true);
Liangwei Dong6663d162017-07-10 03:29:36 -04008222 else
8223 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308224 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308225 }
8226}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05308227
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008228/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008229 * hdd_init_channel_avoidance() - Initialize channel avoidance
8230 * @hdd_ctx: HDD global context
8231 *
8232 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07008233 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008234 * down to the lower layers. Then subscribe to subsequent channel
8235 * avoidance events.
8236 *
8237 * Return: None
8238 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008239static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008240{
8241 uint16_t unsafe_channel_count;
8242 int index;
8243
Yuanyuan Liu13738502016-04-06 17:41:37 -07008244 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
8245 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008246 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08008247 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008248
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008249 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008250 hdd_ctx->unsafe_channel_count);
8251
Anurag Chouhan6d760662016-02-20 16:05:43 +05308252 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08008253 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008254
8255 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008256 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008257 hdd_ctx->unsafe_channel_list[index]);
8258
8259 }
8260
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008261}
Dustin Brown676a2322017-08-15 13:16:13 -07008262
Jeff Johnson9d295242017-08-29 14:39:48 -07008263static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008264 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008265{
8266 uint8_t restart_chan;
8267
8268 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
8269 if (!restart_chan) {
8270 hdd_alert("fail to restart SAP");
8271 return;
8272 }
8273
8274 /* SAP restart due to unsafe channel. While restarting
8275 * the SAP, make sure to clear acs_channel, channel to
8276 * reset to 0. Otherwise these settings will override
8277 * the ACS while restart.
8278 */
8279 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -07008280 adapter->session.ap.sap_config.channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07008281
8282 hdd_debug("sending coex indication");
8283
8284 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8285 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Min Liu2fef5792018-01-19 17:59:42 +08008286 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07008287}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008288
8289int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
8290 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
8291{
8292 uint32_t size;
8293 uint16_t *unsafe_list;
8294 uint16_t chan_count;
8295
8296 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
8297 return -EINVAL;
8298
8299 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
8300 NUM_CHANNELS);
8301 if (chan_count) {
8302 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
8303 unsafe_list = qdf_mem_malloc(size);
8304 if (!unsafe_list) {
8305 hdd_err("No memory for unsafe chan list size%d",
8306 size);
8307 return -ENOMEM;
8308 }
8309 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
8310 } else {
8311 unsafe_list = NULL;
8312 }
8313
8314 *local_unsafe_list = unsafe_list;
8315 *local_unsafe_list_count = chan_count;
8316
8317 return 0;
8318}
8319
8320bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
8321 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
8322{
8323 int i, j;
8324
8325 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
8326 return true;
8327 if (local_unsafe_list_count == 0)
8328 return false;
8329 for (i = 0; i < local_unsafe_list_count; i++) {
8330 for (j = 0; j < local_unsafe_list_count; j++)
8331 if (local_unsafe_list[i] ==
8332 hdd_ctx->unsafe_channel_list[j])
8333 break;
8334 if (j >= local_unsafe_list_count)
8335 break;
8336 }
8337 if (i >= local_unsafe_list_count) {
8338 hdd_info("unsafe chan list same");
8339 return false;
8340 }
8341
8342 return true;
8343}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008344#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008345static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008346{
8347}
Dustin Brown676a2322017-08-15 13:16:13 -07008348
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008349static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008350{
8351}
Dustin Brown676a2322017-08-15 13:16:13 -07008352
Jeff Johnson9d295242017-08-29 14:39:48 -07008353static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008354 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008355{
8356 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
8357}
Yuanyuan Liu13738502016-04-06 17:41:37 -07008358#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008359
8360/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08008361 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
8362 * user space
8363 * @frame_ind: Management frame data to be informed.
8364 *
8365 * This function is used to indicate management frame to
8366 * user space
8367 *
8368 * Return: None
8369 *
8370 */
8371void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
8372{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008373 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07008374 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008375 int i;
8376
Dustin Browne7e71d32018-05-11 16:00:08 -07008377 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8378 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08008379 return;
8380
8381 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
8382 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
8383 adapter =
8384 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
8385 if (adapter)
8386 break;
8387 }
Wu Gaoa0230a62018-01-04 20:56:57 +08008388 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
8389 hdd_for_each_adapter(hdd_ctx, adapter) {
8390 if ((NULL != adapter) &&
8391 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
8392 __hdd_indicate_mgmt_frame(adapter,
8393 frame_ind->frame_len,
8394 frame_ind->frameBuf,
8395 frame_ind->frameType,
8396 frame_ind->rxChan,
8397 frame_ind->rxRssi);
8398 }
8399 }
8400 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008401 } else {
8402 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
8403 frame_ind->sessionId);
8404 }
8405
8406 if ((NULL != adapter) &&
8407 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
8408 __hdd_indicate_mgmt_frame(adapter,
8409 frame_ind->frame_len,
8410 frame_ind->frameBuf,
8411 frame_ind->frameType,
8412 frame_ind->rxChan,
8413 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08008414}
8415
Kapil Gupta8878ad92017-02-13 11:56:04 +05308416void hdd_acs_response_timeout_handler(void *context)
8417{
8418 struct hdd_external_acs_timer_context *timer_context =
8419 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07008420 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008421 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308422 uint8_t reason;
8423
Dustin Brown491d54b2018-03-14 12:39:11 -07008424 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05308425 if (!timer_context) {
8426 hdd_err("invlaid timer context");
8427 return;
8428 }
8429 adapter = timer_context->adapter;
8430 reason = timer_context->reason;
8431
8432
8433 if ((!adapter) ||
8434 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
8435 hdd_err("invalid adapter or adapter has invalid magic");
8436 return;
8437 }
8438 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8439 if (wlan_hdd_validate_context(hdd_ctx))
8440 return;
8441
8442 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
8443 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8444 else
8445 return;
8446
8447 hdd_err("ACS timeout happened for %s reason %d",
8448 adapter->dev->name, reason);
8449 switch (reason) {
8450 /* SAP init case */
8451 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
8452 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
8453 false);
8454 wlan_hdd_cfg80211_start_acs(adapter);
8455 break;
8456 /* DFS detected on current channel */
8457 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
8458 wlan_sap_update_next_channel(
8459 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
8460 sme_update_new_channel_event(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07008461 adapter->session_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308462 break;
8463 /* LTE coex event on current channel */
8464 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
8465 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
8466 break;
8467 default:
8468 hdd_info("invalid reason for timer invoke");
8469
8470 }
8471}
8472
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008473/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008474 * hdd_override_ini_config - Override INI config
8475 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008476 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008477 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008478 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008479 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008480 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008481static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008482{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008483
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008484 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
8485 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008486 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008487 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008488 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008489 if (0 == enable_11d || 1 == enable_11d) {
8490 hdd_ctx->config->Is11dSupportEnabled = enable_11d;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008491 hdd_debug("Module enable_11d set to %d", enable_11d);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008492 }
Leo Chang11545d62016-10-17 14:53:50 -07008493
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05308494 if (!ucfg_ipa_is_present()) {
Leo Chang11545d62016-10-17 14:53:50 -07008495 hdd_ctx->config->IpaConfig = 0;
Jingxiang Ge7a040dc2018-02-02 11:07:59 +08008496 hdd_debug("IpaConfig override to %d",
8497 hdd_ctx->config->IpaConfig);
8498 }
Yeshwanth Sriram Guntuka2ba6fe92017-10-04 14:40:45 +05308499
8500 if (!hdd_ctx->config->rssi_assoc_reject_enabled ||
8501 !hdd_ctx->config->enable_bcast_probe_rsp) {
8502 hdd_debug("OCE disabled, rssi_assoc_reject_enabled: %d enable_bcast_probe_rsp: %d",
8503 hdd_ctx->config->rssi_assoc_reject_enabled,
8504 hdd_ctx->config->enable_bcast_probe_rsp);
8505 hdd_ctx->config->oce_sta_enabled = 0;
8506 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008507}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008508
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008509/**
8510 * hdd_set_trace_level_for_each - Set trace level for each INI config
8511 * @hdd_ctx - HDD context
8512 *
8513 * Set trace level for each module based on INI config.
8514 *
8515 * Return: None
8516 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008517static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008518{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308519 hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
8520 hdd_ctx->config->qdf_trace_enable_wdi);
8521 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
8522 hdd_ctx->config->qdf_trace_enable_hdd);
8523 hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
8524 hdd_ctx->config->qdf_trace_enable_sme);
8525 hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
8526 hdd_ctx->config->qdf_trace_enable_pe);
8527 hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
8528 hdd_ctx->config->qdf_trace_enable_wma);
8529 hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
8530 hdd_ctx->config->qdf_trace_enable_sys);
8531 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
8532 hdd_ctx->config->qdf_trace_enable_qdf);
8533 hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
8534 hdd_ctx->config->qdf_trace_enable_sap);
8535 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
8536 hdd_ctx->config->qdf_trace_enable_hdd_sap);
8537 hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
8538 hdd_ctx->config->qdf_trace_enable_bmi);
8539 hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
8540 hdd_ctx->config->qdf_trace_enable_cfg);
8541 hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
8542 hdd_ctx->config->qdf_trace_enable_epping);
8543 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
8544 hdd_ctx->config->qdf_trace_enable_qdf_devices);
8545 hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
Houston Hoffmanfbf05102017-08-28 11:37:01 -07008546 hdd_ctx->config->qdf_trace_enable_txrx);
8547 hdd_qdf_trace_enable(QDF_MODULE_ID_DP,
8548 hdd_ctx->config->qdf_trace_enable_dp);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308549 hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
8550 hdd_ctx->config->qdf_trace_enable_htc);
8551 hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
8552 hdd_ctx->config->qdf_trace_enable_hif);
8553 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
8554 hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
8555 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
8556 hdd_ctx->config->qdf_trace_enable_hdd_data);
Naveen Rawat7df31862017-03-01 17:09:30 -08008557 hdd_qdf_trace_enable(QDF_MODULE_ID_WIFIPOS,
8558 hdd_ctx->config->qdf_trace_enable_wifi_pos);
Naveen Rawatf2b0dbd2017-03-27 10:00:15 -07008559 hdd_qdf_trace_enable(QDF_MODULE_ID_NAN,
8560 hdd_ctx->config->qdf_trace_enable_nan);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07008561 hdd_qdf_trace_enable(QDF_MODULE_ID_REGULATORY,
8562 hdd_ctx->config->qdf_trace_enable_regulatory);
Naveen Rawat3cb779e2018-02-16 16:36:10 -08008563 hdd_qdf_trace_enable(QDF_MODULE_ID_CP_STATS,
8564 hdd_ctx->config->qdf_trace_enable_cp_stats);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07008565
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008566 hdd_cfg_print(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008567}
8568
8569/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008570 * hdd_context_init() - Initialize HDD context
8571 * @hdd_ctx: HDD context.
8572 *
8573 * Initialize HDD context along with all the feature specific contexts.
8574 *
8575 * return: 0 on success and errno on failure.
8576 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008577static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008578{
8579 int ret;
8580
8581 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
8582 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
8583
8584 hdd_init_ll_stats_ctx();
8585
8586 init_completion(&hdd_ctx->mc_sus_event_var);
8587 init_completion(&hdd_ctx->ready_to_suspend);
8588
8589 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308590 qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008591 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308592
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008593 qdf_list_create(&hdd_ctx->hdd_adapters, MAX_NUMBER_OF_ADAPTERS);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008594
8595 init_completion(&hdd_ctx->set_antenna_mode_cmpl);
8596
8597 ret = hdd_scan_context_init(hdd_ctx);
8598 if (ret)
8599 goto list_destroy;
8600
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008601 hdd_rx_wake_lock_create(hdd_ctx);
8602
8603 ret = hdd_sap_context_init(hdd_ctx);
8604 if (ret)
8605 goto scan_destroy;
8606
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008607 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
8608
8609 hdd_init_offloaded_packets_ctx(hdd_ctx);
8610
8611 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
8612 hdd_ctx->config);
8613 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08008614 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008615
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05308616 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
8617 "monitor_mode_wakelock");
8618
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008619 return 0;
8620
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008621sap_destroy:
8622 hdd_sap_context_destroy(hdd_ctx);
8623
8624scan_destroy:
8625 hdd_scan_context_destroy(hdd_ctx);
8626 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008627list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008628 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08008629
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008630 return ret;
8631}
8632
8633/**
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308634 * ie_whitelist_attrs_init() - initialize ie whitelisting attributes
8635 * @hdd_ctx: pointer to hdd context
8636 *
8637 * Return: status of initialization
8638 * 0 - success
8639 * negative value - failure
8640 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008641static int ie_whitelist_attrs_init(struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308642{
8643 int ret;
8644
8645 if (!hdd_ctx->config->probe_req_ie_whitelist)
8646 return 0;
8647
8648 if (!hdd_validate_prb_req_ie_bitmap(hdd_ctx)) {
8649 hdd_err("invalid ie bitmap and ouis: disable ie whitelisting");
8650 hdd_ctx->config->probe_req_ie_whitelist = false;
8651 return -EINVAL;
8652 }
8653
8654 /* parse ini string probe req oui */
8655 ret = hdd_parse_probe_req_ouis(hdd_ctx);
8656 if (ret) {
8657 hdd_err("parsing error: disable ie whitelisting");
8658 hdd_ctx->config->probe_req_ie_whitelist = false;
8659 }
8660
8661 return ret;
8662}
8663
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308664/**
8665 * hdd_iface_change_callback() - Function invoked when stop modules expires
8666 * @priv: pointer to hdd context
8667 *
8668 * This function is invoked when the timer waiting for the interface change
8669 * expires, it shall cut-down the power to wlan and stop all the modules.
8670 *
8671 * Return: void
8672 */
8673static void hdd_iface_change_callback(void *priv)
8674{
8675 struct hdd_context *hdd_ctx = (struct hdd_context *) priv;
8676 int ret;
8677 int status = wlan_hdd_validate_context(hdd_ctx);
8678
8679 if (status)
8680 return;
8681
Dustin Brown491d54b2018-03-14 12:39:11 -07008682 hdd_enter();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308683 hdd_debug("Interface change timer expired close the modules!");
8684 ret = hdd_wlan_stop_modules(hdd_ctx, false);
8685 if (ret)
8686 hdd_err("Failed to stop modules");
Dustin Browne74003f2018-03-14 12:51:58 -07008687 hdd_exit();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308688}
8689
Nirav Shaheb017be2018-02-15 11:20:58 +05308690#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8691static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
8692{
8693 wlan_logging_set_log_to_console(hdd_ctx->config->
8694 wlan_logging_to_console);
8695 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
8696}
8697#else
8698static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
8699{ }
8700#endif
8701
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308702/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008703 * hdd_context_create() - Allocate and inialize HDD context.
Arun Khandavallifae92942016-08-01 13:31:08 +05308704 * @dev: Device Pointer to the underlying device
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008705 *
8706 * Allocate and initialize HDD context. HDD context is allocated as part of
8707 * wiphy allocation and then context is initialized.
8708 *
8709 * Return: HDD context on success and ERR_PTR on failure
8710 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008711static struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008712{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308713 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008714 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008715 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008716
Dustin Brown491d54b2018-03-14 12:39:11 -07008717 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008718
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008719 hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(struct hdd_context));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008720 if (hdd_ctx == NULL) {
8721 ret = -ENOMEM;
8722 goto err_out;
8723 }
8724
Dustin Brown6f427922017-09-19 12:19:00 -07008725 qdf_create_delayed_work(&hdd_ctx->iface_idle_work,
8726 hdd_iface_change_callback,
8727 (void *)hdd_ctx);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308728
8729 mutex_init(&hdd_ctx->iface_change_lock);
8730
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008731 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05308732 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008733
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308734 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008735 if (hdd_ctx->config == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008736 hdd_err("Failed to alloc memory for HDD config!");
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008737 ret = -ENOMEM;
8738 goto err_free_hdd_context;
8739 }
8740
8741 /* Read and parse the qcom_cfg.ini file */
8742 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308743 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05308744 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008745 WLAN_INI_FILE);
8746 ret = -EINVAL;
8747 goto err_free_config;
8748 }
8749
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308750 ie_whitelist_attrs_init(hdd_ctx);
8751
Dustin Brown7f939932017-05-18 15:02:17 -07008752 hdd_debug("setting timer multiplier: %u",
8753 hdd_ctx->config->timer_multiplier);
8754 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
8755
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008756
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308757 if (hdd_ctx->config->fhostNSOffload)
8758 hdd_ctx->ns_offload_enable = true;
8759
Abhishek Singh5ea86532016-04-27 14:10:53 +05308760 cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
8761
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008762 hdd_override_ini_config(hdd_ctx);
8763
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008764 ret = hdd_context_init(hdd_ctx);
8765
8766 if (ret)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008767 goto err_free_config;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008768
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008769 /* Uses to enabled logging after SSR */
Komal Seelamc11bb222016-01-27 18:57:10 +05308770 hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008771
Anurag Chouhan6d760662016-02-20 16:05:43 +05308772 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008773 goto skip_multicast_logging;
8774
8775 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
8776
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008777 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
8778 if (ret)
8779 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05308780
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008781 ret = hdd_init_netlink_services(hdd_ctx);
8782 if (ret)
8783 goto err_deinit_txrx_histogram;
8784
Nirav Shaheb017be2018-02-15 11:20:58 +05308785 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +05308786
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008787skip_multicast_logging:
8788 hdd_set_trace_level_for_each(hdd_ctx);
8789
Rajeev Kumar493a31b2017-09-29 14:01:24 -07008790 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
8791
Dustin Browne74003f2018-03-14 12:51:58 -07008792 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07008793
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008794 return hdd_ctx;
8795
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008796err_deinit_txrx_histogram:
8797 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
8798
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008799err_deinit_hdd_context:
8800 hdd_context_deinit(hdd_ctx);
8801
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008802err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308803 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008804
8805err_free_hdd_context:
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308806 mutex_destroy(&hdd_ctx->iface_change_lock);
Rajeev Kumarfa55a692018-01-09 14:12:41 -08008807 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008808
8809err_out:
8810 return ERR_PTR(ret);
8811}
8812
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008813#ifdef WLAN_OPEN_P2P_INTERFACE
8814/**
8815 * hdd_open_p2p_interface - Open P2P interface
8816 * @hdd_ctx: HDD context
8817 * @rtnl_held: True if RTNL lock held
8818 *
8819 * Open P2P interface during probe. This function called to open the P2P
8820 * interface at probe along with STA interface.
8821 *
8822 * Return: 0 on success and errno on failure
8823 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008824static int hdd_open_p2p_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008825{
Jeff Johnson9d295242017-08-29 14:39:48 -07008826 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008827 uint8_t *p2p_dev_addr;
8828
8829 if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
8830 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008831 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008832 hdd_ctx->config->intfMacAddr[0].bytes,
8833 sizeof(tSirMacAddr));
8834
8835 /*
8836 * Generate the P2P Device Address. This consists of
8837 * the device's primary MAC address with the locally
8838 * administered bit set.
8839 */
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008840 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008841 } else {
8842 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
8843 if (p2p_dev_addr == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008844 hdd_err("Failed to allocate mac_address for p2p_device");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008845 return -ENOSPC;
8846 }
8847
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008848 qdf_mem_copy(&hdd_ctx->p2p_device_address.bytes[0],
8849 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008850 }
8851
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008852 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008853 &hdd_ctx->p2p_device_address.bytes[0],
Ryan Hsu07495ea2016-01-21 15:25:39 -08008854 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008855
8856 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008857 hdd_err("Failed to do hdd_open_adapter for P2P Device Interface");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008858 return -ENOSPC;
8859 }
8860
8861 return 0;
8862}
8863#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008864static inline int hdd_open_p2p_interface(struct hdd_context *hdd_ctx,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008865 bool rtnl_held)
8866{
8867 return 0;
8868}
8869#endif
8870
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008871static int hdd_open_ocb_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Jeff Johnson957bc272017-02-02 08:54:48 -08008872{
Jeff Johnson9d295242017-08-29 14:39:48 -07008873 struct hdd_adapter *adapter;
Jeff Johnson957bc272017-02-02 08:54:48 -08008874 int ret = 0;
8875
8876 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
8877 wlan_hdd_get_intf_addr(hdd_ctx),
8878 NET_NAME_UNKNOWN, rtnl_held);
8879 if (adapter == NULL) {
8880 hdd_err("Failed to open 802.11p interface");
8881 ret = -ENOSPC;
8882 }
8883
8884 return ret;
8885}
8886
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008887/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308888 * hdd_start_station_adapter()- Start the Station Adapter
8889 * @adapter: HDD adapter
8890 *
8891 * This function initializes the adapter for the station mode.
8892 *
8893 * Return: 0 on success or errno on failure.
8894 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008895int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308896{
8897 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08008898 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308899
Dustin Brownfdf17c12018-03-14 12:55:34 -07008900 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08008901 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8902 hdd_err("session is already opened, %d",
8903 adapter->session_id);
8904 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8905 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308906
Krunal Sonib51eec72017-11-20 21:53:01 -08008907 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
8908 if (ret) {
8909 hdd_err("failed to create vdev: %d", ret);
8910 return ret;
8911 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308912 status = hdd_init_station_mode(adapter);
8913
8914 if (QDF_STATUS_SUCCESS != status) {
8915 hdd_err("Error Initializing station mode: %d", status);
8916 return qdf_status_to_os_return(status);
8917 }
8918
Arun Khandavallifae92942016-08-01 13:31:08 +05308919 hdd_register_tx_flow_control(adapter,
8920 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008921 hdd_tx_resume_cb,
8922 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308923
Dustin Browne74003f2018-03-14 12:51:58 -07008924 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308925 return 0;
8926}
8927
8928/**
8929 * hdd_start_ap_adapter()- Start AP Adapter
8930 * @adapter: HDD adapter
8931 *
8932 * This function initializes the adapter for the AP mode.
8933 *
8934 * Return: 0 on success errno on failure.
8935 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008936int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308937{
8938 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008939 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08008940 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -08008941 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308942
Dustin Brown491d54b2018-03-14 12:39:11 -07008943 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308944
Krunal Sonib51eec72017-11-20 21:53:01 -08008945 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8946 hdd_err("session is already opened, %d",
8947 adapter->session_id);
8948 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8949 }
8950 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008951 * In SSR case no need to create new sap context.
8952 * Otherwise create sap context first and then create
8953 * vdev as while creating the vdev, driver needs to
8954 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08008955 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008956 if (adapter->session.ap.sap_context) {
8957 is_ssr = true;
8958 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08008959 hdd_err("sap creation failed");
8960 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
8961 }
8962
8963 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
8964 adapter->session.ap.sap_context);
8965 if (ret) {
8966 hdd_err("failed to create vdev, status:%d", ret);
8967 hdd_sap_destroy_ctx(adapter);
8968 return ret;
8969 }
Naveen Rawat1af09392018-01-03 17:28:21 -08008970
8971 if (adapter->device_mode == QDF_SAP_MODE)
8972 sme_cli_set_command(adapter->session_id,
8973 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
8974 (bool)(hdd_ctx->config->fine_time_meas_cap &
8975 WMI_FW_AP_RTT_RESPR),
8976 VDEV_CMD);
8977
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008978 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308979
8980 if (QDF_STATUS_SUCCESS != status) {
8981 hdd_err("Error Initializing the AP mode: %d", status);
8982 return qdf_status_to_os_return(status);
8983 }
8984
Arun Khandavallifae92942016-08-01 13:31:08 +05308985 hdd_register_tx_flow_control(adapter,
8986 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008987 hdd_softap_tx_resume_cb,
8988 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308989
Dustin Browne74003f2018-03-14 12:51:58 -07008990 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308991 return 0;
8992}
8993
Sourav Mohapatra57006c72017-11-19 16:15:55 +05308994static int hdd_open_concurrent_interface(struct hdd_context *hdd_ctx,
8995 bool rtnl_held)
8996{
8997 struct hdd_adapter *adapter;
8998
8999 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
9000 hdd_ctx->config->enableConcurrentSTA,
9001 wlan_hdd_get_intf_addr(hdd_ctx),
9002 NET_NAME_UNKNOWN, rtnl_held);
9003
9004 if (!adapter)
9005 return -ENOSPC;
9006
9007 return 0;
9008}
9009
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309010/**
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009011 * hdd_open_interfaces - Open all required interfaces
9012 * hdd_ctx: HDD context
9013 * rtnl_held: True if RTNL lock is held
9014 *
9015 * Open all the interfaces like STA, P2P and OCB based on the configuration.
9016 *
Jeff Johnson957bc272017-02-02 08:54:48 -08009017 * Return: 0 if all interfaces were created, otherwise negative errno
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009018 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009019static int hdd_open_interfaces(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009020{
Jeff Johnson9d295242017-08-29 14:39:48 -07009021 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009022 int ret;
9023
Ravi Joshia307f632017-07-17 23:41:41 -07009024 /* open monitor mode adapter if con_mode is monitor mode */
Lin Bai1c678482017-12-18 18:29:11 +08009025 if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
9026 con_mode == QDF_GLOBAL_FTM_MODE) {
9027 uint8_t session_type = (con_mode == QDF_GLOBAL_MONITOR_MODE) ?
9028 QDF_MONITOR_MODE : QDF_FTM_MODE;
9029
9030 adapter = hdd_open_adapter(hdd_ctx, session_type, "wlan%d",
9031 wlan_hdd_get_intf_addr(hdd_ctx),
9032 NET_NAME_UNKNOWN, rtnl_held);
Ravi Joshia307f632017-07-17 23:41:41 -07009033 if (!adapter) {
9034 hdd_err("open adapter failed");
9035 return -ENOSPC;
9036 }
Lin Bai1c678482017-12-18 18:29:11 +08009037
Ravi Joshia307f632017-07-17 23:41:41 -07009038 return 0;
9039 }
9040
Jeff Johnson957bc272017-02-02 08:54:48 -08009041 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE)
Arun Khandavallifae92942016-08-01 13:31:08 +05309042 /* Create only 802.11p interface */
Jeff Johnson957bc272017-02-02 08:54:48 -08009043 return hdd_open_ocb_interface(hdd_ctx, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009044
Krunal Soni9b04c9b2016-03-10 13:08:05 -08009045 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009046 wlan_hdd_get_intf_addr(hdd_ctx),
Ryan Hsu07495ea2016-01-21 15:25:39 -08009047 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009048
9049 if (adapter == NULL)
Jeff Johnson957bc272017-02-02 08:54:48 -08009050 return -ENOSPC;
9051
Sourav Mohapatra57006c72017-11-19 16:15:55 +05309052 if (strlen(hdd_ctx->config->enableConcurrentSTA) != 0) {
9053 ret = hdd_open_concurrent_interface(hdd_ctx, rtnl_held);
9054 if (ret)
9055 hdd_err("Cannot create concurrent STA interface");
9056 }
9057
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009058 ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
9059 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -08009060 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009061
9062 /* Open 802.11p Interface */
9063 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
Jeff Johnson957bc272017-02-02 08:54:48 -08009064 ret = hdd_open_ocb_interface(hdd_ctx, rtnl_held);
9065 if (ret)
9066 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009067 }
9068
Jeff Johnson957bc272017-02-02 08:54:48 -08009069 return 0;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009070
Jeff Johnson957bc272017-02-02 08:54:48 -08009071err_close_adapters:
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009072 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Jeff Johnson957bc272017-02-02 08:54:48 -08009073 return ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009074}
9075
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009076
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309077#ifdef QCA_LL_TX_FLOW_CONTROL_V2
9078/**
9079 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
9080 * @cds_cfg: CDS Configuration
9081 * @hdd_ctx: Pointer to hdd context
9082 *
9083 * Return: none
9084 */
9085static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9086 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009087 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309088{
9089 cds_cfg->tx_flow_stop_queue_th =
9090 hdd_ctx->config->TxFlowStopQueueThreshold;
9091 cds_cfg->tx_flow_start_queue_offset =
9092 hdd_ctx->config->TxFlowStartQueueOffset;
9093}
9094#else
9095static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9096 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009097 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309098{
9099}
9100#endif
9101
9102#ifdef FEATURE_WLAN_RA_FILTERING
9103/**
9104 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
9105 * @cds_cfg: CDS Configuration
9106 * @hdd_ctx: Pointer to hdd context
9107 *
9108 * Return: none
9109 */
Anand Kumar3b92a912016-12-05 12:01:26 +05309110static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009111 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309112{
9113 cds_cfg->ra_ratelimit_interval =
9114 hdd_ctx->config->RArateLimitInterval;
9115 cds_cfg->is_ra_ratelimit_enabled =
9116 hdd_ctx->config->IsRArateLimitEnabled;
9117}
9118#else
Anand Kumar3b92a912016-12-05 12:01:26 +05309119static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009120 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309121{
9122}
9123#endif
9124
9125/**
9126 * hdd_update_cds_config() - API to update cds configuration parameters
9127 * @hdd_ctx: HDD Context
9128 *
9129 * Return: 0 for Success, errno on failure
9130 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009131static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309132{
9133 struct cds_config_info *cds_cfg;
9134
9135 cds_cfg = (struct cds_config_info *)qdf_mem_malloc(sizeof(*cds_cfg));
9136 if (!cds_cfg) {
9137 hdd_err("failed to allocate cds config");
9138 return -ENOMEM;
9139 }
9140
Srinivas Girigowda35b00312017-06-27 21:52:03 -07009141 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -08009142 if (!hdd_ctx->config->nMaxPsPoll ||
9143 !hdd_ctx->config->enablePowersaveOffload) {
9144 cds_cfg->powersave_offload_enabled =
9145 hdd_ctx->config->enablePowersaveOffload;
9146 } else {
9147 if ((hdd_ctx->config->enablePowersaveOffload ==
9148 PS_QPOWER_NODEEPSLEEP) ||
9149 (hdd_ctx->config->enablePowersaveOffload ==
9150 PS_LEGACY_NODEEPSLEEP))
9151 cds_cfg->powersave_offload_enabled =
9152 PS_LEGACY_NODEEPSLEEP;
9153 else
9154 cds_cfg->powersave_offload_enabled =
9155 PS_LEGACY_DEEPSLEEP;
9156 hdd_info("Qpower disabled in cds config, %d",
9157 cds_cfg->powersave_offload_enabled);
9158 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309159 cds_cfg->sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
9160 cds_cfg->sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
9161 cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
9162 cds_cfg->wow_enable = hdd_ctx->config->wowEnable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309163
9164 /*
9165 * Copy the DFS Phyerr Filtering Offload status.
9166 * This parameter reflects the value of the
9167 * dfs_phyerr_filter_offload flag as set in the ini.
9168 */
9169 cds_cfg->dfs_phyerr_filter_offload =
9170 hdd_ctx->config->fDfsPhyerrFilterOffload;
9171 if (hdd_ctx->config->ssdp)
9172 cds_cfg->ssdp = hdd_ctx->config->ssdp;
9173
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05309174 cds_cfg->force_target_assert_enabled =
9175 hdd_ctx->config->crash_inject_enabled;
9176
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309177 cds_cfg->enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
9178 cds_cfg->ap_maxoffload_peers = hdd_ctx->config->apMaxOffloadPeers;
9179
9180 cds_cfg->ap_maxoffload_reorderbuffs =
9181 hdd_ctx->config->apMaxOffloadReorderBuffs;
9182
9183 cds_cfg->ap_disable_intrabss_fwd =
9184 hdd_ctx->config->apDisableIntraBssFwd;
9185
9186 cds_cfg->dfs_pri_multiplier =
9187 hdd_ctx->config->dfsRadarPriMultiplier;
9188 cds_cfg->reorder_offload =
9189 hdd_ctx->config->reorderOffloadSupport;
9190
9191 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05309192 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Yun Parkde380782016-08-17 16:26:54 -07009193 if (!is_power_of_2(hdd_ctx->config->IpaUcTxBufCount)) {
9194 /* IpaUcTxBufCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009195 hdd_debug("Round down IpaUcTxBufCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07009196 hdd_ctx->config->IpaUcTxBufCount);
9197 hdd_ctx->config->IpaUcTxBufCount =
9198 rounddown_pow_of_two(
9199 hdd_ctx->config->IpaUcTxBufCount);
9200 if (!hdd_ctx->config->IpaUcTxBufCount) {
9201 hdd_err("Failed to round down IpaUcTxBufCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309202 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07009203 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009204 hdd_debug("IpaUcTxBufCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07009205 hdd_ctx->config->IpaUcTxBufCount);
9206 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309207 cds_cfg->uc_txbuf_count = hdd_ctx->config->IpaUcTxBufCount;
9208 cds_cfg->uc_txbuf_size = hdd_ctx->config->IpaUcTxBufSize;
Yun Parkde380782016-08-17 16:26:54 -07009209 if (!is_power_of_2(hdd_ctx->config->IpaUcRxIndRingCount)) {
9210 /* IpaUcRxIndRingCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009211 hdd_debug("Round down IpaUcRxIndRingCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07009212 hdd_ctx->config->IpaUcRxIndRingCount);
9213 hdd_ctx->config->IpaUcRxIndRingCount =
9214 rounddown_pow_of_two(
9215 hdd_ctx->config->IpaUcRxIndRingCount);
9216 if (!hdd_ctx->config->IpaUcRxIndRingCount) {
9217 hdd_err("Failed to round down IpaUcRxIndRingCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309218 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07009219 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009220 hdd_debug("IpaUcRxIndRingCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07009221 hdd_ctx->config->IpaUcRxIndRingCount);
9222 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309223 cds_cfg->uc_rxind_ringcount =
Yun Parkde380782016-08-17 16:26:54 -07009224 hdd_ctx->config->IpaUcRxIndRingCount;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309225 cds_cfg->uc_tx_partition_base =
9226 hdd_ctx->config->IpaUcTxPartitionBase;
9227 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
9228
9229 cds_cfg->ip_tcp_udp_checksum_offload =
9230 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07009231 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309232 cds_cfg->ce_classify_enabled =
9233 hdd_ctx->config->ce_classify_enabled;
Dustin Brownd3fc9ee2016-09-14 13:57:27 -07009234 cds_cfg->bpf_packet_filter_enable =
9235 hdd_ctx->config->bpf_packet_filter_enable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309236 cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
9237 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
9238 cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
Naveen Rawat64e477e2016-05-20 10:34:56 -07009239 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Manjunathappa Prakashfff753c2016-09-01 19:34:56 -07009240 cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07009241 cds_cfg->max_msdus_per_rxinorderind =
9242 hdd_ctx->config->max_msdus_per_rxinorderind;
Naveen Rawat91df30a2016-10-12 21:26:18 -07009243 cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
Sandeep Puligillaafa52892016-10-26 19:03:16 -07009244 cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05309245 cds_cfg->active_uc_bpf_mode = hdd_ctx->config->active_uc_bpf_mode;
9246 cds_cfg->active_mc_bc_bpf_mode = hdd_ctx->config->active_mc_bc_bpf_mode;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05309247 cds_cfg->auto_power_save_fail_mode =
9248 hdd_ctx->config->auto_pwr_save_fail_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309249
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309250 cds_cfg->ito_repeat_count = hdd_ctx->config->ito_repeat_count;
Sandeep Puligilla819d94f2017-10-10 18:33:56 -07009251 cds_cfg->bandcapability = hdd_ctx->config->nBandCapability;
Zhu Jianmina2f8e8d2018-02-11 16:37:10 +08009252 cds_cfg->delay_before_vdev_stop =
9253 hdd_ctx->config->delay_before_vdev_stop;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309254
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309255 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
9256 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
9257 hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07009258 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309259 cds_init_ini_config(cds_cfg);
9260 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309261
9262exit:
9263 qdf_mem_free(cds_cfg);
9264 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309265}
9266
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009267/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009268 * hdd_update_user_config() - API to update user configuration
9269 * parameters to obj mgr which are used by multiple components
9270 * @hdd_ctx: HDD Context
9271 *
9272 * Return: 0 for Success, errno on failure
9273 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009274static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009275{
9276 struct wlan_objmgr_psoc_user_config *user_config;
9277
9278 user_config = qdf_mem_malloc(sizeof(*user_config));
9279 if (user_config == NULL) {
9280 hdd_alert("Failed to alloc memory for user_config!");
9281 return -ENOMEM;
9282 }
9283
9284 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
9285 user_config->dual_mac_feature_disable =
9286 hdd_ctx->config->dual_mac_feature_disable;
9287 user_config->indoor_channel_support =
9288 hdd_ctx->config->indoor_channel_support;
9289 user_config->is_11d_support_enabled =
9290 hdd_ctx->config->Is11dSupportEnabled;
9291 user_config->is_11h_support_enabled =
9292 hdd_ctx->config->Is11hSupportEnabled;
9293 user_config->optimize_chan_avoid_event =
9294 hdd_ctx->config->goptimize_chan_avoid_event;
9295 user_config->skip_dfs_chnl_in_p2p_search =
9296 hdd_ctx->config->skipDfsChnlInP2pSearch;
Naveen Rawat222b2e92017-03-16 09:52:21 -07009297 user_config->band_capability = hdd_ctx->config->nBandCapability;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009298 wlan_objmgr_psoc_set_user_config(hdd_ctx->hdd_psoc, user_config);
9299
9300 qdf_mem_free(user_config);
9301 return 0;
9302}
9303
9304/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009305 * hdd_init_thermal_info - Initialize thermal level
9306 * @hdd_ctx: HDD context
9307 *
9308 * Initialize thermal level at SME layer and set the thermal level callback
9309 * which would be called when a configured thermal threshold is hit.
9310 *
9311 * Return: 0 on success and errno on failure
9312 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009313static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009314{
9315 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309316 QDF_STATUS status;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009317
9318 thermal_param.smeThermalMgmtEnabled =
9319 hdd_ctx->config->thermalMitigationEnable;
9320 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
9321
Poddar, Siddarth83905022016-04-16 17:56:08 -07009322 thermal_param.sme_throttle_duty_cycle_tbl[0] =
9323 hdd_ctx->config->throttle_dutycycle_level0;
9324 thermal_param.sme_throttle_duty_cycle_tbl[1] =
9325 hdd_ctx->config->throttle_dutycycle_level1;
9326 thermal_param.sme_throttle_duty_cycle_tbl[2] =
9327 hdd_ctx->config->throttle_dutycycle_level2;
9328 thermal_param.sme_throttle_duty_cycle_tbl[3] =
9329 hdd_ctx->config->throttle_dutycycle_level3;
9330
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009331 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
9332 hdd_ctx->config->thermalTempMinLevel0;
9333 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
9334 hdd_ctx->config->thermalTempMaxLevel0;
9335 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
9336 hdd_ctx->config->thermalTempMinLevel1;
9337 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
9338 hdd_ctx->config->thermalTempMaxLevel1;
9339 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
9340 hdd_ctx->config->thermalTempMinLevel2;
9341 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
9342 hdd_ctx->config->thermalTempMaxLevel2;
9343 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
9344 hdd_ctx->config->thermalTempMinLevel3;
9345 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
9346 hdd_ctx->config->thermalTempMaxLevel3;
9347
9348 status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);
9349
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309350 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05309351 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009352
9353 sme_add_set_thermal_level_callback(hdd_ctx->hHal,
9354 hdd_set_thermal_level_cb);
9355
9356 return 0;
9357
9358}
9359
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009360#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
9361/**
9362 * hdd_hold_rtnl_lock - Hold RTNL lock
9363 *
9364 * Hold RTNL lock
9365 *
9366 * Return: True if held and false otherwise
9367 */
9368static inline bool hdd_hold_rtnl_lock(void)
9369{
9370 rtnl_lock();
9371 return true;
9372}
9373
9374/**
9375 * hdd_release_rtnl_lock - Release RTNL lock
9376 *
9377 * Release RTNL lock
9378 *
9379 * Return: None
9380 */
9381static inline void hdd_release_rtnl_lock(void)
9382{
9383 rtnl_unlock();
9384}
9385#else
9386static inline bool hdd_hold_rtnl_lock(void) { return false; }
9387static inline void hdd_release_rtnl_lock(void) { }
9388#endif
9389
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009390#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009391
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309392/* MAX iwpriv command support */
9393#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309394#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309395#define MAX_PKTLOG_SIZE 16
9396
9397/**
9398 * hdd_pktlog_set_buff_size() - set pktlog buffer size
9399 * @hdd_ctx: hdd context
9400 * @set_value2: pktlog buffer size value
9401 *
9402 *
9403 * Return: 0 for success or error.
9404 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009405static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309406{
9407 struct sir_wifi_start_log start_log = { 0 };
9408 QDF_STATUS status;
9409
9410 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9411 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
9412 start_log.ini_triggered = cds_is_packet_log_enabled();
9413 start_log.user_triggered = 1;
9414 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309415 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309416
9417 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9418 if (!QDF_IS_STATUS_SUCCESS(status)) {
9419 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009420 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309421 return -EINVAL;
9422 }
9423
9424 return 0;
9425}
9426
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009427/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309428 * hdd_pktlog_clear_buff() - clear pktlog buffer
9429 * @hdd_ctx: hdd context
9430 *
9431 * Return: 0 for success or error.
9432 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009433static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309434{
9435 struct sir_wifi_start_log start_log;
9436 QDF_STATUS status;
9437
9438 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9439 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
9440 start_log.ini_triggered = cds_is_packet_log_enabled();
9441 start_log.user_triggered = 1;
9442 start_log.size = 0;
9443 start_log.is_pktlog_buff_clear = true;
9444
9445 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9446 if (!QDF_IS_STATUS_SUCCESS(status)) {
9447 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009448 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309449 return -EINVAL;
9450 }
9451
9452 return 0;
9453}
9454
9455
9456/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009457 * hdd_process_pktlog_command() - process pktlog command
9458 * @hdd_ctx: hdd context
9459 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309460 * @set_value2: pktlog buffer size value
9461 *
9462 * This function process pktlog command.
9463 * set_value2 only matters when set_value is 3 (set buff size)
9464 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009465 *
9466 * Return: 0 for success or error.
9467 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009468int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309469 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009470{
9471 int ret;
9472 bool enable;
9473 uint8_t user_triggered = 0;
9474
9475 ret = wlan_hdd_validate_context(hdd_ctx);
9476 if (0 != ret)
9477 return ret;
9478
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009479 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009480
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309481 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009482 hdd_err("invalid pktlog value %d", set_value);
9483 return -EINVAL;
9484 }
9485
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309486 if (set_value == PKTLOG_SET_BUFF_SIZE) {
9487 if (set_value2 <= 0) {
9488 hdd_err("invalid pktlog size %d", set_value2);
9489 return -EINVAL;
9490 } else if (set_value2 > MAX_PKTLOG_SIZE) {
9491 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
9492 return -EINVAL;
9493 }
9494 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309495 } else if (set_value == PKTLOG_CLEAR_BUFF) {
9496 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309497 }
9498
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009499 /*
9500 * set_value = 0 then disable packetlog
9501 * set_value = 1 enable packetlog forcefully
9502 * set_vlaue = 2 then disable packetlog if disabled through ini or
9503 * enable packetlog with AUTO type.
9504 */
9505 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
9506 true : false;
9507
9508 if (1 == set_value) {
9509 enable = true;
9510 user_triggered = 1;
9511 }
9512
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309513 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009514}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07009515
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009516/**
9517 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
9518 * @hdd_ctx: HDD context
9519 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309520 * @user_triggered: triggered through iwpriv
9521 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009522 *
9523 * Return: 0 on success; error number otherwise
9524 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009525int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309526 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009527{
9528 struct sir_wifi_start_log start_log;
9529 QDF_STATUS status;
9530
9531 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9532 start_log.verbose_level =
9533 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009534 start_log.ini_triggered = cds_is_packet_log_enabled();
9535 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309536 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309537 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +05309538 /*
9539 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
9540 * commands. Host uses this flag to decide whether to send pktlog
9541 * disable command to fw without sending pktlog enable command
9542 * previously. For eg, If vendor sends pktlog disable command without
9543 * sending pktlog enable command, then host discards the packet
9544 * but for iwpriv command, host will send it to fw.
9545 */
9546 start_log.is_iwpriv_command = 1;
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009547 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9548 if (!QDF_IS_STATUS_SUCCESS(status)) {
9549 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009550 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009551 return -EINVAL;
9552 }
9553
Poddar, Siddarth61fbc932017-12-19 14:27:55 +05309554 if (enable == true)
9555 hdd_ctx->is_pktlog_enabled = 1;
9556 else
9557 hdd_ctx->is_pktlog_enabled = 0;
9558
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009559 return 0;
9560}
9561#endif /* REMOVE_PKT_LOG */
9562
Komal Seelam92fff912016-03-24 11:51:41 +05309563/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009564 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
9565 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +05309566 * @dev: Device Pointer
9567 * @num: Number of Valid Mac address
9568 *
9569 * Return: Pointer to MAC address buffer
9570 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009571static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
9572 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +05309573{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009574 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +05309575}
Komal Seelam92fff912016-03-24 11:51:41 +05309576
9577/**
9578 * hdd_populate_random_mac_addr() - API to populate random mac addresses
9579 * @hdd_ctx: HDD Context
9580 * @num: Number of random mac addresses needed
9581 *
9582 * Generate random addresses using bit manipulation on the base mac address
9583 *
9584 * Return: None
9585 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009586void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +05309587{
9588 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
9589 uint32_t iter;
9590 struct hdd_config *ini = hdd_ctx->config;
9591 uint8_t *buf = NULL;
9592 uint8_t macaddr_b3, tmp_br3;
9593 uint8_t *src = ini->intfMacAddr[0].bytes;
9594
9595 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
9596 buf = ini->intfMacAddr[iter].bytes;
9597 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
9598 macaddr_b3 = buf[3];
9599 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
9600 INTF_MACADDR_MASK;
9601 macaddr_b3 += tmp_br3;
9602 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
9603 buf[0] |= 0x02;
9604 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009605 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309606 }
9607}
9608
9609/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009610 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +05309611 * @hdd_ctx: HDD Context
9612 *
9613 * API to get mac addresses from platform driver and update the driver
9614 * structures and configure FW with the base mac address.
9615 * Return: int
9616 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009617static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309618{
9619 uint32_t no_of_mac_addr, iter;
9620 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
9621 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
9622 uint8_t *addr, *buf;
9623 struct device *dev = hdd_ctx->parent_dev;
9624 struct hdd_config *ini = hdd_ctx->config;
9625 tSirMacAddr mac_addr;
9626 QDF_STATUS status;
9627
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009628 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +05309629
9630 if (no_of_mac_addr == 0 || !addr) {
9631 hdd_warn("Platform Driver Doesn't have wlan mac addresses");
9632 return -EINVAL;
9633 }
9634
9635 if (no_of_mac_addr > max_mac_addr)
9636 no_of_mac_addr = max_mac_addr;
9637
9638 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
9639
9640 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
9641 buf = ini->intfMacAddr[iter].bytes;
9642 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009643 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309644 }
9645
9646 status = sme_set_custom_mac_addr(mac_addr);
9647
9648 if (!QDF_IS_STATUS_SUCCESS(status))
9649 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009650
Komal Seelam92fff912016-03-24 11:51:41 +05309651 if (no_of_mac_addr < max_mac_addr)
9652 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
9653 no_of_mac_addr);
9654 return 0;
9655}
9656
9657/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009658 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
9659 * @hdd_ctx: HDD Context
9660 *
9661 * Update MAC address to FW. If MAC address passed by FW is invalid, host
9662 * will generate its own MAC and update it to FW.
9663 *
9664 * Return: 0 for success
9665 * Non-zero error code for failure
9666 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009667static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009668{
9669 tSirMacAddr customMacAddr;
9670 QDF_STATUS status;
9671
9672 qdf_mem_copy(&customMacAddr,
9673 &hdd_ctx->config->intfMacAddr[0].bytes[0],
9674 sizeof(tSirMacAddr));
9675 status = sme_set_custom_mac_addr(customMacAddr);
9676 if (!QDF_IS_STATUS_SUCCESS(status))
9677 return -EAGAIN;
9678 return 0;
9679}
9680
9681/**
Komal Seelam92fff912016-03-24 11:51:41 +05309682 * hdd_initialize_mac_address() - API to get wlan mac addresses
9683 * @hdd_ctx: HDD Context
9684 *
9685 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
9686 * is provisioned with mac addresses, driver uses it, else it will use
9687 * wlan_mac.bin to update HW MAC addresses.
9688 *
9689 * Return: None
9690 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009691static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309692{
9693 QDF_STATUS status;
9694 int ret;
9695
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009696 ret = hdd_platform_wlan_mac(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +05309697 if (ret == 0)
9698 return;
9699
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009700 hdd_info("MAC is not programmed in platform driver ret: %d, use wlan_mac.bin",
9701 ret);
Komal Seelam92fff912016-03-24 11:51:41 +05309702
9703 status = hdd_update_mac_config(hdd_ctx);
9704
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009705 if (QDF_IS_STATUS_SUCCESS(status))
9706 return;
9707
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009708 hdd_info("MAC is not programmed in wlan_mac.bin ret %d, use default MAC",
9709 status);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009710
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009711 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009712 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009713 if (ret != 0) {
9714 hdd_err("MAC address out-of-sync, ret:%d", ret);
9715 QDF_ASSERT(ret);
9716 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009717 }
Komal Seelam92fff912016-03-24 11:51:41 +05309718}
9719
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009720static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009721{
9722 int vdev_id = 0;
9723 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
9724 int value = hdd_ctx->config->smart_chainmask_enabled;
9725 int vpdev = PDEV_CMD;
9726 int ret;
9727
Naveen Rawat247a8682017-06-05 15:00:31 -07009728 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009729 if (ret)
9730 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
9731
9732 return ret;
9733}
9734
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009735static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009736{
9737 int vdev_id = 0;
9738 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
9739 int value = hdd_ctx->config->alternative_chainmask_enabled;
9740 int vpdev = PDEV_CMD;
9741 int ret;
9742
Naveen Rawat247a8682017-06-05 15:00:31 -07009743 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009744 if (ret)
9745 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
9746 ret);
9747
9748 return ret;
9749}
9750
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009751static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -07009752{
9753 int vdev_id = 0;
9754 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
9755 int value = hdd_ctx->config->ani_enabled;
9756 int vpdev = PDEV_CMD;
9757 int ret;
9758
Naveen Rawat247a8682017-06-05 15:00:31 -07009759 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -07009760 if (ret)
9761 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
9762
9763 return ret;
9764}
9765
Jeff Johnson89c66ff2016-04-22 15:21:37 -07009766/**
Prashanth Bhatta07998752016-04-28 12:35:33 -07009767 * hdd_pre_enable_configure() - Configurations prior to cds_enable
9768 * @hdd_ctx: HDD context
9769 *
9770 * Pre configurations to be done at lower layer before calling cds enable.
9771 *
9772 * Return: 0 on success and errno on failure.
9773 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009774static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -07009775{
9776 int ret;
9777 QDF_STATUS status;
Leo Changfdb45c32016-10-28 11:09:23 -07009778 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009779
Leo Changfdb45c32016-10-28 11:09:23 -07009780 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009781 /*
9782 * Set 802.11p config
9783 * TODO-OCB: This has been temporarily added here to ensure this
9784 * parameter is set in CSR when we init the channel list. This should
9785 * be removed once the 5.9 GHz channels are added to the regulatory
9786 * domain.
9787 */
9788 hdd_set_dot11p_config(hdd_ctx);
9789
9790 /*
9791 * Note that the cds_pre_enable() sequence triggers the cfg download.
9792 * The cfg download must occur before we update the SME config
9793 * since the SME config operation must access the cfg database
9794 */
9795 status = hdd_set_sme_config(hdd_ctx);
9796
9797 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009798 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009799 ret = qdf_status_to_os_return(status);
9800 goto out;
9801 }
9802
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -07009803 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
9804 if (QDF_STATUS_SUCCESS != status) {
9805 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
9806 ret = qdf_status_to_os_return(status);
9807 goto out;
9808 }
9809
Naveen Rawat247a8682017-06-05 15:00:31 -07009810 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
Prashanth Bhatta07998752016-04-28 12:35:33 -07009811 hdd_ctx->config->tx_chain_mask_1ss,
9812 PDEV_CMD);
9813 if (0 != ret) {
9814 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
9815 goto out;
9816 }
9817
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009818 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
9819 if (ret)
9820 goto out;
9821
9822 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
9823 if (ret)
9824 goto out;
9825
Jeff Johnson12a744b2017-04-04 08:19:37 -07009826 ret = hdd_set_ani_enabled(hdd_ctx);
9827 if (ret)
9828 goto out;
9829
Naveen Rawat247a8682017-06-05 15:00:31 -07009830 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -08009831 hdd_ctx->config->arp_ac_category,
9832 PDEV_CMD);
9833 if (0 != ret) {
9834 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
9835 hdd_ctx->config->arp_ac_category, ret);
9836 goto out;
9837 }
9838
Prashanth Bhatta07998752016-04-28 12:35:33 -07009839 status = hdd_set_sme_chan_list(hdd_ctx);
9840 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009841 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009842 ret = qdf_status_to_os_return(status);
9843 goto out;
9844 }
9845
9846 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -07009847 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009848 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -07009849 ret = -EINVAL;
9850 goto out;
9851 }
9852
Prashanth Bhatta07998752016-04-28 12:35:33 -07009853 /*
9854 * Set the MAC Address Currently this is used by HAL to add self sta.
9855 * Remove this once self sta is added as part of session open.
9856 */
Jeff Johnsonbae59f92018-06-01 17:05:43 -07009857 status = sme_cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
9858 hdd_ctx->config->intfMacAddr[0].bytes,
9859 sizeof(hdd_ctx->config->intfMacAddr[0]));
Prashanth Bhatta07998752016-04-28 12:35:33 -07009860
Jeff Johnsonbae59f92018-06-01 17:05:43 -07009861 if (QDF_IS_STATUS_ERROR(status)) {
9862 hdd_err("Failed to set MAC Address, status %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009863 ret = -EINVAL;
9864 goto out;
9865 }
9866
9867 hdd_init_channel_avoidance(hdd_ctx);
9868
Ganesh Kondabattini408fb8d2017-08-08 22:00:20 +05309869 /* update enable sap mandatory chan list */
9870 policy_mgr_enable_disable_sap_mandatory_chan_list(hdd_ctx->hdd_psoc,
9871 hdd_ctx->config->enable_sap_mandatory_chan_list);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009872out:
9873 return ret;
9874}
9875
9876/**
Peng Xu8fdaa492016-06-22 10:20:47 -07009877 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
9878 * @context_ptr - hdd context pointer
9879 * @event_ptr - event structure pointer
9880 *
9881 * This is the p2p listen offload stop event handler, it sends vendor
9882 * event back to supplicant to notify the stop reason.
9883 *
9884 * Return: None
9885 */
9886static void wlan_hdd_p2p_lo_event_callback(void *context_ptr,
9887 void *event_ptr)
9888{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009889 struct hdd_context *hdd_ctx = (struct hdd_context *)context_ptr;
Peng Xu8fdaa492016-06-22 10:20:47 -07009890 struct sir_p2p_lo_event *evt = event_ptr;
9891 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -07009892 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -07009893
Dustin Brown491d54b2018-03-14 12:39:11 -07009894 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -07009895
9896 if (hdd_ctx == NULL) {
9897 hdd_err("Invalid HDD context pointer");
9898 return;
9899 }
9900
Peng Xu5c682812017-08-06 07:39:13 -07009901 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
9902 if (!adapter) {
9903 hdd_err("Cannot find adapter by vdev_id = %d",
9904 evt->vdev_id);
9905 return;
9906 }
9907
Peng Xu8fdaa492016-06-22 10:20:47 -07009908 vendor_event =
9909 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -07009910 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -07009911 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
9912 GFP_KERNEL);
9913
9914 if (!vendor_event) {
9915 hdd_err("cfg80211_vendor_event_alloc failed");
9916 return;
9917 }
9918
9919 if (nla_put_u32(vendor_event,
9920 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
9921 evt->reason_code)) {
9922 hdd_err("nla put failed");
9923 kfree_skb(vendor_event);
9924 return;
9925 }
9926
9927 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -07009928 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
9929 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -07009930}
9931
9932/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309933 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
9934 * @hdd_ctx: HDD context
9935 *
9936 * This function sends the adaptive dwell time config configuration to the
9937 * firmware via WMA
9938 *
9939 * Return: 0 - success, < 0 - failure
9940 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009941static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309942{
9943 QDF_STATUS status;
9944 struct adaptive_dwelltime_params dwelltime_params;
9945
9946 dwelltime_params.is_enabled =
9947 hdd_ctx->config->adaptive_dwell_mode_enabled;
9948 dwelltime_params.dwelltime_mode =
9949 hdd_ctx->config->global_adapt_dwelltime_mode;
9950 dwelltime_params.lpf_weight =
9951 hdd_ctx->config->adapt_dwell_lpf_weight;
9952 dwelltime_params.passive_mon_intval =
9953 hdd_ctx->config->adapt_dwell_passive_mon_intval;
9954 dwelltime_params.wifi_act_threshold =
9955 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
9956
9957 status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
9958 &dwelltime_params);
9959
9960 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
9961 if (!QDF_IS_STATUS_SUCCESS(status)) {
9962 hdd_err("Failed to send Adaptive Dwelltime configuration!");
9963 return -EAGAIN;
9964 }
9965 return 0;
9966}
9967
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009968int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309969{
9970 QDF_STATUS status;
9971 struct wmi_dbs_scan_sel_params dbs_scan_params;
9972 uint32_t i = 0;
9973 uint8_t count = 0, numentries = 0;
9974 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
9975 * CDS_DBS_SCAN_CLIENTS_MAX];
9976
9977 /* check if DBS is enabled or supported */
Bala Venkateshc8236ca2018-03-09 12:38:29 +05309978 if ((hdd_ctx->config->dual_mac_feature_disable ==
9979 DISABLE_DBS_CXN_AND_SCAN) ||
9980 (hdd_ctx->config->dual_mac_feature_disable ==
9981 ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309982 return -EINVAL;
9983
9984 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
9985 dbs_scan_config, &numentries,
9986 (CDS_DBS_SCAN_PARAM_PER_CLIENT
9987 * CDS_DBS_SCAN_CLIENTS_MAX));
9988
9989 hdd_info("numentries %hu", numentries);
9990 if (!numentries) {
9991 hdd_info("Donot send scan_selection_config");
9992 return 0;
9993 }
9994
9995 /* hdd_set_fw_log_params */
9996 dbs_scan_params.num_clients = 0;
9997 while (count < (numentries - 2)) {
9998 dbs_scan_params.module_id[i] = dbs_scan_config[count];
9999 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
10000 dbs_scan_params.num_non_dbs_scans[i] =
10001 dbs_scan_config[count + 2];
10002 dbs_scan_params.num_clients++;
10003 hdd_debug("module:%d NDS:%d NNDS:%d",
10004 dbs_scan_params.module_id[i],
10005 dbs_scan_params.num_dbs_scans[i],
10006 dbs_scan_params.num_non_dbs_scans[i]);
10007 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
10008 i++;
10009 }
10010
10011 dbs_scan_params.pdev_id = 0;
10012
10013 hdd_debug("clients:%d pdev:%d",
10014 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
10015
10016 status = sme_set_dbs_scan_selection_config(hdd_ctx->hHal,
10017 &dbs_scan_params);
10018 hdd_debug("Sending DBS Scan Selection Configuration to fw");
10019 if (!QDF_IS_STATUS_SUCCESS(status)) {
10020 hdd_err("Failed to send DBS Scan selection configuration!");
10021 return -EAGAIN;
10022 }
10023 return 0;
10024}
10025
Arun Khandavallid4349a92016-07-25 11:10:43 +053010026#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10027/**
10028 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
10029 * @hdd_ctx: HDD context
10030 *
10031 * Set auto shutdown callback to get indications from firmware to indicate
10032 * userspace to shutdown WLAN after a configured amount of inactivity.
10033 *
10034 * Return: 0 on success and errno on failure.
10035 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010036static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010037{
10038 QDF_STATUS status;
10039
10040 if (!hdd_ctx->config->WlanAutoShutdown)
10041 return 0;
10042
10043 status = sme_set_auto_shutdown_cb(hdd_ctx->hHal,
10044 wlan_hdd_auto_shutdown_cb);
10045 if (status != QDF_STATUS_SUCCESS)
10046 hdd_err("Auto shutdown feature could not be enabled: %d",
10047 status);
10048
10049 return qdf_status_to_os_return(status);
10050}
10051#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010052static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010053{
10054 return 0;
10055}
10056#endif
10057
10058/**
10059 * hdd_features_init() - Init features
10060 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053010061 *
10062 * Initialize features and their feature context after WLAN firmware is up.
10063 *
10064 * Return: 0 on success and errno on failure.
10065 */
Dustin Browne7e71d32018-05-11 16:00:08 -070010066static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010067{
10068 tSirTxPowerLimit hddtxlimit;
10069 QDF_STATUS status;
Manjeet Singha9cae432017-02-28 11:58:22 +053010070 struct sme_5g_band_pref_params band_pref_params;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010071 int ret;
10072
Dustin Brown491d54b2018-03-14 12:39:11 -070010073 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010074
Arun Khandavallid4349a92016-07-25 11:10:43 +053010075 /* FW capabilities received, Set the Dot11 mode */
10076 sme_setdef_dot11mode(hdd_ctx->hHal);
Kiran Kumar Lokere1aa9c9a2016-10-05 18:50:59 -070010077 sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal,
10078 hdd_ctx->config->sta_prefer_80MHz_over_160MHz);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010079
Arun Khandavallid4349a92016-07-25 11:10:43 +053010080
10081 if (hdd_ctx->config->fIsImpsEnabled)
10082 hdd_set_idle_ps_config(hdd_ctx, true);
10083 else
10084 hdd_set_idle_ps_config(hdd_ctx, false);
10085
Poddar, Siddarth37033032017-10-11 15:47:40 +053010086 /* Send Enable/Disable data stall detection cmd to FW */
10087 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
10088 hdd_ctx->config->enable_data_stall_det, PDEV_CMD);
10089
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053010090 if (hdd_ctx->config->enable_go_cts2self_for_sta)
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010091 sme_set_cts2self_for_p2p_go(hdd_ctx->hHal);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053010092
Nachiket Kukade8983cf62017-10-12 18:14:48 +053010093 if (sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap))
10094 hdd_warn("Error in setting Voltage Corner mode config to FW");
10095
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010096 if (hdd_rx_ol_init(hdd_ctx))
10097 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053010098
10099 if (hdd_adaptive_dwelltime_init(hdd_ctx))
10100 hdd_err("Unable to send adaptive dwelltime setting to FW");
10101
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010102 if (hdd_dbs_scan_selection_init(hdd_ctx))
10103 hdd_err("Unable to send DBS scan selection setting to FW");
10104
Arun Khandavallid4349a92016-07-25 11:10:43 +053010105 ret = hdd_init_thermal_info(hdd_ctx);
10106 if (ret) {
10107 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070010108 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010109 }
10110
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010111 /**
10112 * In case of SSR/PDR, if pktlog was enabled manually before
10113 * SSR/PDR, Then enabled it again automatically after Wlan
10114 * device up.
10115 */
10116 if (cds_is_driver_recovering()) {
10117 if (hdd_ctx->is_pktlog_enabled)
10118 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Tiger Yuf3d5d7f2018-03-15 14:48:11 +080010119 }
Poddar, Siddarth66a46592017-02-22 11:44:44 +053010120
Arun Khandavallid4349a92016-07-25 11:10:43 +053010121 hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
10122 hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
10123 status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
10124 if (!QDF_IS_STATUS_SUCCESS(status))
10125 hdd_err("Error setting txlimit in sme: %d", status);
10126
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010127 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010128
Arun Khandavallid4349a92016-07-25 11:10:43 +053010129 ret = hdd_register_cb(hdd_ctx);
10130 if (ret) {
10131 hdd_err("Failed to register HDD callbacks!");
Dustin Browne7e71d32018-05-11 16:00:08 -070010132 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010133 }
10134
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053010135 if (hdd_ctx->config->goptimize_chan_avoid_event) {
10136 status = sme_enable_disable_chanavoidind_event(
10137 hdd_ctx->hHal, 0);
10138 if (!QDF_IS_STATUS_SUCCESS(status)) {
10139 hdd_err("Failed to disable Chan Avoidance Indication");
10140 goto deregister_cb;
10141 }
10142 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053010143
Manjeet Singha9cae432017-02-28 11:58:22 +053010144 if (hdd_ctx->config->enable_5g_band_pref) {
10145 band_pref_params.rssi_boost_threshold_5g =
10146 hdd_ctx->config->rssi_boost_threshold_5g;
10147 band_pref_params.rssi_boost_factor_5g =
10148 hdd_ctx->config->rssi_boost_factor_5g;
10149 band_pref_params.max_rssi_boost_5g =
10150 hdd_ctx->config->max_rssi_boost_5g;
10151 band_pref_params.rssi_penalize_threshold_5g =
10152 hdd_ctx->config->rssi_penalize_threshold_5g;
10153 band_pref_params.rssi_penalize_factor_5g =
10154 hdd_ctx->config->rssi_penalize_factor_5g;
10155 band_pref_params.max_rssi_penalize_5g =
10156 hdd_ctx->config->max_rssi_penalize_5g;
10157 sme_set_5g_band_pref(hdd_ctx->hHal, &band_pref_params);
10158 }
10159
Arun Khandavallid4349a92016-07-25 11:10:43 +053010160 /* register P2P Listen Offload event callback */
10161 if (wma_is_p2p_lo_capable())
10162 sme_register_p2p_lo_event(hdd_ctx->hHal, hdd_ctx,
10163 wlan_hdd_p2p_lo_event_callback);
10164
10165 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
10166
10167 if (ret)
10168 goto deregister_cb;
10169
Dustin Brown11638b72018-01-25 17:37:25 +053010170 wlan_hdd_init_chan_info(hdd_ctx);
10171
Dustin Browne74003f2018-03-14 12:51:58 -070010172 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010173 return 0;
10174
10175deregister_cb:
10176 hdd_deregister_cb(hdd_ctx);
Dustin Browne7e71d32018-05-11 16:00:08 -070010177
Arun Khandavallid4349a92016-07-25 11:10:43 +053010178 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010179}
10180
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010181/**
10182 * hdd_features_deinit() - Deinit features
10183 * @hdd_ctx: HDD context
10184 *
10185 * De-Initialize features and their feature context.
10186 *
10187 * Return: none.
10188 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010189static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010190{
Dustin Brown11638b72018-01-25 17:37:25 +053010191 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010192 wlan_hdd_tsf_deinit(hdd_ctx);
10193}
10194
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010195/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010196 * hdd_register_bcn_cb() - register scan beacon callback
10197 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010198 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010199 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010200 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010201static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010202{
10203 QDF_STATUS status;
10204
10205 status = ucfg_scan_register_bcn_cb(hdd_ctx->hdd_psoc,
10206 wlan_cfg80211_inform_bss_frame,
10207 SCAN_CB_TYPE_INFORM_BCN);
10208 if (!QDF_IS_STATUS_SUCCESS(status)) {
10209 hdd_err("failed with status code %08d [x%08x]",
10210 status, status);
10211 return status;
10212 }
10213
10214 return QDF_STATUS_SUCCESS;
10215}
Arun Khandavallid4349a92016-07-25 11:10:43 +053010216
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010217/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070010218 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
10219 * @vdev_id: vdev_id, corresponds to flow_pool
10220 *
10221 * Return: none.
10222 */
10223static void hdd_v2_flow_pool_map(int vdev_id)
10224{
10225 QDF_STATUS status;
10226
10227 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
10228 cds_get_context(QDF_MODULE_ID_TXRX),
10229 vdev_id);
10230 /*
10231 * For Adrastea flow control v2 is based on FW MAP events,
10232 * so this above callback is not implemented.
10233 * Hence this is not actual failure. Dont return failure
10234 */
10235 if ((status != QDF_STATUS_SUCCESS) &&
10236 (status != QDF_STATUS_E_INVAL)) {
10237 hdd_err("vdev_id: %d, failed to create flow pool status %d",
10238 vdev_id, status);
10239 }
10240}
10241
10242/**
10243 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
10244 * @vdev_id: vdev_id, corresponds to flow_pool
10245 *
10246 * Return: none.
10247 */
10248static void hdd_v2_flow_pool_unmap(int vdev_id)
10249{
10250 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
10251 cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
10252}
10253
10254/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010255 * hdd_configure_cds() - Configure cds modules
10256 * @hdd_ctx: HDD context
10257 * @adapter: Primary adapter context
10258 *
10259 * Enable Cds modules after WLAN firmware is up.
10260 *
10261 * Return: 0 on success and errno on failure.
10262 */
Dustin Browne7e71d32018-05-11 16:00:08 -070010263int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053010264{
10265 int ret;
10266 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010267 int set_value;
10268 uint32_t num_abg_tx_chains = 0;
10269 uint32_t num_11b_tx_chains = 0;
10270 uint32_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010271 struct policy_mgr_dp_cbacks dp_cbs = {0};
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010272
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010273 if (hdd_ctx->config->is_force_1x1)
10274 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
10275 1, PDEV_CMD);
10276 /* set chip power save failure detected callback */
10277 sme_set_chip_pwr_save_fail_cb(hdd_ctx->hHal,
10278 hdd_chip_pwr_save_fail_detected_cb);
10279
10280 if (hdd_ctx->config->max_mpdus_inampdu) {
10281 set_value = hdd_ctx->config->max_mpdus_inampdu;
10282 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
10283 set_value, PDEV_CMD);
10284 }
10285
10286 if (hdd_ctx->config->enable_rts_sifsbursting) {
10287 set_value = hdd_ctx->config->enable_rts_sifsbursting;
10288 sme_cli_set_command(0,
10289 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
10290 set_value, PDEV_CMD);
10291 }
10292
10293 if (hdd_ctx->config->sap_get_peer_info) {
10294 set_value = hdd_ctx->config->sap_get_peer_info;
10295 sme_cli_set_command(0,
10296 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
10297 set_value, PDEV_CMD);
10298 }
10299
10300 num_11b_tx_chains = hdd_ctx->config->num_11b_tx_chains;
10301 num_11ag_tx_chains = hdd_ctx->config->num_11ag_tx_chains;
10302 if (!hdd_ctx->config->enable2x2) {
10303 if (num_11b_tx_chains > 1)
10304 num_11b_tx_chains = 1;
10305 if (num_11ag_tx_chains > 1)
10306 num_11ag_tx_chains = 1;
10307 }
10308 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
10309 num_11b_tx_chains);
10310 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
10311 num_11ag_tx_chains);
10312 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
10313 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053010314
10315 ret = hdd_pre_enable_configure(hdd_ctx);
10316 if (ret) {
10317 hdd_err("Failed to pre-configure cds");
10318 goto out;
10319 }
10320
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080010321 /* Always get latest IPA resources allocated from cds_open and configure
10322 * IPA module before configuring them to FW. Sequence required as crash
10323 * observed otherwise.
10324 */
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +053010325 if (ucfg_ipa_uc_ol_init(hdd_ctx->hdd_pdev,
10326 cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080010327 hdd_err("Failed to setup pipes");
10328 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080010329 }
10330
Arun Khandavallifae92942016-08-01 13:31:08 +053010331 /*
10332 * Start CDS which starts up the SME/MAC/HAL modules and everything
10333 * else
10334 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -070010335 status = cds_enable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010336
10337 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010338 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053010339 goto out;
10340 }
10341
10342 status = hdd_post_cds_enable_config(hdd_ctx);
10343 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010344 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010345 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053010346 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010347 status = hdd_register_bcn_cb(hdd_ctx);
10348 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080010349 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010350 goto cds_disable;
10351 }
Arun Khandavallifae92942016-08-01 13:31:08 +053010352
Dustin Browne7e71d32018-05-11 16:00:08 -070010353 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053010354 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010355 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053010356
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010357 if (hdd_ctx->ol_enable)
10358 dp_cbs.hdd_disable_rx_ol_in_concurrency =
10359 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070010360 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080010361 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070010362 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
10363 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010364 status = policy_mgr_register_dp_cb(hdd_ctx->hdd_psoc, &dp_cbs);
10365 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070010366 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010367 goto cds_disable;
10368 }
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053010369 status = policy_mgr_register_mode_change_cb(hdd_ctx->hdd_psoc,
10370 wlan_hdd_send_mode_change_event);
10371 if (!QDF_IS_STATUS_SUCCESS(status)) {
10372 hdd_debug("Failed to register mode change cb with Policy Manager");
10373 goto cds_disable;
10374 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010375
Jeff Johnson8bb61112018-03-31 13:33:54 -070010376 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053010377 hdd_debug("enhance green ap is not enabled");
10378
Nachiket Kukadedd302662017-07-13 17:31:44 +053010379 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
10380 hdd_debug("Failed to set wow pulse");
10381
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053010382 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
10383 hdd_ctx->config->gcmp_enabled, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053010384 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
10385 hdd_ctx->config->auto_pwr_save_fail_mode, PDEV_CMD);
10386
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053010387
10388 if (hdd_ctx->config->enable_phy_reg_retention)
10389 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
10390 hdd_ctx->config->enable_phy_reg_retention, PDEV_CMD);
10391
Arun Khandavallifae92942016-08-01 13:31:08 +053010392 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010393
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010394cds_disable:
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -070010395 cds_disable(hdd_ctx->hdd_psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010396
Arun Khandavallifae92942016-08-01 13:31:08 +053010397out:
10398 return -EINVAL;
10399}
10400
10401/**
10402 * hdd_deconfigure_cds() -De-Configure cds
10403 * @hdd_ctx: HDD context
10404 *
10405 * Deconfigure Cds modules before WLAN firmware is down.
10406 *
10407 * Return: 0 on success and errno on failure.
10408 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010409static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053010410{
10411 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070010412 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053010413
Dustin Brown491d54b2018-03-14 12:39:11 -070010414 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010415
10416 /* De-init features */
10417 hdd_features_deinit(hdd_ctx);
10418
Arun Khandavallifae92942016-08-01 13:31:08 +053010419 /* De-register the SME callbacks */
10420 hdd_deregister_cb(hdd_ctx);
10421
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053010422 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->hdd_psoc);
10423 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10424 hdd_debug("Failed to deregister mode change cb with Policy Manager");
10425 }
10426
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -070010427 qdf_status = cds_disable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010428 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10429 hdd_err("Failed to Disable the CDS Modules! :%d",
10430 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070010431 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010432 }
10433
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +053010434 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->hdd_pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053010435 hdd_err("Failed to disconnect pipes");
10436 ret = -EINVAL;
10437 }
10438
Dustin Browne74003f2018-03-14 12:51:58 -070010439 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070010440 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053010441}
10442
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070010443#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
10444static void hdd_deregister_policy_manager_callback(
10445 struct wlan_objmgr_psoc *psoc)
10446{
10447 if (QDF_STATUS_SUCCESS !=
10448 policy_mgr_deregister_hdd_cb(psoc)) {
10449 hdd_err("HDD callback deregister with policy manager failed");
10450 }
10451}
10452#else
10453static void hdd_deregister_policy_manager_callback(
10454 struct wlan_objmgr_psoc *psoc)
10455{
10456}
10457#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053010458
10459/**
10460 * hdd_wlan_stop_modules - Single driver state machine for stoping modules
10461 * @hdd_ctx: HDD context
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010462 * @ftm_mode: ftm mode
Arun Khandavallifae92942016-08-01 13:31:08 +053010463 *
10464 * This function maintains the driver state machine it will be invoked from
10465 * exit, shutdown and con_mode change handler. Depending on the driver state
10466 * shall perform the stopping/closing of the modules.
10467 *
10468 * Return: 0 for success; non-zero for failure
10469 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010470int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053010471{
10472 void *hif_ctx;
10473 qdf_device_t qdf_ctx;
10474 QDF_STATUS qdf_status;
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010475 int ret = 0;
Dustin Brown4bc0a622017-12-06 15:56:50 -080010476 bool is_recovery_stop = cds_is_driver_recovering();
Liangwei Donga78cc1d2018-02-01 02:19:30 -050010477 bool is_idle_stop = !cds_is_driver_unloading() && !is_recovery_stop &&
10478 !cds_is_driver_loading();
Dustin Brown70111822017-03-30 15:31:40 -070010479 int active_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053010480 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053010481
Dustin Brown491d54b2018-03-14 12:39:11 -070010482 hdd_enter();
Yun Parkfec73dc2017-09-06 10:40:07 -070010483 hdd_alert("stop WLAN module: entering driver status=%d",
10484 hdd_ctx->driver_status);
Arun Khandavallifae92942016-08-01 13:31:08 +053010485
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070010486 hdd_deregister_policy_manager_callback(hdd_ctx->hdd_psoc);
10487
Arun Khandavallifae92942016-08-01 13:31:08 +053010488 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
10489 if (!qdf_ctx) {
10490 hdd_err("QDF device context NULL");
10491 return -EINVAL;
10492 }
10493
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010494 mutex_lock(&hdd_ctx->iface_change_lock);
10495 hdd_ctx->stop_modules_in_progress = true;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010496 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053010497
Dustin Brown70111822017-03-30 15:31:40 -070010498 active_threads = cds_return_external_threads_count();
Jeff Johnson214671b2017-10-30 19:45:23 -070010499 if (active_threads > 0 || hdd_ctx->is_wiphy_suspended) {
Rajeev Kumar86177c22017-03-16 19:44:39 -070010500 hdd_warn("External threads %d wiphy suspend %d",
Jeff Johnson214671b2017-10-30 19:45:23 -070010501 active_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -070010502
10503 cds_print_external_threads();
10504
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010505 if (is_idle_stop && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -070010506 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown6f427922017-09-19 12:19:00 -070010507 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
10508 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +053010509 hdd_prevent_suspend_timeout(
10510 hdd_ctx->config->iface_change_wait_time,
10511 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010512 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010513 cds_set_module_stop_in_progress(false);
Dustin Brown70111822017-03-30 15:31:40 -070010514 return 0;
10515 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070010516 }
10517
Arun Khandavallifae92942016-08-01 13:31:08 +053010518 hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
10519
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080010520 /* free user wowl patterns */
10521 hdd_free_user_wowl_ptrns();
10522
Arun Khandavallifae92942016-08-01 13:31:08 +053010523 switch (hdd_ctx->driver_status) {
10524 case DRIVER_MODULES_UNINITIALIZED:
10525 hdd_info("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010526 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010527 case DRIVER_MODULES_CLOSED:
10528 hdd_info("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010529 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010530 case DRIVER_MODULES_ENABLED:
Dustin Brown550f6d22017-12-14 15:44:01 -080010531 hdd_info("Wlan transitioning (OPENED <- ENABLED)");
10532
Komal Seelamf2136bb2016-09-28 18:30:44 +053010533 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053010534 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010535 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053010536 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010537 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010538 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010539 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080010540
Arun Khandavallifae92942016-08-01 13:31:08 +053010541 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -080010542 hdd_info("Wlan transitioned (now OPENED)");
10543
10544 /* fall through */
Arun Khandavallifae92942016-08-01 13:31:08 +053010545 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -080010546 hdd_info("Wlan transitioning (CLOSED <- OPENED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053010547 break;
10548 default:
10549 hdd_err("Trying to stop wlan in a wrong state: %d",
10550 hdd_ctx->driver_status);
10551 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010552 ret = -EINVAL;
10553 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010554 }
10555
Amar Singhal18081642018-01-26 16:04:13 -080010556 hdd_sysfs_destroy_version_interface();
Dustin Brown550f6d22017-12-14 15:44:01 -080010557 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080010558
Rajeev Kumarbe021242017-02-16 16:12:23 -080010559 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +053010560 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10561 hdd_err("Failed to process post CDS disable Modules! :%d",
10562 qdf_status);
10563 ret = -EINVAL;
10564 QDF_ASSERT(0);
10565 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010566
psimhadeea0a12017-12-18 14:50:02 -080010567 hdd_runtime_suspend_context_deinit(hdd_ctx);
10568
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010569 qdf_status = cds_dp_close(hdd_ctx->hdd_psoc);
10570 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10571 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
10572 ret = -EINVAL;
10573 QDF_ASSERT(0);
10574 }
10575
Jeff Johnsone4b14592017-09-13 14:23:33 -070010576 qdf_status = cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010577 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010578 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +053010579 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010580 QDF_ASSERT(0);
10581 }
Krunal Sonid32c6bc2016-10-18 18:00:21 -070010582
Amar Singhal410675c2018-01-10 12:14:21 -080010583 dispatcher_pdev_close(hdd_ctx->hdd_pdev);
Liangwei Dong50a64a72018-01-11 01:17:00 -050010584 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
10585 if (ret) {
10586 hdd_err("Failed to destroy pdev; errno:%d", ret);
10587 QDF_ASSERT(0);
10588 }
10589
10590 /*
10591 * Reset total mac phy during module stop such that during
10592 * next module start same psoc is used to populate new service
10593 * ready data
10594 */
Arunk Khandavallia6305a32018-01-25 11:19:18 +053010595 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->hdd_psoc);
10596 if (tgt_hdl)
10597 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
10598
Liangwei Dong50a64a72018-01-11 01:17:00 -050010599
Arun Khandavallifae92942016-08-01 13:31:08 +053010600 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
10601 if (!hif_ctx) {
10602 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010603 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010604 }
10605
Arunk Khandavalli4b404332017-09-26 12:46:00 +053010606 if (hdd_ctx->target_hw_name) {
10607 qdf_mem_free(hdd_ctx->target_hw_name);
10608 hdd_ctx->target_hw_name = NULL;
10609 }
10610
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053010611 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053010612
10613 ol_cds_free();
10614
Dustin Brown70111822017-03-30 15:31:40 -070010615 if (is_idle_stop) {
Arun Khandavallifae92942016-08-01 13:31:08 +053010616 ret = pld_power_off(qdf_ctx->dev);
10617 if (ret)
10618 hdd_err("CNSS power down failed put device into Low power mode:%d",
10619 ret);
10620 }
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010621
Dustin Brown4bc0a622017-12-06 15:56:50 -080010622 /* many adapter resources are not freed by design in SSR case */
10623 if (!is_recovery_stop)
10624 hdd_check_for_leaks();
Dustin Brown26b3d042017-12-21 11:13:27 -080010625 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080010626
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010627 /* Once the firmware sequence is completed reset this flag */
10628 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053010629 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080010630 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053010631
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010632done:
10633 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010634 cds_set_module_stop_in_progress(false);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010635 mutex_unlock(&hdd_ctx->iface_change_lock);
Yun Parkfec73dc2017-09-06 10:40:07 -070010636 hdd_alert("stop WLAN module: exit driver status=%d",
10637 hdd_ctx->driver_status);
Dustin Brown4bc0a622017-12-06 15:56:50 -080010638
Dustin Browne74003f2018-03-14 12:51:58 -070010639 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053010640
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010641 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053010642}
10643
Arun Khandavallifae92942016-08-01 13:31:08 +053010644
Wen Gong3f003382018-05-14 14:26:37 +080010645#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053010646/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010647 * hdd_state_info_dump() - prints state information of hdd layer
10648 * @buf: buffer pointer
10649 * @size: size of buffer to be filled
10650 *
10651 * This function is used to dump state information of hdd layer
10652 *
10653 * Return: None
10654 */
10655static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
10656{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010657 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070010658 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070010659 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010660 uint16_t len = 0;
10661 char *buf = *buf_ptr;
10662
10663 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10664 if (!hdd_ctx) {
10665 hdd_err("Failed to get hdd context ");
10666 return;
10667 }
10668
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010669 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010670
10671 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070010672 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010673 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080010674 "\n is_scheduler_suspended %d",
10675 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010676
Dustin Brown920397d2017-12-13 16:27:50 -080010677 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010678 if (adapter->dev)
10679 len += scnprintf(buf + len, *size - len,
10680 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080010681 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010682 "\n device_mode: %d", adapter->device_mode);
10683 switch (adapter->device_mode) {
10684 case QDF_STA_MODE:
10685 case QDF_P2P_CLIENT_MODE:
10686 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
10687 len += scnprintf(buf + len, *size - len,
10688 "\n connState: %d",
10689 hdd_sta_ctx->conn_info.connState);
10690 break;
10691
10692 default:
10693 break;
10694 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010695 }
10696
10697 *size -= len;
10698 *buf_ptr += len;
10699}
10700
10701/**
10702 * hdd_register_debug_callback() - registration function for hdd layer
10703 * to print hdd state information
10704 *
10705 * Return: None
10706 */
10707static void hdd_register_debug_callback(void)
10708{
10709 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
10710}
Wen Gong3f003382018-05-14 14:26:37 +080010711#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080010712static void hdd_register_debug_callback(void)
10713{
10714}
Wen Gong3f003382018-05-14 14:26:37 +080010715#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010716
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053010717/*
10718 * wlan_init_bug_report_lock() - Initialize bug report lock
10719 *
10720 * This function is used to create bug report lock
10721 *
10722 * Return: None
10723 */
10724static void wlan_init_bug_report_lock(void)
10725{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070010726 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053010727
10728 p_cds_context = cds_get_global_context();
10729 if (!p_cds_context) {
10730 hdd_err("cds context is NULL");
10731 return;
10732 }
10733
10734 qdf_spinlock_create(&p_cds_context->bug_report_lock);
10735}
10736
Nirav Shahd21a2e32018-04-20 16:34:43 +053010737#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070010738void hdd_dp_trace_init(struct hdd_config *config)
10739{
10740
10741 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
10742 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
10743 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
10744 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
10745 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
10746 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
10747 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080010748 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070010749
Nirav Shahd21a2e32018-04-20 16:34:43 +053010750 if (!config->enable_dp_trace) {
10751 hdd_err("dp trace is disabled from ini");
10752 return;
10753 }
10754
Mohit Khannaf8f96822017-05-17 17:11:59 -070010755 hdd_string_to_u8_array(config->dp_trace_config, config_params,
10756 &num_entries, sizeof(config_params));
10757
10758 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080010759 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010760 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080010761 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010762 else if (bw_compute_interval > 1000) {
10763 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
10764 thresh_time_limit = 1;
10765 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070010766 hdd_err("busBandwidthComputeInterval is 0, using defaults");
10767
10768 switch (num_entries) {
10769 case 4:
10770 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053010771 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070010772 case 3:
10773 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053010774 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070010775 case 2:
10776 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053010777 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070010778 case 1:
10779 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053010780 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070010781 default:
Rajeev Kumar3887f9b2018-01-10 11:24:01 -080010782 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
Mohit Khannaf8f96822017-05-17 17:11:59 -070010783 live_mode, thresh, thresh_time_limit,
10784 verbosity, proto_bitmap);
10785 };
10786
10787 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
10788 verbosity, proto_bitmap);
10789
10790}
Nirav Shahd21a2e32018-04-20 16:34:43 +053010791#endif
10792
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010793/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010794 * hdd_wlan_startup() - HDD init function
10795 * @dev: Pointer to the underlying device
10796 *
10797 * This is the driver startup code executed once a WLAN device has been detected
10798 *
10799 * Return: 0 for success, < 0 for failure
10800 */
Arun Khandavallifae92942016-08-01 13:31:08 +053010801int hdd_wlan_startup(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010802{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010803 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010804 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010805 int ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010806 bool rtnl_held;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010807
Dustin Brown491d54b2018-03-14 12:39:11 -070010808 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010809
Arun Khandavallifae92942016-08-01 13:31:08 +053010810 hdd_ctx = hdd_context_create(dev);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010811
10812 if (IS_ERR(hdd_ctx))
10813 return PTR_ERR(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010814
Abhishek Singhe9068f12017-03-31 14:14:52 +053010815 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx,
10816 DEFAULT_PSOC_ID);
10817 if (ret) {
10818 hdd_err("Psoc creation fails!");
10819 QDF_BUG(0);
10820 goto err_hdd_free_context;
10821 }
10822
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010823 qdf_nbuf_init_replenish_timer();
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053010824#ifdef FEATURE_WLAN_CH_AVOID
10825 mutex_init(&hdd_ctx->avoid_freq_lock);
10826#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053010827
Naveen Rawate02f8f52018-04-05 11:58:04 -070010828 osif_request_manager_init();
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010829 hdd_request_manager_init();
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053010830 qdf_atomic_init(&hdd_ctx->con_mode_flag);
Arun Khandavallifae92942016-08-01 13:31:08 +053010831
Dustin Brown021cecd2017-12-11 13:56:43 -080010832 hdd_driver_memdump_init();
10833
Dustin Browne7e71d32018-05-11 16:00:08 -070010834 ret = hdd_wlan_start_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010835 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010836 hdd_err("Failed to start modules: %d", ret);
Dustin Brown021cecd2017-12-11 13:56:43 -080010837 goto err_memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010838 }
10839
Yingying Tang80e15f32016-09-27 18:23:01 +080010840 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010841
Anurag Chouhan6d760662016-02-20 16:05:43 +053010842 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010843
10844 if (NULL == hdd_ctx->hHal) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010845 hdd_err("HAL context is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053010846 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010847 }
10848
Prashanth Bhatta07998752016-04-28 12:35:33 -070010849 ret = hdd_wiphy_init(hdd_ctx);
10850 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010851 hdd_err("Failed to initialize wiphy: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053010852 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010853 }
10854
Nirav Shahd21a2e32018-04-20 16:34:43 +053010855 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053010856
Yuanyuan Liuc98370e2016-10-13 11:22:13 -070010857 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080010858
Paul Zhangfb02f452017-12-22 11:58:43 +080010859 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10860 if (ret) {
10861 hdd_err("register_netdevice_notifier failed: %d", ret);
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +053010862 goto err_wiphy_unregister;
Paul Zhangfb02f452017-12-22 11:58:43 +080010863 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010864
Arunk Khandavalli830c9692018-03-22 12:17:40 +053010865 ret = register_reboot_notifier(&system_reboot_notifier);
10866 if (ret) {
10867 hdd_err("Failed to register reboot notifier: %d", ret);
10868 goto err_unregister_netdev;
10869 }
10870
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010871 rtnl_held = hdd_hold_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010872
Jeff Johnson957bc272017-02-02 08:54:48 -080010873 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
10874 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010875 hdd_err("Failed to open interfaces: %d", ret);
Jeff Johnson46bde382017-02-01 15:31:16 -080010876 goto err_release_rtnl_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010877 }
10878
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010879 hdd_release_rtnl_lock();
10880 rtnl_held = false;
10881
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080010882 wlan_hdd_update_11n_mode(hdd_ctx->config);
10883
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010884#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +053010885 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +053010886 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010887 hdd_skip_acs_scan_timer_handler,
10888 (void *)hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010889 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -070010890 hdd_err("Failed to init ACS Skip timer");
Liangwei Dongaef84342016-10-21 05:28:00 -040010891 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010892#endif
10893
Prashanth Bhattaab004382016-10-11 16:08:11 -070010894 hdd_bus_bandwidth_init(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010895
Jeff Johnson9afc5012016-09-23 13:56:27 -070010896 hdd_lpass_notify_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010897
Nirav Shahbd36b062016-07-18 11:12:59 +053010898 if (hdd_ctx->rps)
10899 hdd_set_rps_cpu_mask(hdd_ctx);
Peng Xu8fdaa492016-06-22 10:20:47 -070010900
Paul Zhangfb02f452017-12-22 11:58:43 +080010901 ret = hdd_register_notifiers(hdd_ctx);
10902 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -080010903 goto err_close_adapters;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070010904
Paul Zhangfb02f452017-12-22 11:58:43 +080010905 status = wlansap_global_init();
10906 if (QDF_IS_STATUS_ERROR(status)) {
10907 hdd_unregister_notifiers(hdd_ctx);
10908 goto err_close_adapters;
10909 }
10910
Arun Khandavallifae92942016-08-01 13:31:08 +053010911 if (hdd_ctx->config->fIsImpsEnabled)
10912 hdd_set_idle_ps_config(hdd_ctx, true);
Kiran Kumar Lokereb0f19c32017-10-13 12:23:26 -070010913 else
10914 hdd_set_idle_ps_config(hdd_ctx, false);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010915
Mukul Sharma07bd8752017-10-10 16:58:14 +053010916 if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
Dustin Brown6f427922017-09-19 12:19:00 -070010917 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
10918 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +053010919 hdd_prevent_suspend_timeout(
10920 hdd_ctx->config->iface_change_wait_time,
10921 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
10922 }
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053010923
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010924 goto success;
10925
Jeff Johnson957bc272017-02-02 08:54:48 -080010926err_close_adapters:
Jeff Johnson46bde382017-02-01 15:31:16 -080010927 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010928
Jeff Johnson46bde382017-02-01 15:31:16 -080010929err_release_rtnl_lock:
Arunk Khandavalli830c9692018-03-22 12:17:40 +053010930 unregister_reboot_notifier(&system_reboot_notifier);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010931 if (rtnl_held)
10932 hdd_release_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010933
Arunk Khandavalli830c9692018-03-22 12:17:40 +053010934err_unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010935 unregister_netdevice_notifier(&hdd_netdev_notifier);
10936
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010937err_wiphy_unregister:
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010938 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010939
Arun Khandavallifae92942016-08-01 13:31:08 +053010940err_stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010941 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010942
Dustin Brown021cecd2017-12-11 13:56:43 -080010943err_memdump_deinit:
10944 hdd_driver_memdump_deinit();
Dustin Brown021cecd2017-12-11 13:56:43 -080010945
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010946 hdd_request_manager_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070010947 osif_request_manager_deinit();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070010948 hdd_exit_netlink_services(hdd_ctx);
10949
Dustin Brown20912462017-06-07 13:48:25 -070010950 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10951
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010952err_hdd_free_context:
Nachiket Kukade8003d252017-03-30 15:55:58 +053010953 if (cds_is_fw_down())
10954 hdd_err("Not setting the complete event as fw is down");
10955 else
10956 hdd_start_complete(ret);
10957
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010958 qdf_nbuf_deinit_replenish_timer();
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010959 hdd_context_destroy(hdd_ctx);
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -070010960 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010961
10962success:
Dustin Browne74003f2018-03-14 12:51:58 -070010963 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010964 return 0;
10965}
10966
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010967/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010968 * hdd_wlan_update_target_info() - update target type info
10969 * @hdd_ctx: HDD context
10970 * @context: hif context
10971 *
10972 * Update target info received from firmware in hdd context
10973 * Return:None
10974 */
10975
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010976void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053010977{
10978 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
10979
10980 if (!tgt_info) {
10981 hdd_err("Target info is Null");
10982 return;
10983 }
10984
10985 hdd_ctx->target_type = tgt_info->target_type;
10986}
10987
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053010988void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010989{
10990 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010991 int status;
10992 struct hdd_adapter *adapter = NULL;
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053010993 struct hdd_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010994
Dustin Brown491d54b2018-03-14 12:39:11 -070010995 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010996
10997 if (!rsp) {
10998 hdd_err("data is null");
10999 return;
11000 }
11001
11002 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011003 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011004 return;
11005
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011006 request = hdd_request_get(context);
11007 if (!request) {
11008 hdd_err("obselete request");
11009 return;
11010 }
11011
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011012 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
11013 if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
11014 hdd_err("Invalid adapter or adapter has invalid magic");
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011015 hdd_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011016 return;
11017 }
11018
Dustin Brown5e89ef82018-03-14 11:50:23 -070011019 hdd_info("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
11020 hdd_info("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
11021 hdd_info("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
11022 hdd_info("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
11023 hdd_info("rsp->out_of_order_arp_rsp_drop_cnt :%x",
11024 rsp->out_of_order_arp_rsp_drop_cnt);
11025 hdd_info("rsp->dad_detected :%x", rsp->dad_detected);
11026 hdd_info("rsp->connect_status :%x", rsp->connect_status);
11027 hdd_info("rsp->ba_session_establishment_status :%x",
11028 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011029
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011030 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011031 adapter->dad |= rsp->dad_detected;
11032 adapter->con_status = rsp->connect_status;
11033
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011034 /* Flag true indicates connectivity check stats present. */
11035 if (rsp->connect_stats_present) {
11036 hdd_info("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
11037 hdd_info("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
11038 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
11039 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
11040 rsp->icmpv4_rsp_recvd;
11041 }
11042
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011043 hdd_request_complete(request);
11044 hdd_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011045
Dustin Browne74003f2018-03-14 12:51:58 -070011046 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011047}
11048
11049/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011050 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011051 * @hdd_ctx: HDD context
11052 *
11053 * Register the HDD callbacks to CDS/SME.
11054 *
11055 * Return: 0 for success or Error code for failure
11056 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011057int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011058{
11059 QDF_STATUS status;
11060 int ret = 0;
11061
Dustin Brown491d54b2018-03-14 12:39:11 -070011062 hdd_enter();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011063
11064 sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);
11065
11066 sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
11067 hdd_send_oem_data_rsp_msg);
11068
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053011069 sme_register_mgmt_frame_ind_callback(hdd_ctx->hHal,
11070 hdd_indicate_mgmt_frame);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011071 sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
11072 sme_nan_register_callback(hdd_ctx->hHal,
11073 wlan_hdd_cfg80211_nan_callback);
11074 sme_stats_ext_register_callback(hdd_ctx->hHal,
11075 wlan_hdd_cfg80211_stats_ext_callback);
11076
11077 sme_ext_scan_register_callback(hdd_ctx->hHal,
11078 wlan_hdd_cfg80211_extscan_callback);
lifeng66831662017-05-19 16:01:35 +080011079 sme_stats_ext2_register_callback(hdd_ctx->hHal,
11080 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011081
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011082 sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
11083 hdd_rssi_threshold_breached);
11084
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011085 sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
11086 wlan_hdd_cfg80211_link_layer_stats_callback);
11087
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053011088 sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb);
11089
Zhang Qianca38fb12016-12-23 11:10:48 +080011090 sme_set_link_layer_ext_cb(hdd_ctx->hHal,
11091 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
11092
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053011093 status = sme_set_lost_link_info_cb(hdd_ctx->hHal,
11094 hdd_lost_link_info_cb);
11095 /* print error and not block the startup process */
11096 if (!QDF_IS_STATUS_SUCCESS(status))
11097 hdd_err("set lost link info callback failed");
11098
Poddar, Siddarth34872782017-08-10 14:08:51 +053011099 ret = hdd_register_data_stall_detect_cb();
11100 if (ret) {
11101 hdd_err("Register data stall detect detect callback failed.");
11102 return ret;
11103 }
11104
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011105 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
11106
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011107 sme_register_set_connection_info_cb(hdd_ctx->hHal,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011108 hdd_set_connection_in_progress,
11109 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053011110
11111 status = sme_congestion_register_callback(hdd_ctx->hHal,
11112 hdd_update_cca_info_cb);
11113 if (!QDF_IS_STATUS_SUCCESS(status))
11114 hdd_err("set congestion callback failed");
11115
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053011116 status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
11117 hdd_bt_activity_cb);
11118 if (!QDF_IS_STATUS_SUCCESS(status))
11119 hdd_err("set bt activity info callback failed");
11120
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080011121 status = sme_register_tx_queue_cb(hdd_ctx->hHal,
11122 hdd_tx_queue_cb);
11123 if (!QDF_IS_STATUS_SUCCESS(status))
11124 hdd_err("Register tx queue callback failed");
11125
Dustin Browne74003f2018-03-14 12:51:58 -070011126 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011127
11128 return ret;
11129}
11130
11131/**
11132 * hdd_deregister_cb() - De-Register HDD callbacks.
11133 * @hdd_ctx: HDD context
11134 *
11135 * De-Register the HDD callbacks to CDS/SME.
11136 *
11137 * Return: void
11138 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011139void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011140{
11141 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053011142 int ret;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011143
Dustin Brown491d54b2018-03-14 12:39:11 -070011144 hdd_enter();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011145
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080011146 sme_deregister_tx_queue_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011147 status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
11148 if (!QDF_IS_STATUS_SUCCESS(status))
11149 hdd_err("De-register of dcc stats callback failed: %d",
11150 status);
11151
11152 sme_reset_link_layer_stats_ind_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011153 sme_reset_rssi_threshold_breached_cb(hdd_ctx->hHal);
11154
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011155 sme_stats_ext_register_callback(hdd_ctx->hHal,
11156 wlan_hdd_cfg80211_stats_ext_callback);
11157
11158 sme_nan_deregister_callback(hdd_ctx->hHal);
11159 status = sme_reset_tsfcb(hdd_ctx->hHal);
11160 if (!QDF_IS_STATUS_SUCCESS(status))
11161 hdd_err("Failed to de-register tsfcb the callback:%d",
11162 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011163
Poddar, Siddarth34872782017-08-10 14:08:51 +053011164 ret = hdd_deregister_data_stall_detect_cb();
11165 if (ret)
11166 hdd_err("Failed to de-register data stall detect event callback");
11167
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011168 sme_deregister_oem_data_rsp_callback(hdd_ctx->hHal);
11169 sme_deregister11d_scan_done_callback(hdd_ctx->hHal);
11170
Dustin Browne74003f2018-03-14 12:51:58 -070011171 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011172}
11173
11174/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011175 * hdd_softap_sta_deauth() - handle deauth req from HDD
11176 * @adapter: Pointer to the HDD
11177 * @enable: bool value
11178 *
11179 * This to take counter measure to handle deauth req from HDD
11180 *
11181 * Return: None
11182 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011183QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080011184 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011185{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011186 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011187
Dustin Brown491d54b2018-03-14 12:39:11 -070011188 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011189
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011190 /* Ignore request to deauth bcmc station */
11191 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011192 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011193
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011194 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011195 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
11196 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011197
Dustin Browne74003f2018-03-14 12:51:58 -070011198 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011199 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011200}
11201
11202/**
11203 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
11204 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053011205 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011206 *
11207 * This to take counter measure to handle deauth req from HDD
11208 *
11209 * Return: None
11210 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011211void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080011212 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011213{
Dustin Brown491d54b2018-03-14 12:39:11 -070011214 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011215
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011216 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053011217 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011218 return;
11219
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011220 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053011221 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011222}
11223
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011224/**
11225 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
11226 * @hdd_ctx: HDD Context
11227 *
11228 * API to find if there is any STA or P2P-Client is connected
11229 *
11230 * Return: true if connected; false otherwise
11231 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011232QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011233{
11234 return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
11235}
11236
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011237/**
11238 * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
11239 * @adapter: HDD adapter pointer
11240 *
11241 * This function loop through each adapter and disable roaming on each STA
11242 * device mode except the input adapter.
11243 *
11244 * Note: On the input adapter roaming is not enabled yet hence no need to
11245 * disable.
11246 *
11247 * Return: None
11248 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011249void wlan_hdd_disable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011250{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011251 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011252 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011253
11254 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011255 hdd_ctx->config->isRoamOffloadScanEnabled &&
11256 QDF_STA_MODE == adapter->device_mode &&
11257 policy_mgr_is_sta_active_connection_exists(
11258 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011259 hdd_debug("Connect received on STA session Id(%d)",
11260 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011261 /*
11262 * Loop through adapter and disable roaming for each STA device
11263 * mode except the input adapter.
11264 */
Dustin Brown920397d2017-12-13 16:27:50 -080011265 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011266 if (QDF_STA_MODE == adapterIdx->device_mode &&
11267 adapter->session_id != adapterIdx->session_id) {
11268 hdd_debug("Disable Roaming on session Id(%d)",
11269 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011270 sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
11271 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070011272 adapterIdx->session_id, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011273 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011274 }
11275 }
11276}
11277
11278/**
11279 * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
11280 * @adapter: HDD adapter pointer
11281 *
11282 * This function loop through each adapter and enable roaming on each STA
11283 * device mode except the input adapter.
11284 * Note: On the input adapter no need to enable roaming because link got
11285 * disconnected on this.
11286 *
11287 * Return: None
11288 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011289void wlan_hdd_enable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011290{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011291 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011292 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011293
11294 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011295 hdd_ctx->config->isRoamOffloadScanEnabled &&
11296 QDF_STA_MODE == adapter->device_mode &&
11297 policy_mgr_is_sta_active_connection_exists(
11298 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011299 hdd_debug("Disconnect received on STA session Id(%d)",
11300 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011301 /*
11302 * Loop through adapter and enable roaming for each STA device
11303 * mode except the input adapter.
11304 */
Dustin Brown920397d2017-12-13 16:27:50 -080011305 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011306 if (QDF_STA_MODE == adapterIdx->device_mode &&
11307 adapter->session_id != adapterIdx->session_id) {
11308 hdd_debug("Enabling Roaming on session Id(%d)",
11309 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011310 sme_start_roaming(WLAN_HDD_GET_HAL_CTX
11311 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070011312 adapterIdx->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011313 REASON_CONNECT);
11314 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011315 }
11316 }
11317}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011318
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053011319/**
11320 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
11321 * @skb: sk buffer pointer
11322 *
11323 * Sends the bcast message to SVC multicast group with generic nl socket
11324 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
11325 *
11326 * Return: None
11327 */
11328static void nl_srv_bcast_svc(struct sk_buff *skb)
11329{
11330#ifdef CNSS_GENL
11331 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
11332#else
11333 nl_srv_bcast(skb);
11334#endif
11335}
11336
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011337void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011338{
11339 struct sk_buff *skb;
11340 struct nlmsghdr *nlh;
11341 tAniMsgHdr *ani_hdr;
11342 void *nl_data = NULL;
11343 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011344 struct radio_index_tlv *radio_info;
11345 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011346
11347 if (in_interrupt() || irqs_disabled() || in_atomic())
11348 flags = GFP_ATOMIC;
11349
11350 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
11351
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011352 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011353 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011354
11355 nlh = (struct nlmsghdr *)skb->data;
11356 nlh->nlmsg_pid = 0; /* from kernel */
11357 nlh->nlmsg_flags = 0;
11358 nlh->nlmsg_seq = 0;
11359 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
11360
11361 ani_hdr = NLMSG_DATA(nlh);
11362 ani_hdr->type = type;
11363
11364 switch (type) {
11365 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053011366 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011367 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011368 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070011369 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011370 ani_hdr->length = 0;
11371 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011372 break;
11373 case WLAN_SVC_WLAN_STATUS_IND:
11374 case WLAN_SVC_WLAN_VERSION_IND:
11375 case WLAN_SVC_DFS_CAC_START_IND:
11376 case WLAN_SVC_DFS_CAC_END_IND:
11377 case WLAN_SVC_DFS_RADAR_DETECT_IND:
11378 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
11379 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080011380 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053011381 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080011382 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011383 ani_hdr->length = len;
11384 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
11385 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11386 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011387 break;
11388
11389 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070011390 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011391 type);
11392 kfree_skb(skb);
11393 return;
11394 }
11395
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011396 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080011397 * Add radio index at the end of the svc event in TLV format
11398 * to maintain the backward compatibility with userspace
11399 * applications.
11400 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011401
11402 tlv_len = 0;
11403
11404 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
11405 < WLAN_NL_MAX_PAYLOAD) {
11406 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
11407 sizeof(*ani_hdr) + len);
11408 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
11409 radio_info->length = (unsigned short) sizeof(radio_info->radio);
11410 radio_info->radio = radio;
11411 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070011412 hdd_debug("Added radio index tlv - radio index %d",
11413 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011414 }
11415
11416 nlh->nlmsg_len += tlv_len;
11417 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
11418
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053011419 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011420}
11421
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011422#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
11423void wlan_hdd_auto_shutdown_cb(void)
11424{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011425 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011426
11427 if (!hdd_ctx)
11428 return;
11429
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011430 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011431 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
11432 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011433}
11434
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011435void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011436{
Jeff Johnson9d295242017-08-29 14:39:48 -070011437 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011438 bool ap_connected = false, sta_connected = false;
11439 tHalHandle hal_handle;
11440
11441 hal_handle = hdd_ctx->hHal;
11442 if (hal_handle == NULL)
11443 return;
11444
11445 if (hdd_ctx->config->WlanAutoShutdown == 0)
11446 return;
11447
11448 if (enable == false) {
11449 if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011450 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011451 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011452 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011453 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070011454 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011455 return;
11456 }
11457
11458 /* To enable shutdown timer check conncurrency */
Dustin Brown920397d2017-12-13 16:27:50 -080011459 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->hdd_psoc)) {
11460 hdd_for_each_adapter(hdd_ctx, adapter) {
11461 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011462 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
11463 conn_info.connState ==
11464 eConnectionState_Associated) {
11465 sta_connected = true;
11466 break;
11467 }
11468 }
Dustin Brown920397d2017-12-13 16:27:50 -080011469
11470 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011471 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070011472 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011473 ap_connected = true;
11474 break;
11475 }
11476 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011477 }
11478 }
11479
11480 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011481 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011482 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011483 }
Jeff Johnson68755312017-02-10 11:46:55 -080011484
11485 if (sme_set_auto_shutdown_timer(hal_handle,
11486 hdd_ctx->config->WlanAutoShutdown)
11487 != QDF_STATUS_SUCCESS)
11488 hdd_err("Failed to start wlan auto shutdown timer");
11489 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070011490 hdd_info("Auto Shutdown timer for %d seconds enabled",
11491 hdd_ctx->config->WlanAutoShutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011492}
11493#endif
11494
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011495struct hdd_adapter *
11496hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
11497 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011498{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011499 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011500 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011501
11502 con_sap_adapter = NULL;
11503
Dustin Brown920397d2017-12-13 16:27:50 -080011504 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011505 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
11506 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011507 adapter != this_sap_adapter) {
11508 if (check_start_bss) {
11509 if (test_bit(SOFTAP_BSS_STARTED,
11510 &adapter->event_flags)) {
11511 con_sap_adapter = adapter;
11512 break;
11513 }
11514 } else {
11515 con_sap_adapter = adapter;
11516 break;
11517 }
11518 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011519 }
11520
11521 return con_sap_adapter;
11522}
11523
11524#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070011525static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011526{
Dustin Brown5ec6b552017-03-31 12:11:40 -070011527 return adapter->device_mode == QDF_STA_MODE ||
11528 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011529}
11530
Jeff Johnson9d295242017-08-29 14:39:48 -070011531static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011532{
Dustin Brown5ec6b552017-03-31 12:11:40 -070011533 return adapter->device_mode == QDF_SAP_MODE ||
11534 adapter->device_mode == QDF_P2P_GO_MODE;
11535}
11536
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011537static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011538{
Dustin Brown920397d2017-12-13 16:27:50 -080011539 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070011540
Dustin Brown920397d2017-12-13 16:27:50 -080011541 hdd_for_each_adapter(hdd_ctx, adapter) {
11542 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070011543 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
11544 conn_info.connState == eConnectionState_Associated) {
11545 return true;
11546 }
11547
Dustin Brown920397d2017-12-13 16:27:50 -080011548 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070011549 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070011550 return true;
11551 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070011552 }
11553
11554 return false;
11555}
11556
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011557static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011558{
11559 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011560
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053011561 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070011562 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053011563 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011564
Dustin Brown5ec6b552017-03-31 12:11:40 -070011565 return is_running;
11566}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011567
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011568static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011569{
11570 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
11571 hdd_ctx->bus_bw_timer_running = true;
11572 qdf_timer_start(&hdd_ctx->bus_bw_timer,
11573 hdd_ctx->config->busBandwidthComputeInterval);
11574 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
11575}
11576
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011577void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011578{
Dustin Brown491d54b2018-03-14 12:39:11 -070011579 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011580
11581 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11582 hdd_debug("Bandwidth compute timer already started");
11583 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011584 }
11585
Dustin Brown5ec6b552017-03-31 12:11:40 -070011586 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11587
Dustin Browne74003f2018-03-14 12:51:58 -070011588 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011589}
11590
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011591void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011592{
Dustin Brown491d54b2018-03-14 12:39:11 -070011593 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011594
11595 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11596 hdd_debug("Bandwidth compute timer already started");
11597 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070011598 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070011599
11600 if (hdd_any_adapter_is_assoc(hdd_ctx))
11601 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11602
Dustin Browne74003f2018-03-14 12:51:58 -070011603 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011604}
11605
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011606static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011607{
Sravan Kumar Kairam9e99e9a2018-03-12 19:09:45 +053011608 ucfg_ipa_set_perf_level(hdd_ctx->hdd_pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070011609
11610 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
11611 qdf_timer_stop(&hdd_ctx->bus_bw_timer);
11612 hdd_ctx->bus_bw_timer_running = false;
11613 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
11614
11615 hdd_reset_tcp_delack(hdd_ctx);
11616}
11617
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011618void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011619{
Dustin Brown491d54b2018-03-14 12:39:11 -070011620 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011621
11622 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11623 hdd_debug("Bandwidth compute timer already stopped");
11624 return;
11625 }
11626
11627 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11628
Dustin Browne74003f2018-03-14 12:51:58 -070011629 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011630}
11631
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011632void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011633{
Dustin Brown491d54b2018-03-14 12:39:11 -070011634 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011635
11636 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11637 hdd_debug("Bandwidth compute timer already stopped");
11638 return;
11639 }
11640
11641 if (!hdd_any_adapter_is_assoc(hdd_ctx))
11642 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11643
Dustin Browne74003f2018-03-14 12:51:58 -070011644 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011645}
11646#endif
11647
11648/**
11649 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
11650 * and sta's operating channel.
11651 * @sta_adapter: Describe the first argument to foobar.
11652 * @ap_adapter: Describe the second argument to foobar.
11653 * @roam_profile: Roam profile of AP to which STA wants to connect.
11654 * @concurrent_chnl_same: If both SAP and STA channels are same then
11655 * set this flag to true else false.
11656 *
11657 * This function checks the sap's operating channel and sta's operating channel.
11658 * if both are same then it will return false else it will restart the sap in
11659 * sta's channel and return true.
11660 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011661 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011662 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011663QDF_STATUS
11664wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
11665 struct hdd_adapter *ap_adapter,
Jeff Johnson61b5e982018-03-15 11:33:31 -070011666 struct csr_roam_profile *roam_profile,
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011667 tScanResultHandle *scan_cache,
11668 bool *concurrent_chnl_same)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011669{
Jeff Johnson87251032017-08-29 13:31:11 -070011670 struct hdd_ap_ctx *hdd_ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011671 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011672 QDF_STATUS status;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080011673 enum QDF_OPMODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011674 *concurrent_chnl_same = true;
11675
11676 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11677 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070011678 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011679 scan_cache,
11680 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011681 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011682 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011683 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011684 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011685 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011686 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011687 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011688 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011689 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011690 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011691 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011692 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011693 }
11694 }
11695 } else {
11696 /*
11697 * Lets handle worst case scenario here, Scan cache lookup is
11698 * failed so we have to stop the SAP to avoid any channel
11699 * discrepancy between SAP's channel and STA's channel.
11700 * Return the status as failure so caller function could know
11701 * that scan look up is failed.
11702 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070011703 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011704 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011705 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011706 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011707}
11708
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011709/**
11710 * wlan_hdd_stop_sap() - This function stops bss of SAP.
11711 * @ap_adapter: SAP adapter
11712 *
11713 * This function will process the stopping of sap adapter.
11714 *
11715 * Return: None
11716 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011717void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011718{
Jeff Johnson87251032017-08-29 13:31:11 -070011719 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011720 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011721 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011722 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011723
11724 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011725 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011726 return;
11727 }
11728
11729 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11730 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011731 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011732 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011733
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011734 mutex_lock(&hdd_ctx->sap_lock);
11735 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080011736 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011737 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011738 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011739 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011740 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011741 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053011742 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080011743 qdf_stop_bss_event,
11744 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011745 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011746 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070011747 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011748 return;
11749 }
11750 }
11751 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011752 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
11753 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011754 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070011755 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011756 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011757 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011758 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011759 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011760 }
11761 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011762}
11763
11764/**
11765 * wlan_hdd_start_sap() - this function starts bss of SAP.
11766 * @ap_adapter: SAP adapter
11767 *
11768 * This function will process the starting of sap adapter.
11769 *
11770 * Return: None
11771 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011772void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011773{
Jeff Johnson87251032017-08-29 13:31:11 -070011774 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011775 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011776 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011777 struct hdd_context *hdd_ctx;
Jeff Johnsone4c11db2018-05-05 23:22:32 -070011778 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011779
11780 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011781 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011782 return;
11783 }
11784
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011785 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070011786 hdd_err("SoftAp role has not been enabled");
11787 return;
11788 }
11789
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011790 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
11791 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11792 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070011793 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011794
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011795 mutex_lock(&hdd_ctx->sap_lock);
11796 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
11797 goto end;
11798
11799 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011800 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011801 goto end;
11802 }
11803
Wei Song2f76f642016-11-18 16:32:53 +080011804 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011805 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070011806 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011807 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011808 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011809 goto end;
11810
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011811 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053011812 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -080011813 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011814 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011815 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011816 goto end;
11817 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070011818 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053011819 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011820 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011821 if (hostapd_state->bss_state == BSS_START) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011822 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
11823 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011824 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070011825 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011826 true);
11827 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053011828 mutex_unlock(&hdd_ctx->sap_lock);
11829
11830 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011831end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053011832 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011833 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070011834 /* SAP context and beacon cleanup will happen during driver unload
11835 * in hdd_stop_adapter
11836 */
11837 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
11838
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011839}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011840
11841/**
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011842 * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual
11843 * mac scan config
11844 * @status: Status of set antenna mode
11845 *
11846 * Callback on setting the dual mac configuration
11847 *
11848 * Return: None
11849 */
11850void wlan_hdd_soc_set_antenna_mode_cb(
11851 enum set_antenna_mode_status status)
11852{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011853 struct hdd_context *hdd_ctx;
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011854
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011855 hdd_debug("Status: %d", status);
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011856
11857 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11858 if (0 != wlan_hdd_validate_context(hdd_ctx))
11859 return;
11860
11861 /* Signal the completion of set dual mac config */
11862 complete(&hdd_ctx->set_antenna_mode_cmpl);
11863}
11864
11865/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011866 * hdd_get_fw_version() - Get FW version
11867 * @hdd_ctx: pointer to HDD context.
11868 * @major_spid: FW version - major spid.
11869 * @minor_spid: FW version - minor spid
11870 * @ssid: FW version - ssid
11871 * @crmid: FW version - crmid
11872 *
11873 * This function is called to get the firmware build version stored
11874 * as part of the HDD context
11875 *
11876 * Return: None
11877 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011878void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011879 uint32_t *major_spid, uint32_t *minor_spid,
11880 uint32_t *siid, uint32_t *crmid)
11881{
11882 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
11883 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
11884 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
11885 *crmid = hdd_ctx->target_fw_version & 0x7fff;
11886}
11887
11888#ifdef QCA_CONFIG_SMP
11889/**
11890 * wlan_hdd_get_cpu() - get cpu_index
11891 *
11892 * Return: cpu_index
11893 */
11894int wlan_hdd_get_cpu(void)
11895{
11896 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011897
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011898 put_cpu();
11899 return cpu_index;
11900}
11901#endif
11902
11903/**
11904 * hdd_get_fwpath() - get framework path
11905 *
11906 * This function is used to get the string written by
11907 * userspace to start the wlan driver
11908 *
11909 * Return: string
11910 */
11911const char *hdd_get_fwpath(void)
11912{
11913 return fwpath.string;
11914}
11915
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011916static int hdd_qdf_print_init(void)
11917{
11918 int qdf_print_idx;
11919 QDF_STATUS status;
11920
11921 status = qdf_print_setup();
11922 if (status != QDF_STATUS_SUCCESS) {
11923 pr_err("qdf_print_setup failed\n");
11924 return -EINVAL;
11925 }
11926
11927 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
11928
11929 if (qdf_print_idx < 0) {
11930 pr_err("qdf_print_ctrl_register failed, ret = %d\n",
11931 qdf_print_idx);
11932 return -EINVAL;
11933 }
11934
11935 qdf_set_pidx(qdf_print_idx);
11936
11937 return 0;
11938}
11939
11940static void hdd_qdf_print_deinit(void)
11941{
11942 int qdf_print_idx;
11943
11944 qdf_print_idx = qdf_get_pidx();
11945 qdf_print_ctrl_cleanup(qdf_print_idx);
11946}
11947
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011948/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011949 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011950 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011951 * This function initilizes CDS global context with the help of cds_init. This
11952 * has to be the first function called after probe to get a valid global
11953 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011954 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011955 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011956 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011957int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011958{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011959 QDF_STATUS status;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011960 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011961
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011962 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080011963 if (QDF_IS_STATUS_ERROR(status)) {
11964 hdd_err("Failed to allocate CDS context");
11965 ret = -ENOMEM;
11966 goto err_out;
11967 }
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053011968
11969 wlan_init_bug_report_lock();
11970
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011971#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11972 wlan_logging_sock_init_svc();
11973#endif
11974
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011975 qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
11976 (void *)hdd_drv_ops_inactivity_handler, NULL,
11977 QDF_TIMER_TYPE_SW);
11978
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011979 hdd_trace_init();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011980 hdd_qdf_print_init();
11981
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011982 hdd_register_debug_callback();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011983
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011984err_out:
11985 return ret;
11986}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011987
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011988/**
11989 * hdd_deinit() - Deinitialize Driver
11990 *
11991 * This function frees CDS global context with the help of cds_deinit. This
11992 * has to be the last function call in remove callback to free the global
11993 * context.
11994 */
11995void hdd_deinit(void)
11996{
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011997 qdf_timer_free(&hdd_drv_ops_inactivity_timer);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011998
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070011999 wlan_destroy_bug_report_lock();
12000 cds_deinit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070012001
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070012002 hdd_qdf_print_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012003#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12004 wlan_logging_sock_deinit_svc();
12005#endif
12006}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012007
Yue Ma6e7b1a02017-04-03 14:17:46 -070012008#ifdef QCA_WIFI_NAPIER_EMULATION
12009#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
12010#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012011#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070012012#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012013
Sachin Ahujadddd2632017-03-07 19:07:24 +053012014static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
12015 struct file *file)
12016{
12017 return 0;
12018}
12019
12020static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
12021 const char __user *user_buf,
12022 size_t count,
12023 loff_t *f_pos)
12024{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012025 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053012026 static const char wlan_off_str[] = "OFF";
12027 static const char wlan_on_str[] = "ON";
12028 int ret;
12029 unsigned long rc;
12030
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012031 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012032 pr_err("Failed to read buffer\n");
12033 return -EINVAL;
12034 }
12035
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012036 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012037 pr_debug("Wifi turning off from UI\n");
12038 goto exit;
12039 }
12040
Sachin Ahuja16904db2017-12-13 19:56:57 +053012041 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0) {
12042 pr_info("Wifi Turning On from UI\n");
12043 }
12044
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012045 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012046 pr_err("Invalid value received from framework");
12047 goto exit;
12048 }
12049
12050 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053012051 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053012052 rc = wait_for_completion_timeout(&wlan_start_comp,
12053 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
12054 if (!rc) {
12055 hdd_alert("Timed-out waiting in wlan_hdd_state_ctrl_param_write");
12056 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053012057 return ret;
12058 }
12059
12060 hdd_start_complete(0);
12061 }
12062
12063exit:
12064 return count;
12065}
12066
12067
12068const struct file_operations wlan_hdd_state_fops = {
12069 .owner = THIS_MODULE,
12070 .open = wlan_hdd_state_ctrl_param_open,
12071 .write = wlan_hdd_state_ctrl_param_write,
12072};
12073
12074static int wlan_hdd_state_ctrl_param_create(void)
12075{
12076 unsigned int wlan_hdd_state_major = 0;
12077 int ret;
12078 struct device *dev;
12079
12080 device = MKDEV(wlan_hdd_state_major, 0);
12081
12082 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
12083 if (ret) {
12084 pr_err("Failed to register qcwlanstate");
12085 goto dev_alloc_err;
12086 }
12087 wlan_hdd_state_major = MAJOR(device);
12088
12089 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
12090 if (IS_ERR(class)) {
12091 pr_err("wlan_hdd_state class_create error");
12092 goto class_err;
12093 }
12094
12095 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
12096 if (IS_ERR(dev)) {
12097 pr_err("wlan_hdd_statedevice_create error");
12098 goto err_class_destroy;
12099 }
12100
12101 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
12102 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
12103 if (ret) {
12104 pr_err("Failed to add cdev error");
12105 goto cdev_add_err;
12106 }
12107
12108 pr_info("wlan_hdd_state %s major(%d) initialized",
12109 WLAN_MODULE_NAME, wlan_hdd_state_major);
12110
12111 return 0;
12112
12113cdev_add_err:
12114 device_destroy(class, device);
12115err_class_destroy:
12116 class_destroy(class);
12117class_err:
12118 unregister_chrdev_region(device, dev_num);
12119dev_alloc_err:
12120 return -ENODEV;
12121}
12122
12123static void wlan_hdd_state_ctrl_param_destroy(void)
12124{
12125 cdev_del(&wlan_hdd_state_cdev);
12126 device_destroy(class, device);
12127 class_destroy(class);
12128 unregister_chrdev_region(device, dev_num);
12129
12130 pr_info("Device node unregistered");
12131}
12132
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012133/**
Mukul Sharmad75a6672017-06-22 15:40:53 +053012134 * component_init - API to init cld component's
12135 *
12136 * Return: None
12137 */
12138static void component_init(void)
12139{
12140 pmo_init();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012141 disa_init();
Zhang Qian47e22ce2018-01-04 15:38:38 +080012142 ucfg_ocb_init();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053012143 ipa_init();
Mukul Sharmad75a6672017-06-22 15:40:53 +053012144}
12145
12146/**
12147 * component_deinit - API to deinit cld component's
12148 *
12149 * Return: None
12150 */
12151static void component_deinit(void)
12152{
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053012153 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080012154 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053012155 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012156 disa_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012157}
12158
12159void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
12160{
Zhang Qian47e22ce2018-01-04 15:38:38 +080012161 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012162 disa_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012163}
12164
12165void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
12166{
Nachiket Kukade98f562a2017-12-15 12:18:07 +053012167 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080012168 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053012169}
12170
12171/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012172 * __hdd_module_init - Module init helper
12173 *
12174 * Module init helper function used by both module and static driver.
12175 *
12176 * Return: 0 for success, errno on failure
12177 */
12178static int __hdd_module_init(void)
12179{
12180 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012181
Dustin Brown96cd9632017-11-13 12:45:04 -080012182 pr_err("%s: Loading driver v%s (%s)\n",
Dustin Brownab482ac2017-06-09 17:00:44 -070012183 WLAN_MODULE_NAME,
Dustin Brown96cd9632017-11-13 12:45:04 -080012184 g_wlan_driver_version,
Dustin Brownc1034df2018-02-07 14:51:32 -080012185 TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012186
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070012187 pld_init();
12188
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012189 ret = hdd_init();
12190 if (ret) {
12191 pr_err("hdd_init failed %x\n", ret);
12192 goto err_hdd_init;
12193 }
12194
Rajeev Kumar97767a02016-11-30 11:20:40 -080012195 dispatcher_init();
12196
Mukul Sharmad75a6672017-06-22 15:40:53 +053012197 /* Ensure to call post objmgr init */
12198 component_init();
12199
Anurag Chouhana37b5b72016-02-21 14:53:42 +053012200 qdf_wake_lock_create(&wlan_wake_lock, "wlan");
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012201
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012202 hdd_set_conparam((uint32_t) con_mode);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012203
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012204 ret = wlan_hdd_register_driver();
12205 if (ret) {
Mohit Khannafa99aea2016-05-12 21:43:13 -070012206 pr_err("%s: driver load failure, err %d\n", WLAN_MODULE_NAME,
12207 ret);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012208 goto out;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012209 }
12210
Sachin Ahuja16904db2017-12-13 19:56:57 +053012211 ret = wlan_hdd_state_ctrl_param_create();
12212 if (ret) {
12213 pr_err("wlan_hdd_state_create:%x\n", ret);
12214 goto out;
12215 }
12216
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053012217 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012218
12219 return 0;
12220out:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053012221 qdf_wake_lock_destroy(&wlan_wake_lock);
Liangwei Dong9fcc7212017-10-24 13:43:52 +080012222 component_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080012223 dispatcher_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012224 hdd_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080012225
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012226err_hdd_init:
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070012227 pld_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012228 return ret;
12229}
12230
12231/**
12232 * __hdd_module_exit - Module exit helper
12233 *
12234 * Module exit helper function used by both module and static driver.
12235 */
12236static void __hdd_module_exit(void)
12237{
Will Huang36049722018-04-13 11:48:51 +080012238 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053012239
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012240 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
12241 QWLAN_VERSIONSTR);
12242
Arunk Khandavalli830c9692018-03-22 12:17:40 +053012243 if (!hdd_wait_for_recovery_completion())
12244 return;
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053012245
Rajeev Kumar3505ae52018-05-10 18:44:45 -070012246 if (hdd_ctx)
12247 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Will Huang36049722018-04-13 11:48:51 +080012248
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012249 wlan_hdd_unregister_driver();
12250
Anurag Chouhana37b5b72016-02-21 14:53:42 +053012251 qdf_wake_lock_destroy(&wlan_wake_lock);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012252
Mukul Sharmad75a6672017-06-22 15:40:53 +053012253 /* Ensure to call prior to objmgr deinit */
12254 component_deinit();
12255
Rajeev Kumar97767a02016-11-30 11:20:40 -080012256 dispatcher_deinit();
Amar Singhal0928b192017-12-01 10:50:54 -080012257
12258 hdd_sysfs_destroy_version_interface();
12259
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012260 hdd_deinit();
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070012261 pld_deinit();
12262
Sachin Ahujadddd2632017-03-07 19:07:24 +053012263 wlan_hdd_state_ctrl_param_destroy();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012264}
12265
Arun Khandavallifae92942016-08-01 13:31:08 +053012266#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012267/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012268 * wlan_boot_cb() - Wlan boot callback
12269 * @kobj: object whose directory we're creating the link in.
12270 * @attr: attribute the user is interacting with
12271 * @buff: the buffer containing the user data
12272 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012273 *
Arun Khandavallifae92942016-08-01 13:31:08 +053012274 * This callback is invoked when the fs is ready to start the
12275 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012276 *
Arun Khandavallifae92942016-08-01 13:31:08 +053012277 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012278 */
Arun Khandavallifae92942016-08-01 13:31:08 +053012279static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012280 struct kobj_attribute *attr,
12281 const char *buf,
12282 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012283{
Arun Khandavallifae92942016-08-01 13:31:08 +053012284
Arun Khandavallifae92942016-08-01 13:31:08 +053012285 if (wlan_loader->loaded_state) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012286 pr_err("%s: wlan driver already initialized\n", __func__);
12287 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053012288 }
12289
Arun Khandavallifae92942016-08-01 13:31:08 +053012290 if (__hdd_module_init()) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012291 pr_err("%s: wlan driver initialization failed\n", __func__);
12292 return -EIO;
12293 }
12294
12295 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053012296
12297 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012298}
Arun Khandavallifae92942016-08-01 13:31:08 +053012299
12300/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012301 * hdd_sysfs_cleanup() - cleanup sysfs
12302 *
12303 * Return: None
12304 *
12305 */
12306static void hdd_sysfs_cleanup(void)
12307{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012308 /* remove from group */
12309 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
12310 sysfs_remove_group(wlan_loader->boot_wlan_obj,
12311 wlan_loader->attr_group);
12312
12313 /* unlink the object from parent */
12314 kobject_del(wlan_loader->boot_wlan_obj);
12315
12316 /* free the object */
12317 kobject_put(wlan_loader->boot_wlan_obj);
12318
12319 kfree(wlan_loader->attr_group);
12320 kfree(wlan_loader);
12321
12322 wlan_loader = NULL;
12323}
12324
12325/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012326 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
12327 * ready
12328 *
12329 * This is creates the syfs entry boot_wlan. Which shall be invoked
12330 * when the filesystem is ready.
12331 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012332 * QDF API cannot be used here since this function is called even before
12333 * initializing WLAN driver.
12334 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070012335 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053012336 */
12337static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012338{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012339 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053012340
12341 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012342 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012343 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053012344
12345 wlan_loader->boot_wlan_obj = NULL;
12346 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
12347 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012348 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053012349 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053012350
12351 wlan_loader->loaded_state = 0;
12352 wlan_loader->attr_group->attrs = attrs;
12353
12354 wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
12355 kernel_kobj);
12356 if (!wlan_loader->boot_wlan_obj) {
12357 pr_err("%s: sysfs create and add failed\n", __func__);
Arun Khandavallifae92942016-08-01 13:31:08 +053012358 goto error_return;
12359 }
12360
12361 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
12362 wlan_loader->attr_group);
12363 if (ret) {
12364 pr_err("%s: sysfs create group failed %d\n", __func__, ret);
12365 goto error_return;
12366 }
12367
12368 return 0;
12369
12370error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012371 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053012372
12373 return ret;
12374}
12375
12376/**
12377 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
12378 *
12379 * Return: 0 on success or errno on failure
12380 */
12381static int wlan_deinit_sysfs(void)
12382{
Arun Khandavallifae92942016-08-01 13:31:08 +053012383 if (!wlan_loader) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012384 hdd_err("wlan loader context is Null!");
Arun Khandavallifae92942016-08-01 13:31:08 +053012385 return -EINVAL;
12386 }
12387
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012388 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012389 return 0;
12390}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012391
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012392#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053012393
12394#ifdef MODULE
12395/**
12396 * __hdd_module_init - Module init helper
12397 *
12398 * Module init helper function used by both module and static driver.
12399 *
12400 * Return: 0 for success, errno on failure
12401 */
12402static int hdd_module_init(void)
12403{
Arun Khandavallifae92942016-08-01 13:31:08 +053012404 if (__hdd_module_init()) {
12405 pr_err("%s: Failed to register handler\n", __func__);
Dustin Brownab482ac2017-06-09 17:00:44 -070012406 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012407 }
12408
Dustin Brownab482ac2017-06-09 17:00:44 -070012409 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053012410}
12411#else
12412static int __init hdd_module_init(void)
12413{
12414 int ret = -EINVAL;
12415
12416 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070012417 if (ret)
Arun Khandavallifae92942016-08-01 13:31:08 +053012418 pr_err("Failed to create sysfs entry for loading wlan");
12419
12420 return ret;
12421}
12422#endif
12423
12424
12425#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012426/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012427 * hdd_module_exit() - Exit function
12428 *
12429 * This is the driver exit point (invoked when module is unloaded using rmmod)
12430 *
12431 * Return: None
12432 */
12433static void __exit hdd_module_exit(void)
12434{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012435 __hdd_module_exit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012436}
Arun Khandavallifae92942016-08-01 13:31:08 +053012437#else
12438static void __exit hdd_module_exit(void)
12439{
12440 __hdd_module_exit();
12441 wlan_deinit_sysfs();
12442}
12443#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012444
Srinivas Girigowda841da292018-02-21 16:33:00 -080012445static int fwpath_changed_handler(const char *kmessage,
12446 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012447{
12448 return param_set_copystring(kmessage, kp);
12449}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012450
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012451/**
12452 * is_con_mode_valid() check con mode is valid or not
12453 * @mode: global con mode
12454 *
12455 * Return: TRUE on success FALSE on failure
12456 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080012457static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012458{
12459 switch (mode) {
12460 case QDF_GLOBAL_MONITOR_MODE:
12461 case QDF_GLOBAL_FTM_MODE:
12462 case QDF_GLOBAL_EPPING_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012463 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012464 return true;
12465 default:
12466 return false;
12467 }
12468}
12469
12470/**
12471 * hdd_get_adpter_mode() - returns adapter mode based on global con mode
12472 * @mode: global con mode
12473 *
12474 * Return: adapter mode
12475 */
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012476static enum QDF_OPMODE hdd_get_adpter_mode(
Jeff Johnson876c1a62017-12-12 10:43:07 -080012477 enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012478{
12479
12480 switch (mode) {
12481 case QDF_GLOBAL_MISSION_MODE:
12482 return QDF_STA_MODE;
12483 case QDF_GLOBAL_MONITOR_MODE:
12484 return QDF_MONITOR_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012485 case QDF_GLOBAL_EPPING_MODE:
12486 return QDF_EPPING_MODE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012487 case QDF_GLOBAL_FTM_MODE:
12488 return QDF_FTM_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012489 case QDF_GLOBAL_QVIT_MODE:
12490 return QDF_QVIT_MODE;
12491 default:
12492 return QDF_MAX_NO_OF_MODE;
12493 }
12494}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012495
Dustin Brown27cd9942017-09-27 16:11:44 -070012496static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012497 enum QDF_GLOBAL_MODE curr_mode)
Dustin Brown27cd9942017-09-27 16:11:44 -070012498{
12499 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
12500 return;
12501
12502 switch (curr_mode) {
Dustin Brown27cd9942017-09-27 16:11:44 -070012503 case QDF_GLOBAL_MONITOR_MODE:
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012504 hdd_info("Release wakelock for monitor mode!");
12505 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
12506 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
Dundi Raviteja0a2a65b2018-04-30 12:34:11 +053012507 /* fallthrough */
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012508 case QDF_GLOBAL_MISSION_MODE:
Dustin Brown27cd9942017-09-27 16:11:44 -070012509 case QDF_GLOBAL_FTM_MODE:
12510 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +053012511 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, NULL);
Dustin Browndb2a8be2017-12-20 11:49:56 -080012512 hdd_stop_all_adapters(hdd_ctx);
Dustin Brown27cd9942017-09-27 16:11:44 -070012513
Dustin Brown27cd9942017-09-27 16:11:44 -070012514 break;
12515 default:
12516 break;
12517 }
12518}
12519
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012520static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012521 enum QDF_GLOBAL_MODE curr_mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012522{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053012523 int driver_status;
12524
12525 driver_status = hdd_ctx->driver_status;
12526
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012527 switch (curr_mode) {
12528 case QDF_GLOBAL_MISSION_MODE:
12529 case QDF_GLOBAL_MONITOR_MODE:
12530 case QDF_GLOBAL_FTM_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012531 hdd_deinit_all_adapters(hdd_ctx, false);
12532 hdd_close_all_adapters(hdd_ctx, false);
12533 break;
12534 case QDF_GLOBAL_EPPING_MODE:
12535 epping_disable();
12536 epping_close();
12537 break;
12538 default:
12539 return;
12540 }
12541}
12542
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012543static int hdd_register_req_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012544 enum QDF_GLOBAL_MODE mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012545{
Jeff Johnson9d295242017-08-29 14:39:48 -070012546 struct hdd_adapter *adapter;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012547 int ret = 0;
12548 bool rtnl_held;
12549 qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
12550 QDF_STATUS status;
12551
12552 if (!qdf_dev) {
12553 hdd_err("qdf device context is Null return!");
12554 return -EINVAL;
12555 }
12556
12557 rtnl_held = hdd_hold_rtnl_lock();
12558 switch (mode) {
12559 case QDF_GLOBAL_MISSION_MODE:
Jeff Johnson957bc272017-02-02 08:54:48 -080012560 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
12561 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012562 hdd_err("Failed to open interfaces: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012563 break;
12564 case QDF_GLOBAL_FTM_MODE:
12565 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
12566 wlan_hdd_get_intf_addr(hdd_ctx),
12567 NET_NAME_UNKNOWN, rtnl_held);
12568 if (adapter == NULL)
12569 ret = -EINVAL;
12570 break;
12571 case QDF_GLOBAL_MONITOR_MODE:
12572 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
12573 wlan_hdd_get_intf_addr(hdd_ctx),
12574 NET_NAME_UNKNOWN, rtnl_held);
12575 if (adapter == NULL)
12576 ret = -EINVAL;
12577 break;
12578 case QDF_GLOBAL_EPPING_MODE:
12579 status = epping_open();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012580 if (status != QDF_STATUS_SUCCESS) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012581 hdd_err("Failed to open in eeping mode: %d", status);
12582 ret = -EINVAL;
12583 break;
12584 }
12585 ret = epping_enable(qdf_dev->dev);
12586 if (ret) {
12587 hdd_err("Failed to enable in epping mode : %d", ret);
12588 epping_close();
12589 }
12590 break;
12591 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012592 hdd_err("Mode not supported");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012593 ret = -ENOTSUPP;
12594 break;
12595 }
12596 hdd_release_rtnl_lock();
12597 rtnl_held = false;
12598 return ret;
12599}
12600
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012601/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012602 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012603 * @kmessage: con mode name on which driver to be bring up
12604 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012605 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012606 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012607 * This function is invoked when user updates con mode using sys entry,
12608 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012609 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012610 * Return - 0 on success and failure code on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012611 */
Srinivas Girigowda841da292018-02-21 16:33:00 -080012612static int __con_mode_handler(const char *kmessage,
12613 const struct kernel_param *kp,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012614 struct hdd_context *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012615{
12616 int ret;
Jeff Johnson876c1a62017-12-12 10:43:07 -080012617 enum QDF_GLOBAL_MODE curr_mode;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012618 enum QDF_OPMODE adapter_mode;
Dustin Brown20024e32018-01-03 12:34:58 -080012619 int new_con_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012620
Dustin Brownab6029b2017-05-24 13:04:19 -070012621 hdd_info("con_mode handler: %s", kmessage);
12622
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012623 ret = wlan_hdd_validate_context(hdd_ctx);
12624 if (ret)
12625 return ret;
12626
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012627 qdf_atomic_set(&hdd_ctx->con_mode_flag, 1);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012628
Dustin Brown20024e32018-01-03 12:34:58 -080012629 ret = kstrtoint(kmessage, 0, &new_con_mode);
12630 if (ret) {
12631 hdd_err("Failed to parse con_mode '%s'", kmessage);
12632 goto reset_flags;
12633 }
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012634 mutex_lock(&hdd_init_deinit_lock);
Arun Khandavallifae92942016-08-01 13:31:08 +053012635
Dustin Brown20024e32018-01-03 12:34:58 -080012636 if (!is_con_mode_valid(new_con_mode)) {
12637 hdd_err("invalid con_mode %d", new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012638 ret = -EINVAL;
12639 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012640 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012641
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012642 curr_mode = hdd_get_conparam();
Dustin Brown20024e32018-01-03 12:34:58 -080012643 if (curr_mode == new_con_mode) {
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012644 hdd_err("curr mode: %d is same as user triggered mode %d",
Dustin Brown20024e32018-01-03 12:34:58 -080012645 curr_mode, new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012646 ret = 0;
12647 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012648 }
12649
Dustin Brown27cd9942017-09-27 16:11:44 -070012650 /* ensure adapters are stopped */
12651 hdd_stop_present_mode(hdd_ctx, curr_mode);
12652
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012653 ret = hdd_wlan_stop_modules(hdd_ctx, true);
Arun Khandavallifae92942016-08-01 13:31:08 +053012654 if (ret) {
12655 hdd_err("Stop wlan modules failed");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012656 goto reset_flags;
12657 }
12658
Dustin Browndd4e50f2018-05-24 15:43:42 -070012659 /* Cleanup present mode before switching to new mode */
12660 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
Ashish Kumar Dhanotiyacda57662017-08-14 14:45:25 +053012661
Dustin Brown20024e32018-01-03 12:34:58 -080012662 hdd_set_conparam(new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012663
12664 /* Register for new con_mode & then kick_start modules again */
Dustin Brown20024e32018-01-03 12:34:58 -080012665 ret = hdd_register_req_mode(hdd_ctx, new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012666 if (ret) {
12667 hdd_err("Failed to register for new mode");
12668 goto reset_flags;
12669 }
12670
Dustin Brown20024e32018-01-03 12:34:58 -080012671 adapter_mode = hdd_get_adpter_mode(new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012672 if (adapter_mode == QDF_MAX_NO_OF_MODE) {
12673 hdd_err("invalid adapter");
12674 ret = -EINVAL;
12675 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012676 }
12677
Dustin Browne7e71d32018-05-11 16:00:08 -070012678 ret = hdd_wlan_start_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053012679 if (ret) {
12680 hdd_err("Start wlan modules failed: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012681 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012682 }
12683
Dustin Brown20024e32018-01-03 12:34:58 -080012684 if (new_con_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Browne7e71d32018-05-11 16:00:08 -070012685 struct hdd_adapter *adapter =
12686 hdd_get_adapter(hdd_ctx, adapter_mode);
12687
12688 if (!adapter) {
12689 hdd_err("Failed to get adapter:%d", adapter_mode);
12690 goto reset_flags;
12691 }
12692
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012693 if (hdd_start_adapter(adapter)) {
12694 hdd_err("Failed to start %s adapter", kmessage);
12695 ret = -EINVAL;
12696 goto reset_flags;
12697 }
Arun Khandavallifae92942016-08-01 13:31:08 +053012698
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012699 hdd_info("Acquire wakelock for monitor mode!");
12700 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
12701 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
12702 }
12703
Dustin Brown20024e32018-01-03 12:34:58 -080012704 /* con_mode is a global module parameter */
12705 con_mode = new_con_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012706 hdd_info("Mode successfully changed to %s", kmessage);
12707 ret = 0;
12708
12709reset_flags:
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012710 mutex_unlock(&hdd_init_deinit_lock);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012711 qdf_atomic_set(&hdd_ctx->con_mode_flag, 0);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012712 return ret;
12713}
12714
12715
Srinivas Girigowda841da292018-02-21 16:33:00 -080012716static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012717{
12718 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012719 struct hdd_context *hdd_ctx;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012720
12721 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12722 ret = wlan_hdd_validate_context(hdd_ctx);
12723 if (ret)
12724 return ret;
12725
Ashish Kumar Dhanotiya759b3272018-05-18 17:49:46 +053012726 if (!cds_wait_for_external_threads_completion(__func__)) {
12727 hdd_warn("External threads are still active, can not change mode");
12728 return -EAGAIN;
12729 }
12730
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012731 cds_ssr_protect(__func__);
12732 ret = __con_mode_handler(kmessage, kp, hdd_ctx);
12733 cds_ssr_unprotect(__func__);
12734
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012735 return ret;
12736}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012737
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053012738static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080012739 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053012740{
12741 int ret;
12742
12743 ret = param_set_int(kmessage, kp);
12744
12745 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
12746 pr_err("Only FTM mode supported!");
12747 return -ENOTSUPP;
12748 }
12749
12750 hdd_set_conparam(con_mode_ftm);
12751 con_mode = con_mode_ftm;
12752
12753 return ret;
12754}
12755
Ravi Joshia307f632017-07-17 23:41:41 -070012756static int con_mode_handler_monitor(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080012757 const struct kernel_param *kp)
Ravi Joshia307f632017-07-17 23:41:41 -070012758{
12759 int ret;
12760
12761 ret = param_set_int(kmessage, kp);
12762
12763 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
12764 pr_err("Only Monitor mode supported!");
12765 return -ENOTSUPP;
12766 }
12767
12768 hdd_set_conparam(con_mode_monitor);
12769 con_mode = con_mode_monitor;
12770
12771 return ret;
12772}
12773
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012774/**
12775 * hdd_get_conparam() - driver exit point
12776 *
12777 * This is the driver exit point (invoked when module is unloaded using rmmod)
12778 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080012779 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012780 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080012781enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012782{
Jeff Johnson876c1a62017-12-12 10:43:07 -080012783 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012784}
12785
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012786void hdd_set_conparam(uint32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012787{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012788 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012789}
12790
Komal Seelamc11bb222016-01-27 18:57:10 +053012791/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012792 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
12793 * @hdd_ctx: HDD context
12794 *
12795 * Cleans up the pre cac interface, if it exists
12796 *
12797 * Return: None
12798 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012799void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012800{
12801 uint8_t session_id;
12802 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070012803 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012804
12805 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->hHal, &session_id);
12806 if (QDF_IS_STATUS_ERROR(status)) {
12807 hdd_err("failed to get pre cac vdev id");
12808 return;
12809 }
12810
12811 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
12812 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070012813 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012814 return;
12815 }
12816
12817 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
12818 wlan_hdd_sap_pre_cac_failure,
12819 (void *)precac_adapter);
12820 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
12821
12822}
12823
12824/**
Komal Seelamec702b02016-02-24 18:42:16 +053012825 * hdd_update_ol_config - API to update ol configuration parameters
12826 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053012827 *
Komal Seelamc11bb222016-01-27 18:57:10 +053012828 * Return: void
12829 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012830static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053012831{
Komal Seelamec702b02016-02-24 18:42:16 +053012832 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012833 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Komal Seelamc11bb222016-01-27 18:57:10 +053012834
Komal Seelamec702b02016-02-24 18:42:16 +053012835 if (!ol_ctx)
12836 return;
12837
12838 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
12839 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
12840 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
12841 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070012842 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053012843
12844 ol_init_ini_config(ol_ctx, &cfg);
12845}
12846
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012847#ifdef FEATURE_RUNTIME_PM
12848/**
12849 * hdd_populate_runtime_cfg() - populate runtime configuration
12850 * @hdd_ctx: hdd context
12851 * @cfg: pointer to the configuration memory being populated
12852 *
12853 * Return: void
12854 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012855static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012856 struct hif_config_info *cfg)
12857{
12858 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
12859 cfg->runtime_pm_delay = hdd_ctx->config->runtime_pm_delay;
12860}
12861#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012862static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012863 struct hif_config_info *cfg)
12864{
12865}
12866#endif
12867
Komal Seelamec702b02016-02-24 18:42:16 +053012868/**
12869 * hdd_update_hif_config - API to update HIF configuration parameters
12870 * @hdd_ctx: HDD Context
12871 *
12872 * Return: void
12873 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012874static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012875{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012876 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053012877 struct hif_config_info cfg;
12878
12879 if (!scn)
12880 return;
12881
12882 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012883 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053012884 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070012885
12886 if (hdd_ctx->config->prevent_link_down)
12887 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053012888}
12889
12890/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012891 * hdd_update_dp_config() - Propagate config parameters to Lithium
12892 * datapath
12893 * @hdd_ctx: HDD Context
12894 *
12895 * Return: 0 for success/errno for failure
12896 */
12897static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
12898{
12899 struct cdp_config_params params;
12900 QDF_STATUS status;
12901
12902 params.tso_enable = hdd_ctx->config->tso_enable;
12903 params.lro_enable = hdd_ctx->config->lro_enable;
12904#ifdef QCA_LL_TX_FLOW_CONTROL_V2
12905 params.tx_flow_stop_queue_threshold =
12906 hdd_ctx->config->TxFlowStopQueueThreshold;
12907 params.tx_flow_start_queue_offset =
12908 hdd_ctx->config->TxFlowStartQueueOffset;
12909#endif
12910 params.flow_steering_enable = hdd_ctx->config->flow_steering_enable;
12911 params.napi_enable = hdd_ctx->napi_enable;
12912 params.tcp_udp_checksumoffload =
12913 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
12914
12915 status = cdp_update_config_parameters(
12916 cds_get_context(QDF_MODULE_ID_SOC),
12917 &params);
12918 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070012919 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012920 return status;
12921 }
12922
12923 return 0;
12924}
12925
12926/**
Komal Seelamec702b02016-02-24 18:42:16 +053012927 * hdd_update_config() - Initialize driver per module ini parameters
12928 * @hdd_ctx: HDD Context
12929 *
12930 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012931 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053012932 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012933int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012934{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012935 int ret;
12936
Komal Seelamec702b02016-02-24 18:42:16 +053012937 hdd_update_ol_config(hdd_ctx);
12938 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012939 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
12940 ret = hdd_update_cds_config_ftm(hdd_ctx);
12941 else
12942 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080012943 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012944
12945 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053012946}
12947
Mukul Sharma9d797a02017-01-05 20:26:03 +053012948#ifdef FEATURE_WLAN_RA_FILTERING
12949/**
12950 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
12951 * @psoc_cfg: pmo psoc Configuration
12952 * @hdd_ctx: Pointer to hdd context
12953 *
12954 * Return: none
12955 */
12956static inline void hdd_ra_populate_pmo_config(
12957 struct pmo_psoc_cfg *psoc_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012958 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012959{
12960 psoc_cfg->ra_ratelimit_interval =
12961 hdd_ctx->config->RArateLimitInterval;
12962 psoc_cfg->ra_ratelimit_enable =
12963 hdd_ctx->config->IsRArateLimitEnabled;
12964}
12965#else
12966static inline void hdd_ra_populate_pmo_config(
12967 struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012968 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012969{
12970}
12971#endif
Will Huang3cd2b7c2017-11-17 13:16:56 +080012972
Mukul Sharma9d797a02017-01-05 20:26:03 +053012973/**
12974 * hdd_update_pmo_config - API to update pmo configuration parameters
12975 * @hdd_ctx: HDD context
12976 *
12977 * Return: void
12978 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012979static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012980{
Mukul Sharma9d797a02017-01-05 20:26:03 +053012981 struct pmo_psoc_cfg psoc_cfg;
12982 QDF_STATUS status;
12983
12984 /*
12985 * Value of hdd_ctx->wowEnable can be,
12986 * 0 - Disable both magic pattern match and pattern byte match.
12987 * 1 - Enable magic pattern match on all interfaces.
12988 * 2 - Enable pattern byte match on all interfaces.
12989 * 3 - Enable both magic patter and pattern byte match on
12990 * all interfaces.
12991 */
12992 psoc_cfg.magic_ptrn_enable =
12993 (hdd_ctx->config->wowEnable & 0x01) ? true : false;
12994 psoc_cfg.ptrn_match_enable_all_vdev =
12995 (hdd_ctx->config->wowEnable & 0x02) ? true : false;
Dustin Brownb9987af2018-03-01 17:15:11 -080012996 psoc_cfg.apf_enable = hdd_ctx->config->bpf_packet_filter_enable;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012997 psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
Dustin Brown1224e212017-05-12 14:02:12 -070012998 psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode;
Dustin Brownb9987af2018-03-01 17:15:11 -080012999 psoc_cfg.ns_offload_enable_dynamic = hdd_ctx->config->fhostNSOffload;
Mukul Sharma9d797a02017-01-05 20:26:03 +053013000 psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
Dustin Brownb9987af2018-03-01 17:15:11 -080013001 psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
Mukul Sharma9d797a02017-01-05 20:26:03 +053013002 psoc_cfg.ssdp = hdd_ctx->config->ssdp;
13003 psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
Dustin Brownb9987af2018-03-01 17:15:11 -080013004 psoc_cfg.active_mode_offload = hdd_ctx->config->active_mode_offload;
Mukul Sharma9d797a02017-01-05 20:26:03 +053013005 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080013006 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Mukul Sharma9223f232017-03-08 18:42:27 +053013007 psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
13008 psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
13009 psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
Dustin Brownb9987af2018-03-01 17:15:11 -080013010 psoc_cfg.power_save_mode = hdd_ctx->config->enablePowersaveOffload;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +053013011 psoc_cfg.auto_power_save_fail_mode =
13012 hdd_ctx->config->auto_pwr_save_fail_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053013013
13014 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053013015 hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx);
13016 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053013017
Dustin Brownb9987af2018-03-01 17:15:11 -080013018 status = ucfg_pmo_update_psoc_config(hdd_ctx->hdd_psoc, &psoc_cfg);
13019 if (QDF_IS_STATUS_ERROR(status))
13020 hdd_err("failed pmo psoc configuration; status:%d", status);
13021
13022 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053013023}
13024
Abhishek Singhb20db962017-03-03 21:28:46 +053013025#ifdef FEATURE_WLAN_SCAN_PNO
13026static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
13027 struct hdd_config *cfg)
13028{
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070013029 struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
13030
Abhishek Singhb20db962017-03-03 21:28:46 +053013031 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
13032 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
13033 pno_cfg->stationary_thresh = cfg->stationary_thresh;
13034 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
13035 pno_cfg->channel_prediction_full_scan =
13036 cfg->channel_prediction_full_scan;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070013037 mawc_cfg->enable = cfg->MAWCEnabled && cfg->mawc_nlo_enabled;
13038 mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
13039 mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
13040 mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
Abhishek Singhb20db962017-03-03 21:28:46 +053013041}
13042#else
13043static inline void
13044hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Jeff Johnson33a07922017-10-05 09:08:46 -070013045 struct hdd_config *cfg)
Abhishek Singhb20db962017-03-03 21:28:46 +053013046{
Abhishek Singhb20db962017-03-03 21:28:46 +053013047}
13048#endif
13049
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053013050void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
13051 struct hdd_config *cfg)
13052{
13053 uint8_t i = 0;
13054
13055 ie_whitelist->white_list = cfg->probe_req_ie_whitelist;
13056 if (!ie_whitelist->white_list)
13057 return;
13058
13059 ie_whitelist->ie_bitmap[0] = cfg->probe_req_ie_bitmap_0;
13060 ie_whitelist->ie_bitmap[1] = cfg->probe_req_ie_bitmap_1;
13061 ie_whitelist->ie_bitmap[2] = cfg->probe_req_ie_bitmap_2;
13062 ie_whitelist->ie_bitmap[3] = cfg->probe_req_ie_bitmap_3;
13063 ie_whitelist->ie_bitmap[4] = cfg->probe_req_ie_bitmap_4;
13064 ie_whitelist->ie_bitmap[5] = cfg->probe_req_ie_bitmap_5;
13065 ie_whitelist->ie_bitmap[6] = cfg->probe_req_ie_bitmap_6;
13066 ie_whitelist->ie_bitmap[7] = cfg->probe_req_ie_bitmap_7;
13067
13068 ie_whitelist->num_vendor_oui = cfg->no_of_probe_req_ouis;
13069 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
13070 ie_whitelist->voui[i] = cfg->probe_req_voui[i];
13071}
13072
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053013073uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
13074{
13075 uint8_t i, score;
13076
13077 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
13078 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
13079 if (score > MAX_INDEX_SCORE)
13080 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
13081 MAX_INDEX_SCORE, i);
13082 }
13083
13084 return per_index_score;
13085}
13086
13087/**
13088 * hdd_update_score_config - API to update candidate scoring related params
13089 * configuration parameters
13090 * @score_config: score config to update
13091 * @cfg: config params
13092 *
13093 * Return: 0 if success else err
13094 */
13095static void hdd_update_score_config(
13096 struct scoring_config *score_config, struct hdd_config *cfg)
13097{
13098 int total_weight;
13099
13100 score_config->weight_cfg.rssi_weightage = cfg->rssi_weightage;
13101 score_config->weight_cfg.ht_caps_weightage = cfg->ht_caps_weightage;
13102 score_config->weight_cfg.vht_caps_weightage =
13103 cfg->vht_caps_weightage;
13104 score_config->weight_cfg.he_caps_weightage =
13105 cfg->he_caps_weightage;
13106 score_config->weight_cfg.chan_width_weightage =
13107 cfg->chan_width_weightage;
13108 score_config->weight_cfg.chan_band_weightage =
13109 cfg->chan_band_weightage;
13110 score_config->weight_cfg.nss_weightage = cfg->nss_weightage;
13111 score_config->weight_cfg.beamforming_cap_weightage =
13112 cfg->beamforming_cap_weightage;
13113 score_config->weight_cfg.pcl_weightage = cfg->pcl_weightage;
13114 score_config->weight_cfg.channel_congestion_weightage =
13115 cfg->channel_congestion_weightage;
13116 score_config->weight_cfg.oce_wan_weightage = cfg->oce_wan_weightage;
13117
13118 total_weight = score_config->weight_cfg.rssi_weightage +
13119 score_config->weight_cfg.ht_caps_weightage +
13120 score_config->weight_cfg.vht_caps_weightage +
13121 score_config->weight_cfg.he_caps_weightage +
13122 score_config->weight_cfg.chan_width_weightage +
13123 score_config->weight_cfg.chan_band_weightage +
13124 score_config->weight_cfg.nss_weightage +
13125 score_config->weight_cfg.beamforming_cap_weightage +
13126 score_config->weight_cfg.pcl_weightage +
13127 score_config->weight_cfg.channel_congestion_weightage +
13128 score_config->weight_cfg.oce_wan_weightage;
13129
13130 if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
13131 hdd_err("total weight is greater than %d fallback to default values",
13132 BEST_CANDIDATE_MAX_WEIGHT);
13133
13134 score_config->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE;
13135 score_config->weight_cfg.ht_caps_weightage =
13136 HT_CAPABILITY_WEIGHTAGE;
13137 score_config->weight_cfg.vht_caps_weightage = VHT_CAP_WEIGHTAGE;
13138 score_config->weight_cfg.he_caps_weightage = HE_CAP_WEIGHTAGE;
13139 score_config->weight_cfg.chan_width_weightage =
13140 CHAN_WIDTH_WEIGHTAGE;
13141 score_config->weight_cfg.chan_band_weightage =
13142 CHAN_BAND_WEIGHTAGE;
13143 score_config->weight_cfg.nss_weightage = NSS_WEIGHTAGE;
13144 score_config->weight_cfg.beamforming_cap_weightage =
13145 BEAMFORMING_CAP_WEIGHTAGE;
13146 score_config->weight_cfg.pcl_weightage = PCL_WEIGHT;
13147 score_config->weight_cfg.channel_congestion_weightage =
13148 CHANNEL_CONGESTION_WEIGHTAGE;
13149 score_config->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
13150 }
13151
13152 score_config->bandwidth_weight_per_index =
13153 hdd_limit_max_per_index_score(
13154 cfg->bandwidth_weight_per_index);
13155 score_config->nss_weight_per_index =
13156 hdd_limit_max_per_index_score(cfg->nss_weight_per_index);
13157 score_config->band_weight_per_index =
13158 hdd_limit_max_per_index_score(cfg->band_weight_per_index);
13159
13160 score_config->rssi_score.best_rssi_threshold =
13161 cfg->best_rssi_threshold;
13162 score_config->rssi_score.good_rssi_threshold =
13163 cfg->good_rssi_threshold;
13164 score_config->rssi_score.bad_rssi_threshold =
13165 cfg->bad_rssi_threshold;
13166 score_config->rssi_score.good_rssi_pcnt = cfg->good_rssi_pcnt;
13167 score_config->rssi_score.bad_rssi_pcnt = cfg->bad_rssi_pcnt;
13168 score_config->rssi_score.good_rssi_bucket_size =
13169 cfg->good_rssi_bucket_size;
13170 score_config->rssi_score.bad_rssi_bucket_size =
13171 cfg->bad_rssi_bucket_size;
13172 score_config->rssi_score.rssi_pref_5g_rssi_thresh =
13173 cfg->rssi_pref_5g_rssi_thresh;
13174
13175 score_config->esp_qbss_scoring.num_slot = cfg->num_esp_qbss_slots;
13176 score_config->esp_qbss_scoring.score_pcnt3_to_0 =
13177 hdd_limit_max_per_index_score(
13178 cfg->esp_qbss_score_slots3_to_0);
13179 score_config->esp_qbss_scoring.score_pcnt7_to_4 =
13180 hdd_limit_max_per_index_score(
13181 cfg->esp_qbss_score_slots7_to_4);
13182 score_config->esp_qbss_scoring.score_pcnt11_to_8 =
13183 hdd_limit_max_per_index_score(
13184 cfg->esp_qbss_score_slots11_to_8);
13185 score_config->esp_qbss_scoring.score_pcnt15_to_12 =
13186 hdd_limit_max_per_index_score(
13187 cfg->esp_qbss_score_slots15_to_12);
13188
13189 score_config->oce_wan_scoring.num_slot = cfg->num_oce_wan_slots;
13190 score_config->oce_wan_scoring.score_pcnt3_to_0 =
13191 hdd_limit_max_per_index_score(
13192 cfg->oce_wan_score_slots3_to_0);
13193 score_config->oce_wan_scoring.score_pcnt7_to_4 =
13194 hdd_limit_max_per_index_score(
13195 cfg->oce_wan_score_slots7_to_4);
13196 score_config->oce_wan_scoring.score_pcnt11_to_8 =
13197 hdd_limit_max_per_index_score(
13198 cfg->oce_wan_score_slots11_to_8);
13199 score_config->oce_wan_scoring.score_pcnt15_to_12 =
13200 hdd_limit_max_per_index_score(
13201 cfg->oce_wan_score_slots15_to_12);
13202
13203
13204 score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
13205 score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
13206 score_config->nss = cfg->enable2x2 ? 2 : 1;
13207
13208 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
13209 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
13210 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
13211 score_config->he_cap = 1;
13212
13213 if (score_config->he_cap ||
13214 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
13215 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
13216 score_config->vht_cap = 1;
13217
13218 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
13219 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
13220 score_config->ht_cap = 1;
13221
13222 if (score_config->vht_cap && cfg->enableVhtFor24GHzBand)
13223 score_config->vht_24G_cap = 1;
13224
13225 if (cfg->enableTxBF)
13226 score_config->beamformee_cap = 1;
13227
13228}
13229
Abhishek Singh257a9482017-03-06 16:52:39 +053013230/**
bings81fe50a2017-11-27 14:33:26 +080013231 * hdd_update_dfs_config() - API to update dfs configuration parameters.
13232 * @hdd_ctx: HDD context
13233 *
13234 * Return: 0 if success else err
13235 */
13236static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
13237{
13238 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
13239 struct hdd_config *cfg = hdd_ctx->config;
13240 struct dfs_user_config dfs_cfg;
13241 QDF_STATUS status;
13242
13243 dfs_cfg.dfs_is_phyerr_filter_offload = !!cfg->fDfsPhyerrFilterOffload;
13244 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
13245 if (QDF_IS_STATUS_ERROR(status)) {
13246 hdd_err("failed dfs psoc configuration");
13247 return -EINVAL;
13248 }
13249
13250 return 0;
13251}
13252
13253/**
Abhishek Singh257a9482017-03-06 16:52:39 +053013254 * hdd_update_scan_config - API to update scan configuration parameters
13255 * @hdd_ctx: HDD context
13256 *
13257 * Return: 0 if success else err
13258 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013259static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053013260{
13261 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
13262 struct scan_user_cfg scan_cfg;
13263 struct hdd_config *cfg = hdd_ctx->config;
13264 QDF_STATUS status;
13265
13266 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
13267 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
13268 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
13269 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
13270 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
13271 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
13272 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053013273 /* convert to ms */
13274 scan_cfg.scan_cache_aging_time =
13275 cfg->scanAgingTimeout * 1000;
13276 scan_cfg.prefer_5ghz = cfg->nRoamPrefer5GHz;
13277 scan_cfg.select_5ghz_margin = cfg->nSelect5GHzMargin;
13278 scan_cfg.scan_bucket_threshold = cfg->first_scan_bucket_threshold;
13279 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053013280 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053013281 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Jeff Johnson81c00d02017-11-07 12:34:36 -080013282 scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
13283 scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
Abhishek Singhb58164a2017-07-19 18:47:23 +053013284 scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
Kiran Kumar Lokered547fdd2017-09-13 17:20:55 -070013285 scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
Abhishek Singhc87bb042018-01-30 17:10:42 +053013286 scan_cfg.sta_miracast_mcc_rest_time =
13287 cfg->sta_miracast_mcc_rest_time_val;
Abhishek Singh257a9482017-03-06 16:52:39 +053013288
Abhishek Singhb20db962017-03-03 21:28:46 +053013289 hdd_update_pno_config(&scan_cfg.pno_cfg, cfg);
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053013290 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, cfg);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053013291 hdd_update_score_config(&scan_cfg.score_config, cfg);
Abhishek Singhb20db962017-03-03 21:28:46 +053013292
Abhishek Singh257a9482017-03-06 16:52:39 +053013293 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
13294 if (status != QDF_STATUS_SUCCESS) {
13295 hdd_err("failed pmo psoc configuration");
13296 return -EINVAL;
13297 }
13298
13299 return 0;
13300}
Abhishek Singh257a9482017-03-06 16:52:39 +053013301
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013302int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053013303{
13304 int ret;
13305
13306 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053013307 if (ret)
13308 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013309
Abhishek Singh257a9482017-03-06 16:52:39 +053013310 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080013311 if (ret)
13312 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013313
Frank Liud4b2fa02017-03-29 11:46:48 +080013314 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013315 if (ret)
13316 return ret;
13317
13318 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080013319 if (ret)
13320 return ret;
13321
13322 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053013323
13324 return ret;
13325}
13326
Agrawal Ashish65634612016-08-18 13:24:32 +053013327/**
13328 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
13329 * @mode : cfg80211 DFS mode
13330 *
13331 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
13332 */
13333enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
13334{
13335 switch (mode) {
13336 case DFS_MODE_ENABLE:
13337 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013338 case DFS_MODE_DISABLE:
13339 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013340 case DFS_MODE_DEPRIORITIZE:
13341 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013342 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013343 hdd_debug("ACS dfs mode is NONE");
13344 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013345 }
13346}
13347
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013348/**
13349 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
13350 * @hddctx: pointer to hdd context
13351 * @set_value: enable/disable
13352 *
13353 * When Host sends vendor command enable, FW will send *ONE* CA ind to
13354 * Host(even though it is duplicate). When Host send vendor command
13355 * disable,FW doesn't perform any action. Whenever any change in
13356 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
13357 *
13358 * return - 0 on success, appropriate error values on failure.
13359 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013360int hdd_enable_disable_ca_event(struct hdd_context *hddctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013361{
13362 QDF_STATUS status;
13363
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013364 if (0 != wlan_hdd_validate_context(hddctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013365 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013366
13367 if (!hddctx->config->goptimize_chan_avoid_event) {
13368 hdd_warn("goptimize_chan_avoid_event ini param disabled");
13369 return -EINVAL;
13370 }
13371
13372 status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
13373 if (!QDF_IS_STATUS_SUCCESS(status)) {
13374 hdd_err("Failed to send chan avoid command to SME");
13375 return -EINVAL;
13376 }
13377 return 0;
13378}
Agrawal Ashish65634612016-08-18 13:24:32 +053013379
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013380/**
13381 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
13382 * @value: value to set
13383 *
13384 * This function will set the passed value to roaming in progress flag.
13385 *
13386 * Return: None
13387 */
13388void hdd_set_roaming_in_progress(bool value)
13389{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013390 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013391
13392 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13393 if (!hdd_ctx) {
13394 hdd_err("HDD context is NULL");
13395 return;
13396 }
13397
13398 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013399 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013400}
13401
13402/**
13403 * hdd_is_roaming_in_progress() - check if roaming is in progress
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013404 * @adapter - HDD adapter
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013405 *
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013406 * Return: true if roaming is in progress for STA type, else false
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013407 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013408bool hdd_is_roaming_in_progress(struct hdd_adapter *adapter)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013409{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013410 struct hdd_context *hdd_ctx;
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013411 bool ret_status = false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013412
13413 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13414 if (!hdd_ctx) {
13415 hdd_err("HDD context is NULL");
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013416 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013417 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013418 hdd_debug("dev mode = %d, roaming_in_progress = %d",
13419 adapter->device_mode, hdd_ctx->roaming_in_progress);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013420 ret_status = ((adapter->device_mode == QDF_STA_MODE) &&
13421 hdd_ctx->roaming_in_progress);
13422
13423 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013424}
13425
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013426/**
13427 * hdd_is_connection_in_progress() - check if connection is in
13428 * progress
13429 * @session_id: session id
13430 * @reason: scan reject reason
13431 *
13432 * Go through each adapter and check if Connection is in progress
13433 *
13434 * Return: true if connection is in progress else false
13435 */
13436bool hdd_is_connection_in_progress(uint8_t *session_id,
13437 enum scan_reject_states *reason)
13438{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070013439 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070013440 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013441 uint8_t sta_id = 0;
13442 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013443 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013444
13445 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13446 if (!hdd_ctx) {
13447 hdd_err("HDD context is NULL");
13448 return false;
13449 }
13450
Dustin Brown920397d2017-12-13 16:27:50 -080013451 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya929afa42018-06-01 15:04:44 -070013452 hdd_debug("Adapter with device mode %s(%d) exists",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013453 hdd_device_mode_to_string(adapter->device_mode),
13454 adapter->device_mode);
13455 if (((QDF_STA_MODE == adapter->device_mode)
13456 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
13457 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
13458 && (eConnectionState_Connecting ==
13459 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
13460 conn_info.connState)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013461 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013462 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013463 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013464 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013465 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013466 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013467 }
13468 return true;
13469 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070013470 /*
13471 * sme_neighbor_middle_of_roaming is for LFR2
13472 * hdd_is_roaming_in_progress is for LFR3
13473 */
13474 if (((QDF_STA_MODE == adapter->device_mode) &&
13475 sme_neighbor_middle_of_roaming(
13476 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013477 adapter->session_id)) ||
Archana Ramachandran62886ce2017-03-24 14:46:32 -070013478 hdd_is_roaming_in_progress(adapter)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013479 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013480 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013481 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013482 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013483 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013484 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013485 }
13486 return true;
13487 }
13488 if ((QDF_STA_MODE == adapter->device_mode) ||
13489 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
13490 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
13491 hdd_sta_ctx =
13492 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
13493 if ((eConnectionState_Associated ==
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053013494 hdd_sta_ctx->conn_info.connState)
13495 && sme_is_sta_key_exchange_in_progress(
13496 hdd_ctx->hHal, adapter->session_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013497 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070013498 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013499 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013500 " is in middle of WPS/EAPOL exchange.",
13501 MAC_ADDR_ARRAY(sta_mac));
13502 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013503 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013504 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013505 }
13506 return true;
13507 }
13508 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
13509 (QDF_P2P_GO_MODE == adapter->device_mode)) {
13510 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
13511 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013512 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013513 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013514 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013515 continue;
13516
13517 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013518 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070013519 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013520 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013521 " of SAP/GO is in middle of WPS/EAPOL exchange",
13522 MAC_ADDR_ARRAY(sta_mac));
13523 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013524 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013525 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013526 }
13527 return true;
13528 }
13529 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013530 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013531 return true;
13532 }
13533 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013534 }
Dustin Brown920397d2017-12-13 16:27:50 -080013535
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013536 return false;
13537}
13538
13539/**
13540 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070013541 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013542 *
13543 * Return: None
13544 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013545void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013546{
Jeff Johnson87251032017-08-29 13:31:11 -070013547 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013548 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013549 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013550 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnsone4c11db2018-05-05 23:22:32 -070013551 tsap_config_t *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013552 void *sap_ctx;
13553
13554 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070013555 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013556 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013557
13558 mutex_lock(&hdd_ctx->sap_lock);
13559 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
13560 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013561 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
13562 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
13563 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
13564 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053013565 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013566 qdf_stop_bss_event,
13567 SME_CMD_TIMEOUT_VALUE);
13568
13569 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013570 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013571 goto end;
13572 }
13573 }
13574 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013575 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -070013576 ap_adapter->device_mode, ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013577 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013578 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070013579 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013580
13581 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013582 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013583 wlansap_reset_sap_config_add_ie(sap_config,
13584 eUPDATE_IE_ALL);
13585 goto end;
13586 }
13587
13588 qdf_event_reset(&hostapd_state->qdf_event);
13589 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
13590 sap_config,
13591 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013592 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013593 wlansap_reset_sap_config_add_ie(sap_config,
13594 eUPDATE_IE_ALL);
13595 goto end;
13596 }
13597
Jeff Johnson6867ec32017-09-29 20:30:20 -070013598 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013599 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053013600 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013601 SME_CMD_TIMEOUT_VALUE);
13602 wlansap_reset_sap_config_add_ie(sap_config,
13603 eUPDATE_IE_ALL);
13604 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013605 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013606 goto end;
13607 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070013608 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013609 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013610 if (hostapd_state->bss_state == BSS_START) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013611 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
13612 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070013613 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013614 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013615 ap_adapter->device_mode,
13616 true);
13617 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013618 }
13619end:
13620 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013621}
13622
13623/**
13624 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
13625 * with non dfs acs
13626 *
13627 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
13628 *
13629 * Return: None
13630 */
13631void hdd_check_and_restart_sap_with_non_dfs_acs(void)
13632{
Jeff Johnson9d295242017-08-29 14:39:48 -070013633 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013634 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070013635 struct cds_context *cds_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013636
13637 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13638 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013639 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013640 return;
13641 }
13642
13643 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
13644 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013645 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013646 return;
13647 }
13648
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013649 if (policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc)
13650 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013651 hdd_info("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013652 return;
13653 }
13654
13655 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070013656 if (ap_adapter != NULL && test_bit(SOFTAP_BSS_STARTED,
13657 &ap_adapter->event_flags) &&
13658 wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Jeff Johnsonb9424862017-10-30 08:49:35 -070013659 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013660
Jeff Johnson6867ec32017-09-29 20:30:20 -070013661 hdd_warn("STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS");
Jeff Johnsonb9424862017-10-30 08:49:35 -070013662 ap_adapter->session.ap.sap_config.channel =
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013663 AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -070013664 ap_adapter->session.ap.sap_config.
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013665 acs_cfg.acs_mode = true;
13666
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013667 hdd_restart_sap(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013668 }
13669}
13670
13671/**
13672 * hdd_set_connection_in_progress() - to set the connection in
13673 * progress flag
13674 * @value: value to set
13675 *
13676 * This function will set the passed value to connection in progress flag.
13677 * If value is previously being set to true then no need to set it again.
13678 *
13679 * Return: true if value is being set correctly and false otherwise.
13680 */
13681bool hdd_set_connection_in_progress(bool value)
13682{
13683 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013684 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013685
13686 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13687 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013688 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013689 return false;
13690 }
13691
13692 qdf_spin_lock(&hdd_ctx->connection_status_lock);
13693 /*
13694 * if the value is set to true previously and if someone is
13695 * trying to make it true again then it could be some race
13696 * condition being triggered. Avoid this situation by returning
13697 * false
13698 */
13699 if (hdd_ctx->connection_in_progress && value)
13700 status = false;
13701 else
13702 hdd_ctx->connection_in_progress = value;
13703 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
13704 return status;
13705}
13706
Jeff Johnson9d295242017-08-29 14:39:48 -070013707int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013708{
13709 if (!adapter) {
13710 hdd_err("Invalid adapter");
13711 return -EINVAL;
13712 }
13713 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013714 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013715 WMA_VDEV_MCC_SET_TIME_QUOTA,
13716 set_value, VDEV_CMD);
13717 return 0;
13718
13719}
13720
Jeff Johnson9d295242017-08-29 14:39:48 -070013721int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013722{
13723 if (!adapter) {
13724 hdd_err("Invalid adapter");
13725 return -EINVAL;
13726 }
13727
13728 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013729 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013730 WMA_VDEV_MCC_SET_TIME_LATENCY,
13731 set_value, VDEV_CMD);
13732 return 0;
13733}
13734
Jeff Johnson9d295242017-08-29 14:39:48 -070013735struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013736 *psoc, uint8_t vdev_id)
13737{
Jeff Johnson9d295242017-08-29 14:39:48 -070013738 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013739 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013740
13741 /*
13742 * Currently PSOC is not being used. But this logic will
13743 * change once we have the converged implementation of
13744 * HDD context per PSOC in place. This would break if
13745 * multiple vdev objects reuse the vdev id.
13746 */
13747 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
13748 if (!adapter)
13749 hdd_err("Get adapter by vdev id failed");
13750
13751 return adapter;
13752}
13753
Jeff Johnson9d295242017-08-29 14:39:48 -070013754int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013755 int8_t *rssi, int8_t *snr)
13756{
13757 QDF_STATUS status;
Jeff Johnson025618c2018-03-18 14:41:00 -070013758 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013759
Jeff Johnson025618c2018-03-18 14:41:00 -070013760 roam_profile = hdd_roam_profile(adapter);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013761 status = sme_get_rssi_snr_by_bssid(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson025618c2018-03-18 14:41:00 -070013762 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013763 if (QDF_STATUS_SUCCESS != status) {
13764 hdd_warn("sme_get_rssi_snr_by_bssid failed");
13765 return -EINVAL;
13766 }
13767
13768 return 0;
13769}
13770
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013771/**
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013772 * hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
13773 * @adapter - HDD adapter
13774 * @tos - type of service
13775 * @status - status of the traffic
13776 *
13777 * Return: 0 on success and non zero value on failure
13778 */
13779
13780int hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter, enum tos tos,
13781 bool is_tos_active)
13782{
13783 int ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013784 struct hdd_context *hdd_ctx;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013785 uint32_t max_off_chan_time = 0;
13786 QDF_STATUS status;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013787 int ret;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013788 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013789
13790 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13791 ret = wlan_hdd_validate_context(hdd_ctx);
13792
13793 if (ret < 0) {
13794 hdd_err("failed to set limit off chan params");
13795 return ret;
13796 }
13797
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013798 ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
13799
13800 if (is_tos_active)
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013801 adapter->active_ac |= ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013802 else
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013803 adapter->active_ac &= ~ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013804
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013805 if (adapter->active_ac) {
13806 if (adapter->active_ac & HDD_AC_VO_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013807 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013808 limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
13809 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13810 PM_LATENCY);
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013811 } else if (adapter->active_ac & HDD_AC_VI_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013812 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013813 limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
13814 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13815 PM_LATENCY);
13816 } else {
13817 /*ignore this command if only BE/BK is active */
13818 is_tos_active = false;
13819 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13820 hdd_ctx->config->conc_system_pref);
13821 }
13822 } else {
13823 /* No active tos */
13824 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13825 hdd_ctx->config->conc_system_pref);
13826 }
13827
Jeff Johnson1b780e42017-10-31 14:11:45 -070013828 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013829 is_tos_active, max_off_chan_time,
13830 hdd_ctx->config->nRestTimeConc, true);
13831 if (!QDF_IS_STATUS_SUCCESS(status)) {
13832 hdd_err("failed to set limit off chan params");
13833 ret = -EINVAL;
13834 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013835
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013836 return ret;
13837}
13838
13839/**
13840 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
13841 * @adapter - HDD adapter
13842 *
13843 * Return: 0 on success and non zero value on failure
13844 */
13845int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
13846{
13847 struct hdd_context *hdd_ctx;
13848 int ret;
13849 QDF_STATUS status;
13850 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
13851
13852 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13853 ret = wlan_hdd_validate_context(hdd_ctx);
13854 if (ret < 0)
13855 return ret;
13856
13857 /* set the system preferece to default */
13858 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13859 hdd_ctx->config->conc_system_pref);
13860
13861 /* clear the bitmap */
13862 adapter->active_ac = 0;
13863
13864 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson1b780e42017-10-31 14:11:45 -070013865 adapter->session_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013866
Jeff Johnson1b780e42017-10-31 14:11:45 -070013867 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013868 false, 0, 0, false);
13869 if (!QDF_IS_STATUS_SUCCESS(status)) {
13870 hdd_err("failed to reset limit off chan params");
13871 ret = -EINVAL;
13872 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013873
13874 return ret;
13875}
13876
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013877/**
13878 * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
13879 * @drv_op: Enum indicating driver op
13880 *
13881 * Return: none
13882 */
13883void hdd_start_driver_ops_timer(int drv_op)
13884{
13885 memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
13886 switch (drv_op) {
13887 case eHDD_DRV_OP_PROBE:
13888 memcpy(drv_ops_string, "probe", sizeof("probe"));
13889 break;
13890 case eHDD_DRV_OP_REMOVE:
13891 memcpy(drv_ops_string, "remove", sizeof("remove"));
13892 break;
13893 case eHDD_DRV_OP_SHUTDOWN:
13894 memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
13895 break;
13896 case eHDD_DRV_OP_REINIT:
13897 memcpy(drv_ops_string, "reinit", sizeof("reinit"));
13898 break;
Arunk Khandavallie9ef42a2017-10-04 14:49:51 +053013899 case eHDD_DRV_OP_IFF_UP:
13900 memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
13901 break;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013902 }
13903
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013904 hdd_drv_ops_task = current;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013905 qdf_timer_start(&hdd_drv_ops_inactivity_timer,
13906 HDD_OPS_INACTIVITY_TIMEOUT);
13907}
13908
13909/**
13910 * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
13911 *
13912 * Return: none
13913 */
13914void hdd_stop_driver_ops_timer(void)
13915{
13916 qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
13917}
13918
13919/**
13920 * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
13921 * inactivity timer
13922 *
13923 * Return: None
13924 */
13925void hdd_drv_ops_inactivity_handler(void)
13926{
13927 hdd_err("%s: %d Sec timer expired while in .%s",
13928 __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
13929
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013930 if (hdd_drv_ops_task) {
13931 printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
13932 qdf_print_thread_trace(hdd_drv_ops_task);
13933 } else {
13934 hdd_err("hdd_drv_ops_task is null");
13935 }
13936
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013937 /* Driver shutdown is stuck, no recovery possible at this point */
13938 if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
13939 sizeof("shutdown")))
13940 QDF_BUG(0);
13941
Rajeev Kumar1e57b9c2018-01-04 16:17:10 -080013942 if (cds_is_fw_down()) {
13943 hdd_err("FW is down");
13944 return;
13945 }
13946
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013947 if (cds_is_self_recovery_enabled())
Anurag Chouhan4085ff72017-10-05 18:09:56 +053013948 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013949 else
13950 QDF_BUG(0);
13951}
13952
Sravan Kumar Kairamd80c7662017-10-03 16:11:05 +053013953void hdd_pld_ipa_uc_shutdown_pipes(void)
13954{
13955 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13956
13957 if (!hdd_ctx)
13958 return;
13959
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +053013960 ucfg_ipa_uc_force_pipe_shutdown(hdd_ctx->hdd_pdev);
Sravan Kumar Kairamd80c7662017-10-03 16:11:05 +053013961}
13962
Yun Parkff6a16a2017-09-26 16:38:18 -070013963/**
13964 * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
13965 * @struct hdd_context *hdd_ctx
13966 * @struct hdd_adapter *padapter
13967 * @bool enble
13968 *
13969 * Return: none
13970 */
13971void hdd_set_rx_mode_rps(bool enable)
13972{
13973 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070013974 struct hdd_context *hdd_ctx;
13975 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070013976
Ryan Hsu0e878fa2018-05-04 15:22:09 -070013977 if (!cds_cfg)
13978 return;
13979
13980 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13981 if (!hdd_ctx)
13982 return;
13983
13984 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
13985 if (!adapter)
13986 return;
13987
13988 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070013989 if (enable && !cds_cfg->rps_enabled)
13990 hdd_send_rps_ind(adapter);
13991 else if (!enable && cds_cfg->rps_enabled)
13992 hdd_send_rps_disable_ind(adapter);
13993 }
13994}
13995
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +053013996bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx)
13997{
13998 struct hdd_adapter *adapter = NULL;
13999
14000 hdd_for_each_adapter(hdd_ctx, adapter) {
14001 if ((adapter->device_mode == QDF_STA_MODE ||
14002 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
14003 qdf_atomic_test_bit(DEVICE_IFACE_OPENED,
14004 &adapter->event_flags)){
14005 return true;
14006 }
14007 }
14008
14009 return false;
14010}
14011
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014012/* Register the module init/exit functions */
14013module_init(hdd_module_init);
14014module_exit(hdd_module_exit);
14015
14016MODULE_LICENSE("Dual BSD/GPL");
14017MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14018MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14019
Srinivas Girigowda841da292018-02-21 16:33:00 -080014020static const struct kernel_param_ops con_mode_ops = {
14021 .set = con_mode_handler,
14022 .get = param_get_int,
14023};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014024
Srinivas Girigowda841da292018-02-21 16:33:00 -080014025static const struct kernel_param_ops con_mode_ftm_ops = {
14026 .set = con_mode_handler_ftm,
14027 .get = param_get_int,
14028};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014029
Srinivas Girigowda841da292018-02-21 16:33:00 -080014030static const struct kernel_param_ops con_mode_monitor_ops = {
14031 .set = con_mode_handler_monitor,
14032 .get = param_get_int,
14033};
Ravi Joshia307f632017-07-17 23:41:41 -070014034
Srinivas Girigowda841da292018-02-21 16:33:00 -080014035static const struct kernel_param_ops fwpath_ops = {
14036 .set = fwpath_changed_handler,
14037 .get = param_get_string,
14038};
14039
14040module_param_cb(con_mode, &con_mode_ops, &con_mode,
14041 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
14042
14043module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
14044 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
14045
14046module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
14047 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
14048
14049module_param_cb(fwpath, &fwpath_ops, &fwpath,
14050 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014051
14052module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
14053
14054module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
14055
14056module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);