blob: b50dfe0bc3c414158cff36aa9d3535569db308d1 [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 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_main.c
30 *
31 * WLAN Host Device Driver implementation
32 *
33 */
34
35/* Include Files */
36#include <wlan_hdd_includes.h>
37#include <cds_api.h>
38#include <cds_sched.h>
Arun Khandavallifae92942016-08-01 13:31:08 +053039#include <linux/cpu.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include <linux/etherdevice.h>
41#include <linux/firmware.h>
42#include <wlan_hdd_tx_rx.h>
43#include <wni_api.h>
44#include <wlan_hdd_cfg.h>
45#include <wlan_ptt_sock_svc.h>
46#include <dbglog_host.h>
47#include <wlan_logging_sock_svc.h>
48#include <wlan_hdd_wowl.h>
49#include <wlan_hdd_misc.h>
50#include <wlan_hdd_wext.h>
51#include "wlan_hdd_trace.h"
52#include "wlan_hdd_ioctl.h"
53#include "wlan_hdd_ftm.h"
54#include "wlan_hdd_power.h"
55#include "wlan_hdd_stats.h"
Prashanth Bhatta527fd752016-04-28 12:35:23 -070056#include "wlan_hdd_scan.h"
Jeff Johnsonce0032c2017-01-20 07:18:27 -080057#include "wlan_hdd_request_manager.h"
Dustin Brown26b3d042017-12-21 11:13:27 -080058#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4bc0a622017-12-06 15:56:50 -080059#include "qdf_debug_domain.h"
Dustin Brown26b3d042017-12-21 11:13:27 -080060#endif
Dustin Brownd4241942018-02-26 12:51:37 -080061#include "qdf_str.h"
62#include "qdf_trace.h"
63#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070064#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080065#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070066#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067
68#include <net/addrconf.h>
69#include <linux/wireless.h>
70#include <net/cfg80211.h>
71#include <linux/inetdevice.h>
72#include <net/addrconf.h>
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_ext_scan.h"
75#include "wlan_hdd_p2p.h"
76#include <linux/rtnetlink.h>
77#include "sap_api.h"
78#include <linux/semaphore.h>
79#include <linux/ctype.h>
80#include <linux/compat.h>
81#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082#include <soc/qcom/subsystem_restart.h>
83#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084#include <wlan_hdd_hostapd.h>
85#include <wlan_hdd_softap_tx_rx.h>
86#include "cfg_api.h"
87#include "qwlan_version.h"
88#include "wma_types.h"
89#include "wlan_hdd_tdls.h"
90#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053091#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070093#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070094#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080095#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096#include "wlan_hdd_nan.h"
97#include "wlan_hdd_debugfs.h"
98#include "wlan_hdd_driver_ops.h"
99#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +0530100#include "wlan_hdd_data_stall_detection.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101
102#include <wlan_hdd_ipa.h>
103#include "hif.h"
104#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800105#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700106#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530107#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700108#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700109#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530110#include "nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700111#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530112#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800113#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800114#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530115#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800116#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800117#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530118#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530119#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800120#include "os_if_wifi_pos.h"
121#include "wifi_pos_api.h"
122#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800123#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700124#include "os_if_nan.h"
125#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700126#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800127#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700128#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530129#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530130#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700131#include <cdp_txrx_cmn_struct.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800132#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530133#include "wlan_disa_ucfg_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530134#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530135#include <target_if.h>
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530136
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530137#ifdef CNSS_GENL
138#include <net/cnss_nl.h>
139#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800140#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800141#include "wlan_ocb_ucfg_api.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530142
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530143#include <wlan_green_ap_ucfg_api.h>
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800144#include <wlan_hdd_spectralscan.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800145#ifdef MODULE
146#define WLAN_MODULE_NAME module_name(THIS_MODULE)
147#else
148#define WLAN_MODULE_NAME "wlan"
149#endif
150
151#ifdef TIMER_MANAGER
152#define TIMER_MANAGER_STR " +TIMER_MANAGER"
153#else
154#define TIMER_MANAGER_STR ""
155#endif
156
157#ifdef MEMORY_DEBUG
158#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
159#else
160#define MEMORY_DEBUG_STR ""
161#endif
162
Dustin Brownc1034df2018-02-07 14:51:32 -0800163#ifdef PANIC_ON_BUG
164#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
165#else
166#define PANIC_ON_BUG_STR ""
167#endif
168
Sachin Ahujadddd2632017-03-07 19:07:24 +0530169int wlan_start_ret_val;
170static DECLARE_COMPLETION(wlan_start_comp);
171static unsigned int dev_num = 1;
172static struct cdev wlan_hdd_state_cdev;
173static struct class *class;
174static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530175#ifndef MODULE
176static struct gwlan_loader *wlan_loader;
177static ssize_t wlan_boot_cb(struct kobject *kobj,
178 struct kobj_attribute *attr,
179 const char *buf, size_t count);
180struct gwlan_loader {
181 bool loaded_state;
182 struct kobject *boot_wlan_obj;
183 struct attribute_group *attr_group;
184};
185
186static struct kobj_attribute wlan_boot_attribute =
187 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
188
189static struct attribute *attrs[] = {
190 &wlan_boot_attribute.attr,
191 NULL,
192};
193
194#define MODULE_INITIALIZED 1
195#endif
196
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530197#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
198#define MAX_OPS_NAME_STRING_SIZE 20
Rajeev Kumar6d0b2ea2017-12-26 17:55:33 -0800199#define RATE_LIMIT_ERROR_LOG (256)
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530200
201static qdf_timer_t hdd_drv_ops_inactivity_timer;
Dustin Brown45ed4bb2017-12-18 12:00:13 -0800202static struct task_struct *hdd_drv_ops_task;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530203static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205/* the Android framework expects this param even though we don't use it */
206#define BUF_LEN 20
207static char fwpath_buffer[BUF_LEN];
208static struct kparam_string fwpath = {
209 .string = fwpath_buffer,
210 .maxlen = BUF_LEN,
211};
212
213static char *country_code;
214static int enable_11d = -1;
215static int enable_dfs_chan_scan = -1;
216
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217/*
218 * spinlock for synchronizing asynchronous request/response
219 * (full description of use in wlan_hdd_main.h)
220 */
221DEFINE_SPINLOCK(hdd_context_lock);
Arunk Khandavalli16d84252017-06-21 15:26:29 +0530222DEFINE_MUTEX(hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800224#define WLAN_NLINK_CESIUM 30
225
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530226static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227
228#define WOW_MAX_FILTER_LISTS 1
229#define WOW_MAX_FILTERS_PER_LIST 4
230#define WOW_MIN_PATTERN_SIZE 6
231#define WOW_MAX_PATTERN_SIZE 64
232
233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
234static const struct wiphy_wowlan_support wowlan_support_reg_init = {
235 .flags = WIPHY_WOWLAN_ANY |
236 WIPHY_WOWLAN_MAGIC_PKT |
237 WIPHY_WOWLAN_DISCONNECT |
238 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
239 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
240 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
241 WIPHY_WOWLAN_4WAY_HANDSHAKE |
242 WIPHY_WOWLAN_RFKILL_RELEASE,
243 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
244 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
245 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
246};
247#endif
248
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700249static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
250 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
251 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
252 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
253 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
254 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
255 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
256 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
257 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
258 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
259 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
260 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
261 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
262 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
263 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
264 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
265 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
266 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
267 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
268 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
269 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
270 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
271 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
272 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
273 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
274 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
275 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
276 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
277 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
278 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
279 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
280 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
281 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
282 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
283 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700284 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700285 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700286 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530287 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800288 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700289};
290
Ganesh Kondabattini35739572017-06-21 16:26:39 +0530291int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
292 { HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
293 { HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
294 { HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
295 { HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
296};
297
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298/* internal function declaration */
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530299struct notifier_block hdd_netdev_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800300
301struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700303static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304#endif
305
Sachin Ahujadddd2632017-03-07 19:07:24 +0530306void hdd_start_complete(int ret)
307{
308 wlan_start_ret_val = ret;
309
310 complete(&wlan_start_comp);
311}
312
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800313/**
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +0530314 * hdd_check_green_ap_enable() - to check whether to enable green ap or not
315 * @hdd_ctx: hdd context
316 * @enable_green_ap: 1 - enable green ap enabled, 0 - disbale green ap
317 *
318 * Return: 0 - success, < 0 - failure
319 */
320static int hdd_check_green_ap_enable(struct hdd_context *hdd_ctx,
321 bool *enable_green_ap)
322{
323 uint8_t num_sessions, mode;
324 QDF_STATUS status;
325
326 for (mode = 0;
327 mode < QDF_MAX_NO_OF_MODE;
328 mode++) {
329 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
330 continue;
331
332 status = policy_mgr_mode_specific_num_active_sessions(
333 hdd_ctx->hdd_psoc, mode, &num_sessions);
334 hdd_debug("No. of active sessions for mode: %d is %d",
335 mode, num_sessions);
336 if (status != QDF_STATUS_SUCCESS) {
337 hdd_err("Failed to get num sessions for mode: %d",
338 mode);
339 return -EINVAL;
340 } else if (num_sessions) {
341 *enable_green_ap = false;
342 return 0;
343 }
344 }
345 *enable_green_ap = true;
346 return 0;
347}
348
349int hdd_start_green_ap_state_mc(struct hdd_context *hdd_ctx,
350 enum QDF_OPMODE mode, bool is_session_start)
351{
352 struct hdd_config *cfg;
353 bool enable_green_ap = false;
354 uint8_t num_sap_sessions = 0, num_p2p_go_sessions = 0, ret = 0;
355
356 cfg = hdd_ctx->config;
357 if (!cfg) {
358 hdd_err("NULL hdd config");
359 return -EINVAL;
360 }
361
362 if (!cfg->enable2x2 || !cfg->enableGreenAP) {
363 hdd_info("Green AP support not present: enable2x2: %d, enableGreenAp: %d",
364 cfg->enable2x2, cfg->enableGreenAP);
365 return 0;
366 }
367
368 policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
369 QDF_SAP_MODE,
370 &num_sap_sessions);
371 policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
372 QDF_P2P_GO_MODE,
373 &num_p2p_go_sessions);
374
375 switch (mode) {
376 case QDF_STA_MODE:
377 case QDF_P2P_CLIENT_MODE:
378 case QDF_IBSS_MODE:
379 if (!num_sap_sessions && !num_p2p_go_sessions)
380 return 0;
381
382 if (is_session_start) {
383 hdd_debug("Disabling Green AP");
384 ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
385 false);
386 wlan_green_ap_stop(hdd_ctx->hdd_pdev);
387 } else {
388 ret = hdd_check_green_ap_enable(hdd_ctx,
389 &enable_green_ap);
390 if (!ret) {
391 if (enable_green_ap) {
392 hdd_debug("Enabling Green AP");
393 ucfg_green_ap_set_ps_config(
394 hdd_ctx->hdd_pdev, true);
395 wlan_green_ap_start(hdd_ctx->hdd_pdev);
396 }
397 } else {
398 hdd_err("Failed to check Green AP enable status");
399 }
400 }
401 break;
402 case QDF_SAP_MODE:
403 case QDF_P2P_GO_MODE:
404 if (is_session_start) {
405 ret = hdd_check_green_ap_enable(hdd_ctx,
406 &enable_green_ap);
407 if (!ret) {
408 if (enable_green_ap) {
409 hdd_debug("Enabling Green AP");
410 ucfg_green_ap_set_ps_config(
411 hdd_ctx->hdd_pdev, true);
412 wlan_green_ap_start(hdd_ctx->hdd_pdev);
413 }
414 } else {
415 hdd_err("Failed to check Green AP enable status");
416 }
417 } else {
418 if (!num_sap_sessions && !num_p2p_go_sessions) {
419 hdd_debug("Disabling Green AP");
420 ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
421 false);
422 wlan_green_ap_stop(hdd_ctx->hdd_pdev);
423 }
424 }
425 break;
426 default:
427 break;
428 }
429 return ret;
430}
431
432/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530433 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700434 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530435 *
436 * Return: none
437 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700438static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530439{
Jeff Johnson9d295242017-08-29 14:39:48 -0700440 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530441
Dustin Brown920397d2017-12-13 16:27:50 -0800442 hdd_for_each_adapter(hdd_ctx, adapter)
443 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530444}
445
446/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
448 * @vdev_id: vdev_id
449 * @action: action type
450 * @reason: reason type
451 *
452 * Return: none
453 */
454void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
455 enum netif_action_type action, enum netif_reason_type reason)
456{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700457 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700458 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459
460 if (!hdd_ctx) {
461 hdd_err("hdd ctx is NULL");
462 return;
463 }
464 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
465
466 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467}
468
469/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700470 * Store WLAN driver version and timestamp info in global variables such that
471 * crash debugger can extract them from driver debug symbol and crashdump for
472 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800474#ifdef BUILD_TAG
475uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR "; " BUILD_TAG;
476#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;
Naveen Rawat93836252017-06-20 16:30:59 -0700478#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479
480/**
481 * hdd_device_mode_to_string() - return string conversion of device mode
482 * @device_mode: device mode
483 *
484 * This utility function helps log string conversion of device mode.
485 *
486 * Return: string conversion of device mode, if match found;
487 * "Unknown" otherwise.
488 */
489const char *hdd_device_mode_to_string(uint8_t device_mode)
490{
491 switch (device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -0800492 CASE_RETURN_STRING(QDF_STA_MODE);
493 CASE_RETURN_STRING(QDF_SAP_MODE);
494 CASE_RETURN_STRING(QDF_P2P_CLIENT_MODE);
495 CASE_RETURN_STRING(QDF_P2P_GO_MODE);
496 CASE_RETURN_STRING(QDF_FTM_MODE);
497 CASE_RETURN_STRING(QDF_IBSS_MODE);
498 CASE_RETURN_STRING(QDF_P2P_DEVICE_MODE);
499 CASE_RETURN_STRING(QDF_OCB_MODE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700500 CASE_RETURN_STRING(QDF_NDI_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800501 default:
502 return "Unknown";
503 }
504}
505
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530506/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500507 * hdd_get_valid_chan() - return current chan list from regulatory.
508 * @hdd_ctx: HDD context
509 * @chan_list: buf hold returned chan list
510 * @chan_num: input buf size and output returned chan num
511 *
512 * This function helps get current available chan list from regulatory
513 * module. It excludes the "disabled" and "invalid" channels.
514 *
515 * Return: 0 for success.
516 */
517static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
518 uint8_t *chan_list,
519 uint32_t *chan_num)
520{
521 int i = 0, j = 0;
522 struct regulatory_channel *cur_chan_list;
523 struct wlan_objmgr_pdev *pdev;
524
525 if (!hdd_ctx || !hdd_ctx->hdd_pdev || !chan_list || !chan_num)
526 return -EINVAL;
527
528 pdev = hdd_ctx->hdd_pdev;
529 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
530 sizeof(struct regulatory_channel));
531 if (!cur_chan_list)
532 return -ENOMEM;
533
534 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
535 QDF_STATUS_SUCCESS) {
536 qdf_mem_free(cur_chan_list);
537 return -EINVAL;
538 }
539
540 for (i = 0; i < NUM_CHANNELS; i++) {
541 uint32_t ch = cur_chan_list[i].chan_num;
542 enum channel_state state = wlan_reg_get_channel_state(pdev,
543 ch);
544
545 if (state != CHANNEL_STATE_DISABLE &&
546 state != CHANNEL_STATE_INVALID &&
547 j < *chan_num) {
548 chan_list[j] = (uint8_t)ch;
549 j++;
550 }
551 }
552 *chan_num = j;
553 qdf_mem_free(cur_chan_list);
554 return 0;
555}
556
557/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530558 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
559 * @adapter: HDD adapter
560 * @chan_number: Channel number
561 * @chan_bw: Bandwidth
562 *
563 * Checks if the given bandwidth is valid for the given channel number.
564 *
565 * Return: 0 for success, non-zero for failure
566 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700567int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530568 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800569 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530570{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500571 uint8_t chan[NUM_CHANNELS];
572 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530573 bool found = false;
574 tHalHandle hal;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500575 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530576
577 hal = WLAN_HDD_GET_HAL_CTX(adapter);
578 if (!hal) {
579 hdd_err("Invalid HAL context");
580 return -EINVAL;
581 }
582
Liangwei Dong17bf2662018-01-05 02:02:05 -0500583 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
584 &len);
585 if (ret) {
586 hdd_err("error %d in getting valid channel list", ret);
587 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530588 }
589
590 for (i = 0; i < len; i++) {
591 if (chan[i] == chan_number) {
592 found = true;
593 break;
594 }
595 }
596
597 if (found == false) {
598 hdd_err("Channel not in driver's valid channel list");
599 return -EOPNOTSUPP;
600 }
601
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700602 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
603 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530604 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
605 return -EINVAL;
606 }
607
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700608 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530609 if (chan_bw == CH_WIDTH_80MHZ) {
610 hdd_err("BW80 not possible in 2.4GHz band");
611 return -EINVAL;
612 }
613 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
614 (chan_bw != CH_WIDTH_MAX)) {
615 hdd_err("Only BW20 possible on channel 14");
616 return -EINVAL;
617 }
618 }
619
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700620 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530621 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
622 (chan_bw != CH_WIDTH_MAX)) {
623 hdd_err("Only BW20 possible on channel 165");
624 return -EINVAL;
625 }
626 }
627
628 return 0;
629}
630
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530631/**
632 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
633 *
634 * Block the unloading of the driver (or) interface up until the
635 * cds recovery is completed
636 *
637 * Return: true for recovery completion else false
638 */
639static bool hdd_wait_for_recovery_completion(void)
640{
641 int retry = 0;
642
643 /* Wait for recovery to complete */
644 while (cds_is_driver_recovering()) {
645 if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
646 hdd_err("Recovery in progress; wait here!!!");
647 msleep(1000);
648 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
649 hdd_err("SSR never completed, error");
650 /*
651 * Trigger the bug_on in the internal builds, in the
652 * customer builds self-recovery will be enabled
653 * in those cases just return error.
654 */
655 if (cds_is_self_recovery_enabled())
656 return false;
657 QDF_BUG(0);
658 }
659 }
660
661 hdd_info("Recovery completed successfully!");
662 return true;
663}
664
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665static int __hdd_netdev_notifier_call(struct notifier_block *nb,
666 unsigned long state, void *data)
667{
668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
669 struct netdev_notifier_info *dev_notif_info = data;
670 struct net_device *dev = dev_notif_info->dev;
671#else
672 struct net_device *dev = data;
673#endif
Jeff Johnson9d295242017-08-29 14:39:48 -0700674 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700675 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676
Dustin Brownfdf17c12018-03-14 12:55:34 -0700677 hdd_enter_dev(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800678
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800679 /* Make sure that this callback corresponds to our device. */
680 if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
681 return NOTIFY_DONE;
682
Samuel Ahnc9c48ca2016-09-19 15:46:36 +0530683 if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800684 (adapter->dev != dev)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700685 hdd_err("device adapter is not matching!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686 return NOTIFY_DONE;
687 }
688
689 if (!dev->ieee80211_ptr) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700690 hdd_err("ieee80211_ptr is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691 return NOTIFY_DONE;
692 }
693
694 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
695 if (NULL == hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800696 hdd_err("HDD Context Null Pointer");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530697 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 return NOTIFY_DONE;
699 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800700
701 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
702 hdd_err("%s: Driver module is closed", __func__);
703 return NOTIFY_DONE;
704 }
705
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530706 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state())
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707 return NOTIFY_DONE;
708
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800709 hdd_debug("%s New Net Device State = %lu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710 dev->name, state);
711
712 switch (state) {
713 case NETDEV_REGISTER:
714 break;
715
716 case NETDEV_UNREGISTER:
717 break;
718
719 case NETDEV_UP:
720 sme_ch_avoid_update_req(hdd_ctx->hHal);
721 break;
722
723 case NETDEV_DOWN:
724 break;
725
726 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700727 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 complete(&adapter->linkup_event_var);
729 break;
730
731 case NETDEV_GOING_DOWN:
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700732 if (ucfg_scan_get_vdev_status(adapter->hdd_vdev) !=
733 SCAN_NOT_IN_PROGRESS) {
Abhishek Singh69ccb512017-04-25 11:58:16 +0530734 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -0700735 adapter->session_id, INVALID_SCAN_ID, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736 } else {
hqueaa33ee2017-05-04 17:56:35 +0800737 cds_flush_work(&adapter->scan_block_work);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800738 hdd_debug("Scan is not Pending from user");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 }
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530740 /*
741 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
742 * of return status of hdd_stop call, kernel resets the IFF_UP
743 * flag after which driver does not send the cfg80211_scan_done.
744 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
745 */
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +0530746 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 break;
748
749 default:
750 break;
751 }
752
753 return NOTIFY_DONE;
754}
755
756/**
757 * hdd_netdev_notifier_call() - netdev notifier callback function
758 * @nb: pointer to notifier block
759 * @state: state
760 * @ndev: ndev pointer
761 *
762 * Return: 0 on success, error number otherwise.
763 */
764static int hdd_netdev_notifier_call(struct notifier_block *nb,
765 unsigned long state,
766 void *ndev)
767{
768 int ret;
769
770 cds_ssr_protect(__func__);
771 ret = __hdd_netdev_notifier_call(nb, state, ndev);
772 cds_ssr_unprotect(__func__);
773
774 return ret;
775}
776
777struct notifier_block hdd_netdev_notifier = {
778 .notifier_call = hdd_netdev_notifier_call,
779};
780
781/* variable to hold the insmod parameters */
782static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800783
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530784static int con_mode_ftm;
Ravi Joshia307f632017-07-17 23:41:41 -0700785int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530786
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800787/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800789
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530790/**
791 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
792 * @ch_width: NL channel width
793 *
794 * Converts the NL channel width to the driver's internal representation
795 *
796 * Return: Converted channel width. In case of non matching NL channel width,
797 * CH_WIDTH_MAX will be returned.
798 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800799enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530800{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800801 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700802
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800803 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530804 switch (ch_width) {
805 case NL80211_CHAN_WIDTH_20_NOHT:
806 case NL80211_CHAN_WIDTH_20:
807 return CH_WIDTH_20MHZ;
808 case NL80211_CHAN_WIDTH_40:
809 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530810 case NL80211_CHAN_WIDTH_80:
811 return CH_WIDTH_80MHZ;
812 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800813 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
814 return CH_WIDTH_80P80MHZ;
815 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
816 return CH_WIDTH_160MHZ;
817 else
818 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530819 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800820 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
821 return CH_WIDTH_160MHZ;
822 else
823 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530824 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800825 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530826 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800827 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530828 default:
829 hdd_err("Invalid channel width %d, setting to default",
830 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800831 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530832 }
833}
834
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530835/* wlan_hdd_find_opclass() - Find operating class for a channel
836 * @hal: handler to HAL
837 * @channel: channel id
838 * @bw_offset: bandwidth offset
839 *
840 * Function invokes sme api to find the operating class
841 *
842 * Return: operating class
843 */
844uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
845 uint8_t bw_offset)
846{
847 uint8_t opclass = 0;
848
849 sme_get_opclass(hal, channel, bw_offset, &opclass);
850 return opclass;
851}
852
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530854 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530855 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856 * @bitmask: Bitmask of log levels to be enabled
857 *
858 * Called immediately after the cfg.ini is read in order to configure
859 * the desired trace levels.
860 *
861 * Return: None
862 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530863int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530865 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530866 int qdf_print_idx = -1;
867 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 /*
869 * if the bitmask is the default value, then a bitmask was not
870 * specified in cfg.ini, so leave the logging level alone (it
871 * will remain at the "compiled in" default value)
872 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700873 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530874 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530876 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530878 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530879 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530880 QDF_TRACE_LEVEL_NONE, 0);
881
882 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530883 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +0530885 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 while (0 != bitmask) {
887 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530888 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530889 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530890 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530891 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700893
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 level++;
895 bitmask >>= 1;
896 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530897 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898}
899
900/**
Chris Guo1751acf2017-07-03 14:09:01 +0800901 * wlan_hdd_validate_context_in_loading() - check the HDD context in loading
902 * @hdd_ctx: HDD context pointer
903 *
904 * Return: 0 if the context is valid. Error code otherwise
905 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700906int wlan_hdd_validate_context_in_loading(struct hdd_context *hdd_ctx)
Chris Guo1751acf2017-07-03 14:09:01 +0800907{
908 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
909 hdd_info("%pS HDD context is Null", (void *)_RET_IP_);
910 return -ENODEV;
911 }
912
913 if (cds_is_driver_recovering()) {
914 hdd_info("%pS Recovery in Progress. State: 0x%x Ignore!!!",
915 (void *)_RET_IP_, cds_get_driver_state());
916 return -EAGAIN;
917 }
918
919 if (hdd_ctx->start_modules_in_progress ||
920 hdd_ctx->stop_modules_in_progress) {
921 hdd_info("%pS Start/Stop Modules in progress. Ignore!!!",
922 (void *)_RET_IP_);
923 return -EAGAIN;
924 }
925
926 return 0;
927}
928
929
930/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931 * wlan_hdd_validate_context() - check the HDD context
932 * @hdd_ctx: HDD context pointer
933 *
934 * Return: 0 if the context is valid. Error code otherwise
935 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700936int wlan_hdd_validate_context(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530939 hdd_err("%pS HDD context is Null", (void *)_RET_IP_);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 return -ENODEV;
941 }
942
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800943 if (cds_is_driver_recovering()) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800944 hdd_debug("%pS Recovery in Progress. State: 0x%x Ignore!!!",
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530945 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946 return -EAGAIN;
947 }
948
Yue Ma9f275d92017-09-14 16:58:41 -0700949 if (cds_is_load_or_unload_in_progress()) {
950 hdd_debug("%pS Load or unload in progress, state: 0x%x, ignore!",
951 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800952 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -0700953 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530954
955 if (hdd_ctx->start_modules_in_progress ||
956 hdd_ctx->stop_modules_in_progress) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800957 hdd_debug("%pS Start/Stop Modules in progress. Ignore!!!",
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530958 (void *)_RET_IP_);
959 return -EAGAIN;
960 }
961
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530962 if (cds_is_driver_in_bad_state()) {
963 hdd_debug("%pS driver in bad State: 0x%x Ignore!!!",
964 (void *)_RET_IP_, cds_get_driver_state());
965 return -ENODEV;
966 }
967
Arunk Khandavalli2859fa12018-02-14 10:46:26 +0530968 if (cds_is_fw_down()) {
969 hdd_debug("%pS FW is down: 0x%x Ignore!!!",
970 (void *)_RET_IP_, cds_get_driver_state());
971 return -ENODEV;
972 }
973
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974 return 0;
975}
976
Jeff Johnson9d295242017-08-29 14:39:48 -0700977int hdd_validate_adapter(struct hdd_adapter *adapter)
Dustin Brownf13b8c32017-05-19 17:23:08 -0700978{
979 if (!adapter) {
980 hdd_err("adapter is null");
981 return -EINVAL;
982 }
983
984 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
985 hdd_err("bad adapter magic: 0x%x (should be 0x%x)",
986 adapter->magic, WLAN_HDD_ADAPTER_MAGIC);
987 return -EINVAL;
988 }
989
990 if (!adapter->dev) {
991 hdd_err("adapter net_device is null");
992 return -EINVAL;
993 }
994
995 if (!(adapter->dev->flags & IFF_UP)) {
996 hdd_info("adapter net_device is not up");
997 return -EAGAIN;
998 }
999
Jeff Johnson1b780e42017-10-31 14:11:45 -07001000 if (wlan_hdd_validate_session_id(adapter->session_id)) {
Dustin Brownf13b8c32017-05-19 17:23:08 -07001001 hdd_info("adapter session is not open");
1002 return -EAGAIN;
1003 }
1004
Jeff Johnson1b780e42017-10-31 14:11:45 -07001005 if (adapter->session_id >= MAX_NUMBER_OF_ADAPTERS) {
1006 hdd_err("bad adapter session Id: %u", adapter->session_id);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001007 return -EINVAL;
1008 }
1009
1010 return 0;
1011}
1012
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301014 * wlan_hdd_validate_modules_state() - Check modules status
1015 * @hdd_ctx: HDD context pointer
1016 *
1017 * Check's the driver module's state and returns true if the
1018 * modules are enabled returns false if modules are closed.
1019 *
1020 * Return: True if modules are enabled or false.
1021 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001022bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301023{
1024 mutex_lock(&hdd_ctx->iface_change_lock);
1025 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1026 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown5e89ef82018-03-14 11:50:23 -07001027 hdd_info("Modules not enabled, Present status: %d",
1028 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301029 return false;
1030 }
1031 mutex_unlock(&hdd_ctx->iface_change_lock);
1032 return true;
1033}
1034
1035/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -07001037 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001038 *
1039 * This function sets the IBSS power save config parameters to WMA
1040 * which will send it to firmware if FW supports IBSS power save
1041 * before vdev start.
1042 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301043 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 * on failure.
1045 */
Jeff Johnson9d295242017-08-29 14:39:48 -07001046QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001047{
1048 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001049 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001050
1051 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001052 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301053 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054 }
1055
Jeff Johnson1b780e42017-10-31 14:11:45 -07001056 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
1058 hdd_ctx->config->ibssATIMWinSize,
1059 VDEV_CMD);
1060 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001061 hdd_err("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301062 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001063 }
1064
Jeff Johnson1b780e42017-10-31 14:11:45 -07001065 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
1067 hdd_ctx->config->isIbssPowerSaveAllowed,
1068 VDEV_CMD);
1069 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001070 hdd_err("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d",
1071 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301072 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001073 }
1074
Jeff Johnson1b780e42017-10-31 14:11:45 -07001075 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001076 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
1077 hdd_ctx->config->
1078 isIbssPowerCollapseAllowed, VDEV_CMD);
1079 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001080 hdd_err("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d",
1081 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301082 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 }
1084
Jeff Johnson1b780e42017-10-31 14:11:45 -07001085 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001086 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
1087 hdd_ctx->config->isIbssAwakeOnTxRx,
1088 VDEV_CMD);
1089 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001090 hdd_err("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301091 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092 }
1093
Jeff Johnson1b780e42017-10-31 14:11:45 -07001094 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001095 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
1096 hdd_ctx->config->ibssInactivityCount,
1097 VDEV_CMD);
1098 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001099 hdd_err("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301100 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001101 }
1102
Jeff Johnson1b780e42017-10-31 14:11:45 -07001103 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001104 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
1105 hdd_ctx->config->ibssTxSpEndInactivityTime,
1106 VDEV_CMD);
1107 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001108 hdd_err("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d",
1109 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301110 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001111 }
1112
Jeff Johnson1b780e42017-10-31 14:11:45 -07001113 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
1115 hdd_ctx->config->ibssPsWarmupTime,
1116 VDEV_CMD);
1117 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001118 hdd_err("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d",
1119 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 }
1122
Jeff Johnson1b780e42017-10-31 14:11:45 -07001123 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001124 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
1125 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
1126 VDEV_CMD);
1127 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001128 hdd_err("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d",
1129 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301130 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001131 }
1132
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301133 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134}
1135
Yue Macd359b72017-10-03 15:21:00 -07001136#ifdef FEATURE_RUNTIME_PM
1137/**
1138 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1139 * @hdd_ctx: HDD context
1140 *
1141 * Return: None
1142 */
1143static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1144{
1145 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1146
Yue Macd359b72017-10-03 15:21:00 -07001147 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001148 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001149
1150 wlan_scan_runtime_pm_init(hdd_ctx->hdd_pdev);
1151}
1152
1153/**
1154 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1155 * @hdd_ctx: HDD Context
1156 *
1157 * Return: None
1158 */
1159static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1160{
1161 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1162
Yue Macd359b72017-10-03 15:21:00 -07001163 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001164 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001165
1166 wlan_scan_runtime_pm_deinit(hdd_ctx->hdd_pdev);
1167}
1168
Yue Macd359b72017-10-03 15:21:00 -07001169#else /* FEATURE_RUNTIME_PM */
1170static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1171static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001172#endif /* FEATURE_RUNTIME_PM */
1173
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001174#define INTF_MACADDR_MASK 0x7
1175
1176/**
1177 * hdd_update_macaddr() - update mac address
1178 * @config: hdd configuration
1179 * @hw_macaddr: mac address
1180 *
1181 * Mac address for multiple virtual interface is found as following
1182 * i) The mac address of the first interface is just the actual hw mac address.
1183 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
1184 * define the mac address for the remaining interfaces and locally
1185 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
1186 * supported virtual interfaces, right now this is 0x07 (meaning 8
1187 * interface).
1188 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
1189 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
1190 *
1191 * Return: None
1192 */
1193void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301194 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001195{
1196 int8_t i;
1197 uint8_t macaddr_b3, tmp_br3;
1198
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301199 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301200 QDF_MAC_ADDR_SIZE);
1201 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301202 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301203 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204 macaddr_b3 = config->intfMacAddr[i].bytes[3];
1205 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1206 INTF_MACADDR_MASK;
1207 macaddr_b3 += tmp_br3;
1208
1209 /* XOR-ing bit-24 of the mac address. This will give enough
1210 * mac address range before collision
1211 */
1212 macaddr_b3 ^= (1 << 7);
1213
1214 /* Set locally administered bit */
1215 config->intfMacAddr[i].bytes[0] |= 0x02;
1216 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001217 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001218 MAC_ADDRESS_STR, i,
1219 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
1220 }
1221}
1222
Kabilan Kannan44a58372017-12-06 18:16:11 -08001223static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1224{
1225 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
1226 struct tdls_start_params tdls_cfg;
1227 struct tdls_user_config *config = &tdls_cfg.config;
1228 struct hdd_config *cfg = hdd_ctx->config;
1229 QDF_STATUS status;
1230
1231 config->tdls_tx_states_period = cfg->fTDLSTxStatsPeriod;
1232 config->tdls_tx_pkt_threshold = cfg->fTDLSTxPacketThreshold;
1233 config->tdls_rx_pkt_threshold = cfg->fTDLSRxFrameThreshold;
1234 config->tdls_max_discovery_attempt = cfg->fTDLSMaxDiscoveryAttempt;
1235 config->tdls_idle_timeout = cfg->tdls_idle_timeout;
1236 config->tdls_idle_pkt_threshold = cfg->fTDLSIdlePacketThreshold;
1237 config->tdls_rssi_trigger_threshold = cfg->fTDLSRSSITriggerThreshold;
1238 config->tdls_rssi_teardown_threshold = cfg->fTDLSRSSITeardownThreshold;
1239 config->tdls_rssi_delta = cfg->fTDLSRSSIDelta;
1240 config->tdls_uapsd_mask = cfg->fTDLSUapsdMask;
1241 config->tdls_uapsd_inactivity_time = cfg->fTDLSPuapsdInactivityTimer;
1242 config->tdls_uapsd_pti_window = cfg->fTDLSPuapsdPTIWindow;
1243 config->tdls_uapsd_ptr_timeout = cfg->fTDLSPuapsdPTRTimeout;
1244 config->tdls_pre_off_chan_num = cfg->fTDLSPrefOffChanNum;
1245 config->tdls_pre_off_chan_bw = cfg->fTDLSPrefOffChanBandwidth;
1246 config->tdls_peer_kickout_threshold = cfg->tdls_peer_kickout_threshold;
1247 config->delayed_trig_framint = cfg->DelayedTriggerFrmInt;
1248 config->tdls_feature_flags = ((cfg->fEnableTDLSOffChannel ?
1249 1 << TDLS_FEATURE_OFF_CHANNEL : 0) |
1250 (cfg->fEnableTDLSWmmMode ? 1 << TDLS_FEATURE_WMM : 0) |
1251 (cfg->fEnableTDLSBufferSta ? 1 << TDLS_FEATURE_BUFFER_STA : 0) |
1252 (cfg->fEnableTDLSSleepSta ? 1 << TDLS_FEATURE_SLEEP_STA : 0) |
1253 (cfg->enable_tdls_scan ? 1 << TDLS_FEATURE_SCAN : 0) |
1254 (cfg->fEnableTDLSSupport ? 1 << TDLS_FEATURE_ENABLE : 0) |
1255 (cfg->fEnableTDLSImplicitTrigger ?
1256 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) |
1257 (cfg->fTDLSExternalControl ?
1258 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0));
1259 config->tdls_vdev_nss_2g = CFG_TDLS_NSS(cfg->vdev_type_nss_2g);
1260 config->tdls_vdev_nss_5g = CFG_TDLS_NSS(cfg->vdev_type_nss_5g);
1261
1262 tdls_cfg.tdls_send_mgmt_req = eWNI_SME_TDLS_SEND_MGMT_REQ;
1263 tdls_cfg.tdls_add_sta_req = eWNI_SME_TDLS_ADD_STA_REQ;
1264 tdls_cfg.tdls_del_sta_req = eWNI_SME_TDLS_DEL_STA_REQ;
1265 tdls_cfg.tdls_update_peer_state = WMA_UPDATE_TDLS_PEER_STATE;
1266 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1267 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1268 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1269 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001270 tdls_cfg.tdls_peer_context = hdd_ctx;
1271 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1272 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001273 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1274 tdls_cfg.tdls_wmm_cb_data = psoc;
1275 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1276 tdls_cfg.tdls_rx_cb_data = psoc;
1277 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1278
1279 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1280 if (status != QDF_STATUS_SUCCESS) {
1281 hdd_err("failed pmo psoc configuration");
1282 return -EINVAL;
1283 }
1284
1285 hdd_ctx->tdls_umac_comp_active = true;
1286 /* enable napier specific tdls data path */
1287 hdd_ctx->tdls_nap_active = true;
1288
1289 return 0;
1290}
1291
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001292static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001293 struct wma_tgt_services *cfg)
1294{
1295 struct hdd_config *config = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296
1297 /* Set up UAPSD */
1298 config->apUapsdEnabled &= cfg->uapsd;
1299
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001300 /* 11AX mode support */
1301 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1302 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1303 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 /* 11AC mode support */
1306 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1307 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1308 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001309
1310 /* ARP offload: override user setting if invalid */
1311 config->fhostArpOffload &= cfg->arp_offload;
1312
1313#ifdef FEATURE_WLAN_SCAN_PNO
1314 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001315 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316 if (cfg->pno_offload)
1317 config->PnoOffload = true;
1318#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319#ifdef FEATURE_WLAN_TDLS
1320 config->fEnableTDLSSupport &= cfg->en_tdls;
Manjeet Singhfdd2ac72016-09-02 18:11:43 +05301321 config->fEnableTDLSOffChannel = config->fEnableTDLSOffChannel &&
1322 cfg->en_tdls_offchan;
1323 config->fEnableTDLSBufferSta = config->fEnableTDLSBufferSta &&
1324 cfg->en_tdls_uapsd_buf_sta;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001325 if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 config->fEnableTDLSSleepSta = true;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001327 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 config->fEnableTDLSSleepSta = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1331 config->isRoamOffloadEnabled &= cfg->en_roam_offload;
1332#endif
Will Huang496b36c2017-07-11 16:38:50 +08001333 config->sap_get_peer_info &= cfg->get_peer_info_enabled;
Varun Reddy Yeturu62c32652017-10-26 15:32:35 -07001334 config->MAWCEnabled &= cfg->is_fw_mawc_capable;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001335 hdd_update_tdls_config(hdd_ctx);
Krishna Kumaar Natarajan052c6e62015-09-28 15:32:55 -07001336 sme_update_tgt_services(hdd_ctx->hHal, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001337
1338}
1339
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001340/**
1341 * hdd_update_vdev_nss() - sets the vdev nss
1342 * @hdd_ctx: HDD context
1343 *
1344 * Sets the Nss per vdev type based on INI
1345 *
1346 * Return: None
1347 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001348static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001349{
1350 struct hdd_config *cfg_ini = hdd_ctx->config;
1351 uint8_t max_supp_nss = 1;
1352
Naveen Rawat10b1c152017-01-18 11:16:06 -08001353 if (cfg_ini->enable2x2 && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001354 max_supp_nss = 2;
1355
1356 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001357 cfg_ini->vdev_type_nss_2g, BAND_2G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001358
1359 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001360 cfg_ini->vdev_type_nss_5g, BAND_5G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001361}
1362
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301363/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301364 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1365 * @hdd_ctx: HDD context
1366 *
1367 * Updates wiphy vhtcap fields
1368 *
1369 * Return: None
1370 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001371static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301372{
1373 struct ieee80211_supported_band *band_5g =
1374 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
1375 uint32_t val;
1376
1377 if (!band_5g) {
1378 hdd_debug("5GHz band disabled, skipping capability population");
1379 return;
1380 }
1381
1382 val = hdd_ctx->config->txBFCsnValue;
1383 band_5g->vht_cap.cap |= (val << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
1384
1385 val = NUM_OF_SOUNDING_DIMENSIONS;
1386 band_5g->vht_cap.cap |=
1387 (val << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
1388
1389 hdd_info("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
1390 band_5g->vht_cap.cap, hdd_ctx->config->txBFCsnValue, val);
1391}
1392
1393/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301394 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
1395 * @hdd_ctx: HDD context
1396 *
1397 * Sets the DBS capability as per INI and firmware capability
1398 *
1399 * Return: None
1400 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001401static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301402{
1403 struct hdd_config *cfg_ini = hdd_ctx->config;
1404 uint8_t hw_dbs_capable = 0;
1405
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07001406 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc) &&
1407 ((cfg_ini->dual_mac_feature_disable ==
1408 ENABLE_DBS_CXN_AND_SCAN) ||
1409 (cfg_ini->dual_mac_feature_disable ==
1410 ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF)))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301411 hw_dbs_capable = 1;
1412
1413 sme_update_hw_dbs_capable(hdd_ctx->hHal, hw_dbs_capable);
1414}
1415
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001416static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417 struct wma_tgt_ht_cap *cfg)
1418{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301419 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001420 uint32_t value, val32;
1421 uint16_t val16;
1422 struct hdd_config *pconfig = hdd_ctx->config;
1423 tSirMacHTCapabilityInfo *phtCapInfo;
1424 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
1425 uint8_t enable_tx_stbc;
1426
1427 /* check and update RX STBC */
1428 if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
1429 pconfig->enableRxSTBC = cfg->ht_rx_stbc;
1430
1431 /* get the MPDU density */
1432 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);
1433
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301434 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001435 hdd_err("could not get MPDU DENSITY");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 value = 0;
1437 }
1438
1439 /*
1440 * MPDU density:
1441 * override user's setting if value is larger
1442 * than the one supported by target
1443 */
1444 if (value > cfg->mpdu_density) {
1445 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
1446 cfg->mpdu_density);
1447
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301448 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001449 hdd_err("could not set MPDU DENSITY to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 }
1451
1452 /* get the HT capability info */
1453 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301454 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001455 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 return;
1457 }
1458 val16 = (uint16_t) val32;
1459 phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;
1460
1461 /* Set the LDPC capability */
1462 phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;
1463
1464 if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
1465 pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;
1466
1467 if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
1468 pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;
1469
1470 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1471 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1472
1473 enable_tx_stbc = pconfig->enableTxSTBC;
1474
1475 if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
1476 pconfig->enable2x2 = 1;
1477 } else {
1478 pconfig->enable2x2 = 0;
1479 enable_tx_stbc = 0;
1480
1481 /* 1x1 */
1482 /* Update Rx Highest Long GI data Rate */
1483 if (sme_cfg_set_int(hdd_ctx->hHal,
1484 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001485 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301486 == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001487 hdd_err("Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488 }
1489
1490 /* Update Tx Highest Long GI data Rate */
1491 if (sme_cfg_set_int
1492 (hdd_ctx->hHal,
1493 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001494 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301495 QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001496 hdd_err("VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497 }
1498 }
1499 if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
1500 enable_tx_stbc = 0;
1501 phtCapInfo->txSTBC = enable_tx_stbc;
1502
1503 val32 = val16;
1504 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301505 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001506 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
1508 value = SIZE_OF_SUPPORTED_MCS_SET;
1509 if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301510 &value) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001511 hdd_debug("Read MCS rate set");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512
1513 if (pconfig->enable2x2) {
1514 for (value = 0; value < cfg->num_rf_chains; value++)
1515 mcs_set[value] =
1516 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1517
1518 status =
1519 sme_cfg_set_str(hdd_ctx->hHal,
1520 WNI_CFG_SUPPORTED_MCS_SET,
1521 mcs_set,
1522 SIZE_OF_SUPPORTED_MCS_SET);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301523 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001524 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 }
1526 }
1527#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1528}
1529
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001530static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 struct wma_tgt_vht_cap *cfg)
1532{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301533 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 uint32_t value = 0;
1535 struct hdd_config *pconfig = hdd_ctx->config;
1536 struct wiphy *wiphy = hdd_ctx->wiphy;
1537 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001538 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001539 uint32_t temp = 0;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001540 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
jiad4a7a33c2017-08-08 15:32:24 +08001541 uint32_t hw_rx_ldpc_enabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542
Dustin Brown5e06bd32016-10-04 12:49:10 -07001543 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001544 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001545 return;
1546 }
1547
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 /* Get the current MPDU length */
1549 status =
1550 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
1551 &value);
1552
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301553 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001554 hdd_err("could not get MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001555 value = 0;
1556 }
1557
1558 /*
1559 * VHT max MPDU length:
1560 * override if user configured value is too high
1561 * that the target cannot support
1562 */
1563 if (value > cfg->vht_max_mpdu) {
1564 status = sme_cfg_set_int(hdd_ctx->hHal,
1565 WNI_CFG_VHT_MAX_MPDU_LENGTH,
1566 cfg->vht_max_mpdu);
1567
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001568 if (status == QDF_STATUS_E_FAILURE)
1569 hdd_err("could not set VHT MAX MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 }
1571
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001572 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
1573 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1574
1575 if (pconfig->enable2x2)
1576 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1577
1578 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) ==
1579 QDF_STATUS_E_FAILURE) {
1580 hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM");
1581 }
1582
1583 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
1584 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1585 if (pconfig->enable2x2)
1586 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1587
1588 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) ==
1589 QDF_STATUS_E_FAILURE) {
1590 hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM");
1591 }
1592
1593 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
1594 temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
1595 if (pconfig->enable2x2)
1596 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
1597
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001598 hdd_debug("vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001599 pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
1600
1601 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) ==
1602 QDF_STATUS_E_FAILURE) {
1603 hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM");
1604 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605 /* Get the current RX LDPC setting */
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001606 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 &value);
1608
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301609 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001610 hdd_err("could not get VHT LDPC CODING CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 value = 0;
1612 }
1613
jiad4a7a33c2017-08-08 15:32:24 +08001614 /* Set HW RX LDPC capability */
1615 hw_rx_ldpc_enabled = !!cfg->vht_rx_ldpc;
1616 if (hw_rx_ldpc_enabled != value) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001617 status = sme_cfg_set_int(hdd_ctx->hHal,
1618 WNI_CFG_VHT_LDPC_CODING_CAP,
jiad4a7a33c2017-08-08 15:32:24 +08001619 hw_rx_ldpc_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001621 if (status == QDF_STATUS_E_FAILURE)
1622 hdd_err("could not set VHT LDPC CODING CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 }
1624
1625 /* Get current GI 80 value */
1626 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
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 SHORT GI 80MHZ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 value = 0;
1632 }
1633
1634 /* set the Guard interval 80MHz */
1635 if (value && !cfg->vht_short_gi_80) {
1636 status = sme_cfg_set_int(hdd_ctx->hHal,
1637 WNI_CFG_VHT_SHORT_GI_80MHZ,
1638 cfg->vht_short_gi_80);
1639
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001640 if (status == QDF_STATUS_E_FAILURE)
1641 hdd_err("could not set SHORT GI 80MHZ to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 }
1643
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 /* Get VHT TX STBC cap */
1645 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);
1646
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301647 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001648 hdd_err("could not get VHT TX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 value = 0;
1650 }
1651
1652 /* VHT TX STBC cap */
1653 if (value && !cfg->vht_tx_stbc) {
1654 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
1655 cfg->vht_tx_stbc);
1656
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001657 if (status == QDF_STATUS_E_FAILURE)
1658 hdd_err("could not set the VHT TX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 }
1660
1661 /* Get VHT RX STBC cap */
1662 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);
1663
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301664 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001665 hdd_err("could not get VHT RX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 value = 0;
1667 }
1668
1669 /* VHT RX STBC cap */
1670 if (value && !cfg->vht_rx_stbc) {
1671 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
1672 cfg->vht_rx_stbc);
1673
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001674 if (status == QDF_STATUS_E_FAILURE)
1675 hdd_err("could not set the VHT RX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 }
1677
1678 /* Get VHT SU Beamformer cap */
1679 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1680 &value);
1681
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301682 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001683 hdd_err("could not get VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684 value = 0;
1685 }
1686
1687 /* set VHT SU Beamformer cap */
1688 if (value && !cfg->vht_su_bformer) {
1689 status = sme_cfg_set_int(hdd_ctx->hHal,
1690 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1691 cfg->vht_su_bformer);
1692
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001693 if (status == QDF_STATUS_E_FAILURE)
1694 hdd_err("could not set VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695 }
1696
1697 /* check and update SU BEAMFORMEE capabality */
1698 if (pconfig->enableTxBF && !cfg->vht_su_bformee)
1699 pconfig->enableTxBF = cfg->vht_su_bformee;
1700
1701 status = sme_cfg_set_int(hdd_ctx->hHal,
1702 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1703 pconfig->enableTxBF);
1704
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001705 if (status == QDF_STATUS_E_FAILURE)
1706 hdd_err("could not set VHT SU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001707
1708 /* Get VHT MU Beamformer cap */
1709 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1710 &value);
1711
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301712 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001713 hdd_err("could not get VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 value = 0;
1715 }
1716
1717 /* set VHT MU Beamformer cap */
1718 if (value && !cfg->vht_mu_bformer) {
1719 status = sme_cfg_set_int(hdd_ctx->hHal,
1720 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1721 cfg->vht_mu_bformer);
1722
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001723 if (status == QDF_STATUS_E_FAILURE)
1724 hdd_err("could not set the VHT MU BEAMFORMER CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725 }
1726
1727 /* Get VHT MU Beamformee cap */
1728 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1729 &value);
1730
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301731 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001732 hdd_err("could not get VHT MU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 value = 0;
1734 }
1735
1736 /* set VHT MU Beamformee cap */
1737 if (value && !cfg->vht_mu_bformee) {
1738 status = sme_cfg_set_int(hdd_ctx->hHal,
1739 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1740 cfg->vht_mu_bformee);
1741
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001742 if (status == QDF_STATUS_E_FAILURE)
1743 hdd_err("could not set VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001744 }
1745
1746 /* Get VHT MAX AMPDU Len exp */
1747 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1748 &value);
1749
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301750 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001751 hdd_err("could not get VHT AMPDU LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752 value = 0;
1753 }
1754
1755 /*
1756 * VHT max AMPDU len exp:
1757 * override if user configured value is too high
1758 * that the target cannot support.
1759 * Even though Rome publish ampdu_len=7, it can
1760 * only support 4 because of some h/w bug.
1761 */
1762
1763 if (value > cfg->vht_max_ampdu_len_exp) {
1764 status = sme_cfg_set_int(hdd_ctx->hHal,
1765 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1766 cfg->vht_max_ampdu_len_exp);
1767
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001768 if (status == QDF_STATUS_E_FAILURE)
1769 hdd_err("could not set the VHT AMPDU LEN EXP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001770 }
1771
1772 /* Get VHT TXOP PS CAP */
1773 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);
1774
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301775 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001776 hdd_err("could not get VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 value = 0;
1778 }
1779
1780 /* set VHT TXOP PS cap */
1781 if (value && !cfg->vht_txop_ps) {
1782 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
1783 cfg->vht_txop_ps);
1784
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001785 if (status == QDF_STATUS_E_FAILURE)
1786 hdd_err("could not set the VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001787 }
1788
1789 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1790 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1791 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1792 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1793 else
1794 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1795
1796
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001797 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
1798 status = sme_cfg_set_int(hdd_ctx->hHal,
1799 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1800 VHT_CAP_160_AND_80P80_SUPP);
1801 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001802 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803 band_5g->vht_cap.cap |=
1804 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001805 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1806 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
1807 status = sme_cfg_set_int(hdd_ctx->hHal,
1808 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1809 VHT_CAP_160_SUPP);
1810 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001811 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 band_5g->vht_cap.cap |=
1813 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001814 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1815 }
1816 pconfig->vhtChannelWidth = QDF_MIN(pconfig->vhtChannelWidth,
1817 ch_width);
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301818 /* Get the current GI 160 value */
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001819 status = sme_cfg_get_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301820 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001821 &value);
1822 if (status != QDF_STATUS_SUCCESS) {
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301823 hdd_err("could not get GI 80 & 160");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001824 value = 0;
1825 }
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301826 /* set the Guard interval 160MHz */
1827 if (value && !cfg->vht_short_gi_160) {
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001828 status = sme_cfg_set_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301829 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
1830 cfg->vht_short_gi_160);
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001831
1832 if (status == QDF_STATUS_E_FAILURE)
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301833 hdd_err("failed to set SHORT GI 160MHZ");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001834 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835
1836 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC)
1837 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1838
1839 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1840 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1841 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1842 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1843
1844 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1845 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1846
1847 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1848 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1849 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1850 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1851 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1852 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1853
1854 band_5g->vht_cap.cap |=
1855 (cfg->vht_max_ampdu_len_exp <<
1856 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1857
1858 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1859 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1860 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1861 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1862 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1863 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1864 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1865 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1866
1867 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1868 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1869
1870}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001872/**
1873 * hdd_generate_macaddr_auto() - Auto-generate mac address
1874 * @hdd_ctx: Pointer to the HDD context
1875 *
1876 * Auto-generate mac address using device serial number.
1877 * Keep the first 3 bytes of OUI as before and replace
1878 * the last 3 bytes with the lower 3 bytes of serial number.
1879 *
1880 * Return: 0 for success
1881 * Non zero failure code for errors
1882 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001883static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001884{
1885 unsigned int serialno = 0;
1886 struct qdf_mac_addr mac_addr = {
1887 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1888 };
1889
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001890 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001891 if (serialno == 0)
1892 return -EINVAL;
1893
1894 serialno &= 0x00ffffff;
1895
1896 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1897 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1898 mac_addr.bytes[5] = serialno & 0xff;
1899
1900 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1901 return 0;
1902}
1903
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301904/**
1905 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1906 * configuration to cfg_ini in HDD
1907 * @hdd_ctx: Pointer to hdd_ctx
1908 * @cfg: target configuration
1909 *
1910 * Return: None
1911 */
1912#ifdef FEATURE_WLAN_RA_FILTERING
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001913static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301914 struct wma_tgt_cfg *cfg)
1915{
1916 hdd_ctx->config->IsRArateLimitEnabled = cfg->is_ra_rate_limit_enabled;
1917}
1918#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001919static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301920 struct wma_tgt_cfg *cfg)
1921{
1922}
1923#endif
1924
Himanshu Agarwalb229a142017-12-21 10:16:45 +05301925static int hdd_update_green_ap_config(struct hdd_context *hdd_ctx)
1926{
1927 struct green_ap_user_cfg green_ap_cfg;
1928 struct hdd_config *cfg = hdd_ctx->config;
1929 QDF_STATUS status;
1930
1931 green_ap_cfg.host_enable_egap = cfg->enable_egap;
1932 green_ap_cfg.egap_inactivity_time = cfg->egap_inact_time;
1933 green_ap_cfg.egap_wait_time = cfg->egap_wait_time;
1934 green_ap_cfg.egap_feature_flags = cfg->egap_feature_flag;
1935
1936 status = ucfg_green_ap_update_user_config(hdd_ctx->hdd_pdev,
1937 &green_ap_cfg);
1938 if (status != QDF_STATUS_SUCCESS) {
1939 hdd_err("failed to update green ap user configuration");
1940 return -EINVAL;
1941 }
1942
1943 return 0;
1944}
1945
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001946void hdd_update_tgt_cfg(void *context, void *param)
1947{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001948 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001949 struct hdd_context *hdd_ctx = (struct hdd_context *) context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950 struct wma_tgt_cfg *cfg = param;
1951 uint8_t temp_band_cap;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001952 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301953 uint8_t antenna_mode;
Arif Hussainee10f902017-12-27 16:30:17 -08001954 QDF_STATUS status;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301955
Dustin Brownbd68fe12017-11-21 15:28:52 -08001956 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1957 if (ret) {
1958 hdd_err("Failed to create pdev; errno:%d", ret);
1959 QDF_BUG(0);
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07001960 } else {
Dustin Brownbd68fe12017-11-21 15:28:52 -08001961 hdd_debug("New pdev has been created with pdev_id = %u",
Arif Hussainee10f902017-12-27 16:30:17 -08001962 hdd_ctx->hdd_pdev->pdev_objmgr.wlan_pdev_id);
Amar Singhal410675c2018-01-10 12:14:21 -08001963 if (dispatcher_pdev_open(hdd_ctx->hdd_pdev)) {
1964 hdd_err("dispatcher pdev open failed");
1965 QDF_BUG(0);
1966 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301967 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001968
Himanshu Agarwalb229a142017-12-21 10:16:45 +05301969 ret = hdd_update_green_ap_config(hdd_ctx);
1970
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301971 ucfg_ipa_set_dp_handle(hdd_ctx->hdd_psoc,
1972 cds_get_context(QDF_MODULE_ID_SOC));
1973 ucfg_ipa_set_txrx_handle(hdd_ctx->hdd_psoc,
1974 cds_get_context(QDF_MODULE_ID_TXRX));
1975
Naveen Rawat64e477e2016-05-20 10:34:56 -07001976 if (cds_cfg) {
1977 if (hdd_ctx->config->enable_sub_20_channel_width !=
1978 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
1979 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1980 cds_cfg->sub_20_channel_width =
1981 WLAN_SUB_20_CH_WIDTH_NONE;
1982 } else {
1983 cds_cfg->sub_20_channel_width =
1984 hdd_ctx->config->enable_sub_20_channel_width;
1985 }
1986 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987
1988 /* first store the INI band capability */
1989 temp_band_cap = hdd_ctx->config->nBandCapability;
1990
1991 hdd_ctx->config->nBandCapability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301992 hdd_ctx->is_fils_roaming_supported =
1993 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05301995 hdd_ctx->config->is_11k_offload_supported =
1996 cfg->services.is_11k_offload_supported;
1997
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001998 /*
1999 * now overwrite the target band capability with INI
2000 * setting if INI setting is a subset
2001 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002003 if ((hdd_ctx->config->nBandCapability == BAND_ALL) &&
2004 (temp_band_cap != BAND_ALL))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 hdd_ctx->config->nBandCapability = temp_band_cap;
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002006 else if ((hdd_ctx->config->nBandCapability != BAND_ALL) &&
2007 (temp_band_cap != BAND_ALL) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07002009 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 }
2011
Amar Singhal58b45ef2017-08-01 13:43:54 -07002012 hdd_ctx->curr_band = hdd_ctx->config->nBandCapability;
2013
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302014 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 hdd_ctx->reg.reg_domain = cfg->reg_domain;
2016 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2017 }
2018
2019 /* This can be extended to other configurations like ht, vht cap... */
2020
Anurag Chouhanc5548422016-02-24 18:33:27 +05302021 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002022 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002023 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002024 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07002025 static struct qdf_mac_addr default_mac_addr = {
2026 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
2027 };
2028 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
2029 &default_mac_addr)) {
2030 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
2031 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
2032 MAC_ADDRESS_STR,
2033 MAC_ADDR_ARRAY(hdd_ctx->config->
2034 intfMacAddr[0].bytes));
2035 } else {
2036 hdd_err("Invalid MAC passed from target, using MAC from ini file "
2037 MAC_ADDRESS_STR,
2038 MAC_ADDR_ARRAY(hdd_ctx->config->
2039 intfMacAddr[0].bytes));
2040 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002041 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002042 }
2043
2044 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07002045 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046
2047 hdd_ctx->max_intf_count = cfg->max_intf_count;
2048
Jeff Johnsonc875e242016-09-23 18:12:34 -07002049 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08002050
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2052 hdd_update_tgt_services(hdd_ctx, &cfg->services);
2053
2054 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2055
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002057 if (cfg->services.en_11ax) {
2058 hdd_info("11AX: 11ax is enabled - update HDD config");
2059 hdd_update_tgt_he_cap(hdd_ctx, cfg);
2060 }
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002061
2062 hdd_update_vdev_nss(hdd_ctx);
2063
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05302064 hdd_update_hw_dbs_capable(hdd_ctx);
2065
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08002066 hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
Krunal Sonie3531942016-04-12 17:43:53 -07002067 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002068 hdd_debug("fine_time_meas_cap: 0x%x",
Arif Hussainee10f902017-12-27 16:30:17 -08002069 hdd_ctx->config->fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002070
Nitesh Shahe50711f2017-04-26 16:30:45 +05302071 antenna_mode = (hdd_ctx->config->enable2x2 == 0x01) ?
2072 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2073 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002074 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002075 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002076
Rajeev Kumardd3bc602016-08-16 14:21:05 -07002077 hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
2078 hdd_ctx->config->bpf_packet_filter_enable);
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05302079 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05302080 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302081
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302082 if ((hdd_ctx->config->txBFCsnValue >
Arif Hussainee10f902017-12-27 16:30:17 -08002083 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
2084 !cfg->tx_bfee_8ss_enabled)
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302085 hdd_ctx->config->txBFCsnValue =
2086 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF;
2087
Arif Hussainee10f902017-12-27 16:30:17 -08002088 status = sme_cfg_set_int(hdd_ctx->hHal,
2089 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
2090 hdd_ctx->config->txBFCsnValue);
2091 if (QDF_IS_STATUS_ERROR(status))
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302092 hdd_err("fw update WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED to CFG fails");
2093
2094
2095 hdd_debug("Target BPF %d Host BPF %d 8ss fw support %d txBFCsnValue %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002096 cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable,
2097 cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302098
2099 /*
2100 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2101 */
2102 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302103
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302104 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2105
Yue Macd359b72017-10-03 15:21:00 -07002106 /*
2107 * This needs to be done after HDD pdev is created and stored since
2108 * it will access the HDD pdev object lock.
2109 */
2110 hdd_runtime_suspend_context_init(hdd_ctx);
2111
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002112 /* Configure NAN datapath features */
2113 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07002114 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002115 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Arif Hussainee10f902017-12-27 16:30:17 -08002116 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_OBSS_DETECTION_OFFLOAD,
2117 cfg->obss_detection_offloaded);
2118 if (QDF_IS_STATUS_ERROR(status))
2119 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002120
2121 status = sme_cfg_set_int(hdd_ctx->hHal,
2122 WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
2123 cfg->obss_color_collision_offloaded);
2124 if (QDF_IS_STATUS_ERROR(status))
2125 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002126}
2127
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002128bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002129{
Jeff Johnson9d295242017-08-29 14:39:48 -07002130 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002131 struct hdd_ap_ctx *ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132
Jiachao Wuf610d912018-01-23 17:47:32 +08002133 if (!hdd_ctx) {
2134 hdd_info("Couldn't get hdd_ctx");
2135 return true;
2136 }
2137
2138 if (hdd_ctx->config->disableDFSChSwitch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002139 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussaincd151632017-02-11 16:57:19 -08002140 hdd_ctx, hdd_ctx->config->disableDFSChSwitch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302141 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002142 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143
Dustin Brown920397d2017-12-13 16:27:50 -08002144 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002145 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2146
2147 if ((QDF_SAP_MODE == adapter->device_mode ||
2148 QDF_P2P_GO_MODE == adapter->device_mode) &&
2149 (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002150 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002151 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2152 true;
2153 hdd_info("tx blocked for session: %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07002154 adapter->session_id);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302155 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002156 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302157
2158 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002159}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160
2161/**
2162 * hdd_is_valid_mac_address() - validate MAC address
2163 * @pMacAddr: Pointer to the input MAC address
2164 *
2165 * This function validates whether the given MAC address is valid or not
2166 * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
2167 * where X is the hexa decimal digit character and separated by ':'
2168 * This algorithm works even if MAC address is not separated by ':'
2169 *
2170 * This code checks given input string mac contains exactly 12 hexadecimal
2171 * digits and a separator colon : appears in the input string only after
2172 * an even number of hex digits.
2173 *
2174 * Return: 1 for valid and 0 for invalid
2175 */
2176bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
2177{
2178 int xdigit = 0;
2179 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002180
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002181 while (*pMacAddr) {
2182 if (isxdigit(*pMacAddr)) {
2183 xdigit++;
2184 } else if (':' == *pMacAddr) {
2185 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2186 break;
2187
2188 ++separator;
2189 } else {
2190 /* Invalid MAC found */
2191 return 0;
2192 }
2193 ++pMacAddr;
2194 }
2195 return xdigit == 12 && (separator == 5 || separator == 0);
2196}
2197
2198/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302199 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2200 * @dev: Handle to struct net_device to be updated.
2201 *
2202 * Return: None
2203 */
2204static void hdd_mon_mode_ether_setup(struct net_device *dev)
2205{
2206 dev->header_ops = NULL;
2207 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2208 dev->hard_header_len = ETH_HLEN;
2209 dev->mtu = ETH_DATA_LEN;
2210 dev->addr_len = ETH_ALEN;
2211 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2212 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2213 dev->priv_flags |= IFF_TX_SKB_SHARING;
2214
2215 memset(dev->broadcast, 0xFF, ETH_ALEN);
2216}
2217
2218/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002219 * __hdd__mon_open() - HDD Open function
2220 * @dev: Pointer to net_device structure
2221 *
2222 * This is called in response to ifconfig up
2223 *
2224 * Return: 0 for success; non-zero for failure
2225 */
2226static int __hdd_mon_open(struct net_device *dev)
2227{
2228 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002229 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2230 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002231
Dustin Brownfdf17c12018-03-14 12:55:34 -07002232 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002233
2234 ret = wlan_hdd_validate_context(hdd_ctx);
2235 if (ret)
2236 return ret;
2237
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302238 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002239
2240 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
2241 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
2242 if (ret) {
2243 hdd_err("Failed to start WLAN modules return");
2244 return ret;
2245 }
2246 hdd_err("hdd_wlan_start_modules() successful !");
2247
2248 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2249 ret = hdd_start_adapter(adapter);
2250 if (ret) {
2251 hdd_err("Failed to start adapter :%d",
2252 adapter->device_mode);
2253 return ret;
2254 }
2255 hdd_err("hdd_start_adapters() successful !");
2256 }
2257 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2258 }
2259
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002260 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002261
2262 if (!ret)
2263 ret = hdd_enable_monitor_mode(dev);
2264
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002265 return ret;
2266}
2267
2268/**
2269 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2270 * @dev: Pointer to net_device structure
2271 *
2272 * This is called in response to ifconfig up
2273 *
2274 * Return: 0 for success; non-zero for failure
2275 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002276static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002277{
2278 int ret;
2279
2280 cds_ssr_protect(__func__);
2281 ret = __hdd_mon_open(dev);
2282 cds_ssr_unprotect(__func__);
2283
2284 return ret;
2285}
2286
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002287static QDF_STATUS
2288wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2289{
2290 struct policy_mgr_dual_mac_config cfg = {0};
2291 QDF_STATUS status;
2292 uint32_t channel_select_logic_conc;
2293 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2294
2295 if (!hdd_ctx) {
2296 hdd_err("HDD context is NULL");
2297 return QDF_STATUS_E_FAILURE;
2298 }
2299
2300
2301 if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc))
2302 return QDF_STATUS_SUCCESS;
2303
2304 cfg.scan_config = 0;
2305 cfg.fw_mode_config = 0;
2306 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
2307
2308 channel_select_logic_conc = hdd_ctx->config->
2309 channel_select_logic_conc;
2310
2311 if (hdd_ctx->config->dual_mac_feature_disable !=
2312 DISABLE_DBS_CXN_AND_SCAN) {
2313 status = policy_mgr_get_updated_scan_and_fw_mode_config(
2314 hdd_ctx->hdd_psoc, &cfg.scan_config,
2315 &cfg.fw_mode_config,
2316 hdd_ctx->config->dual_mac_feature_disable,
2317 channel_select_logic_conc);
2318
2319 if (status != QDF_STATUS_SUCCESS) {
2320 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2321 status);
2322 return status;
2323 }
2324 }
2325
2326 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2327 cfg.scan_config, cfg.fw_mode_config);
2328
2329 status = sme_soc_set_dual_mac_config(cfg);
2330 if (status != QDF_STATUS_SUCCESS) {
2331 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2332 return status;
2333 }
2334
2335 return QDF_STATUS_SUCCESS;
2336}
2337
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002338/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302339 * hdd_start_adapter() - Wrapper function for device specific adapter
2340 * @adapter: pointer to HDD adapter
2341 *
2342 * This function is called to start the device specific adapter for
2343 * the mode passed in the adapter's device_mode.
2344 *
2345 * Return: 0 for success; non-zero for failure
2346 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002347int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302348{
2349
2350 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002351 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302352
Dustin Brownfdf17c12018-03-14 12:55:34 -07002353 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002354 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302355
2356 switch (device_mode) {
2357 case QDF_P2P_CLIENT_MODE:
2358 case QDF_P2P_DEVICE_MODE:
2359 case QDF_OCB_MODE:
2360 case QDF_STA_MODE:
2361 case QDF_MONITOR_MODE:
2362 ret = hdd_start_station_adapter(adapter);
2363 if (ret)
2364 goto err_start_adapter;
2365 break;
2366 case QDF_P2P_GO_MODE:
2367 case QDF_SAP_MODE:
2368 ret = hdd_start_ap_adapter(adapter);
2369 if (ret)
2370 goto err_start_adapter;
2371 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302372 case QDF_IBSS_MODE:
2373 /*
2374 * For IBSS interface is initialized as part of
2375 * hdd_init_station_mode()
2376 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002377 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302378 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002379 /* vdevs are dynamically managed by firmware in FTM */
2380 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302381 default:
2382 hdd_err("Invalid session type %d", device_mode);
2383 QDF_ASSERT(0);
2384 goto err_start_adapter;
2385 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002386
Arun Khandavallifae92942016-08-01 13:31:08 +05302387 if (hdd_set_fw_params(adapter))
2388 hdd_err("Failed to set the FW params for the adapter!");
2389
2390 /*
2391 * Action frame registered in one adapter which will
2392 * applicable to all interfaces
2393 */
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302394 ret = wlan_hdd_cfg80211_register_frames(adapter);
2395 if (ret < 0) {
2396 hdd_err("Failed to register frames - ret %d", ret);
2397 goto err_start_adapter;
2398 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002399 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302400
Dustin Browndb2a8be2017-12-20 11:49:56 -08002401exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002402 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002403
Arun Khandavallifae92942016-08-01 13:31:08 +05302404 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002405
Arun Khandavallifae92942016-08-01 13:31:08 +05302406err_start_adapter:
2407 return -EINVAL;
2408}
2409
2410/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302411 * hdd_enable_power_management() - API to Enable Power Management
2412 *
2413 * API invokes Bus Interface Layer power management functionality
2414 *
2415 * Return: None
2416 */
2417static void hdd_enable_power_management(void)
2418{
2419 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2420
2421 if (!hif_ctx) {
2422 hdd_err("Bus Interface Context is Invalid");
2423 return;
2424 }
2425
2426 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2427}
2428
2429/**
2430 * hdd_disable_power_management() - API to disable Power Management
2431 *
2432 * API disable Bus Interface Layer Power management functionality
2433 *
2434 * Return: None
2435 */
2436static void hdd_disable_power_management(void)
2437{
2438 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2439
2440 if (!hif_ctx) {
2441 hdd_err("Bus Interface Context is Invalid");
2442 return;
2443 }
2444
2445 hif_disable_power_management(hif_ctx);
2446}
2447
2448/**
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302449 * hdd_update_hw_sw_info() - API to update the HW/SW information
2450 *
2451 * API to update the HW and SW information in the driver
2452 *
2453 * Return: None
2454 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002455static void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302456{
2457 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002458 size_t target_hw_name_len;
2459 const char *target_hw_name;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302460
2461 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2462 if (!hif_sc) {
2463 hdd_err("HIF context is NULL");
2464 return;
2465 }
2466
2467 /*
2468 * target hw version/revision would only be retrieved after firmware
2469 * download
2470 */
Dustin Brown6f17a022017-07-19 13:40:55 -07002471 hif_get_hw_info(hif_sc,
2472 &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302473 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002474 &target_hw_name);
2475
2476 if (hdd_ctx->target_hw_name)
2477 qdf_mem_free(hdd_ctx->target_hw_name);
2478
2479 target_hw_name_len = strlen(target_hw_name) + 1;
2480 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2481 if (hdd_ctx->target_hw_name)
2482 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2483 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302484
2485 /* Get the wlan hw/fw version */
2486 hdd_wlan_get_version(hdd_ctx, NULL, NULL);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302487}
2488
2489/**
gbian62edd7e2017-03-07 13:12:13 +08002490 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2491 * @hdd_ctx: Pointer to hdd context
2492 *
2493 * Return: none
2494 */
2495static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002496hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002497{
2498 uint8_t num_entries = 0;
2499 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
2500 uint8_t *tx_sched_wrr_ac;
2501 int i;
2502 cds_context_type *cds_ctx;
2503
2504 if (NULL == hdd_ctx)
2505 return;
2506
2507 if (NULL == hdd_ctx->config) {
2508 /* Do nothing if hdd_ctx is invalid */
2509 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2510 return;
2511 }
2512
2513 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2514
2515 if (!cds_ctx) {
2516 hdd_err("Invalid CDS Context");
2517 return;
2518 }
2519
2520 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
2521 switch (i) {
2522 case OL_TX_WMM_AC_BE:
2523 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_be;
2524 break;
2525 case OL_TX_WMM_AC_BK:
2526 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_bk;
2527 break;
2528 case OL_TX_WMM_AC_VI:
2529 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vi;
2530 break;
2531 case OL_TX_WMM_AC_VO:
2532 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vo;
2533 break;
2534 default:
2535 tx_sched_wrr_ac = NULL;
2536 break;
2537 }
2538
2539 hdd_string_to_u8_array(tx_sched_wrr_ac,
2540 tx_sched_wrr_param,
2541 &num_entries,
2542 sizeof(tx_sched_wrr_param));
2543
2544 if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
2545 cds_ctx->ac_specs[i].wrr_skip_weight =
2546 tx_sched_wrr_param[0];
2547 cds_ctx->ac_specs[i].credit_threshold =
2548 tx_sched_wrr_param[1];
2549 cds_ctx->ac_specs[i].send_limit =
2550 tx_sched_wrr_param[2];
2551 cds_ctx->ac_specs[i].credit_reserve =
2552 tx_sched_wrr_param[3];
2553 cds_ctx->ac_specs[i].discard_weight =
2554 tx_sched_wrr_param[4];
2555 }
2556
2557 num_entries = 0;
2558 }
2559}
2560
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302561#ifdef IPA_OFFLOAD
2562/**
2563 * hdd_update_ipa_component_config() - update ipa config
2564 * @hdd_ctx: Pointer to hdd context
2565 *
2566 * Return: none
2567 */
2568static void hdd_update_ipa_component_config(struct hdd_context *hdd_ctx)
2569{
2570 struct hdd_config *cfg = hdd_ctx->config;
2571 struct wlan_ipa_config ipa_cfg;
2572
2573 ipa_cfg.ipa_config = cfg->IpaConfig;
2574 ipa_cfg.desc_size = cfg->IpaDescSize;
2575 ipa_cfg.txbuf_count = cfg->IpaUcTxBufCount;
2576 ipa_cfg.bus_bw_high = cfg->busBandwidthHighThreshold;
2577 ipa_cfg.bus_bw_medium = cfg->busBandwidthMediumThreshold;
2578 ipa_cfg.bus_bw_low = cfg->busBandwidthLowThreshold;
2579 ipa_cfg.ipa_bw_high = cfg->IpaHighBandwidthMbps;
2580 ipa_cfg.ipa_bw_medium = cfg->IpaMediumBandwidthMbps;
2581 ipa_cfg.ipa_bw_low = cfg->IpaLowBandwidthMbps;
2582
2583 ucfg_ipa_update_config(&ipa_cfg);
2584}
2585#else
2586static void hdd_update_ipa_component_config(struct hdd_context *hdd_ctx)
2587{
2588}
2589#endif
2590
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002591#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002592static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2593 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2594{
Jeff Johnson9d295242017-08-29 14:39:48 -07002595 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002596 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002597
2598 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2599 if (!adapter) {
2600 hdd_err("Adapter is NULL");
2601 return PM_MAX_NUM_OF_MODE;
2602 }
2603
2604 return policy_mgr_convert_device_mode_to_qdf_type(
2605 adapter->device_mode);
2606}
2607
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002608static void hdd_register_policy_manager_callback(
2609 struct wlan_objmgr_psoc *psoc)
2610{
2611 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002612
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002613 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002614 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002615 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2616 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002617 hdd_cbacks.get_mode_for_non_connected_vdev =
2618 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302619 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002620
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002621 if (QDF_STATUS_SUCCESS !=
2622 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2623 hdd_err("HDD callback registration with policy manager failed");
2624 }
2625}
2626#else
2627static void hdd_register_policy_manager_callback(
2628 struct wlan_objmgr_psoc *psoc)
2629{
2630}
2631#endif
2632
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002633static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002634{
2635 struct nan_callbacks cb_obj = {0};
2636
2637 cb_obj.ndi_open = hdd_ndi_open;
2638 cb_obj.ndi_close = hdd_ndi_close;
2639 cb_obj.ndi_start = hdd_ndi_start;
2640 cb_obj.ndi_delete = hdd_ndi_delete;
2641 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2642 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2643
Naveen Rawat37f62c82017-03-26 22:24:43 -07002644 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2645 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002646 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002647
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002648 os_if_nan_register_hdd_callbacks(hdd_ctx->hdd_psoc, &cb_obj);
2649}
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002650
Dustin Brown26b3d042017-12-21 11:13:27 -08002651#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002652/**
2653 * hdd_check_for_leaks() - Perform runtime memory leak checks
2654 *
2655 * This API triggers runtime memory leak detection. This feature enforces the
2656 * policy that any memory allocated at runtime must also be released at runtime.
2657 *
2658 * Allocating memory at runtime and releasing it at unload is effectively a
2659 * memory leak for configurations which never unload (e.g. LONU, statically
2660 * compiled driver). Such memory leaks are NOT false positives, and must be
2661 * fixed.
2662 *
2663 * Return: None
2664 */
Dustin Brown4bc0a622017-12-06 15:56:50 -08002665static void hdd_check_for_leaks(void)
2666{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002667 /* DO NOT REMOVE these checks; for false positives, read above first */
2668
Dustin Brown677e0862017-10-10 16:30:09 -07002669 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08002670 qdf_nbuf_map_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08002671 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002672}
2673
Dustin Brown26b3d042017-12-21 11:13:27 -08002674#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
2675#else
2676static inline void hdd_check_for_leaks(void) {}
2677
2678#define hdd_debug_domain_set(domain)
2679#endif /* CONFIG_LEAK_DETECTION */
2680
gbian62edd7e2017-03-07 13:12:13 +08002681/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08002682 * hdd_update_country_code - Update country code
2683 * @hdd_ctx: HDD context
2684 *
2685 * Update country code based on module parameter country_code
2686 *
2687 * Return: 0 on success and errno on failure
2688 */
2689static int hdd_update_country_code(struct hdd_context *hdd_ctx)
2690{
2691 if (!country_code)
2692 return 0;
2693
2694 return hdd_reg_set_country(hdd_ctx, country_code);
2695}
2696
2697/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302698 * hdd_wlan_start_modules() - Single driver state machine for starting modules
2699 * @hdd_ctx: HDD context
2700 * @adapter: HDD adapter
2701 * @reinit: flag to indicate from SSR or normal path
2702 *
2703 * This function maintains the driver state machine it will be invoked from
2704 * startup, reinit and change interface. Depending on the driver state shall
2705 * perform the opening of the modules.
2706 *
2707 * Return: 0 for success; non-zero for failure
2708 */
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002709int hdd_wlan_start_modules(struct hdd_context *hdd_ctx,
2710 struct hdd_adapter *adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05302711 bool reinit)
2712{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002713 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302714 qdf_device_t qdf_dev;
2715 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302716 bool unint = false;
2717 void *hif_ctx;
2718
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002719 hdd_debug("state:%d reinit:%d", hdd_ctx->driver_status, reinit);
Arun Khandavallifae92942016-08-01 13:31:08 +05302720
2721 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2722 if (!qdf_dev) {
2723 hdd_err("QDF Device Context is Invalid return");
2724 return -EINVAL;
2725 }
2726
Dustin Brown6f427922017-09-19 12:19:00 -07002727 hdd_set_idle_ps_config(hdd_ctx, false);
2728 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Arun Khandavallifae92942016-08-01 13:31:08 +05302729
Dustin Brown1fe30a82017-10-03 16:13:36 -07002730 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302731 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
2732 mutex_unlock(&hdd_ctx->iface_change_lock);
2733 hdd_info("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07002734 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302735 return 0;
2736 }
2737
Dustin Brown1fe30a82017-10-03 16:13:36 -07002738 hdd_ctx->start_modules_in_progress = true;
2739
Arun Khandavallifae92942016-08-01 13:31:08 +05302740 switch (hdd_ctx->driver_status) {
2741 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002742 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302743 unint = true;
2744 /* Fall through dont add break here */
2745 case DRIVER_MODULES_CLOSED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002746 hdd_info("Wlan transitioning (CLOSED -> OPENED)");
2747
Dustin Brown26b3d042017-12-21 11:13:27 -08002748 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002749
Arun Khandavallifae92942016-08-01 13:31:08 +05302750 if (!reinit && !unint) {
2751 ret = pld_power_on(qdf_dev->dev);
2752 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002753 hdd_err("Failed to Powerup the device; errno: %d",
2754 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302755 goto release_lock;
2756 }
2757 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002758
2759 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2760 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05302761 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2762 qdf_dev->bus_type,
2763 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2764 HIF_ENABLE_TYPE_PROBE);
2765 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002766 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302767 goto power_down;
2768 }
2769
2770 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302771 if (!hif_ctx) {
2772 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002773 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302774 goto power_down;
2775 }
2776
Arun Khandavallifae92942016-08-01 13:31:08 +05302777 status = ol_cds_init(qdf_dev, hif_ctx);
2778 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002779 hdd_err("No Memory to Create BMI Context; status: %d",
2780 status);
2781 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302782 goto hif_close;
2783 }
2784
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302785 hdd_update_ipa_component_config(hdd_ctx);
2786
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002787 ret = hdd_update_config(hdd_ctx);
2788 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002789 hdd_err("Failed to update configuration; errno: %d",
2790 ret);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002791 goto cds_free;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002792 }
2793
gbian62edd7e2017-03-07 13:12:13 +08002794 hdd_update_cds_ac_specs_params(hdd_ctx);
2795
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302796 status = cds_open(hdd_ctx->hdd_psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002797 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002798 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002799 ret = qdf_status_to_os_return(status);
2800 goto deinit_config;
Arun Khandavallifae92942016-08-01 13:31:08 +05302801 }
2802
Mukul Sharma9d797a02017-01-05 20:26:03 +05302803 /* initalize components configurations after psoc open */
2804 ret = hdd_update_components_config(hdd_ctx);
2805 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002806 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302807 ret);
2808 goto close;
2809 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002810 status = cds_dp_open(hdd_ctx->hdd_psoc);
2811 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002812 hdd_err("Failed to Open cds post open; status: %d",
2813 status);
2814 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002815 goto close;
2816 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302817
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002818 /*
2819 * NAN compoenet requires certian operations like, open adapter,
2820 * close adapter, etc. to be initiated by HDD, for those
2821 * register HDD callbacks with UMAC's NAN componenet.
2822 */
2823 hdd_nan_register_callbacks(hdd_ctx);
2824
Arun Khandavallifae92942016-08-01 13:31:08 +05302825 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
2826
Jeff Johnson3a280122017-09-13 07:42:00 -07002827 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302828 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002829 hdd_err("Failed to pre-enable CDS; status: %d", status);
2830 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002831 goto cds_txrx_free;
Arun Khandavallifae92942016-08-01 13:31:08 +05302832 }
2833
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002834 hdd_register_policy_manager_callback(
2835 hdd_ctx->hdd_psoc);
2836
Amar Singhal0928b192017-12-01 10:50:54 -08002837 hdd_sysfs_create_version_interface(hdd_ctx->hdd_psoc);
2838
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302839 hdd_update_hw_sw_info(hdd_ctx);
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05302840 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002841 hdd_info("Wlan transitioned (now OPENED)");
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302842
Arun Khandavallifae92942016-08-01 13:31:08 +05302843 if (unint) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002844 hdd_debug("In phase-1 initialization don't enable modules");
Arun Khandavallifae92942016-08-01 13:31:08 +05302845 break;
2846 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302847
2848 if (reinit) {
Dustin Browndca39692017-11-09 15:30:25 -08002849 ret = hdd_ipa_uc_ssr_reinit(hdd_ctx);
2850 if (ret) {
2851 hdd_err("HDD IPA UC reinit failed; errno: %d",
2852 ret);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002853 goto post_disable;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08002854 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302855 }
2856
Arun Khandavallifae92942016-08-01 13:31:08 +05302857 /* Fall through dont add break here */
2858 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002859 hdd_info("Wlan transitioning (OPENED -> ENABLED)");
2860
Arun Khandavallifae92942016-08-01 13:31:08 +05302861 if (!adapter) {
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002862 hdd_alert("adapter is Null");
Dustin Browndca39692017-11-09 15:30:25 -08002863 ret = -EINVAL;
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002864 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302865 }
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302866 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2867 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002868 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302869 break;
2870 }
Dustin Browndca39692017-11-09 15:30:25 -08002871
2872 ret = hdd_configure_cds(hdd_ctx, adapter);
2873 if (ret) {
2874 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002875 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302876 }
Dustin Browndca39692017-11-09 15:30:25 -08002877
Komal Seelamf2136bb2016-09-28 18:30:44 +05302878 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08002879
Arun Khandavallifae92942016-08-01 13:31:08 +05302880 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002881 hdd_info("Wlan transitioned (now ENABLED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302882 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08002883
Arun Khandavallifae92942016-08-01 13:31:08 +05302884 default:
2885 hdd_err("WLAN start invoked in wrong state! :%d\n",
2886 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08002887 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05302888 goto release_lock;
2889 }
Dustin Brown550f6d22017-12-14 15:44:01 -08002890
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302891 hdd_ctx->start_modules_in_progress = false;
Paul Zhange03cf4c2018-01-19 18:33:22 +08002892 if (DRIVER_MODULES_ENABLED == hdd_ctx->driver_status) {
2893 ret = hdd_update_country_code(hdd_ctx);
2894 if (ret)
2895 hdd_err("Failed to update command line country code!");
2896 }
Arun Khandavallifae92942016-08-01 13:31:08 +05302897 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown550f6d22017-12-14 15:44:01 -08002898
Dustin Browne74003f2018-03-14 12:51:58 -07002899 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08002900
Arun Khandavallifae92942016-08-01 13:31:08 +05302901 return 0;
2902
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002903post_disable:
Rajeev Kumarbe021242017-02-16 16:12:23 -08002904 cds_post_disable();
Amar Singhal410675c2018-01-10 12:14:21 -08002905 dispatcher_pdev_close(hdd_ctx->hdd_pdev);
Dustin Brownbd68fe12017-11-21 15:28:52 -08002906 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002907
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002908cds_txrx_free:
2909 cds_dp_close(hdd_ctx->hdd_psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08002910
Arun Khandavallifae92942016-08-01 13:31:08 +05302911close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002912 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002913 hdd_info("Wlan transition aborted (now CLOSED)");
2914
Jeff Johnsone4b14592017-09-13 14:23:33 -07002915 cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05302916
Dustin Brown28b17892017-10-10 13:29:38 -07002917deinit_config:
2918 cds_deinit_ini_config();
2919
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002920cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05302921 ol_cds_free();
2922
2923hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002924 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2925 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302926power_down:
2927 if (!reinit && !unint)
2928 pld_power_off(qdf_dev->dev);
2929release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302930 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302931 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002932
2933 /* many adapter resources are not freed by design in SSR case */
2934 if (!reinit)
2935 hdd_check_for_leaks();
Dustin Brown26b3d042017-12-21 11:13:27 -08002936 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002937
Dustin Browne74003f2018-03-14 12:51:58 -07002938 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002939
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002940 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05302941}
2942
Naveen Rawat910726a2017-03-06 11:42:51 -08002943#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002944static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002945{
2946 int ret = os_if_wifi_pos_register_nl();
2947
2948 if (ret)
2949 hdd_err("os_if_wifi_pos_register_nl failed");
2950
2951 return ret;
2952}
2953
2954static int hdd_deactivate_wifi_pos(void)
2955{
2956 int ret = os_if_wifi_pos_deregister_nl();
2957
2958 if (ret)
2959 hdd_err("os_if_wifi_pos_deregister_nl failed");
2960
2961 return ret;
2962}
2963
2964/**
2965 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
2966 * @hdd_ctx: hdd context
2967 *
2968 * Return: status of operation
2969 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002970static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002971{
2972 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
2973 struct hdd_config *cfg = hdd_ctx->config;
2974
2975 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
2976 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
2977 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
2978 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
2979 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
2980 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
2981 wifi_pos_set_dwell_time_min(psoc, cfg->nNeighborScanMinChanTime);
2982 wifi_pos_set_dwell_time_max(psoc, cfg->nNeighborScanMaxChanTime);
2983}
2984#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002985static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002986{
2987 return oem_activate_service(hdd_ctx);
2988}
2989
2990static int hdd_deactivate_wifi_pos(void)
2991{
2992 return 0;
2993}
2994
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002995static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002996{
2997}
2998#endif
2999
Arun Khandavallifae92942016-08-01 13:31:08 +05303000/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003001 * __hdd_open() - HDD Open function
3002 * @dev: Pointer to net_device structure
3003 *
3004 * This is called in response to ifconfig up
3005 *
3006 * Return: 0 for success; non-zero for failure
3007 */
3008static int __hdd_open(struct net_device *dev)
3009{
Jeff Johnson9d295242017-08-29 14:39:48 -07003010 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003011 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003012 int ret;
3013
Dustin Brownfdf17c12018-03-14 12:55:34 -07003014 hdd_enter_dev(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303015 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003016 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003017
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303018 /* Nothing to be done if device is unloading */
3019 if (cds_is_driver_unloading()) {
3020 hdd_err("Driver is unloading can not open the hdd");
3021 return -EBUSY;
3022 }
3023
Dustin Brown01847752017-10-25 13:56:27 -07003024 if (cds_is_driver_recovering()) {
3025 hdd_err("WLAN is currently recovering; Please try again.");
3026 return -EBUSY;
3027 }
3028
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303029 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
3030 hdd_err("con_mode_handler is in progress; Please try again.");
3031 return -EBUSY;
3032 }
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303033
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303034 mutex_lock(&hdd_init_deinit_lock);
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303035 hdd_start_driver_ops_timer(eHDD_DRV_OP_IFF_UP);
3036
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303037 /*
3038 * This scenario can be hit in cases where in the wlan driver after
3039 * registering the netdevices and there is a failure in driver
3040 * initialization. So return error gracefully because the netdevices
3041 * will be de-registered as part of the load failure.
3042 */
3043
3044 if (!cds_is_driver_loaded()) {
3045 hdd_err("Failed to start the wlan driver!!");
3046 ret = -EIO;
3047 goto err_hdd_hdd_init_deinit_lock;
3048 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303049
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003050
Arun Khandavallifae92942016-08-01 13:31:08 +05303051 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
3052 if (ret) {
3053 hdd_err("Failed to start WLAN modules return");
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303054 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303055 }
3056
3057
3058 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3059 ret = hdd_start_adapter(adapter);
3060 if (ret) {
3061 hdd_err("Failed to start adapter :%d",
3062 adapter->device_mode);
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303063 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303064 }
3065 }
3066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3068 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003069 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003070 /* Enable TX queues only when we are connected */
3071 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303072 WLAN_START_ALL_NETIF_QUEUE,
3073 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003074 }
3075
Naveen Rawat286def52016-09-23 15:38:02 -07003076 /* Enable carrier and transmit queues for NDI */
3077 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003078 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003079 wlan_hdd_netif_queue_control(adapter,
3080 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3081 WLAN_CONTROL_PATH);
3082 }
3083
Naveen Rawat910726a2017-03-06 11:42:51 -08003084 hdd_populate_wifi_pos_cfg(hdd_ctx);
3085
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303086err_hdd_hdd_init_deinit_lock:
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303087 hdd_stop_driver_ops_timer();
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303088 mutex_unlock(&hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 return ret;
3090}
3091
Arun Khandavallifae92942016-08-01 13:31:08 +05303092
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093/**
3094 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
3095 * @dev: Pointer to net_device structure
3096 *
3097 * This is called in response to ifconfig up
3098 *
3099 * Return: 0 for success; non-zero for failure
3100 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003101static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102{
3103 int ret;
3104
3105 cds_ssr_protect(__func__);
3106 ret = __hdd_open(dev);
3107 cds_ssr_unprotect(__func__);
3108
3109 return ret;
3110}
3111
3112/**
3113 * __hdd_stop() - HDD stop function
3114 * @dev: Pointer to net_device structure
3115 *
3116 * This is called in response to ifconfig down
3117 *
3118 * Return: 0 for success; non-zero for failure
3119 */
3120static int __hdd_stop(struct net_device *dev)
3121{
Jeff Johnson9d295242017-08-29 14:39:48 -07003122 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003123 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003124 int ret;
3125
Dustin Brownfdf17c12018-03-14 12:55:34 -07003126 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303128 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003129 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130
3131 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303132 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003133 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003134
3135 /* Nothing to be done if the interface is not opened */
3136 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003137 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138 return -ENODEV;
3139 }
3140
3141 /* Make sure the interface is marked as closed */
3142 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303143
3144 hdd_debug("Disabling Auto Power save timer");
3145 sme_ps_disable_auto_ps_timer(
3146 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07003147 adapter->session_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303148
3149 /*
3150 * Disable TX on the interface, after this hard_start_xmit() will not
3151 * be called on that interface
3152 */
Dustin Brown5e89ef82018-03-14 11:50:23 -07003153 hdd_info("Disabling queues, adapter device mode: %s(%d)",
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003154 hdd_device_mode_to_string(adapter->device_mode),
3155 adapter->device_mode);
3156
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303157 wlan_hdd_netif_queue_control(adapter,
3158 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3159 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003160
3161 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003162 * NAN data interface is different in some sense. The traffic on NDI is
3163 * bursty in nature and depends on the need to transfer. The service
3164 * layer may down the interface after the usage and up again when
3165 * required. In some sense, the NDI is expected to be available
3166 * (like SAP) iface until NDI delete request is issued by the service
3167 * layer. Skip BSS termination and adapter deletion for NAN Data
3168 * interface (NDI).
3169 */
3170 if (WLAN_HDD_IS_NDI(adapter))
3171 return 0;
3172
3173 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003174 * The interface is marked as down for outside world (aka kernel)
3175 * But the driver is pretty much alive inside. The driver needs to
3176 * tear down the existing connection on the netdev (session)
3177 * cleanup the data pipes and wait until the control plane is stabilized
3178 * for this interface. The call also needs to wait until the above
3179 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003180 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003181 * That is intentional to be able to scan if it is a STA/P2P interface
3182 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003183 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003184
3185 /* DeInit the adapter. This ensures datapath cleanup as well */
3186 hdd_deinit_adapter(hdd_ctx, adapter, true);
3187
Arun Khandavallifae92942016-08-01 13:31:08 +05303188
3189 /*
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +05303190 * Upon wifi turn off, DUT has to flush the scan results so if
3191 * this is the last cli iface, flush the scan database.
3192 */
3193 if (!hdd_is_cli_iface_up(hdd_ctx))
3194 sme_scan_flush_result(hdd_ctx->hHal);
3195
3196 /*
Arun Khandavallifae92942016-08-01 13:31:08 +05303197 * Find if any iface is up. If any iface is up then can't put device to
3198 * sleep/power save mode
3199 */
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05303200 if (hdd_check_for_opened_interfaces(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003201 hdd_debug("Closing all modules from the hdd_stop");
Dustin Brown6f427922017-09-19 12:19:00 -07003202 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
3203 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +05303204 hdd_prevent_suspend_timeout(
3205 hdd_ctx->config->iface_change_wait_time,
3206 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Arun Khandavallifae92942016-08-01 13:31:08 +05303207 }
3208
Dustin Browne74003f2018-03-14 12:51:58 -07003209 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003210 return 0;
3211}
3212
3213/**
3214 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3215 * @dev: pointer to net_device structure
3216 *
3217 * This is called in response to ifconfig down
3218 *
3219 * Return: 0 for success and error number for failure
3220 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003221static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003222{
3223 int ret;
3224
3225 cds_ssr_protect(__func__);
3226 ret = __hdd_stop(dev);
3227 cds_ssr_unprotect(__func__);
3228
3229 return ret;
3230}
3231
3232/**
3233 * __hdd_uninit() - HDD uninit function
3234 * @dev: Pointer to net_device structure
3235 *
3236 * This is called during the netdev unregister to uninitialize all data
3237 * associated with the device
3238 *
3239 * Return: None
3240 */
3241static void __hdd_uninit(struct net_device *dev)
3242{
Jeff Johnson9d295242017-08-29 14:39:48 -07003243 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003244 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003245
Dustin Brownfdf17c12018-03-14 12:55:34 -07003246 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003247
3248 do {
3249 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003250 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003251 break;
3252 }
3253
Jeff Johnson399c6272017-08-30 10:51:00 -07003254 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3255 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003256 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003257 break;
3258 }
3259
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003260 if (dev != adapter->dev)
3261 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262
Jeff Johnson399c6272017-08-30 10:51:00 -07003263 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003264
3265 /* after uninit our adapter structure will no longer be valid */
3266 adapter->dev = NULL;
3267 adapter->magic = 0;
3268 } while (0);
3269
Dustin Browne74003f2018-03-14 12:51:58 -07003270 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271}
3272
3273/**
3274 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
3275 * @dev: pointer to net_device structure
3276 *
3277 * This is called during the netdev unregister to uninitialize all data
3278 * associated with the device
3279 *
3280 * Return: none
3281 */
3282static void hdd_uninit(struct net_device *dev)
3283{
3284 cds_ssr_protect(__func__);
3285 __hdd_uninit(dev);
3286 cds_ssr_unprotect(__func__);
3287}
3288
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003289static int hdd_open_cesium_nl_sock(void)
3290{
3291#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3292 struct netlink_kernel_cfg cfg = {
3293 .groups = WLAN_NLINK_MCAST_GRP_ID,
3294 .input = NULL
3295 };
3296#endif
3297 int ret = 0;
3298
3299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3300 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3301#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3302 THIS_MODULE,
3303#endif
3304 &cfg);
3305#else
3306 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3307 WLAN_NLINK_MCAST_GRP_ID,
3308 NULL, NULL, THIS_MODULE);
3309#endif
3310
3311 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003312 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003313 ret = -ECONNREFUSED;
3314 }
3315
3316 return ret;
3317}
3318
3319static void hdd_close_cesium_nl_sock(void)
3320{
3321 if (NULL != cesium_nl_srv_sock) {
3322 netlink_kernel_release(cesium_nl_srv_sock);
3323 cesium_nl_srv_sock = NULL;
3324 }
3325}
3326
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003327/**
3328 * __hdd_set_mac_address() - set the user specified mac address
3329 * @dev: Pointer to the net device.
3330 * @addr: Pointer to the sockaddr.
3331 *
3332 * This function sets the user specified mac address using
3333 * the command ifconfig wlanX hw ether <mac adress>.
3334 *
3335 * Return: 0 for success, non zero for failure
3336 */
3337static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3338{
Jeff Johnson9d295242017-08-29 14:39:48 -07003339 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003340 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303342 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003343 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303344 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003345
Dustin Brownfdf17c12018-03-14 12:55:34 -07003346 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003347
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303348 if (netif_running(dev)) {
3349 hdd_err("On iface up, set mac address change isn't supported");
3350 return -EBUSY;
3351 }
3352
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3354 ret = wlan_hdd_validate_context(hdd_ctx);
3355 if (0 != ret)
3356 return ret;
3357
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303358 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
3359
3360 if (qdf_is_macaddr_zero(&mac_addr)) {
3361 hdd_err("MAC is all zero");
3362 return -EINVAL;
3363 }
3364
3365 if (qdf_is_macaddr_broadcast(&mac_addr)) {
3366 hdd_err("MAC is Broadcast");
3367 return -EINVAL;
3368 }
3369
3370 if (ETHER_IS_MULTICAST(psta_mac_addr->sa_data)) {
3371 hdd_err("MAC is Multicast");
3372 return -EINVAL;
3373 }
3374
Jeff Johnson1e851a12017-10-28 14:36:12 -07003375 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003376 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3377
Dustin Browne74003f2018-03-14 12:51:58 -07003378 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303379 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003380}
3381
3382/**
3383 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
3384 * function from SSR
3385 * @dev: pointer to net_device structure
3386 * @addr: Pointer to the sockaddr
3387 *
3388 * This function sets the user specified mac address using
3389 * the command ifconfig wlanX hw ether <mac adress>.
3390 *
3391 * Return: 0 for success.
3392 */
3393static int hdd_set_mac_address(struct net_device *dev, void *addr)
3394{
3395 int ret;
3396
3397 cds_ssr_protect(__func__);
3398 ret = __hdd_set_mac_address(dev, addr);
3399 cds_ssr_unprotect(__func__);
3400
3401 return ret;
3402}
3403
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003404uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405{
3406 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003407
Anurag Chouhan6d760662016-02-20 16:05:43 +05303408 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003409 if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
3410 break;
3411 }
3412
Anurag Chouhan6d760662016-02-20 16:05:43 +05303413 if (QDF_MAX_CONCURRENCY_PERSONA == i)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003414 return NULL;
3415
3416 hdd_ctx->config->intfAddrMask |= (1 << i);
3417 return &hdd_ctx->config->intfMacAddr[i].bytes[0];
3418}
3419
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003420void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3421 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003422{
3423 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003424
Anurag Chouhan6d760662016-02-20 16:05:43 +05303425 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003426 if (!memcmp(releaseAddr,
3427 &hdd_ctx->config->intfMacAddr[i].bytes[0],
3428 6)) {
3429 hdd_ctx->config->intfAddrMask &= ~(1 << i);
3430 break;
3431 }
3432 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003433}
3434
3435#ifdef WLAN_FEATURE_PACKET_FILTERING
3436/**
3437 * __hdd_set_multicast_list() - set the multicast address list
3438 * @dev: Pointer to the WLAN device.
3439 * @skb: Pointer to OS packet (sk_buff).
3440 *
3441 * This funciton sets the multicast address list.
3442 *
3443 * Return: None
3444 */
3445static void __hdd_set_multicast_list(struct net_device *dev)
3446{
Jeff Johnson9d295242017-08-29 14:39:48 -07003447 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003448 int i = 0, status;
3449 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003450 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303451 struct pmo_mc_addr_list_params *mc_list_request = NULL;
3452 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
3453 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003454
Dustin Brownfdf17c12018-03-14 12:55:34 -07003455 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303456 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303457 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303458
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303460 if (0 != status)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303461 goto out;
3462
Dustin Brownc788acb2017-08-01 17:43:51 -07003463 status = hdd_validate_adapter(adapter);
3464 if (status)
3465 goto out;
3466
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303467 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3468 hdd_err("%s: Driver module is closed", __func__);
3469 return;
3470 }
3471
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303472 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
3473 if (!mc_list_request) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003474 hdd_err("Cannot allocate mc_list_request");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303475 goto out;
3476 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003477
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303478 /* Delete already configured multicast address list */
3479 if (adapter->mc_addr_list.mc_cnt > 0) {
3480 hdd_info("clear previously configured MC address list");
3481 hdd_disable_and_flush_mc_addr_list(adapter,
3482 pmo_mc_list_change_notify);
3483 }
3484
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003485 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003486 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303487 hdd_disable_and_flush_mc_addr_list(adapter,
3488 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003489 } else {
3490 mc_count = netdev_mc_count(dev);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303491 if (mc_count > pmo_ucfg_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003492 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303493 pmo_ucfg_max_mc_addr_supported(psoc));
3494 hdd_disable_and_flush_mc_addr_list(adapter,
3495 pmo_mc_list_change_notify);
3496 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003497 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003498 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003499 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303500 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003501 if (i == mc_count)
3502 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303503 memset(&(mc_list_request->mc_addr[i].bytes),
3504 0, ETH_ALEN);
3505 memcpy(&(mc_list_request->mc_addr[i].bytes),
3506 ha->addr, ETH_ALEN);
3507 hdd_info("mlist[%d] = %pM", i,
3508 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003509 i++;
3510 }
3511 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303512
3513 mc_list_request->psoc = psoc;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003514 mc_list_request->vdev_id = adapter->session_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303515 mc_list_request->count = mc_count;
3516 status = hdd_cache_mc_addr_list(mc_list_request);
3517 if (status == 0) {
3518 hdd_enable_mc_addr_filtering(adapter,
3519 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003520 } else {
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303521 hdd_err("error while caching mc list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003522 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303523out:
3524 if (mc_list_request)
3525 qdf_mem_free(mc_list_request);
Dustin Browne74003f2018-03-14 12:51:58 -07003526 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003527}
3528
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303529
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003530/**
3531 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
3532 * @dev: pointer to net_device
3533 *
3534 * Return: none
3535 */
3536static void hdd_set_multicast_list(struct net_device *dev)
3537{
3538 cds_ssr_protect(__func__);
3539 __hdd_set_multicast_list(dev);
3540 cds_ssr_unprotect(__func__);
3541}
3542#endif
3543
3544/**
3545 * hdd_select_queue() - used by Linux OS to decide which queue to use first
3546 * @dev: Pointer to the WLAN device.
3547 * @skb: Pointer to OS packet (sk_buff).
3548 *
3549 * This function is registered with the Linux OS for network
3550 * core to decide which queue to use first.
3551 *
3552 * Return: ac, Queue Index/access category corresponding to UP in IP header
3553 */
3554static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
3555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
3556 , void *accel_priv
3557#endif
3558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3559 , select_queue_fallback_t fallback
3560#endif
3561)
3562{
3563 return hdd_wmm_select_queue(dev, skb);
3564}
3565
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003566static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567 .ndo_open = hdd_open,
3568 .ndo_stop = hdd_stop,
3569 .ndo_uninit = hdd_uninit,
3570 .ndo_start_xmit = hdd_hard_start_xmit,
3571 .ndo_tx_timeout = hdd_tx_timeout,
3572 .ndo_get_stats = hdd_get_stats,
3573 .ndo_do_ioctl = hdd_ioctl,
3574 .ndo_set_mac_address = hdd_set_mac_address,
3575 .ndo_select_queue = hdd_select_queue,
3576#ifdef WLAN_FEATURE_PACKET_FILTERING
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003577 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003578#endif
3579};
3580
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003581/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003582static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003583 .ndo_open = hdd_mon_open,
3584 .ndo_stop = hdd_stop,
3585 .ndo_get_stats = hdd_get_stats,
3586};
3587
3588/**
3589 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003590 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003591 * Return: None
3592 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003593void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003595 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
Jeff Johnson5505db82017-11-02 21:19:23 -07003596 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003597 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003598 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003599}
3600
3601/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003602 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3603 * @hdd_ctx: global hdd context
3604 * @macAddr: mac address to assign to the interface
3605 * @name: User-visible name of the interface
3606 *
3607 * hdd adapter pointer would point to the netdev->priv space, this function
3608 * would retrive the pointer, and setup the hdd adapter configuration.
3609 *
3610 * Return: the pointer to hdd adapter, otherwise NULL
3611 */
Jeff Johnson9d295242017-08-29 14:39:48 -07003612static struct hdd_adapter *hdd_alloc_station_adapter(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003613 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003614 unsigned char name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615 const char *name)
3616{
Jeff Johnson5505db82017-11-02 21:19:23 -07003617 struct net_device *dev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07003618 struct hdd_adapter *adapter = NULL;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003619 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303620 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003621 /*
3622 * cfg80211 initialization and registration....
3623 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003624 dev = alloc_netdev_mq(sizeof(struct hdd_adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
3626 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003627#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003628 (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
3629 hdd_mon_mode_ether_setup : ether_setup),
3630 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003631
Jeff Johnson5505db82017-11-02 21:19:23 -07003632 if (dev != NULL) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003633
3634 /* Save the pointer to the net_device in the HDD adapter */
Jeff Johnson5505db82017-11-02 21:19:23 -07003635 adapter = (struct hdd_adapter *) netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003636
Jeff Johnson9d295242017-08-29 14:39:48 -07003637 qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
Jeff Johnsonb9424862017-10-30 08:49:35 -07003638 sta_ctx = &adapter->session.station;
Hanumanth Reddy Pothula18553ae2017-04-28 15:03:10 +05303639 qdf_mem_set(sta_ctx->conn_info.staId,
3640 sizeof(sta_ctx->conn_info.staId),
3641 HDD_WLAN_INVALID_STA_ID);
Jeff Johnson5505db82017-11-02 21:19:23 -07003642 adapter->dev = dev;
Jeff Johnsondba0db62017-08-30 11:12:39 -07003643 adapter->hdd_ctx = hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003644 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003645 adapter->session_id = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003646
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303647 qdf_status = qdf_event_create(
3648 &adapter->qdf_session_open_event);
3649 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3650 hdd_err("Session open QDF event init failed!");
3651 free_netdev(adapter->dev);
3652 return NULL;
3653 }
3654
3655 qdf_status = qdf_event_create(
3656 &adapter->qdf_session_close_event);
3657 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3658 hdd_err("Session close QDF event init failed!");
3659 free_netdev(adapter->dev);
3660 return NULL;
3661 }
3662
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003663 init_completion(&adapter->disconnect_comp_var);
Abhishek Singh533c9da2017-05-04 10:23:34 +05303664 init_completion(&adapter->roaming_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003665 init_completion(&adapter->linkup_event_var);
3666 init_completion(&adapter->cancel_rem_on_chan_var);
3667 init_completion(&adapter->rem_on_chan_ready_event);
3668 init_completion(&adapter->sta_authorized_event);
3669 init_completion(&adapter->offchannel_tx_event);
3670 init_completion(&adapter->tx_action_cnf_event);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003671 init_completion(&adapter->ibss_peer_info_comp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003672 init_completion(&adapter->change_country_code);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05303673 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003674
3675 adapter->offloads_configured = false;
Jeff Johnsonc72c5732017-10-28 12:49:37 -07003676 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003677 /* Init the net_device structure */
Jeff Johnson5505db82017-11-02 21:19:23 -07003678 strlcpy(dev->name, name, IFNAMSIZ);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679
Jeff Johnson5505db82017-11-02 21:19:23 -07003680 qdf_mem_copy(dev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003681 sizeof(tSirMacAddr));
Jeff Johnson1e851a12017-10-28 14:36:12 -07003682 qdf_mem_copy(adapter->mac_addr.bytes, macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003683 sizeof(tSirMacAddr));
Jeff Johnson5505db82017-11-02 21:19:23 -07003684 dev->watchdog_timeo = HDD_TX_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003685
3686 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
Jeff Johnson5505db82017-11-02 21:19:23 -07003687 dev->features |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003688 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
Jeff Johnson5505db82017-11-02 21:19:23 -07003689 dev->features |= NETIF_F_RXCSUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003690
Jeff Johnson5505db82017-11-02 21:19:23 -07003691 hdd_set_tso_flags(hdd_ctx, dev);
Dhanashri Atre83d373d2015-07-28 16:45:59 -07003692
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003693 hdd_set_station_ops(adapter->dev);
3694
Jeff Johnson5505db82017-11-02 21:19:23 -07003695 hdd_dev_setup_destructor(dev);
3696 dev->ieee80211_ptr = &adapter->wdev;
3697 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003698 adapter->wdev.wiphy = hdd_ctx->wiphy;
Jeff Johnson5505db82017-11-02 21:19:23 -07003699 adapter->wdev.netdev = dev;
3700 /* set dev's parent to underlying device */
3701 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003702 hdd_wmm_init(adapter);
3703 spin_lock_init(&adapter->pause_map_lock);
Nirav Shah617cff92016-04-25 10:24:24 +05303704 adapter->start_time = adapter->last_time = qdf_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003705 }
3706
3707 return adapter;
3708}
3709
Jeff Johnson9d295242017-08-29 14:39:48 -07003710static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003711{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003712 struct net_device *dev = adapter->dev;
3713 int ret;
3714
Dustin Brown491d54b2018-03-14 12:39:11 -07003715 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003716
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003717 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003718 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3719
3720 ret = dev_alloc_name(dev, dev->name);
3721 if (ret < 0) {
3722 hdd_err(
3723 "unable to get dev name: %s, err = 0x%x",
3724 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303725 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003726 }
3727 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003728
3729 ret = register_netdevice(dev);
3730 if (ret) {
3731 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3732 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303733 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003734 }
3735 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003736 ret = register_netdev(dev);
3737 if (ret) {
3738 hdd_err("register_netdev(%s) failed, err = 0x%x",
3739 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303740 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 }
3742 }
3743 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3744
Dustin Browne74003f2018-03-14 12:51:58 -07003745 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003746
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303747 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003748}
3749
Krunal Sonib51eec72017-11-20 21:53:01 -08003750QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003751{
Krunal Sonib51eec72017-11-20 21:53:01 -08003752 struct hdd_adapter *adapter;
3753 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003754
Krunal Sonib51eec72017-11-20 21:53:01 -08003755 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3756 if (!hdd_ctx) {
3757 hdd_err("Invalid HDD_CTX");
3758 return QDF_STATUS_E_FAILURE;
3759 }
3760
3761 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
3762 if (NULL == adapter) {
3763 hdd_err("NULL adapter");
3764 return QDF_STATUS_E_INVAL;
3765 }
3766 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303767 qdf_event_set(&adapter->qdf_session_open_event);
Krunal Sonib51eec72017-11-20 21:53:01 -08003768 hdd_debug("session %d opened", adapter->session_id);
3769
3770 return QDF_STATUS_SUCCESS;
3771}
3772
3773QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
3774{
3775 struct hdd_adapter *adapter;
3776 struct hdd_context *hdd_ctx;
3777
3778 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3779 if (!hdd_ctx) {
3780 hdd_err("Invalid HDD_CTX");
3781 return QDF_STATUS_E_FAILURE;
3782 }
3783
3784 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003786 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303787 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003788 }
3789
3790 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003791 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303792 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003793 }
3794
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003795 /*
3796 * For NAN Data interface, the close session results in the final
3797 * indication to the userspace
3798 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003799 if (adapter->device_mode == QDF_NDI_MODE)
3800 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003801
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003802 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3803
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804 /*
3805 * We can be blocked while waiting for scheduled work to be
3806 * flushed, and the adapter structure can potentially be freed, in
3807 * which case the magic will have been reset. So make sure the
3808 * magic is still good, and hence the adapter structure is still
3809 * valid, before signaling completion
3810 */
3811 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303812 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003813
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303814 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003815}
3816
Jeff Johnson9d295242017-08-29 14:39:48 -07003817int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003818{
Dustin Brownd28772b2017-03-17 14:16:07 -07003819 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003820
Dustin Brownd28772b2017-03-17 14:16:07 -07003821 status = pmo_vdev_ready(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003822 if (QDF_IS_STATUS_ERROR(status))
3823 return qdf_status_to_os_return(status);
3824
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003825 status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003826 if (QDF_IS_STATUS_ERROR(status))
3827 return qdf_status_to_os_return(status);
3828
3829 if (wma_capability_enhanced_mcast_filter())
3830 status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev);
3831 else
3832 status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07003833
3834 return qdf_status_to_os_return(status);
3835}
3836
Jeff Johnson9d295242017-08-29 14:39:48 -07003837int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07003838{
3839 QDF_STATUS status;
Jiachao Wu2c42c222018-01-15 18:13:19 +08003840 int errno = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003841 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003842 uint8_t vdev_id;
Dustin Brownd28772b2017-03-17 14:16:07 -07003843
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003844 vdev_id = adapter->session_id;
3845 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003846
3847 /* vdev created sanity check */
3848 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07003849 hdd_err("vdev for Id %d does not exist", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003850 return -EINVAL;
3851 }
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003852 status = ucfg_reg_11d_vdev_delete_update(adapter->hdd_vdev);
Yue Maf9782842017-05-08 12:49:49 -07003853
Dustin Brownd28772b2017-03-17 14:16:07 -07003854 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303855 qdf_event_reset(&adapter->qdf_session_close_event);
Dustin Brownd28772b2017-03-17 14:16:07 -07003856 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08003857 status = sme_close_session(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003858 if (QDF_IS_STATUS_ERROR(status)) {
3859 hdd_err("failed to close sme session: %d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003860 errno = qdf_status_to_os_return(status);
3861 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07003862 }
3863
3864 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303865 status = qdf_wait_for_event_completion(
3866 &adapter->qdf_session_close_event,
3867 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3868 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003869 if (adapter->device_mode == QDF_NDI_MODE)
3870 hdd_ndp_session_end_handler(adapter);
3871 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303872 adapter->session_id = HDD_SESSION_ID_INVALID;
3873 if (QDF_STATUS_E_TIMEOUT != status) {
3874 hdd_err("timed out waiting for close sme session: %u", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003875 errno = -ETIMEDOUT;
3876 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303877 } else if (adapter->qdf_session_close_event.force_set) {
3878 hdd_err("Session close evt focefully set, SSR/PDR has occurred");
Jiachao Wu2c42c222018-01-15 18:13:19 +08003879 errno = -EINVAL;
3880 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303881 } else {
3882 hdd_err("Failed to close sme session (%u)", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08003883 errno = -EINVAL;
3884 goto release_vdev;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303885 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003886 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08003887
Yue Maf9782842017-05-08 12:49:49 -07003888release_vdev:
Frank Liuc66d4bf2018-01-26 16:18:18 +08003889 /*
3890 * In SSR or driver unloading case, directly exit may cause objects
3891 * leak, if sme_close_session failed. Free objects anyway.
Jiachao Wu2c42c222018-01-15 18:13:19 +08003892 */
Kabilan Kannanb867c312018-02-15 17:43:21 -08003893 if (errno && !cds_is_driver_recovering() && !cds_is_driver_unloading())
Jiachao Wu2c42c222018-01-15 18:13:19 +08003894 return errno;
3895
Sandeep Puligillaef415362017-08-30 16:37:13 -07003896 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08003897 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07003898 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08003899 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07003900 return errno;
3901 }
3902
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003903 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003904
3905 return 0;
3906}
3907
Krunal Sonib51eec72017-11-20 21:53:01 -08003908static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
3909 struct sme_session_params *session_param,
3910 csr_roam_completeCallback callback,
3911 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07003912{
Dustin Brownd28772b2017-03-17 14:16:07 -07003913 uint32_t type;
3914 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08003915 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07003916
3917 /* determine vdev (sub)type */
3918 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303919 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003920 hdd_err("failed to get vdev type: %d", status);
3921 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003922 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003923 session_param->sme_session_id = adapter->session_id;
3924 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
3925 session_param->type_of_persona = type;
3926 session_param->subtype_of_persona = sub_type;
3927 session_param->session_open_cb = hdd_sme_open_session_callback;
3928 session_param->session_close_cb = hdd_sme_close_session_callback;
3929 session_param->callback = callback;
3930 session_param->callback_ctx = callback_ctx;
3931
3932 return 0;
3933}
3934
3935int hdd_vdev_create(struct hdd_adapter *adapter,
3936 csr_roam_completeCallback callback, void *ctx)
3937{
3938 QDF_STATUS status;
3939 int errno;
3940 struct hdd_context *hdd_ctx;
3941 struct sme_session_params sme_session_params = {0};
Krunal Sonib51eec72017-11-20 21:53:01 -08003942
3943 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07003944
3945 /* do vdev create via objmgr */
3946 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown7d043f62017-03-27 12:07:36 -07003947 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07003948 if (errno) {
3949 hdd_err("failed to create objmgr vdev: %d", errno);
3950 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003951 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003952
3953 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303954 status = qdf_event_reset(&adapter->qdf_session_open_event);
3955 if (QDF_STATUS_SUCCESS != status) {
3956 hdd_err("failed to reinit session open event");
3957 return -EINVAL;
3958 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003959 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
3960 callback, ctx);
3961 if (errno) {
3962 hdd_err("failed to populating SME params");
3963 goto objmgr_vdev_destroy_procedure;
3964 }
3965
3966 status = sme_open_session(hdd_ctx->hHal, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07003967 if (QDF_IS_STATUS_ERROR(status)) {
3968 hdd_err("failed to open sme session: %d", status);
3969 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07003970 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003971 }
3972
3973 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303974 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
3975 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3976 if (QDF_STATUS_SUCCESS != status) {
3977 if (adapter->qdf_session_open_event.force_set) {
3978 /*
3979 * SSR/PDR has caused shutdown, which has forcefully
3980 * set the event. Return without the closing session.
3981 */
3982 adapter->session_id = HDD_SESSION_ID_INVALID;
3983 hdd_err("Session open event forcefully set");
3984 return -EINVAL;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303985 }
Jeff Johnsonc66d3102018-02-28 11:58:26 -08003986
3987 if (QDF_STATUS_E_TIMEOUT == status)
3988 hdd_err("Session failed to open within timeout period");
3989 else
3990 hdd_err("Failed to wait for session open event(status-%d)",
3991 status);
3992 errno = -ETIMEDOUT;
3993 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3994 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003995 }
3996
3997 /* firmware ready for component communication, raise vdev_ready event */
3998 errno = hdd_vdev_ready(adapter);
3999 if (errno) {
4000 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004001 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004002 }
4003
Jeff Johnson1b780e42017-10-31 14:11:45 -07004004 hdd_info("vdev %d created successfully", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004005
4006 return 0;
4007
4008 /*
4009 * Due to legacy constraints, we need to destroy in the same order as
4010 * create. So, split error handling into 2 cases to accommodate.
4011 */
4012
Krunal Soni4a020c72017-10-30 20:58:40 -07004013objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07004014 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07004015
4016 return errno;
4017
Krunal Soni4a020c72017-10-30 20:58:40 -07004018hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004019 QDF_BUG(!hdd_vdev_destroy(adapter));
4020
4021 return errno;
4022}
4023
Jeff Johnson9d295242017-08-29 14:39:48 -07004024QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004025{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004026 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004027 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004028 QDF_STATUS status;
4029 int ret_val;
4030
Dustin Brownd28772b2017-03-17 14:16:07 -07004031 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4032 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
4033 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Jeff Johnson1b780e42017-10-31 14:11:45 -07004034 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004035
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004036 /* Register wireless extensions */
Dustin Brownd28772b2017-03-17 14:16:07 -07004037 status = hdd_register_wext(adapter->dev);
4038 if (QDF_IS_STATUS_ERROR(status)) {
4039 hdd_err("failed to register wireless extensions: %d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004040 goto error_register_wext;
4041 }
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004042 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043
Jeff Johnsond377dce2017-10-04 10:32:42 -07004044 qdf_mem_set(sta_ctx->conn_info.staId,
4045 sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304046
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004047 /* set fast roaming capability in sme session */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004048 status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->session_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304049 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004050 /* Set the default operation channel */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004051 sta_ctx->conn_info.operationChannel =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004052 hdd_ctx->config->OperatingChannel;
4053
4054 /* Make the default Auth Type as OPEN */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004055 sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004056
4057 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304058 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004059 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004060 status, status);
4061 goto error_init_txrx;
4062 }
4063
4064 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4065
4066 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304067 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004068 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004069 status, status);
4070 goto error_wmm_init;
4071 }
4072
4073 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4074
Jeff Johnson1b780e42017-10-31 14:11:45 -07004075 ret_val = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076 WMI_PDEV_PARAM_BURST_ENABLE,
4077 hdd_ctx->config->enableSifsBurst,
4078 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004079 if (ret_val)
4080 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004081
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304082 /*
4083 * In case of USB tethering, LRO is disabled. If SSR happened
4084 * during that time, then as part of SSR init, do not enable
4085 * the LRO again. Keep the LRO state same as before SSR.
4086 */
4087 if (!(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Dhanashri Atre1a6a4ce2017-05-03 19:40:33 -07004088 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304089
4090 /* rcpi info initialization */
4091 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4092
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304093 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004094
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004095error_wmm_init:
4096 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4097 hdd_deinit_tx_rx(adapter);
4098error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004099 hdd_unregister_wext(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004100error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07004101 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004102
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004103 return status;
4104}
4105
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304106/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004107 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304108 * @hdd_ctx: global hdd context
4109 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004110 * @rtnl_held: Used to indicate whether or not the caller is holding
4111 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304112 *
4113 * This function De-initializes the STA/P2P/OCB adapter.
4114 *
4115 * Return: None.
4116 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004117static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004118 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004119 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304120{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004121 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304122
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304123 if (adapter->dev) {
4124 if (rtnl_held)
4125 adapter->dev->wireless_handlers = NULL;
4126 else {
4127 rtnl_lock();
4128 adapter->dev->wireless_handlers = NULL;
4129 rtnl_unlock();
4130 }
4131 }
4132
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304133 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4134 hdd_deinit_tx_rx(adapter);
4135 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4136 }
4137
4138 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4139 hdd_wmm_adapter_close(adapter);
4140 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4141 }
4142
Krunal Sonib51eec72017-11-20 21:53:01 -08004143
Dustin Browne74003f2018-03-14 12:51:58 -07004144 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304145}
4146
Krunal Sonib51eec72017-11-20 21:53:01 -08004147void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4148 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004149 bool rtnl_held)
4150{
Dustin Brown491d54b2018-03-14 12:39:11 -07004151 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004153 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004154 case QDF_STA_MODE:
4155 case QDF_P2P_CLIENT_MODE:
4156 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004157 case QDF_IBSS_MODE:
4158 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004159 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004160 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004161 break;
4162 }
4163
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004164 case QDF_SAP_MODE:
4165 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004166 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004167 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004168 break;
4169 }
4170
4171 default:
4172 break;
4173 }
4174
Dustin Browne74003f2018-03-14 12:51:58 -07004175 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004176}
4177
Jeff Johnson9d295242017-08-29 14:39:48 -07004178static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004179 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004180{
Jeff Johnson5505db82017-11-02 21:19:23 -07004181 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004182
4183 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004184 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004185 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004186 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187 return;
4188 }
4189
Rajeev Kumardca5f812016-02-04 17:28:06 -08004190 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304191
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192 /*
4193 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4194 * the driver is almost closed and cannot handle either control
4195 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004196 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4197 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004198 * is not right. Setting this flag helps hdd_stop() to recognize that
4199 * the interface is closed and restricts any operations on that
4200 */
4201 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4202
4203 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004204 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004205 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004206 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004207 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004208 /*
4209 * Note that the adapter is no longer valid at this point
4210 * since the memory has been reclaimed
4211 */
4212 }
4213}
4214
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004215static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07004216 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004217{
Jeff Johnson9d295242017-08-29 14:39:48 -07004218 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004219
Dustin Brown920397d2017-12-13 16:27:50 -08004220 hdd_for_each_adapter(hdd_ctx, adapter) {
4221 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
4222 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304223 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004224 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004225 }
Dustin Brown920397d2017-12-13 16:27:50 -08004226
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304227 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004229
Arun Khandavalli2358d522016-05-16 18:05:37 +05304230#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4231/**
4232 * hdd_set_fw_log_params() - Set log parameters to FW
4233 * @hdd_ctx: HDD Context
4234 * @adapter: HDD Adapter
4235 *
4236 * This function set the FW Debug log level based on the INI.
4237 *
4238 * Return: None
4239 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004240static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004241 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304242{
4243 uint8_t count = 0, numentries = 0,
4244 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
4245 uint32_t value = 0;
4246 int ret;
4247
Arun Khandavallifae92942016-08-01 13:31:08 +05304248 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4249 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004250 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304251 return;
4252 }
4253
Arun Khandavallifae92942016-08-01 13:31:08 +05304254 /* Enable FW logs based on INI configuration */
Arun Khandavalli2358d522016-05-16 18:05:37 +05304255 hdd_ctx->fw_log_settings.dl_type =
4256 hdd_ctx->config->enableFwLogType;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004257 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304258 WMI_DBGLOG_TYPE,
4259 hdd_ctx->config->enableFwLogType,
4260 DBG_CMD);
4261 if (ret != 0)
4262 hdd_err("Failed to enable FW log type ret %d",
4263 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304264
4265 hdd_ctx->fw_log_settings.dl_loglevel =
Arun Khandavallifae92942016-08-01 13:31:08 +05304266 hdd_ctx->config->enableFwLogLevel;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004267 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304268 WMI_DBGLOG_LOG_LEVEL,
4269 hdd_ctx->config->enableFwLogLevel,
4270 DBG_CMD);
4271 if (ret != 0)
4272 hdd_err("Failed to enable FW log level ret %d",
4273 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304274
4275 hdd_string_to_u8_array(
4276 hdd_ctx->config->enableFwModuleLogLevel,
4277 moduleloglevel,
4278 &numentries,
4279 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
4280
4281 while (count < numentries) {
4282 /*
4283 * FW module log level input string looks like
4284 * below:
4285 * gFwDebugModuleLoglevel=<FW Module ID>,
4286 * <Log Level>,...
4287 * For example:
4288 * gFwDebugModuleLoglevel=
4289 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
4290 * Above input string means :
4291 * For FW module ID 1 enable log level 0
4292 * For FW module ID 2 enable log level 1
4293 * For FW module ID 3 enable log level 2
4294 * For FW module ID 4 enable log level 3
4295 * For FW module ID 5 enable log level 4
4296 * For FW module ID 6 enable log level 5
4297 * For FW module ID 7 enable log level 6
4298 */
4299
Nishank Aggarwale239d962017-03-03 12:26:02 +05304300 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
4301 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
4302 hdd_err("Module id %d and dbglog level %d input length is more than max",
4303 moduleloglevel[count],
4304 moduleloglevel[count + 1]);
4305 return;
4306 }
4307
4308 value = moduleloglevel[count] << 16;
4309 value |= moduleloglevel[count + 1];
Jeff Johnson1b780e42017-10-31 14:11:45 -07004310 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304311 WMI_DBGLOG_MOD_LOG_LEVEL,
4312 value, DBG_CMD);
4313 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304314 hdd_err("Failed to enable FW module log level %d ret %d",
4315 value, ret);
4316
4317 count += 2;
4318 }
Arun Khandavallifae92942016-08-01 13:31:08 +05304319
Arun Khandavalli2358d522016-05-16 18:05:37 +05304320}
4321#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004322static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004323 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304324{
4325}
4326
4327#endif
4328
4329/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004330 * hdd_configure_chain_mask() - programs chain mask to firmware
4331 * @adapter: HDD adapter
4332 *
4333 * Return: 0 on success or errno on failure
4334 */
4335static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4336{
4337 int ret_val;
4338 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4339
4340 hdd_debug("enable2x2: %d, lte_coex: %d, ChainMask1x1: tx: %d rx: %d",
4341 hdd_ctx->config->enable2x2, hdd_ctx->lte_coex_ant_share,
4342 hdd_ctx->config->txchainmask1x1,
4343 hdd_ctx->config->rxchainmask1x1);
4344 hdd_debug("disable_DBS: %d, tx_chain_mask_2g: %d, rx_chain_mask_2g: %d",
4345 hdd_ctx->config->dual_mac_feature_disable,
4346 hdd_ctx->config->tx_chain_mask_2g,
4347 hdd_ctx->config->rx_chain_mask_2g);
4348 hdd_debug("tx_chain_mask_5g: %d, rx_chain_mask_5g: %d",
4349 hdd_ctx->config->tx_chain_mask_5g,
4350 hdd_ctx->config->rx_chain_mask_5g);
4351
4352 if (hdd_ctx->config->enable2x2) {
4353 hdd_info("2x2 enabled. skip chain mask programming");
4354 return 0;
4355 }
4356
Naveen Rawatb54c72b2018-02-05 10:39:06 -08004357 if (hdd_ctx->config->dual_mac_feature_disable !=
4358 DISABLE_DBS_CXN_AND_SCAN) {
4359 hdd_info("DBS enabled(%d). skip chain mask programming",
4360 hdd_ctx->config->dual_mac_feature_disable);
4361 return 0;
4362 }
4363
Naveen Rawatdacb5032018-02-08 15:23:24 -08004364 if (hdd_ctx->lte_coex_ant_share) {
4365 hdd_info("lte ant sharing enabled. skip chainmask programming");
4366 return 0;
4367 }
4368
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004369 if (hdd_ctx->config->txchainmask1x1) {
4370 ret_val = sme_cli_set_command(adapter->session_id,
4371 WMI_PDEV_PARAM_TX_CHAIN_MASK,
4372 hdd_ctx->config->txchainmask1x1,
4373 PDEV_CMD);
4374 if (ret_val)
4375 goto error;
4376 }
4377
4378 if (hdd_ctx->config->rxchainmask1x1) {
4379 ret_val = sme_cli_set_command(adapter->session_id,
4380 WMI_PDEV_PARAM_RX_CHAIN_MASK,
4381 hdd_ctx->config->rxchainmask1x1,
4382 PDEV_CMD);
4383 if (ret_val)
4384 goto error;
4385 }
4386
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004387 if (hdd_ctx->config->txchainmask1x1 ||
4388 hdd_ctx->config->rxchainmask1x1) {
4389 hdd_info("band agnostic tx/rx chain mask set. skip per band chain mask");
4390 return 0;
4391 }
4392
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004393 if (hdd_ctx->config->tx_chain_mask_2g) {
4394 ret_val = sme_cli_set_command(adapter->session_id,
4395 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
4396 hdd_ctx->config->tx_chain_mask_2g, PDEV_CMD);
4397 if (0 != ret_val)
4398 goto error;
4399 }
4400
4401 if (hdd_ctx->config->rx_chain_mask_2g) {
4402 ret_val = sme_cli_set_command(adapter->session_id,
4403 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
4404 hdd_ctx->config->rx_chain_mask_2g, PDEV_CMD);
4405 if (0 != ret_val)
4406 goto error;
4407 }
4408
4409 if (hdd_ctx->config->tx_chain_mask_5g) {
4410 ret_val = sme_cli_set_command(adapter->session_id,
4411 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
4412 hdd_ctx->config->tx_chain_mask_5g, PDEV_CMD);
4413 if (0 != ret_val)
4414 goto error;
4415 }
4416
4417 if (hdd_ctx->config->rx_chain_mask_5g) {
4418 ret_val = sme_cli_set_command(adapter->session_id,
4419 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
4420 hdd_ctx->config->rx_chain_mask_5g, PDEV_CMD);
4421 if (0 != ret_val)
4422 goto error;
4423 }
4424
4425 return 0;
4426
4427error:
4428 hdd_err("WMI PDEV set param failed %d", ret_val);
4429 return -EINVAL;
4430}
4431
4432/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304433 * hdd_set_fw_params() - Set parameters to firmware
4434 * @adapter: HDD adapter
4435 *
4436 * This function Sets various parameters to fw once the
4437 * adapter is started.
4438 *
4439 * Return: 0 on success or errno on failure
4440 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004441int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304442{
4443 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004444 struct hdd_context *hdd_ctx;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304445
Dustin Brownfdf17c12018-03-14 12:55:34 -07004446 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304447
4448 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4449 if (!hdd_ctx)
4450 return -EINVAL;
4451
Dustin Brown732ab9c2017-06-15 13:24:09 -07004452 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4453 hdd_debug("FTM Mode is active; nothing to do");
4454 return 0;
4455 }
4456
Jeff Johnson1b780e42017-10-31 14:11:45 -07004457 ret = sme_cli_set_command(adapter->session_id,
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304458 WMI_PDEV_PARAM_DTIM_SYNTH,
4459 hdd_ctx->config->enable_lprx, PDEV_CMD);
4460 if (ret) {
4461 hdd_err("Failed to set LPRx");
4462 goto error;
4463 }
4464
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304465
4466 ret = sme_cli_set_command(
4467 adapter->session_id,
4468 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
4469 hdd_ctx->config->enable_dtim_selection_diversity,
4470 PDEV_CMD);
4471 if (ret) {
4472 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
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 }
4502 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304503#define HDD_DTIM_1CHAIN_RX_ID 0x5
4504#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004505 hdd_debug("configuring 1x1 mode fw params");
4506
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004507 /*
4508 * Disable DTIM 1 chain Rx when in 1x1,
4509 * we are passing two value
4510 * as param_id << 29 | param_value.
4511 * Below param_value = 0(disable)
4512 */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004513 ret = sme_cli_set_command(adapter->session_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004514 WMI_STA_SMPS_PARAM_CMDID,
4515 HDD_DTIM_1CHAIN_RX_ID <<
4516 HDD_SMPS_PARAM_VALUE_S,
4517 VDEV_CMD);
4518 if (ret) {
4519 hdd_err("DTIM 1 chain set failed %d", ret);
4520 goto error;
4521 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304522
Arun Khandavalli2358d522016-05-16 18:05:37 +05304523#undef HDD_DTIM_1CHAIN_RX_ID
4524#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004525
4526 if (hdd_configure_chain_mask(adapter))
4527 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004528 }
4529
Jeff Johnson1b780e42017-10-31 14:11:45 -07004530 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004531 WMI_PDEV_PARAM_HYST_EN,
4532 hdd_ctx->config->enableMemDeepSleep,
4533 PDEV_CMD);
4534 if (ret) {
4535 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4536 goto error;
4537 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304538
Jeff Johnson1b780e42017-10-31 14:11:45 -07004539 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004540 WMI_VDEV_PARAM_ENABLE_RTSCTS,
4541 hdd_ctx->config->rts_profile,
4542 VDEV_CMD);
4543 if (ret) {
4544 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4545 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304546 }
4547
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004548 hdd_debug("SET AMSDU num %d", hdd_ctx->config->max_amsdu_num);
4549
Jeff Johnson1b780e42017-10-31 14:11:45 -07004550 ret = wma_cli_set_command(adapter->session_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004551 GEN_VDEV_PARAM_AMSDU,
4552 hdd_ctx->config->max_amsdu_num,
4553 GEN_CMD);
4554 if (ret != 0) {
4555 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4556 goto error;
4557 }
4558
Arun Khandavalli2358d522016-05-16 18:05:37 +05304559 hdd_set_fw_log_params(hdd_ctx, adapter);
Dustin Browne74003f2018-03-14 12:51:58 -07004560 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004561
Arun Khandavalli2358d522016-05-16 18:05:37 +05304562 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304563
Arun Khandavalli2358d522016-05-16 18:05:37 +05304564error:
4565 return -EINVAL;
4566}
4567
Ryan Hsu07495ea2016-01-21 15:25:39 -08004568/**
4569 * hdd_open_adapter() - open and setup the hdd adatper
4570 * @hdd_ctx: global hdd context
4571 * @session_type: type of the interface to be created
4572 * @iface_name: User-visible name of the interface
4573 * @macAddr: MAC address to assign to the interface
4574 * @name_assign_type: the name of assign type of the netdev
4575 * @rtnl_held: the rtnl lock hold flag
4576 *
4577 * This function open and setup the hdd adpater according to the device
4578 * type request, assign the name, the mac address assigned, and then prepared
4579 * the hdd related parameters, queue, lock and ready to start.
4580 *
4581 * Return: the pointer of hdd adapter, otherwise NULL.
4582 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004583struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004584 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08004585 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004586 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004587{
Jeff Johnson9d295242017-08-29 14:39:48 -07004588 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304589 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004590
4591 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
4592 /*
4593 * Max limit reached on the number of vdevs configured by the
4594 * host. Return error
4595 */
Arun Khandavallifae92942016-08-01 13:31:08 +05304596 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
4597 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004598 return NULL;
4599 }
4600
4601 if (macAddr == NULL) {
4602 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05304603 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004604 return NULL;
4605 }
4606 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304607 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304608 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
4609 " already exists",
4610 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004611 return NULL;
4612 }
4613
4614 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004615 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004616 /* Reset locally administered bit if the device mode is STA */
4617 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
Arunk Khandavalli794fdfc2017-09-13 18:00:40 +05304618 hdd_info("locally administered bit reset in sta mode: "
4619 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004620 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004621 case QDF_P2P_CLIENT_MODE:
4622 case QDF_P2P_DEVICE_MODE:
4623 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07004624 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304625 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004626 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4627 name_assign_type,
4628 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004629
4630 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304631 hdd_err("failed to allocate adapter for session %d",
4632 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004633 return NULL;
4634 }
4635
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004636 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004637 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004638 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004639 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304640 else if (QDF_MONITOR_MODE == session_type)
4641 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004642 else
4643 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4644
4645 adapter->device_mode = session_type;
4646
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004647
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004648 /*
4649 * Workqueue which gets scheduled in IPv4 notification
4650 * callback
4651 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004652 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004653 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004654
4655#ifdef WLAN_NS_OFFLOAD
4656 /*
4657 * Workqueue which gets scheduled in IPv6
4658 * notification callback.
4659 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004660 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004661 hdd_ipv6_notifier_work_queue);
4662#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004663 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004664 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004665 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004666
4667 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004668 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004669 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304670 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4671 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05304672
Ravi Joshi1a292562017-05-18 16:28:54 -07004673 /* Initialize NAN Data Interface */
4674 if (QDF_NDI_MODE == session_type) {
4675 status = hdd_init_nan_data_mode(adapter);
4676 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004677 goto err_free_netdev;
Ravi Joshi1a292562017-05-18 16:28:54 -07004678 }
4679
4680 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004681
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004682 case QDF_P2P_GO_MODE:
4683 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004684 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
4685 name_assign_type,
4686 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004687 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004688 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05304689 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004690 return NULL;
4691 }
4692
4693 adapter->wdev.iftype =
4694 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004695 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004696 NL80211_IFTYPE_P2P_GO;
4697 adapter->device_mode = session_type;
4698
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004699 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004700 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004702
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004703 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004704 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304705 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4706 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304707
4708 /*
4709 * Workqueue which gets scheduled in IPv4 notification
4710 * callback
4711 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004712 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304713 hdd_ipv4_notifier_work_queue);
4714
4715#ifdef WLAN_NS_OFFLOAD
4716 /*
4717 * Workqueue which gets scheduled in IPv6
4718 * notification callback.
4719 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004720 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304721 hdd_ipv6_notifier_work_queue);
4722#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004723 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304724 case QDF_FTM_MODE:
4725 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4726 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08004727 iface_name);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304728 if (NULL == adapter) {
4729 hdd_err("Failed to allocate adapter for FTM mode");
4730 return NULL;
4731 }
4732 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4733 adapter->device_mode = session_type;
4734 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004735 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08004736 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004737
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304738 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004739 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304740 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304741 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4742 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304743 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004744 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004745 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304746 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004747 return NULL;
4748 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004749
hqueaa33ee2017-05-04 17:56:35 +08004750 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
4751
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304752 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004753 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08004754 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004755 }
4756
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304757 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004758 if (NULL != adapter) {
4759 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4760 adapter = NULL;
4761 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004762
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004763 return NULL;
4764 }
4765
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304766 if (QDF_STATUS_SUCCESS == status) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004767 policy_mgr_set_concurrency_mode(hdd_ctx->hdd_psoc,
4768 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004770 /* Adapter successfully added. Increment the vdev count */
4771 hdd_ctx->current_intf_count++;
4772
Jeff Johnson5880d792016-08-15 13:32:30 -07004773 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004774 hdd_ctx->current_intf_count);
4775
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004776 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004777 }
4778
Rajeev Kumardca5f812016-02-04 17:28:06 -08004779 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07004780 hdd_err("Interface %s wow debug_fs init failed",
4781 netdev_name(adapter->dev));
4782
4783 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
4784 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004785
4786 return adapter;
4787
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004788err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07004789 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05304790 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004791
4792 return NULL;
4793}
4794
Nirav Shaheb017be2018-02-15 11:20:58 +05304795#ifdef MSM_PLATFORM
4796static inline
4797void hdd_cancel_bus_bw_work(struct hdd_context *hdd_ctx)
4798{
4799 cancel_work_sync(&hdd_ctx->bus_bw_work);
4800}
4801#else
4802static inline
4803void hdd_cancel_bus_bw_work(struct hdd_context *hdd_ctx)
4804{
4805}
4806#endif
4807
Jeff Johnson9d295242017-08-29 14:39:48 -07004808QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004809 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004810{
Dustin Brown920397d2017-12-13 16:27:50 -08004811 /*
4812 * Here we are stopping global bus_bw timer & work per adapter.
4813 *
4814 * The reason is to fix one race condition between
4815 * bus bandwidth work and cleaning up an adapter.
4816 * Under some conditions, it is possible for the bus bandwidth
4817 * work to access a particularly destroyed adapter, leading to
4818 * use-after-free.
4819 */
4820 hdd_debug("wait for bus bw work to flush");
4821 hdd_bus_bw_compute_timer_stop(hdd_ctx);
4822 hdd_bus_bw_cancel_work(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004823
Dustin Brown920397d2017-12-13 16:27:50 -08004824 /* cleanup adapter */
4825 policy_mgr_clear_concurrency_mode(hdd_ctx->hdd_psoc,
4826 adapter->device_mode);
4827 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4828 hdd_remove_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004829
Dustin Brown920397d2017-12-13 16:27:50 -08004830 /* conditionally restart the bw timer */
4831 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004832
Dustin Brown920397d2017-12-13 16:27:50 -08004833 /* Adapter removed. Decrement vdev count */
4834 if (hdd_ctx->current_intf_count != 0)
4835 hdd_ctx->current_intf_count--;
Dustin Brown5ec6b552017-03-31 12:11:40 -07004836
Dustin Brown920397d2017-12-13 16:27:50 -08004837 /* Fw will take care incase of concurrency */
4838 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004839}
4840
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004841/**
4842 * hdd_close_all_adapters - Close all open adapters
4843 * @hdd_ctx: Hdd context
4844 * rtnl_held: True if RTNL lock held
4845 *
4846 * Close all open adapters.
4847 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304848 * Return: QDF status code
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004849 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004850QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851{
Dustin Brown920397d2017-12-13 16:27:50 -08004852 struct hdd_adapter *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304853 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004854
Dustin Brown491d54b2018-03-14 12:39:11 -07004855 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004856
4857 do {
Dustin Brown920397d2017-12-13 16:27:50 -08004858 status = hdd_remove_front_adapter(hdd_ctx, &adapter);
4859 if (QDF_IS_STATUS_SUCCESS(status)) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304860 wlan_hdd_release_intf_addr(hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08004861 adapter->mac_addr.bytes);
4862 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4863
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304864 /* Adapter removed. Decrement vdev count */
4865 if (hdd_ctx->current_intf_count != 0)
4866 hdd_ctx->current_intf_count--;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004867 }
Dustin Brown920397d2017-12-13 16:27:50 -08004868 } while (QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004869
Dustin Browne74003f2018-03-14 12:51:58 -07004870 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004871
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304872 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004873}
4874
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004875void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004876{
Anurag Chouhan6d760662016-02-20 16:05:43 +05304877 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 tSirUpdateIE updateIE;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004879
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004880 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004881 case QDF_STA_MODE:
4882 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07004884 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004885 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -07004886 bssid = &sta_ctx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887 break;
4888 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004889 case QDF_SAP_MODE:
4890 case QDF_P2P_GO_MODE:
4891 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004892 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07004893 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004894 break;
4895 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004896 case QDF_FTM_MODE:
4897 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004898 default:
4899 /*
4900 * wlan_hdd_reset_prob_rspies should not have been called
4901 * for these kind of devices
4902 */
Jeff Johnson5880d792016-08-15 13:32:30 -07004903 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004904 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004905 return;
4906 }
4907
Anurag Chouhanc5548422016-02-24 18:33:27 +05304908 qdf_copy_macaddr(&updateIE.bssid, bssid);
Jeff Johnson1b780e42017-10-31 14:11:45 -07004909 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004910 updateIE.ieBufferlength = 0;
4911 updateIE.pAdditionIEBuffer = NULL;
4912 updateIE.append = true;
4913 updateIE.notify = false;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004914 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004915 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304916 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004917 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004918 }
4919}
4920
Dustin Browndb2a8be2017-12-20 11:49:56 -08004921QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
4922 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004923{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304924 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Jeff Johnson025618c2018-03-18 14:41:00 -07004925 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004926 union iwreq_data wrqu;
4927 tSirUpdateIE updateIE;
4928 unsigned long rc;
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05304929 tsap_Config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004930
Dustin Brown491d54b2018-03-14 12:39:11 -07004931 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004932
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004933 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304934 wlan_hdd_netif_queue_control(adapter,
4935 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4936 WLAN_CONTROL_PATH);
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08004937 /*
4938 * if this is the last active connection check & stop the
4939 * opportunistic timer first
4940 */
4941 if (((policy_mgr_get_connection_count(hdd_ctx->hdd_psoc) == 1) &&
4942 (policy_mgr_mode_specific_connection_count(hdd_ctx->hdd_psoc,
4943 policy_mgr_convert_device_mode_to_qdf_type(
4944 adapter->device_mode), NULL) == 1)) ||
4945 !policy_mgr_get_connection_count(hdd_ctx->hdd_psoc))
4946 policy_mgr_check_and_stop_opportunistic_timer(
4947 hdd_ctx->hdd_psoc, adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004948 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004949 case QDF_STA_MODE:
4950 case QDF_P2P_CLIENT_MODE:
4951 case QDF_IBSS_MODE:
4952 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004953 case QDF_NDI_MODE:
4954 if ((QDF_NDI_MODE == adapter->device_mode) ||
4955 hdd_conn_is_connected(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004956 WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
4957 hdd_is_connecting(
4958 WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004959 INIT_COMPLETION(adapter->disconnect_comp_var);
Jeff Johnson025618c2018-03-18 14:41:00 -07004960 roam_profile = hdd_roam_profile(adapter);
4961 /* For NDI do not use roam_profile */
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004962 if (QDF_NDI_MODE == adapter->device_mode)
4963 qdf_ret_status = sme_roam_disconnect(
4964 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004965 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004966 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07004967 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004968 eCSR_BSS_TYPE_START_IBSS)
4969 qdf_ret_status = sme_roam_disconnect(
4970 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004971 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004972 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004973 else if (QDF_STA_MODE == adapter->device_mode) {
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004974 qdf_ret_status =
4975 wlan_hdd_try_disconnect(adapter);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004976 hdd_debug("Send disconnected event to userspace");
4977 wlan_hdd_cfg80211_indicate_disconnect(
4978 adapter->dev, true,
4979 WLAN_REASON_UNSPECIFIED);
Jeff Johnson109e79d2018-02-27 15:10:04 -08004980 } else
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004981 qdf_ret_status = sme_roam_disconnect(
4982 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004983 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004984 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004985 /* success implies disconnect command got
4986 * queued up successfully
4987 */
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004988 if (qdf_ret_status == QDF_STATUS_SUCCESS &&
4989 QDF_STA_MODE != adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004990 rc = wait_for_completion_timeout(
4991 &adapter->disconnect_comp_var,
4992 msecs_to_jiffies
4993 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004994 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004995 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004996 }
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004997 if (qdf_ret_status != QDF_STATUS_SUCCESS)
4998 hdd_warn("failed to post disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004999 memset(&wrqu, '\0', sizeof(wrqu));
5000 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5001 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5002 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5003 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305004 }
Wu Gaoaceec6c2017-08-30 16:08:21 +08005005 wlan_hdd_scan_abort(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005006
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305007 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305008 hdd_clear_fils_connection_info(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005009
5010#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005011 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005012#endif
5013
5014 hdd_deregister_tx_flow_control(adapter);
5015
5016#ifdef WLAN_NS_OFFLOAD
5017#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005018 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005019#endif
5020#endif
5021
Hanumanth Reddy Pothula05860142017-07-26 18:45:27 +05305022 if (adapter->device_mode == QDF_STA_MODE)
5023 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
5024 adapter->dev);
Dustin Browndb2a8be2017-12-20 11:49:56 -08005025
5026 if (wlan_hdd_try_disconnect(adapter)) {
5027 hdd_err("Error: Can't disconnect adapter");
5028 return QDF_STATUS_E_FAILURE;
Krunal Soni985b8132017-02-10 18:49:08 -08005029 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005030
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305031 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005032 break;
5033
Rajeev Kumar3b906202018-02-01 10:55:14 -08005034 case QDF_MONITOR_MODE:
5035 wlan_hdd_scan_abort(adapter);
5036 hdd_deregister_tx_flow_control(adapter);
5037 hdd_vdev_destroy(adapter);
5038 break;
5039
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005040 case QDF_SAP_MODE:
wadesongf9b15ed2017-12-14 14:12:32 +08005041 wlan_hdd_scan_abort(adapter);
Govind Singh1dab23b2017-08-12 13:31:00 +05305042 /* Flush IPA exception path packets */
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305043 sap_config = &adapter->session.ap.sap_config;
5044 if (sap_config)
5045 wlansap_reset_sap_config_add_ie(sap_config,
5046 eUPDATE_IE_ALL);
Govind Singh1dab23b2017-08-12 13:31:00 +05305047 hdd_ipa_flush(hdd_ctx);
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08005048 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005049
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005050 case QDF_P2P_GO_MODE:
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07005051 if (QDF_SAP_MODE == adapter->device_mode) {
5052 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5053 cds_flush_delayed_work(
5054 &adapter->acs_pending_work);
5055 clear_bit(ACS_PENDING, &adapter->event_flags);
5056 }
5057 }
Krunal Soni22208392017-09-29 18:10:34 -07005058 cds_flush_work(&adapter->sap_stop_bss_work);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005059
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005060 /* Any softap specific cleanup here... */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005061 wlan_hdd_undo_acs(adapter);
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005062 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005063 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5064
5065 hdd_deregister_tx_flow_control(adapter);
5066
Kapil Guptac1224bf2017-06-22 21:22:40 +05305067 hdd_destroy_acs_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005068 mutex_lock(&hdd_ctx->sap_lock);
5069 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305070 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305071 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005072
5073 /* Stop Bss. */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005074 status = wlansap_stop_bss(
5075 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005076
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305077 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005078 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005079 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305080 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305081 qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305082 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +05305083 qdf_wait_for_event_completion(
5084 &hostapd_state->qdf_stop_bss_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -08005085 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086
Anurag Chouhance0dc992016-02-16 18:18:03 +05305087 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005088 hdd_err("failure waiting for wlansap_stop_bss %d",
5089 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090 }
5091 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005092 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005093 }
5094 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005095 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
5096 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005097 adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305098 hdd_start_green_ap_state_mc(hdd_ctx,
5099 adapter->device_mode,
5100 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005101
Anurag Chouhanc5548422016-02-24 18:33:27 +05305102 qdf_copy_macaddr(&updateIE.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005103 &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005104 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005105 updateIE.ieBufferlength = 0;
5106 updateIE.pAdditionIEBuffer = NULL;
5107 updateIE.append = false;
5108 updateIE.notify = false;
5109 /* Probe bcn reset */
5110 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
5111 &updateIE, eUPDATE_IE_PROBE_BCN)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305112 == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005113 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005114 }
5115 /* Assoc resp reset */
5116 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
5117 &updateIE,
5118 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305119 QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005120 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005121 }
5122 /* Reset WNI_CFG_PROBE_RSP Flags */
5123 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07005125 qdf_mem_free(adapter->session.ap.beacon);
5126 adapter->session.ap.beacon = NULL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305127 /*
5128 * If Do_Not_Break_Stream was enabled clear avoid channel list.
5129 */
5130 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev))
5131 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
5132
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305133#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005134 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305135#endif
5136
5137#ifdef WLAN_NS_OFFLOAD
5138#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005139 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305140#endif
5141#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08005142
5143 hdd_vdev_destroy(adapter);
5144
Krunal Sonib51eec72017-11-20 21:53:01 -08005145 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005146 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005147 case QDF_OCB_MODE:
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08005148 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005149 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
Leo Changfdb45c32016-10-28 11:09:23 -07005150 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.staId[0]);
Zhang Qian79d0d132018-02-05 13:40:16 +08005151 hdd_deregister_tx_flow_control(adapter);
5152 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 break;
5154 default:
5155 break;
5156 }
5157
Dustin Brown04348372017-12-14 16:13:39 -08005158 if (adapter->scan_info.default_scan_ies) {
5159 qdf_mem_free(adapter->scan_info.default_scan_ies);
5160 adapter->scan_info.default_scan_ies = NULL;
5161 }
5162
Dustin Browne74003f2018-03-14 12:51:58 -07005163 hdd_exit();
Dustin Brown04348372017-12-14 16:13:39 -08005164
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305165 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166}
5167
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305168/**
5169 * hdd_deinit_all_adapters - deinit all adapters
5170 * @hdd_ctx: HDD context
5171 * @rtnl_held: True if RTNL lock held
5172 *
5173 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005174void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305175{
Jeff Johnson9d295242017-08-29 14:39:48 -07005176 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305177
Dustin Brown491d54b2018-03-14 12:39:11 -07005178 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305179
Dustin Brown920397d2017-12-13 16:27:50 -08005180 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305181 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305182
Dustin Browne74003f2018-03-14 12:51:58 -07005183 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305184}
5185
Dustin Browndb2a8be2017-12-20 11:49:56 -08005186QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187{
Jeff Johnson9d295242017-08-29 14:39:48 -07005188 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005189
Dustin Brown491d54b2018-03-14 12:39:11 -07005190 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005191
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305192 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5193
Dustin Brown920397d2017-12-13 16:27:50 -08005194 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08005195 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005196
Dustin Browne74003f2018-03-14 12:51:58 -07005197 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005198
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305199 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005200}
5201
Paul Zhang84fa9382017-11-10 21:18:21 +08005202static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
5203 struct hdd_adapter *adapter)
5204{
5205 switch (adapter->device_mode) {
5206 case QDF_STA_MODE:
5207 case QDF_P2P_CLIENT_MODE:
5208 case QDF_IBSS_MODE:
5209 case QDF_P2P_DEVICE_MODE:
5210 case QDF_NDI_MODE:
5211 wlan_hdd_scan_abort(adapter);
5212 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5213 if (adapter->device_mode == QDF_STA_MODE)
5214 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
5215 adapter->dev);
5216 break;
5217 case QDF_P2P_GO_MODE:
5218 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5219 break;
5220 case QDF_SAP_MODE:
5221 wlan_hdd_undo_acs(adapter);
5222 break;
5223 default:
5224 break;
5225 }
5226}
5227
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005228QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005229{
Jeff Johnson9d295242017-08-29 14:39:48 -07005230 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07005231 struct hdd_station_ctx *sta_ctx;
Yue Mad5b4b9f2017-05-26 16:23:40 -07005232 struct qdf_mac_addr peerMacAddr;
Yue Ma42654682018-01-11 16:55:24 -08005233 int sta_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005234
Dustin Brown491d54b2018-03-14 12:39:11 -07005235 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005236
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305237 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5238
Dustin Brown920397d2017-12-13 16:27:50 -08005239 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07005240 hdd_info("[SSR] reset adapter with device mode %s(%d)",
5241 hdd_device_mode_to_string(adapter->device_mode),
5242 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305243
5244 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08005245 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305246 /* Stop tdls timers */
Kabilan Kannan00d20412017-06-04 14:20:32 -07005247 hdd_notify_tdls_reset_adapter(adapter->hdd_vdev);
Paul Zhang679025e2018-03-08 22:39:44 +08005248 adapter->session.station.hdd_reassoc_scenario = false;
5249 }
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305250
Arun Khandavallicc544b32017-01-30 19:52:16 +05305251 if (hdd_ctx->config->sap_internal_restart &&
5252 adapter->device_mode == QDF_SAP_MODE) {
5253 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305254 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305255 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005256 if (test_bit(SOFTAP_BSS_STARTED,
Krunal Sonib51eec72017-11-20 21:53:01 -08005257 &adapter->event_flags))
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005258 hdd_sap_indicate_disconnect_for_sta(adapter);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005259 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
5260 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05305261 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305262 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005263 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005264 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005265
Paul Zhang84fa9382017-11-10 21:18:21 +08005266 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005267
5268 hdd_deinit_tx_rx(adapter);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005269 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005270 adapter->device_mode, adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305271 hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
5272 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005273 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
5274 hdd_wmm_adapter_close(adapter);
5275 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
5276 }
5277
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05305278 if (adapter->device_mode == QDF_STA_MODE)
5279 hdd_clear_fils_connection_info(adapter);
5280
Wu Gao3545e642017-07-14 19:24:41 +08005281 if (adapter->device_mode == QDF_SAP_MODE) {
5282 /*
5283 * If adapter is SAP, set session ID to invalid
5284 * since SAP session will be cleanup during SSR.
5285 */
Wu Gao36717432016-11-21 15:09:48 +08005286 wlansap_set_invalid_session(
5287 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
5288
Wu Gao3545e642017-07-14 19:24:41 +08005289 wlansap_cleanup_cac_timer(
5290 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
5291 }
5292
Yue Ma42654682018-01-11 16:55:24 -08005293 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07005294 if (adapter->device_mode == QDF_STA_MODE ||
5295 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005296 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005297 qdf_copy_macaddr(&peerMacAddr,
Jeff Johnsond377dce2017-10-04 10:32:42 -07005298 &sta_ctx->conn_info.bssId);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005299
5300 hdd_objmgr_remove_peer_object(adapter->hdd_vdev,
5301 peerMacAddr.bytes);
Yue Ma42654682018-01-11 16:55:24 -08005302 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
5303 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
5304 if (adapter->sta_info[sta_id].in_use) {
5305 hdd_debug("[SSR] deregister STA with ID %d",
5306 sta_id);
5307 hdd_softap_deregister_sta(adapter,
5308 sta_id);
5309 adapter->sta_info[sta_id].in_use = 0;
5310 }
5311 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07005312 }
5313
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005314 hdd_softap_deinit_tx_rx(adapter);
5315
Yue Maf9782842017-05-08 12:49:49 -07005316 /* Destroy vdev which will be recreated during reinit. */
5317 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005318 }
5319
Dustin Browne74003f2018-03-14 12:51:58 -07005320 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005321
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305322 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005323}
5324
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005325bool hdd_check_for_opened_interfaces(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305326{
Dustin Brown920397d2017-12-13 16:27:50 -08005327 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305328 bool close_modules = true;
5329
Arun Khandavalliba479c42017-07-26 21:29:40 +05305330 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
5331 hdd_info("FTM mode, don't close the module");
5332 return false;
5333 }
5334
Dustin Brown920397d2017-12-13 16:27:50 -08005335 hdd_for_each_adapter(hdd_ctx, adapter) {
5336 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
5337 test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005338 hdd_debug("Still other ifaces are up cannot close modules");
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305339 close_modules = false;
5340 break;
5341 }
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305342 }
5343
5344 return close_modules;
5345}
5346
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05305347bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05305348{
5349 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
5350 return true;
5351 else
5352 return false;
5353}
5354
Anurag Chouhanc4092922016-09-08 15:56:11 +05305355#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08005356 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305357struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5358 struct ieee80211_channel *channel,
5359 const u8 *bssid, const u8 *ssid,
5360 size_t ssid_len)
5361{
5362 return cfg80211_get_bss(wiphy, channel, bssid,
5363 ssid, ssid_len,
5364 WLAN_CAPABILITY_ESS,
5365 WLAN_CAPABILITY_ESS);
5366}
5367#else
5368struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5369 struct ieee80211_channel *channel,
5370 const u8 *bssid, const u8 *ssid,
5371 size_t ssid_len)
5372{
5373 return cfg80211_get_bss(wiphy, channel, bssid,
5374 ssid, ssid_len,
5375 IEEE80211_BSS_TYPE_ESS,
5376 IEEE80211_PRIVACY_ANY);
5377}
5378#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305379
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305380#if defined CFG80211_CONNECT_BSS || \
5381 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305382#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305383 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305384/**
5385 * hdd_convert_timeout_reason() - Convert to kernel specific enum
5386 * @timeout_reason: reason for connect timeout
5387 *
5388 * This function is used to convert host timeout
5389 * reason enum to kernel specific enum.
5390 *
5391 * Return: nl timeout enum
5392 */
5393static enum nl80211_timeout_reason hdd_convert_timeout_reason(
5394 tSirResultCodes timeout_reason)
5395{
5396 switch (timeout_reason) {
5397 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5398 return NL80211_TIMEOUT_SCAN;
5399 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5400 return NL80211_TIMEOUT_AUTH;
5401 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5402 return NL80211_TIMEOUT_ASSOC;
5403 default:
5404 return NL80211_TIMEOUT_UNSPECIFIED;
5405 }
5406}
5407
5408/**
5409 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5410 * @dev: network device
5411 * @bssid: bssid to which we want to associate
5412 * @timeout_reason: reason for connect timeout
5413 *
5414 * This API is used to send connection timeout reason to supplicant
5415 *
5416 * Return: void
5417 */
5418static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5419 const u8 *bssid,
5420 tSirResultCodes timeout_reason)
5421{
5422 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005423
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305424 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5425
5426 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
5427 nl_timeout_reason);
5428}
5429
5430/**
5431 * __hdd_connect_bss() - API to send connection status to supplicant
5432 * @dev: network device
5433 * @bssid: bssid to which we want to associate
5434 * @req_ie: Request Information Element
5435 * @req_ie_len: len of the req IE
5436 * @resp_ie: Response IE
5437 * @resp_ie_len: len of ht response IE
5438 * @status: status
5439 * @gfp: Kernel Flag
5440 * @timeout_reason: reason for connect timeout
5441 *
5442 * Return: void
5443 */
5444static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5445 struct cfg80211_bss *bss, const u8 *req_ie,
5446 size_t req_ie_len, const u8 *resp_ie,
5447 size_t resp_ie_len, int status, gfp_t gfp,
5448 tSirResultCodes timeout_reason)
5449{
5450 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005451
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305452 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5453
5454 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5455 resp_ie, resp_ie_len, status, gfp,
5456 nl_timeout_reason);
5457}
5458#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305459#if defined CFG80211_CONNECT_TIMEOUT || \
5460 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305461static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5462 const u8 *bssid,
5463 tSirResultCodes timeout_reason)
5464{
5465 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
5466}
5467#endif
5468
5469static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5470 struct cfg80211_bss *bss, const u8 *req_ie,
5471 size_t req_ie_len, const u8 *resp_ie,
5472 size_t resp_ie_len, int status, gfp_t gfp,
5473 tSirResultCodes timeout_reason)
5474{
5475 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5476 resp_ie, resp_ie_len, status, gfp);
5477}
5478#endif
5479
Abhishek Singha84d3952016-09-13 13:45:05 +05305480/**
5481 * hdd_connect_bss() - API to send connection status to supplicant
5482 * @dev: network device
5483 * @bssid: bssid to which we want to associate
5484 * @req_ie: Request Information Element
5485 * @req_ie_len: len of the req IE
5486 * @resp_ie: Response IE
5487 * @resp_ie_len: len of ht response IE
5488 * @status: status
5489 * @gfp: Kernel Flag
5490 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305491 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05305492 *
5493 * The API is a wrapper to send connection status to supplicant
5494 *
5495 * Return: Void
5496 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305497#if defined CFG80211_CONNECT_TIMEOUT || \
5498 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05305499static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5500 struct cfg80211_bss *bss, const u8 *req_ie,
5501 size_t req_ie_len, const u8 *resp_ie,
5502 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305503 bool connect_timeout,
5504 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305505{
5506 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305507 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305508 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305509 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5510 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305511}
5512#else
5513static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5514 struct cfg80211_bss *bss, const u8 *req_ie,
5515 size_t req_ie_len, const u8 *resp_ie,
5516 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305517 bool connect_timeout,
5518 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305519{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305520 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5521 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305522}
5523#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305524
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305525#if defined(WLAN_FEATURE_FILS_SK)
5526#if defined(CFG80211_CONNECT_DONE) || \
5527 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
5528#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
5529 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305530/**
5531 * hdd_populate_fils_params() - Populate FILS keys to connect response
5532 * @fils_params: connect response to supplicant
5533 * @fils_kek: FILS kek
5534 * @fils_kek_len: FILS kek length
5535 * @pmk: FILS PMK
5536 * @pmk_len: FILS PMK length
5537 * @pmkid: PMKID
5538 * @fils_seq_num: FILS Seq number
5539 *
5540 * Return: None
5541 */
5542static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5543 *fils_params, const uint8_t *fils_kek,
5544 size_t fils_kek_len, const uint8_t *pmk,
5545 size_t pmk_len, const uint8_t *pmkid,
5546 uint16_t fils_seq_num)
5547{
5548 /* Increament seq number to be used for next FILS */
5549 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
5550 fils_params->update_erp_next_seq_num = true;
5551 fils_params->fils_kek = fils_kek;
5552 fils_params->fils_kek_len = fils_kek_len;
5553 fils_params->pmk = pmk;
5554 fils_params->pmk_len = pmk_len;
5555 fils_params->pmkid = pmkid;
5556}
5557#else
5558static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5559 *fils_params, const uint8_t
5560 *fils_kek, size_t fils_kek_len,
5561 const uint8_t *pmk, size_t pmk_len,
5562 const uint8_t *pmkid,
5563 uint16_t fils_seq_num)
5564{ }
5565#endif
5566
Jeff Johnson172237b2017-11-07 15:32:59 -08005567void hdd_update_hlp_info(struct net_device *dev,
5568 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305569{
5570 struct sk_buff *skb;
5571 uint16_t skb_len;
5572 struct llc_snap_hdr_t *llc_hdr;
5573 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305574 uint8_t *hlp_data;
5575 uint16_t hlp_data_len;
5576 struct fils_join_rsp_params *roam_fils_params
5577 = roam_info->fils_join_rsp;
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305578 struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
5579
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305580 if (!roam_fils_params) {
5581 hdd_err("FILS Roam Param NULL");
5582 return;
5583 }
5584
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08005585 if (!roam_fils_params->hlp_data_len) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305586 hdd_err("FILS HLP Data NULL, len %d",
5587 roam_fils_params->hlp_data_len);
5588 return;
5589 }
5590
5591 hlp_data = roam_fils_params->hlp_data;
5592 hlp_data_len = roam_fils_params->hlp_data_len;
5593
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305594 /* Calculate skb length */
5595 skb_len = (2 * ETH_ALEN) + hlp_data_len;
5596 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
5597 if (skb == NULL) {
5598 hdd_err("HLP packet nbuf alloc fails");
5599 return;
5600 }
5601
5602 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
5603 QDF_MAC_ADDR_SIZE);
5604 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
5605 QDF_MAC_ADDR_SIZE);
5606
5607 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
5608 if (IS_SNAP(llc_hdr)) {
5609 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5610 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5611 }
5612
5613 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
5614
5615 /*
5616 * This HLP packet is formed from HLP info encapsulated
5617 * in assoc response frame which is AEAD encrypted.
5618 * Hence, this checksum validation can be set unnecessary.
5619 * i.e. network layer need not worry about checksum.
5620 */
5621 skb->ip_summed = CHECKSUM_UNNECESSARY;
5622
5623 status = hdd_rx_packet_cbk(padapter, skb);
5624 if (QDF_IS_STATUS_ERROR(status)) {
5625 hdd_err("Sending HLP packet fails");
5626 return;
5627 }
5628 hdd_debug("send HLP packet to netif successfully");
5629}
5630
5631/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305632 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
5633 * @dev: network device
5634 * @bssid: bssid to which we want to associate
5635 * @bss: cfg80211 bss info
5636 * @roam_info: information about connected bss
5637 * @req_ie: Request Information Element
5638 * @req_ie_len: len of the req IE
5639 * @resp_ie: Response IE
5640 * @resp_ie_len: len of ht response IE
5641 * @status: status
5642 * @gfp: allocation flags
5643 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5644 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305645 *
5646 * This API is used as wrapper to send FILS key/sequence number
5647 * params etc. to supplicant in case of FILS connection
5648 *
5649 * Return: None
5650 */
5651static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005652 struct cfg80211_bss *bss,
5653 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305654 const u8 *req_ie, size_t req_ie_len,
5655 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005656 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305657 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305658{
5659 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305660 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5661 struct fils_join_rsp_params *roam_fils_params =
5662 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005663
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305664 qdf_mem_zero(&fils_params, sizeof(fils_params));
5665
5666 if (!roam_fils_params) {
5667 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
5668 } else {
5669 fils_params.status = status;
5670 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08005671 fils_params.timeout_reason =
5672 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305673 fils_params.req_ie = req_ie;
5674 fils_params.req_ie_len = req_ie_len;
5675 fils_params.resp_ie = resp_ie;
5676 fils_params.resp_ie_len = resp_ie_len;
5677 fils_params.bss = bss;
5678 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
5679 roam_fils_params->kek_len,
5680 roam_fils_params->fils_pmk,
5681 roam_fils_params->fils_pmk_len,
5682 roam_fils_params->fils_pmkid,
5683 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05305684 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305685 }
5686 hdd_debug("FILS indicate connect status %d seq no %d",
5687 fils_params.status,
5688 fils_params.fils_erp_next_seq_num);
5689
5690 cfg80211_connect_done(dev, &fils_params, gfp);
5691
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305692 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305693 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305694
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305695 /* Clear all the FILS key info */
5696 if (roam_fils_params && roam_fils_params->fils_pmk)
5697 qdf_mem_free(roam_fils_params->fils_pmk);
5698 if (roam_fils_params)
5699 qdf_mem_free(roam_fils_params);
5700 roam_info->fils_join_rsp = NULL;
5701}
5702#else
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005703static inline void
5704hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005705 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005706 const u8 *req_ie, size_t req_ie_len,
5707 const u8 *resp_ie, size_t resp_ie_len, u16 status,
5708 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305709 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305710{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305711#endif
5712#endif
5713
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305714#if defined(WLAN_FEATURE_FILS_SK) && \
5715 (defined(CFG80211_CONNECT_DONE) || \
5716 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305717/**
5718 * hdd_fils_update_connect_results() - API to send fils connection status to
5719 * supplicant.
5720 * @dev: network device
5721 * @bssid: bssid to which we want to associate
5722 * @bss: cfg80211 bss info
5723 * @roam_info: information about connected bss
5724 * @req_ie: Request Information Element
5725 * @req_ie_len: len of the req IE
5726 * @resp_ie: Response IE
5727 * @resp_ie_len: len of ht response IE
5728 * @status: status
5729 * @gfp: allocation flags
5730 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5731 * @timeout_reason: reason for connect timeout
5732 *
5733 * The API is a wrapper to send connection status to supplicant
5734 *
5735 * Return: 0 if success else failure
5736 */
5737static int hdd_fils_update_connect_results(struct net_device *dev,
5738 const u8 *bssid,
5739 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005740 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305741 size_t req_ie_len, const u8 *resp_ie,
5742 size_t resp_ie_len, u16 status, gfp_t gfp,
5743 bool connect_timeout,
5744 tSirResultCodes timeout_reason)
5745{
Dustin Brown491d54b2018-03-14 12:39:11 -07005746 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305747 if (!roam_info || !roam_info->is_fils_connection)
5748 return -EINVAL;
5749
5750 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
5751 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305752 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305753 return 0;
5754}
5755#else
5756static inline int hdd_fils_update_connect_results(struct net_device *dev,
5757 const u8 *bssid,
5758 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005759 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305760 size_t req_ie_len, const u8 *resp_ie,
5761 size_t resp_ie_len, u16 status, gfp_t gfp,
5762 bool connect_timeout,
5763 tSirResultCodes timeout_reason)
5764{
5765 return -EINVAL;
5766}
5767#endif
5768
Anurag Chouhanc4092922016-09-08 15:56:11 +05305769/**
5770 * hdd_connect_result() - API to send connection status to supplicant
5771 * @dev: network device
5772 * @bssid: bssid to which we want to associate
5773 * @roam_info: information about connected bss
5774 * @req_ie: Request Information Element
5775 * @req_ie_len: len of the req IE
5776 * @resp_ie: Response IE
5777 * @resp_ie_len: len of ht response IE
5778 * @status: status
5779 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05305780 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305781 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05305782 *
5783 * The API is a wrapper to send connection status to supplicant
5784 * and allow runtime suspend
5785 *
5786 * Return: Void
5787 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05305788void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005789 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305790 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305791 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305792 bool connect_timeout,
5793 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305794{
Jeff Johnson9d295242017-08-29 14:39:48 -07005795 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305796 struct cfg80211_bss *bss = NULL;
Jingxiang Ge929c7932018-01-24 14:01:12 +08005797 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305798
5799 if (WLAN_STATUS_SUCCESS == status) {
5800 struct ieee80211_channel *chan;
5801 int freq;
5802 int chan_no = roam_info->pBssDesc->channelId;
5803
5804 if (chan_no <= 14)
5805 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005806 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305807 else
5808 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005809 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305810
5811 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
5812 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
5813 roam_info->u.pConnectedProfile->SSID.ssId,
5814 roam_info->u.pConnectedProfile->SSID.length);
5815 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305816
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305817 if (hdd_fils_update_connect_results(dev, bssid, bss,
5818 roam_info, req_ie, req_ie_len, resp_ie,
5819 resp_ie_len, status, gfp, connect_timeout,
5820 timeout_reason) != 0) {
5821 hdd_connect_bss(dev, bssid, bss, req_ie,
5822 req_ie_len, resp_ie, resp_ie_len,
5823 status, gfp, connect_timeout, timeout_reason);
5824 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305825
Jingxiang Geb49aa302018-01-17 20:54:15 +08005826 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005827 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305828}
5829#else
5830void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005831 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305832 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305833 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305834 bool connect_timeout,
5835 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305836{
Jeff Johnson9d295242017-08-29 14:39:48 -07005837 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Jingxiang Ge929c7932018-01-24 14:01:12 +08005838 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05305839
Anurag Chouhanc4092922016-09-08 15:56:11 +05305840 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
5841 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08005842
Jingxiang Geb49aa302018-01-17 20:54:15 +08005843 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005844 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305845}
5846#endif
5847
5848
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005849QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005850{
Jeff Johnson9d295242017-08-29 14:39:48 -07005851 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005852#ifndef MSM_PLATFORM
Dustin Brownce5b3d32018-01-17 15:07:38 -08005853 struct qdf_mac_addr bcastMac = QDF_MAC_ADDR_BCAST_INIT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005854#endif
5855 eConnectionState connState;
5856
Dustin Brown491d54b2018-03-14 12:39:11 -07005857 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005858
Dustin Brown920397d2017-12-13 16:27:50 -08005859 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305860 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08005861 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05305862
Yue Ma42654682018-01-11 16:55:24 -08005863 hdd_debug("[SSR] start adapter with device mode %s(%d)",
5864 hdd_device_mode_to_string(adapter->device_mode),
5865 adapter->device_mode);
5866
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005867 hdd_wmm_init(adapter);
5868
5869 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005870 case QDF_STA_MODE:
5871 case QDF_P2P_CLIENT_MODE:
5872 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005873
5874 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
5875 ->conn_info.connState;
5876
Krunal Sonib51eec72017-11-20 21:53:01 -08005877 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005878 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07005879 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005880
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005881 /* Indicate disconnect event to supplicant
5882 * if associated previously
5883 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005884 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07005885 eConnectionState_IbssConnected == connState ||
5886 eConnectionState_NotConnected == connState ||
5887 eConnectionState_IbssDisconnected == connState ||
5888 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005889 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005890
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005891 memset(&wrqu, '\0', sizeof(wrqu));
5892 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5893 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5894 wireless_send_event(adapter->dev, SIOCGIWAP,
5895 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005896 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07005897 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005898
5899 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05305900 wlan_hdd_cfg80211_indicate_disconnect(
5901 adapter->dev, false,
5902 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005903 } else if (eConnectionState_Connecting == connState) {
5904 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005905 * Indicate connect failure to supplicant if we
5906 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005907 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05305908 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305909 NULL, 0, NULL, 0,
5910 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005911 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005912 }
5913
5914 hdd_register_tx_flow_control(adapter,
5915 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08005916 hdd_tx_resume_cb,
5917 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005918
5919 break;
5920
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005921 case QDF_SAP_MODE:
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005922 if (hdd_ctx->config->sap_internal_restart)
Krunal Sonib51eec72017-11-20 21:53:01 -08005923 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05305924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005925 break;
5926
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005927 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005928#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005929 hdd_debug("[SSR] send stop ap to supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005930 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
5931#else
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005932 hdd_debug("[SSR] send restart supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005933 /* event supplicant to restart */
5934 cfg80211_del_sta(adapter->dev,
5935 (const u8 *)&bcastMac.bytes[0],
5936 GFP_KERNEL);
5937#endif
5938 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05305939 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08005940 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05305941 hdd_set_mon_rx_cb(adapter->dev);
5942 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
5943 adapter->mon_bandwidth);
5944 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005945 default:
5946 break;
5947 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07005948 /*
5949 * Action frame registered in one adapter which will
5950 * applicable to all interfaces
5951 */
5952 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005953 }
5954
Dustin Browne74003f2018-03-14 12:51:58 -07005955 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005956
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305957 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005958}
5959
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005960QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005961 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005962{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305963 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08005964 qdf_list_node_t *node;
5965
5966 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005967
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005968 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005969 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005970 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005971
5972 if (QDF_IS_STATUS_ERROR(status))
5973 return status;
5974
5975 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
5976
5977 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005978}
5979
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005980QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005981 struct hdd_adapter *current_adapter,
5982 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005983{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305984 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08005985 qdf_list_node_t *node;
5986
5987 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005988
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005989 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07005990 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08005991 &current_adapter->node,
5992 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005993 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005994
5995 if (QDF_IS_STATUS_ERROR(status))
5996 return status;
5997
5998 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
5999
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006000 return status;
6001}
6002
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006003QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006004 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006005{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306006 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006007
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006008 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006009 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006010 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006011
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006012 return status;
6013}
6014
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006015QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006016 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006017{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306018 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006019 qdf_list_node_t *node;
6020
6021 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006022
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006023 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006024 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006025 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006026
6027 if (QDF_IS_STATUS_ERROR(status))
6028 return status;
6029
6030 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6031
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006032 return status;
6033}
6034
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006035QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006036 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006037{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306038 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006039
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006040 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006041 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006042 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006043
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006044 return status;
6045}
6046
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006047QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006048 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006049{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306050 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006051
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006052 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006053 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006054 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006055
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006056 return status;
6057}
6058
Jeff Johnson9d295242017-08-29 14:39:48 -07006059struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006060 tSirMacAddr macAddr)
6061{
Jeff Johnson9d295242017-08-29 14:39:48 -07006062 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006063
Dustin Brown920397d2017-12-13 16:27:50 -08006064 hdd_for_each_adapter(hdd_ctx, adapter) {
6065 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
6066 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006067 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006068 }
6069
6070 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006071}
6072
Jeff Johnson9d295242017-08-29 14:39:48 -07006073struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006074 uint32_t vdev_id)
6075{
Jeff Johnson9d295242017-08-29 14:39:48 -07006076 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006077
Dustin Brown920397d2017-12-13 16:27:50 -08006078 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07006079 if (adapter->session_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006080 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006081 }
6082
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006083 return NULL;
6084}
6085
Abhishek Singh7996eb72015-12-30 17:24:02 +05306086/**
6087 * hdd_get_adapter_by_sme_session_id() - Return adapter with
6088 * the sessionid
6089 * @hdd_ctx: hdd context.
6090 * @sme_session_id: sme session is for the adapter to get.
6091 *
6092 * This function is used to get the adapter with provided session id
6093 *
6094 * Return: adapter pointer if found
6095 *
6096 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07006097struct hdd_adapter *
6098hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
6099 uint32_t sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306100{
Jeff Johnson9d295242017-08-29 14:39:48 -07006101 struct hdd_adapter *adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306102
Dustin Brown920397d2017-12-13 16:27:50 -08006103 hdd_for_each_adapter(hdd_ctx, adapter) {
6104 if (adapter->session_id == sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306105 return adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306106 }
Dustin Brown920397d2017-12-13 16:27:50 -08006107
Abhishek Singh7996eb72015-12-30 17:24:02 +05306108 return NULL;
6109}
6110
Jeff Johnson9d295242017-08-29 14:39:48 -07006111struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07006112 const char *iface_name)
6113{
Jeff Johnson9d295242017-08-29 14:39:48 -07006114 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006115
Dustin Brown920397d2017-12-13 16:27:50 -08006116 hdd_for_each_adapter(hdd_ctx, adapter) {
6117 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07006118 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006119 }
Dustin Brown920397d2017-12-13 16:27:50 -08006120
Naveen Rawat4edb6822017-04-12 10:09:17 -07006121 return NULL;
6122}
6123
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006124/**
6125 * hdd_get_adapter() - to get adapter matching the mode
6126 * @hdd_ctx: hdd context
6127 * @mode: adapter mode
6128 *
6129 * This routine will return the pointer to adapter matching
6130 * with the passed mode.
6131 *
6132 * Return: pointer to adapter or null
6133 */
Jeff Johnson9d295242017-08-29 14:39:48 -07006134struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006135 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006136{
Jeff Johnson9d295242017-08-29 14:39:48 -07006137 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006138
Dustin Brown920397d2017-12-13 16:27:50 -08006139 hdd_for_each_adapter(hdd_ctx, adapter) {
6140 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006141 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006142 }
6143
6144 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006145}
6146
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306147enum tQDF_ADAPTER_MODE hdd_get_device_mode(uint32_t session_id)
6148{
6149 struct hdd_context *hdd_ctx;
6150 struct hdd_adapter *adapter;
6151
6152 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6153 if (!hdd_ctx) {
6154 hdd_err("Invalid HDD context");
6155 return QDF_MAX_NO_OF_MODE;
6156 }
6157
6158 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
6159 if (!adapter) {
6160 hdd_err("Invalid HDD adapter");
6161 return QDF_MAX_NO_OF_MODE;
6162 }
6163
6164 return adapter->device_mode;
6165}
6166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006167/**
6168 * hdd_get_operating_channel() - return operating channel of the device mode
6169 * @hdd_ctx: Pointer to the HDD context.
6170 * @mode: Device mode for which operating channel is required.
6171 * Suported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006172 * QDF_STA_MODE,
6173 * QDF_P2P_CLIENT_MODE,
6174 * QDF_SAP_MODE,
6175 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006176 *
6177 * This API returns the operating channel of the requested device mode
6178 *
6179 * Return: channel number. "0" id the requested device is not found OR it is
6180 * not connected.
6181 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006182uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006183 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006184{
Jeff Johnson9d295242017-08-29 14:39:48 -07006185 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006186 uint8_t operatingChannel = 0;
6187
Dustin Brown920397d2017-12-13 16:27:50 -08006188 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006189 if (mode == adapter->device_mode) {
6190 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006191 case QDF_STA_MODE:
6192 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006193 if (hdd_conn_is_connected
6194 (WLAN_HDD_GET_STATION_CTX_PTR
6195 (adapter))) {
6196 operatingChannel =
6197 (WLAN_HDD_GET_STATION_CTX_PTR
6198 (adapter))->conn_info.
6199 operationChannel;
6200 }
6201 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006202 case QDF_SAP_MODE:
6203 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006204 /* softap connection info */
6205 if (test_bit
6206 (SOFTAP_BSS_STARTED,
6207 &adapter->event_flags))
6208 operatingChannel =
6209 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07006210 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006211 break;
6212 default:
6213 break;
6214 }
6215
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006216 /* Found the device of interest. break the loop */
6217 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006218 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006219 }
Dustin Brown920397d2017-12-13 16:27:50 -08006220
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006221 return operatingChannel;
6222}
6223
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006224static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006225 hdd_ctx)
6226{
Jeff Johnson9d295242017-08-29 14:39:48 -07006227 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006228
Dustin Brown491d54b2018-03-14 12:39:11 -07006229 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006230
Dustin Brown920397d2017-12-13 16:27:50 -08006231 hdd_for_each_adapter(hdd_ctx, adapter) {
6232 if (adapter->device_mode == QDF_STA_MODE ||
6233 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6234 adapter->device_mode == QDF_IBSS_MODE ||
6235 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6236 adapter->device_mode == QDF_SAP_MODE ||
6237 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006238 wlan_hdd_cfg80211_deregister_frames(adapter);
6239 hdd_unregister_wext(adapter->dev);
6240 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006241 }
6242
Dustin Browne74003f2018-03-14 12:51:58 -07006243 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006244
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306245 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006246}
6247
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006248QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006249{
Jeff Johnson9d295242017-08-29 14:39:48 -07006250 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006251
Dustin Brown491d54b2018-03-14 12:39:11 -07006252 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006253
Dustin Brown920397d2017-12-13 16:27:50 -08006254 hdd_for_each_adapter(hdd_ctx, adapter) {
6255 if (adapter->device_mode == QDF_STA_MODE ||
6256 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6257 adapter->device_mode == QDF_IBSS_MODE ||
6258 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6259 adapter->device_mode == QDF_SAP_MODE ||
6260 adapter->device_mode == QDF_P2P_GO_MODE) {
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07006261 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006262 adapter->session_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05306263 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006264 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006265 }
6266
Dustin Browne74003f2018-03-14 12:51:58 -07006267 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006268
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306269 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006270}
6271
Dustin Brownf27bce82016-11-03 12:52:27 -07006272/**
6273 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
6274 * adapters
6275 * @hdd_ctx: The HDD context containing the adapters to operate on
6276 *
6277 * return: QDF_STATUS_SUCCESS
6278 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006279static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07006280{
Jeff Johnson9d295242017-08-29 14:39:48 -07006281 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07006282 int err;
6283
Dustin Brown491d54b2018-03-14 12:39:11 -07006284 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07006285
Dustin Brown920397d2017-12-13 16:27:50 -08006286 hdd_for_each_adapter(hdd_ctx, adapter) {
6287 if (adapter->device_mode == QDF_STA_MODE ||
6288 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6289 adapter->device_mode == QDF_IBSS_MODE ||
6290 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6291 adapter->device_mode == QDF_SAP_MODE ||
6292 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07006293 err = wlan_hdd_sched_scan_stop(adapter->dev);
6294 if (err)
6295 hdd_err("Unable to stop scheduled scan");
6296 }
Dustin Brownf27bce82016-11-03 12:52:27 -07006297 }
6298
Dustin Browne74003f2018-03-14 12:51:58 -07006299 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07006300
6301 return QDF_STATUS_SUCCESS;
6302}
6303
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006304#ifdef WLAN_NS_OFFLOAD
6305/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006306 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006307 * @hdd_ctx: Pointer to hdd context
6308 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006309 * Unregister for IPv6 address change notifications.
6310 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006311 * Return: None
6312 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006313static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006314{
6315 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006316}
6317
6318/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006319 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006320 * @hdd_ctx: Pointer to hdd context
6321 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006322 * Register for IPv6 address change notifications.
6323 *
6324 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006325 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006326static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006327{
6328 int ret;
6329
6330 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6331 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006332 if (ret) {
6333 hdd_err("Failed to register IPv6 notifier: %d", ret);
6334 goto out;
6335 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006336
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006337 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006338out:
6339 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006340}
6341#else
6342/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006343 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006344 * @hdd_ctx: Pointer to hdd context
6345 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006346 * Unregister for IPv6 address change notifications.
6347 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006348 * Return: None
6349 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006350static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006351{
6352}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006353
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006354/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006355 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006356 * @hdd_ctx: Pointer to hdd context
6357 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006358 * Register for IPv6 address change notifications.
6359 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006360 * Return: None
6361 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006362static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006363{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006364 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006365}
6366#endif
6367
6368/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006369 * hdd_register_notifiers - Register netdev notifiers.
6370 * @hdd_ctx: HDD context
6371 *
6372 * Register netdev notifiers like IPv4 and IPv6.
6373 *
6374 * Return: 0 on success and errno on failure
6375 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006376static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006377{
6378 int ret;
6379
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006380 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
6381 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05306382 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006383
6384 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
6385 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
6386 if (ret) {
6387 hdd_err("Failed to register IPv4 notifier: %d", ret);
6388 goto unregister_ip6_notifier;
6389 }
6390
6391 return 0;
6392
6393unregister_ip6_notifier:
6394 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006395out:
6396 return ret;
6397
6398}
6399
6400/**
6401 * hdd_unregister_notifiers - Unregister netdev notifiers.
6402 * @hdd_ctx: HDD context
6403 *
6404 * Unregister netdev notifiers like IPv4 and IPv6.
6405 *
6406 * Return: None.
6407 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006408void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006409{
6410 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
6411
6412 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006413}
6414
6415/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006416 * hdd_exit_netlink_services - Exit netlink services
6417 * @hdd_ctx: HDD context
6418 *
6419 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
6420 * nl service.
6421 *
6422 * Return: None.
6423 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006424static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006425{
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006426 hdd_close_cesium_nl_sock();
Naveen Rawat910726a2017-03-06 11:42:51 -08006427 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006428 ptt_sock_deactivate_svc();
6429
6430 nl_srv_exit();
6431}
6432
6433/**
6434 * hdd_init_netlink_services- Init netlink services
6435 * @hdd_ctx: HDD context
6436 *
6437 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
6438 * nl service.
6439 *
6440 * Return: 0 on success and errno on failure.
6441 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006442static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006443{
6444 int ret;
6445
Ryan Hsuceddceb2016-04-28 10:20:14 -07006446 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006447 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006448 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006449 goto out;
6450 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07006451 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006452
Naveen Rawat910726a2017-03-06 11:42:51 -08006453 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006454 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006455 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006456 goto err_nl_srv;
6457 }
6458
6459 ret = ptt_sock_activate_svc();
6460 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006461 hdd_err("ptt_sock_activate_svc failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006462 goto err_nl_srv;
6463 }
6464
6465 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07006466 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006467 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006468
6469 ret = cnss_diag_activate_service();
6470 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006471 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006472 goto err_close_cesium;
6473 }
6474
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08006475 ret = spectral_scan_activate_service();
6476 if (ret) {
6477 hdd_alert("spectral_scan_activate_service failed: %d", ret);
6478 goto err_close_cesium;
6479 }
6480
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006481 return 0;
6482
6483err_close_cesium:
6484 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006485 ptt_sock_deactivate_svc();
6486err_nl_srv:
6487 nl_srv_exit();
6488out:
6489 return ret;
6490}
6491
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006492/**
6493 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
6494 * @hdd_ctx: HDD context.
6495 *
6496 * Destroy RX wakelock.
6497 *
6498 * Return: None.
6499 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006500static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006501{
6502 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
6503}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006504
6505/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006506 * hdd_rx_wake_lock_create() - Create RX wakelock
6507 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006508 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006509 * Create RX wakelock.
6510 *
6511 * Return: None.
6512 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006513static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006514{
6515 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
6516}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006517
6518/**
Houston Hoffman160db392016-10-10 17:37:51 -07006519 * hdd_context_deinit() - Deinitialize HDD context
6520 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006521 *
Houston Hoffman160db392016-10-10 17:37:51 -07006522 * Deinitialize HDD context along with all the feature specific contexts but
6523 * do not free hdd context itself. Caller of this API is supposed to free
6524 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006525 *
Houston Hoffman160db392016-10-10 17:37:51 -07006526 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006527 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006528static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006529{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306530 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
6531
Houston Hoffman160db392016-10-10 17:37:51 -07006532 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006533
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006534 hdd_sap_context_destroy(hdd_ctx);
6535
6536 hdd_rx_wake_lock_destroy(hdd_ctx);
6537
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006538 hdd_scan_context_destroy(hdd_ctx);
6539
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006540 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006541
Houston Hoffman160db392016-10-10 17:37:51 -07006542 return 0;
6543}
6544
6545/**
6546 * hdd_context_destroy() - Destroy HDD context
6547 * @hdd_ctx: HDD context to be destroyed.
6548 *
6549 * Free config and HDD context as well as destroy all the resources.
6550 *
6551 * Return: None
6552 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006553static void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07006554{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07006555 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05306556
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05306557 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
6558
Houston Hoffman160db392016-10-10 17:37:51 -07006559 hdd_context_deinit(hdd_ctx);
6560
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306561 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006562 hdd_ctx->config = NULL;
6563
6564 wiphy_free(hdd_ctx->wiphy);
6565}
6566
6567/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05306568 * wlan_destroy_bug_report_lock() - Destroy bug report lock
6569 *
6570 * This function is used to destroy bug report lock
6571 *
6572 * Return: None
6573 */
6574static void wlan_destroy_bug_report_lock(void)
6575{
6576 p_cds_contextType p_cds_context;
6577
6578 p_cds_context = cds_get_global_context();
6579 if (!p_cds_context) {
6580 hdd_err("cds context is NULL");
6581 return;
6582 }
6583
6584 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
6585}
6586
6587/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006588 * hdd_wlan_exit() - HDD WLAN exit function
6589 * @hdd_ctx: Pointer to the HDD Context
6590 *
6591 * This is the driver exit point (invoked during rmmod)
6592 *
6593 * Return: None
6594 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006595static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006596{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006597 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05306598 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006599
Dustin Brown491d54b2018-03-14 12:39:11 -07006600 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006601
Dustin Brown6f427922017-09-19 12:19:00 -07006602 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Arun Khandavallifae92942016-08-01 13:31:08 +05306603
6604 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006605
Prashanth Bhattaab004382016-10-11 16:08:11 -07006606 hdd_bus_bandwidth_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006607
6608#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05306609 if (QDF_TIMER_STATE_RUNNING ==
6610 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
6611 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006612 }
6613
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306614 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05306615 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07006616 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006617 }
Liangwei Dongaef84342016-10-21 05:28:00 -04006618 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6619 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6620 hdd_ctx->last_acs_channel_list = NULL;
6621 hdd_ctx->num_of_channels = 0;
6622 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006623#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006624
Arun Khandavallifae92942016-08-01 13:31:08 +05306625 mutex_lock(&hdd_ctx->iface_change_lock);
6626 driver_status = hdd_ctx->driver_status;
6627 mutex_unlock(&hdd_ctx->iface_change_lock);
6628
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006629 /*
6630 * Powersave Offload Case
6631 * Disable Idle Power Save Mode
6632 */
6633 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07006634 /* clear the scan queue in all the scenarios */
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +05306635 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006636
Arun Khandavallifae92942016-08-01 13:31:08 +05306637 if (driver_status != DRIVER_MODULES_CLOSED) {
6638 hdd_unregister_wext_all_adapters(hdd_ctx);
6639 /*
6640 * Cancel any outstanding scan requests. We are about to close
6641 * all of our adapters, but an adapter structure is what SME
6642 * passes back to our callback function. Hence if there
6643 * are any outstanding scan requests then there is a
6644 * race condition between when the adapter is closed and
6645 * when the callback is invoked. We try to resolve that
6646 * race condition here by canceling any outstanding scans
6647 * before we close the adapters.
6648 * Note that the scans may be cancelled in an asynchronous
6649 * manner, so ideally there needs to be some kind of
6650 * synchronization. Rather than introduce a new
6651 * synchronization here, we will utilize the fact that we are
6652 * about to Request Full Power, and since that is synchronized,
6653 * the expectation is that by the time Request Full Power has
6654 * completed, all scans will be cancelled
6655 */
6656 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07006657 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08006658 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08006659 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006660 }
6661
Arun Khandavalli08479ba2017-08-07 19:56:23 +05306662 unregister_netdevice_notifier(&hdd_netdev_notifier);
6663
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07006664 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05306665
Dustin Brown021cecd2017-12-11 13:56:43 -08006666 hdd_driver_memdump_deinit();
6667
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05306668 qdf_nbuf_deinit_replenish_timer();
6669
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306670 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
6671 hdd_info("Release wakelock for monitor mode!");
6672 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
6673 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
6674 }
6675
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05306676 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
6677 qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
6678 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
6679
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006680 /*
6681 * Close CDS
6682 * This frees pMac(HAL) context. There should not be any call
6683 * that requires pMac access after this.
6684 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006685
Jeff Johnsonce0032c2017-01-20 07:18:27 -08006686 hdd_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006687
Dustin Brownd005ad82018-01-19 10:32:13 -08006688 hdd_close_all_adapters(hdd_ctx, false);
6689
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006690 hdd_ipa_cleanup(hdd_ctx);
6691
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05306692 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306693 /*
6694 * If there is re_init failure wiphy would have already de-registered
6695 * check the wiphy status before un-registering again
6696 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05306697 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306698 wiphy_unregister(wiphy);
6699 wlan_hdd_cfg80211_deinit(wiphy);
6700 hdd_lpass_notify_stop(hdd_ctx);
6701 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07006702
Arun Khandavallifae92942016-08-01 13:31:08 +05306703 hdd_exit_netlink_services(hdd_ctx);
6704 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05306705#ifdef FEATURE_WLAN_CH_AVOID
6706 mutex_destroy(&hdd_ctx->avoid_freq_lock);
6707#endif
Abhishek Singhe9068f12017-03-31 14:14:52 +05306708
Abhishek Singhe9068f12017-03-31 14:14:52 +05306709 driver_status = hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
6710 if (driver_status)
6711 hdd_err("Psoc delete failed");
Dustin Brown6f17a022017-07-19 13:40:55 -07006712
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006713 hdd_context_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006714}
6715
6716void __hdd_wlan_exit(void)
6717{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006718 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006719
Dustin Brown491d54b2018-03-14 12:39:11 -07006720 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006721
Anurag Chouhan6d760662016-02-20 16:05:43 +05306722 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006723 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006724 hdd_err("Invalid HDD Context");
Dustin Browne74003f2018-03-14 12:51:58 -07006725 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006726 return;
6727 }
6728
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006729 /* Do all the cleanup before deregistering the driver */
6730 hdd_wlan_exit(hdd_ctx);
Mohit Khannaebf8a862016-04-28 17:53:59 -07006731
Dustin Browne74003f2018-03-14 12:51:58 -07006732 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006733}
6734
6735#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04006736/**
6737 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006738 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04006739 *
6740 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
6741 * Then new ACS request will do a fresh scan without reusing the cached
6742 * scan information.
6743 *
6744 * Return: void
6745 */
Tang Yingying523322d2017-01-17 23:28:43 +08006746static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006747{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006748 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006749
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006750 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006751 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04006752 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6753 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6754 hdd_ctx->last_acs_channel_list = NULL;
6755 hdd_ctx->num_of_channels = 0;
6756 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006757
6758 if (!hdd_ctx->hHal)
6759 return;
6760 sme_scan_flush_result(hdd_ctx->hHal);
6761}
6762#endif
6763
6764#ifdef QCA_HT_2040_COEX
Jeff Johnsone7672e72017-10-21 15:10:04 -07006765int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
6766 struct qdf_mac_addr sta_mac, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006767{
6768 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306769 QDF_STATUS qdf_status;
Jeff Johnsone7672e72017-10-21 15:10:04 -07006770 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006771
6772 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6773
6774 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306775 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006776 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306777
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006778 if (!hdd_ctx->hHal)
6779 return -EINVAL;
6780
Jeff Johnsone7672e72017-10-21 15:10:04 -07006781 qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, sta_id, sta_mac,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006782 adapter->session_id, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306783 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006784 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006785 return -EINVAL;
6786 }
6787
6788 return 0;
6789}
6790#endif
6791
6792/**
6793 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
6794 * @state: state
6795 *
6796 * This function notifies FW with modem power status
6797 *
6798 * Return: 0 if successful, error number otherwise
6799 */
6800int hdd_wlan_notify_modem_power_state(int state)
6801{
6802 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306803 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006804 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006805
Anurag Chouhan6d760662016-02-20 16:05:43 +05306806 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006807 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306808 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006809 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306810
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006811 if (!hdd_ctx->hHal)
6812 return -EINVAL;
6813
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306814 qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
6815 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006816 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006817 state);
6818 return -EINVAL;
6819 }
6820 return 0;
6821}
6822
6823/**
6824 *
6825 * hdd_post_cds_enable_config() - HDD post cds start config helper
6826 * @adapter - Pointer to the HDD
6827 *
6828 * Return: None
6829 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006830QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006831{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306832 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006833
6834 /*
6835 * Send ready indication to the HDD. This will kick off the MAC
6836 * into a 'running' state and should kick off an initial scan.
6837 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306838 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
6839 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006840 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
6841 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306842 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006843 }
6844
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306845 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006846}
6847
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05306848struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
6849{
6850 struct hdd_adapter *adapter;
6851
6852 hdd_for_each_adapter(hdd_ctx, adapter) {
6853 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
6854 return adapter;
6855 }
6856
6857 return NULL;
6858}
6859
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006860/* wake lock APIs for HDD */
6861void hdd_prevent_suspend(uint32_t reason)
6862{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05306863 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006864}
6865
6866void hdd_allow_suspend(uint32_t reason)
6867{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05306868 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006869}
6870
6871void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
6872{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05306873 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
6874 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006875}
6876
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006877/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006878QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006879{
Amar Singhal5cccafe2017-02-15 12:42:58 -08006880
Amar Singhal6f8592b2017-04-26 14:31:58 -07006881 return sme_init_chan_list(hdd_ctx->hHal,
6882 hdd_ctx->reg.alpha2,
6883 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006884}
6885
6886/**
6887 * hdd_is_5g_supported() - check if hardware supports 5GHz
6888 * @hdd_ctx: Pointer to the hdd context
6889 *
6890 * HDD function to know if hardware supports 5GHz
6891 *
6892 * Return: true if hardware supports 5GHz
6893 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006894bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006895{
Amar Singhal58b45ef2017-08-01 13:43:54 -07006896 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08006897 return true;
6898
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08006899 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08006900 return true;
6901 else
6902 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006903}
6904
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006905static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006906{
6907 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07006908 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006909
6910 wiphy = hdd_ctx->wiphy;
6911
6912 /*
6913 * The channel information in
6914 * wiphy needs to be initialized before wiphy registration
6915 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006916 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
6917 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006918 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07006919 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006920 }
6921
6922#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
6923 wiphy->wowlan = &wowlan_support_reg_init;
6924#else
6925 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
6926 WIPHY_WOWLAN_MAGIC_PKT |
6927 WIPHY_WOWLAN_DISCONNECT |
6928 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
6929 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
6930 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
6931 WIPHY_WOWLAN_4WAY_HANDSHAKE |
6932 WIPHY_WOWLAN_RFKILL_RELEASE;
6933
6934 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
6935 WOW_MAX_FILTERS_PER_LIST);
6936 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
6937 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
6938#endif
6939
6940 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006941 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306942 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07006943 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306944 return ret_val;
6945 }
6946
Amar Singhal2d812012018-02-03 15:06:47 +08006947 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006948
Amar Singhale4f28ee2015-10-21 14:36:56 -07006949 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006950}
6951
Mohit Khannaca4173b2017-09-12 21:52:19 -07006952#ifdef MSM_PLATFORM
6953/**
6954 * hdd_display_periodic_stats() - Function to display periodic stats
6955 * @hdd_ctx - handle to hdd context
6956 * @bool data_in_interval - true, if data detected in bw time interval
6957 *
6958 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
6959 * Stats show up in wlan driver logs.
6960 *
6961 * Returns: None
6962 */
6963static inline
6964void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
6965 bool data_in_interval)
6966{
6967 static u32 counter;
6968 static bool data_in_time_period;
6969 ol_txrx_pdev_handle pdev;
6970
6971 if (hdd_ctx->config->periodic_stats_disp_time == 0)
6972 return;
6973
6974 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
6975 if (!pdev) {
6976 hdd_err("pdev is NULL");
6977 return;
6978 }
6979
6980 counter++;
6981 if (data_in_interval)
6982 data_in_time_period = data_in_interval;
6983
6984 if (counter * hdd_ctx->config->busBandwidthComputeInterval >=
6985 hdd_ctx->config->periodic_stats_disp_time * 1000) {
6986 if (data_in_time_period) {
6987 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
6988 CDP_TXRX_PATH_STATS,
6989 QDF_STATS_VERBOSITY_LEVEL_LOW);
6990 wlan_hdd_display_netif_queue_history
6991 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
6992 qdf_dp_trace_dump_stats();
6993 }
6994 counter = 0;
6995 data_in_time_period = false;
6996 }
6997}
6998
Ravi Joshie2331e82015-07-01 18:18:54 -07006999/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07007000 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07007001 * @hdd_ctx - handle to hdd context
7002 * @tx_packets - transmit packet count
7003 * @rx_packets - receive packet count
7004 *
7005 * The function controls the bus bandwidth and dynamic control of
7006 * tcp delayed ack configuration
7007 *
7008 * Returns: None
7009 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007010
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007011static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07007012 const uint64_t tx_packets,
7013 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007014{
Mohit Khannaca4173b2017-09-12 21:52:19 -07007015 u64 total_pkts = tx_packets + rx_packets;
Mohit Khannae71e2262015-11-10 09:37:24 -08007016 uint64_t temp_rx = 0;
7017 uint64_t temp_tx = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007018 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08007019 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08007020 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007021 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007022 uint16_t index = 0;
7023 bool vote_level_change = false;
7024 bool rx_level_change = false;
7025 bool tx_level_change = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007026
Mohit Khannaca4173b2017-09-12 21:52:19 -07007027 if (total_pkts > hdd_ctx->config->busBandwidthHighThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007028 next_vote_level = PLD_BUS_WIDTH_HIGH;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007029 else if (total_pkts > hdd_ctx->config->busBandwidthMediumThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007030 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007031 else if (total_pkts > hdd_ctx->config->busBandwidthLowThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007032 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07007033 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07007034 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007035
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007036 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07007037 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
7038 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007039 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007040 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007041 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Nirav Shah3bbfa512016-05-12 16:43:49 +05307042 if (next_vote_level == PLD_BUS_WIDTH_LOW) {
Nirav Shahffc6a092016-06-09 16:09:08 +05307043 if (hdd_ctx->hbw_requested) {
7044 pld_remove_pm_qos(hdd_ctx->parent_dev);
7045 hdd_ctx->hbw_requested = false;
7046 }
Nirav Shah3bbfa512016-05-12 16:43:49 +05307047 if (cds_sched_handle_throughput_req(false))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007048 hdd_warn("low bandwidth set rx affinity fail");
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007049 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05307050 if (!hdd_ctx->hbw_requested) {
7051 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
7052 hdd_ctx->hbw_requested = true;
7053 }
7054
Nirav Shah3bbfa512016-05-12 16:43:49 +05307055 if (cds_sched_handle_throughput_req(true))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007056 hdd_warn("high bandwidth set rx affinity fail");
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007057 }
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -07007058 hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007059 }
Mohit Khannae71e2262015-11-10 09:37:24 -08007060
Mohit Khannaf8f96822017-05-17 17:11:59 -07007061 qdf_dp_trace_throttle_live_mode(
7062 (next_vote_level > PLD_BUS_WIDTH_NONE) ? true : false);
7063
Mohit Khannae71e2262015-11-10 09:37:24 -08007064 /* fine-tuning parameters for RX Flows */
7065 temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
7066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007067 hdd_ctx->prev_rx = rx_packets;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08007068
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307069 if (temp_rx < hdd_ctx->config->busBandwidthLowThreshold)
7070 hdd_disable_lro_for_low_tput(hdd_ctx, true);
7071 else
7072 hdd_disable_lro_for_low_tput(hdd_ctx, false);
7073
Ravi Joshifed83572016-10-07 16:20:37 -07007074 if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) {
7075 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
7076 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
7077 next_rx_level = WLAN_SVC_TP_HIGH;
7078 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07007079 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07007080 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08007081 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007082 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007083
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007084 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007085 struct wlan_rx_tp_data rx_tp_data = {0};
7086
Ravi Joshie2331e82015-07-01 18:18:54 -07007087 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007088 next_rx_level, temp_rx);
7089 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007090 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07007091 /* Send throughput indication only if it is enabled.
7092 * Disabling tcp_del_ack will revert the tcp stack behavior
7093 * to default delayed ack. Note that this will disable the
7094 * dynamic delayed ack mechanism across the system
7095 */
7096 if (hdd_ctx->config->enable_tcp_delack)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007097 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
7098
Mohit Khanna6272fb682017-04-13 09:34:36 -07007099 if (hdd_ctx->config->enable_tcp_adv_win_scale)
7100 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
7101
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007102 rx_tp_data.level = next_rx_level;
7103 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7104 WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
7105 sizeof(rx_tp_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007106 }
7107
Mohit Khannae71e2262015-11-10 09:37:24 -08007108 /* fine-tuning parameters for TX Flows */
7109 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
7110 hdd_ctx->prev_tx = tx_packets;
7111 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
7112 next_tx_level = WLAN_SVC_TP_HIGH;
7113 else
7114 next_tx_level = WLAN_SVC_TP_LOW;
7115
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08007116 if ((hdd_ctx->config->enable_tcp_limit_output) &&
7117 (hdd_ctx->cur_tx_level != next_tx_level)) {
Mohit Khannae71e2262015-11-10 09:37:24 -08007118 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
7119 next_tx_level, temp_tx);
7120 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007121 tx_level_change = true;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05307122 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7123 WLAN_SVC_WLAN_TP_TX_IND,
Mohit Khannae71e2262015-11-10 09:37:24 -08007124 &next_tx_level,
7125 sizeof(next_tx_level));
7126 }
7127
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007128 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007129 if (vote_level_change || tx_level_change || rx_level_change) {
7130 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
7131 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
7132 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
7133 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
7134 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
7135 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
7136 hdd_ctx->hdd_txrx_hist_idx++;
7137 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
7138 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07007139
7140 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007141}
7142
7143#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307144static void hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007145{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007146 struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307147 bus_bw_work);
Jeff Johnson9d295242017-08-29 14:39:48 -07007148 struct hdd_adapter *adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307149 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05307150 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
7151 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007152 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307153 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007154 bool connected = false;
7155 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
7156
Prashanth Bhattaab004382016-10-11 16:08:11 -07007157 if (wlan_hdd_validate_context(hdd_ctx))
7158 return;
7159
Jeff Johnson214671b2017-10-30 19:45:23 -07007160 if (hdd_ctx->is_wiphy_suspended)
Jingxiang Gec64e1932017-08-22 14:38:59 +08007161 goto restart_timer;
7162
Dustin Brown920397d2017-12-13 16:27:50 -08007163 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05307164 /*
7165 * Validate magic so we don't end up accessing
7166 * an invalid adapter.
7167 */
7168 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
7169 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007170
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007171 if ((adapter->device_mode == QDF_STA_MODE ||
7172 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007173 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
7174 != eConnectionState_Associated) {
7175
7176 continue;
7177 }
7178
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007179 if ((adapter->device_mode == QDF_SAP_MODE ||
7180 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07007181 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007182
7183 continue;
7184 }
7185
7186 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
7187 adapter->prev_tx_packets);
7188 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
7189 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307190
7191 if (adapter->device_mode == QDF_SAP_MODE ||
7192 adapter->device_mode == QDF_P2P_GO_MODE ||
7193 adapter->device_mode == QDF_IBSS_MODE) {
7194
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08007195 ret = cdp_get_intra_bss_fwd_pkts_count(
7196 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07007197 adapter->session_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307198 &fwd_tx_packets, &fwd_rx_packets);
7199 if (ret == A_OK) {
7200 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
7201 fwd_tx_packets,
7202 adapter->prev_fwd_tx_packets);
7203 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
7204 fwd_tx_packets,
7205 adapter->prev_fwd_rx_packets);
7206 }
7207 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007208
7209 total_rx += adapter->stats.rx_packets;
7210 total_tx += adapter->stats.tx_packets;
7211
7212 spin_lock_bh(&hdd_ctx->bus_bw_lock);
7213 adapter->prev_tx_packets = adapter->stats.tx_packets;
7214 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307215 adapter->prev_fwd_tx_packets = fwd_tx_packets;
7216 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007217 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
7218 connected = true;
7219 }
7220
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307221 /* add intra bss forwarded tx and rx packets */
7222 tx_packets += fwd_tx_packets_diff;
7223 rx_packets += fwd_rx_packets_diff;
7224
Sravan Kumar Kairam271fab22018-03-07 18:57:41 +05307225 ucfg_ipa_uc_stat_query(hdd_ctx->hdd_pdev, &ipa_tx_packets,
7226 &ipa_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007227 tx_packets += (uint64_t)ipa_tx_packets;
7228 rx_packets += (uint64_t)ipa_rx_packets;
7229
Yun Park2aa880c2017-08-22 10:58:10 -07007230 if (adapter) {
7231 adapter->stats.tx_packets += ipa_tx_packets;
7232 adapter->stats.rx_packets += ipa_rx_packets;
7233 }
7234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007235 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007236 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007237 return;
7238 }
7239
Yuanyuan Liu13738502016-04-06 17:41:37 -07007240 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007241
Sravan Kumar Kairam9e99e9a2018-03-12 19:09:45 +05307242 ucfg_ipa_set_perf_level(hdd_ctx->hdd_pdev, tx_packets, rx_packets);
Sravan Kumar Kairam271fab22018-03-07 18:57:41 +05307243 ucfg_ipa_uc_stat_request(hdd_ctx->hdd_pdev, 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007244
Jingxiang Gec64e1932017-08-22 14:38:59 +08007245restart_timer:
Dustin Brown2ed60362017-01-18 12:25:50 -08007246 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08007247 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08007248 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05307249 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
Dustin Brownfce08d12017-01-17 16:29:38 -08007250 hdd_ctx->config->busBandwidthComputeInterval);
Dustin Brownfce08d12017-01-17 16:29:38 -08007251 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007252}
Prashanth Bhattaab004382016-10-11 16:08:11 -07007253
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307254/**
7255 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
7256 * @arg: Argument of timer function
7257 *
7258 * Schedule a workqueue in this function where all the processing is done.
7259 *
7260 * Return: None.
7261 */
7262static void __hdd_bus_bw_cbk(void *arg)
7263{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007264 struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307265
7266 if (wlan_hdd_validate_context(hdd_ctx))
7267 return;
7268
7269 schedule_work(&hdd_ctx->bus_bw_work);
7270}
7271
7272/**
7273 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
7274 * @arg: Argument of timer function
7275 *
7276 * Return: None.
7277 */
7278static void hdd_bus_bw_cbk(void *arg)
7279{
7280 cds_ssr_protect(__func__);
7281 __hdd_bus_bw_cbk(arg);
7282 cds_ssr_unprotect(__func__);
7283}
7284
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007285int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007286{
7287 spin_lock_init(&hdd_ctx->bus_bw_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307288 INIT_WORK(&hdd_ctx->bus_bw_work,
7289 hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08007290 hdd_ctx->bus_bw_timer_running = false;
7291 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307292 qdf_timer_init(NULL,
7293 &hdd_ctx->bus_bw_timer,
7294 hdd_bus_bw_cbk, (void *)hdd_ctx,
7295 QDF_TIMER_TYPE_SW);
Prashanth Bhattaab004382016-10-11 16:08:11 -07007296
7297 return 0;
7298}
7299
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007300void hdd_bus_bandwidth_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007301{
Dustin Brownfce08d12017-01-17 16:29:38 -08007302 if (hdd_ctx->bus_bw_timer_running)
Prashanth Bhattaab004382016-10-11 16:08:11 -07007303 hdd_reset_tcp_delack(hdd_ctx);
7304
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007305 hdd_debug("wait for bus bw work to flush");
Nirav Shaheb017be2018-02-15 11:20:58 +05307306 hdd_cancel_bus_bw_work(hdd_ctx);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307307 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08007308 hdd_ctx->bus_bw_timer_running = false;
7309 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Prashanth Bhattaab004382016-10-11 16:08:11 -07007310}
Lin Baic5c06882017-09-21 13:58:43 +08007311
7312void hdd_bus_bw_cancel_work(struct hdd_context *hdd_ctx)
7313{
7314 if (hdd_ctx)
7315 cancel_work_sync(&hdd_ctx->bus_bw_work);
7316}
jiadcdaf9bd2017-10-26 12:20:21 +08007317
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007318#endif
7319
7320/**
Nirav Shahed34b212016-04-25 10:59:16 +05307321 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
7322 * @hdd_ctx: hdd context
7323 *
7324 * Return: 0 for success or error code
7325 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007326static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05307327{
7328 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
7329 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
7330 if (hdd_ctx->hdd_txrx_hist == NULL) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007331 hdd_err("Failed malloc for hdd_txrx_hist");
Nirav Shahed34b212016-04-25 10:59:16 +05307332 return -ENOMEM;
7333 }
7334 return 0;
7335}
7336
7337/**
7338 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
7339 * @hdd_ctx: hdd context
7340 *
7341 * Return: none
7342 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007343void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05307344{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307345 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
7346 return;
7347
7348 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
7349 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05307350}
7351
Nirav Shahda008342016-05-17 18:50:40 +05307352static uint8_t *convert_level_to_string(uint32_t level)
7353{
7354 switch (level) {
7355 /* initialize the wlan sub system */
7356 case WLAN_SVC_TP_NONE:
7357 return "NONE";
7358 case WLAN_SVC_TP_LOW:
7359 return "LOW";
7360 case WLAN_SVC_TP_MEDIUM:
7361 return "MED";
7362 case WLAN_SVC_TP_HIGH:
7363 return "HIGH";
7364 default:
7365 return "INVAL";
7366 }
7367}
7368
Nirav Shahed34b212016-04-25 10:59:16 +05307369
7370/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007371 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
7372 * @hdd_ctx: hdd context
7373 *
7374 * Return: none
7375 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007376void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007377{
7378 int i;
7379
7380#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007381 hdd_debug("BW compute Interval: %dms",
Nirav Shahda008342016-05-17 18:50:40 +05307382 hdd_ctx->config->busBandwidthComputeInterval);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007383 hdd_debug("BW High TH: %d BW Med TH: %d BW Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007384 hdd_ctx->config->busBandwidthHighThreshold,
7385 hdd_ctx->config->busBandwidthMediumThreshold,
7386 hdd_ctx->config->busBandwidthLowThreshold);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007387 hdd_debug("Enable TCP DEL ACK: %d",
Nirav Shahda008342016-05-17 18:50:40 +05307388 hdd_ctx->config->enable_tcp_delack);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007389 hdd_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007390 hdd_ctx->config->tcpDelackThresholdHigh,
7391 hdd_ctx->config->tcpDelackThresholdLow);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007392 hdd_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
Nirav Shahda008342016-05-17 18:50:40 +05307393 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007394#endif
7395
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007396 hdd_debug("Total entries: %d Current index: %d",
Nirav Shahda008342016-05-17 18:50:40 +05307397 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
7398
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007399 hdd_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007400
7401 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007402 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007403 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Dustin Brown632af712018-03-14 15:03:55 -07007404 hdd_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
7405 i, hdd_ctx->hdd_txrx_hist[i].qtime,
7406 hdd_ctx->hdd_txrx_hist[i].interval_rx,
7407 hdd_ctx->hdd_txrx_hist[i].interval_tx,
7408 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007409 hdd_ctx->hdd_txrx_hist[i].
7410 next_vote_level),
Dustin Brown632af712018-03-14 15:03:55 -07007411 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007412 hdd_ctx->hdd_txrx_hist[i].
7413 next_rx_level),
Dustin Brown632af712018-03-14 15:03:55 -07007414 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007415 hdd_ctx->hdd_txrx_hist[i].
7416 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007417 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007418}
7419
7420/**
7421 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
7422 * @hdd_ctx: hdd context
7423 *
7424 * Return: none
7425 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007426void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007427{
7428 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05307429 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
7430 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007431}
7432
Mohit Khannaca4173b2017-09-12 21:52:19 -07007433/* length of the netif queue log needed per adapter */
7434#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
7435
7436/**
7437 *
7438 * hdd_display_netif_queue_history_compact() - display compact netifq history
7439 * @hdd_ctx: hdd context
7440 *
7441 * Return: none
7442 */
7443static void
7444hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
7445{
7446 int adapter_num = 0;
7447 int i;
7448 int bytes_written;
7449 u32 tbytes;
7450 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007451 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08007452 char *comb_log_str;
7453 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007454 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007455
jiadbdefb252018-01-03 14:27:06 +08007456 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * MAX_NUMBER_OF_ADAPTERS) + 1;
7457 comb_log_str = qdf_mem_malloc(comb_log_str_size);
7458 if (!comb_log_str) {
7459 hdd_err("failed to alloc comb_log_str");
7460 return;
7461 }
7462
Mohit Khannaca4173b2017-09-12 21:52:19 -07007463 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007464
Dustin Brown920397d2017-12-13 16:27:50 -08007465 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07007466 curr_time = qdf_system_ticks();
7467 total = curr_time - adapter->start_time;
7468 delta = curr_time - adapter->last_time;
7469
7470 if (adapter->pause_map) {
7471 pause = adapter->total_pause_time + delta;
7472 unpause = adapter->total_unpause_time;
7473 } else {
7474 unpause = adapter->total_unpause_time + delta;
7475 pause = adapter->total_pause_time;
7476 }
7477
7478 tbytes = 0;
7479 qdf_mem_set(temp_str, 0, sizeof(temp_str));
7480 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7481 if (adapter->queue_oper_stats[i].pause_count == 0)
7482 continue;
7483 tbytes +=
7484 snprintf(
7485 &temp_str[tbytes],
7486 (tbytes >= sizeof(temp_str) ?
7487 0 : sizeof(temp_str) - tbytes),
7488 "%d(%d,%d) ",
7489 i,
7490 adapter->queue_oper_stats[i].
7491 pause_count,
7492 adapter->queue_oper_stats[i].
7493 unpause_count);
7494 }
7495 if (tbytes >= sizeof(temp_str))
7496 hdd_warn("log truncated");
7497
7498 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08007499 bytes_written >= comb_log_str_size ? 0 :
7500 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07007501 "[%d %d] (%d) %u/%ums %s|",
7502 adapter->session_id, adapter->device_mode,
7503 adapter->pause_map,
7504 qdf_system_ticks_to_msecs(pause),
7505 qdf_system_ticks_to_msecs(total),
7506 temp_str);
7507
Mohit Khannaca4173b2017-09-12 21:52:19 -07007508 adapter_num++;
7509 }
7510
7511 /* using QDF_TRACE to avoid printing function name */
7512 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
7513 "STATS |%s", comb_log_str);
7514
jiadbdefb252018-01-03 14:27:06 +08007515 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007516 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08007517
7518 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07007519}
7520
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007521/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007522 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07007523 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007524 *
7525 * Return: none
7526 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007527void
7528wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
7529 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007530{
7531
Jeff Johnson9d295242017-08-29 14:39:48 -07007532 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007533 int i;
Nirav Shahda008342016-05-17 18:50:40 +05307534 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007535
Mohit Khannaca4173b2017-09-12 21:52:19 -07007536 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
7537 hdd_display_netif_queue_history_compact(hdd_ctx);
7538 return;
7539 }
7540
Dustin Brown920397d2017-12-13 16:27:50 -08007541 hdd_for_each_adapter(hdd_ctx, adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007542 hdd_debug("Netif queue operation statistics:");
7543 hdd_debug("Session_id %d device mode %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07007544 adapter->session_id, adapter->device_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007545 hdd_debug("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05307546 curr_time = qdf_system_ticks();
7547 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05307548 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05307549 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05307550 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307551 unpause = adapter->total_unpause_time;
7552 } else {
Nirav Shahda008342016-05-17 18:50:40 +05307553 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307554 pause = adapter->total_pause_time;
7555 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007556 hdd_debug("Total: %ums Pause: %ums Unpause: %ums",
Nirav Shah617cff92016-04-25 10:24:24 +05307557 qdf_system_ticks_to_msecs(total),
7558 qdf_system_ticks_to_msecs(pause),
7559 qdf_system_ticks_to_msecs(unpause));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007560 hdd_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007561
Nirav Shahda008342016-05-17 18:50:40 +05307562 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7563 qdf_time_t pause_delta = 0;
7564
7565 if (adapter->pause_map & (1 << i))
7566 pause_delta = delta;
7567
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007568 /* using hdd_log to avoid printing function name */
Dustin Brown632af712018-03-14 15:03:55 -07007569 hdd_debug("%s: %d: %d: %ums",
7570 hdd_reason_type_to_string(i),
7571 adapter->queue_oper_stats[i].pause_count,
7572 adapter->queue_oper_stats[i].unpause_count,
7573 qdf_system_ticks_to_msecs(
7574 adapter->queue_oper_stats[i].total_pause_time +
7575 pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007576 }
7577
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007578 hdd_debug("Netif queue operation history:");
7579 hdd_debug("Total entries: %d current index %d",
Nirav Shahda008342016-05-17 18:50:40 +05307580 WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index);
7581
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007582 hdd_debug("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007583
7584 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007585 /* using hdd_log to avoid printing function name */
7586 if (adapter->queue_oper_history[i].time == 0)
7587 continue;
Dustin Brown632af712018-03-14 15:03:55 -07007588 hdd_debug("%d: %u: %s: %s: %x",
7589 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007590 adapter->queue_oper_history[i].time),
Dustin Brown632af712018-03-14 15:03:55 -07007591 hdd_action_type_to_string(
7592 adapter->queue_oper_history[i].netif_action),
7593 hdd_reason_type_to_string(
7594 adapter->queue_oper_history[i].netif_reason),
7595 adapter->queue_oper_history[i].pause_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007596 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007597 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007598}
7599
7600/**
7601 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
7602 * @hdd_ctx: hdd context
7603 *
7604 * Return: none
7605 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007606void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007607{
Jeff Johnson9d295242017-08-29 14:39:48 -07007608 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007609
Dustin Brown920397d2017-12-13 16:27:50 -08007610 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307611 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007612 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307613 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007614 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05307615 adapter->history_index = 0;
7616 adapter->start_time = adapter->last_time = qdf_system_ticks();
7617 adapter->total_pause_time = 0;
7618 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007619 }
7620}
7621
7622/**
7623 * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
7624 * @halHandle: Hal handle
7625 * @pContext: Pointer to the context
7626 * @sessionId: Session ID
7627 * @scanId: Scan ID
7628 * @status: Status
7629 *
7630 * This is the callback to be executed when 11d scan is completed to flush out
7631 * the scan results
7632 *
7633 * 11d scan is done during driver load and is a passive scan on all
7634 * channels supported by the device, 11d scans may find some APs on
7635 * frequencies which are forbidden to be used in the regulatory domain
7636 * the device is operating in. If these APs are notified to the supplicant
7637 * it may try to connect to these APs, thus flush out all the scan results
7638 * which are present in SME after 11d scan is done.
7639 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307640 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007641 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307642static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007643 uint8_t sessionId, uint32_t scanId,
7644 eCsrScanStatus status)
7645{
Dustin Brown491d54b2018-03-14 12:39:11 -07007646 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007647
7648 sme_scan_flush_result(halHandle);
7649
Dustin Browne74003f2018-03-14 12:51:58 -07007650 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007651
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307652 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007653}
7654
7655#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7656/**
7657 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
7658 * @hdd_ctx: hdd global context
7659 *
7660 * Return: none
7661 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007662static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007663{
7664 uint8_t i;
7665
7666 mutex_init(&hdd_ctx->op_ctx.op_lock);
7667 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
7668 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
7669 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
7670 }
7671}
7672#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007673static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007674{
7675}
7676#endif
7677
Yingying Tang95409972016-10-20 15:16:15 +08007678#ifdef WLAN_FEATURE_WOW_PULSE
7679/**
7680 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007681 * @phddctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08007682 * @enable: enable or disable this behaviour
7683 *
7684 * Return: int
7685 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007686static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007687{
7688 struct hdd_config *pcfg_ini = phddctx->config;
7689 struct wow_pulse_mode wow_pulse_set_info;
7690 QDF_STATUS status;
7691
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007692 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08007693
7694 if (false == phddctx->config->wow_pulse_support)
7695 return 0;
7696
7697 /* prepare the request to send to SME */
7698 if (enable == true) {
7699 wow_pulse_set_info.wow_pulse_enable = true;
7700 wow_pulse_set_info.wow_pulse_pin =
7701 pcfg_ini->wow_pulse_pin;
7702 wow_pulse_set_info.wow_pulse_interval_low =
7703 pcfg_ini->wow_pulse_interval_low;
7704 wow_pulse_set_info.wow_pulse_interval_high =
7705 pcfg_ini->wow_pulse_interval_high;
7706 } else {
7707 wow_pulse_set_info.wow_pulse_enable = false;
7708 wow_pulse_set_info.wow_pulse_pin = 0;
7709 wow_pulse_set_info.wow_pulse_interval_low = 0;
7710 wow_pulse_set_info.wow_pulse_interval_high = 0;
7711 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007712 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08007713 wow_pulse_set_info.wow_pulse_enable,
7714 wow_pulse_set_info.wow_pulse_pin,
7715 wow_pulse_set_info.wow_pulse_interval_low,
7716 wow_pulse_set_info.wow_pulse_interval_high);
7717
7718 status = sme_set_wow_pulse(&wow_pulse_set_info);
7719 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007720 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08007721 return -EIO;
7722 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007723 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08007724 return 0;
7725}
7726#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007727static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007728{
7729 return 0;
7730}
7731#endif
7732
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007733#ifdef WLAN_FEATURE_FASTPATH
7734/**
7735 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
7736 * @hdd_cfg: hdd config
7737 * @context: lower layer context
7738 *
7739 * Return: none
7740 */
Arun Khandavallifae92942016-08-01 13:31:08 +05307741void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007742 void *context)
7743{
7744 if (hdd_cfg->fastpath_enable)
7745 hif_enable_fastpath(context);
7746}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007747#endif
7748
Yuanyuan Liu13738502016-04-06 17:41:37 -07007749#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007750/**
7751 * hdd_set_thermal_level_cb() - set thermal level callback function
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007752 * @context: hdd context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007753 * @level: thermal level
7754 *
7755 * Change IPA data path to SW path when the thermal throttle level greater
7756 * than 0, and restore the original data path when throttle level is 0
7757 *
7758 * Return: none
7759 */
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007760static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007761{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007762 struct hdd_context *hdd_ctx = context;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007763
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007764 /* Change IPA to SW path when throttle level greater than 0 */
7765 if (level > THROTTLE_LEVEL_0)
7766 hdd_ipa_send_mcc_scc_msg(hdd_ctx, true);
7767 else
7768 /* restore original concurrency mode */
7769 hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode);
7770}
7771
7772/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307773 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
7774 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05307775 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007776 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307777 * Get a safe channel to restart SAP. PCL already takes into account the
7778 * unsafe channels. So, the PCL is validated with the ACS range to provide
7779 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007780 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307781 * Return: Channel number to restart SAP in case of success. In case of any
7782 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007783 */
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307784static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range(
Jeff Johnson9d295242017-08-29 14:39:48 -07007785 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007786{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307787 struct sir_pcl_list pcl;
7788 QDF_STATUS status;
7789 uint32_t i, j;
7790 tHalHandle *hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007791 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307792 bool found = false;
Liangwei Dong17bf2662018-01-05 02:02:05 -05007793 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007794
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307795 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7796 if (!hdd_ctx) {
7797 hdd_err("invalid HDD context");
7798 return INVALID_CHANNEL_ID;
7799 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007800
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05307801 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
7802 if (!hal_handle) {
7803 hdd_err("invalid HAL handle");
7804 return INVALID_CHANNEL_ID;
7805 }
7806
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007807 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->hdd_psoc,
7808 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08007809 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
7810 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307811 if (QDF_IS_STATUS_ERROR(status)) {
7812 hdd_err("Get PCL failed");
7813 return INVALID_CHANNEL_ID;
7814 }
7815
Frank Liudc2cefb2017-06-21 15:38:18 +08007816 /*
7817 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
7818 * channel is unsafe channel, the pcl may be empty, instead of return,
7819 * try to choose a safe channel from acs range.
7820 */
7821 if (!pcl.pcl_len)
7822 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307823
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007824 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07007825 adapter->session.ap.sap_config.acs_cfg.start_ch,
7826 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307827
7828 /* PCL already takes unsafe channel into account */
7829 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007830 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307831 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007832 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307833 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007834 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007835 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307836 return pcl.pcl_list[i];
7837 }
7838 }
7839
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007840 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307841
7842 /* Try for safe channel from all valid channel */
7843 pcl.pcl_len = MAX_NUM_CHAN;
Liangwei Dong17bf2662018-01-05 02:02:05 -05007844 ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
7845 &pcl.pcl_len);
7846 if (ret) {
7847 hdd_err("error %d in getting valid channel list", ret);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307848 return INVALID_CHANNEL_ID;
7849 }
7850
7851 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007852 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307853 found = false;
7854 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
Krunal Soni15f0db12016-10-11 18:53:37 -07007855 if (pcl.pcl_list[i] ==
7856 hdd_ctx->unsafe_channel_list[j]) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007857 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307858 found = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007859 break;
7860 }
7861 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307862
7863 if (found)
7864 continue;
7865
7866 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007867 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307868 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007869 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007870 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307871 return pcl.pcl_list[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007872 }
7873 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307874
7875 return INVALID_CHANNEL_ID;
7876}
Nirav Shaheb017be2018-02-15 11:20:58 +05307877#endif
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307878
7879/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007880 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307881 * @adapter: AP adapter
7882 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08007883 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307884 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007885 * Moves the SAP interface by invoking the function which
7886 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307887 *
7888 * Return: None
7889 */
Min Liu2fef5792018-01-19 17:59:42 +08007890void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
7891 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307892{
Jeff Johnson87251032017-08-29 13:31:11 -07007893 struct hdd_ap_ctx *hdd_ap_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307894 tHalHandle *hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007895 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307896
7897 if (!adapter) {
7898 hdd_err("invalid adapter");
7899 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307901
7902 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
7903
7904 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
7905 if (!hal_handle) {
7906 hdd_err("invalid HAL handle");
7907 return;
7908 }
7909
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007910 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7911
Jeff Johnson91df29d2017-10-27 19:29:50 -07007912 hdd_ap_ctx->sap_config.channel = channel;
7913 hdd_ap_ctx->sap_config.ch_params.ch_width =
7914 hdd_ap_ctx->sap_config.ch_width_orig;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307915
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007916 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07007917 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307918
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07007919 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
Jeff Johnson91df29d2017-10-27 19:29:50 -07007920 hdd_ap_ctx->sap_config.channel,
7921 hdd_ap_ctx->sap_config.sec_ch,
7922 &hdd_ap_ctx->sap_config.ch_params);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307923
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007924 policy_mgr_change_sap_channel_with_csa(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07007925 adapter->session_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08007926 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007927}
Kapil Gupta8878ad92017-02-13 11:56:04 +05307928
Jeff Johnson9d295242017-08-29 14:39:48 -07007929int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05307930{
7931 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307932 int status;
7933 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307934
7935 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
7936
7937 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07007938 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05307939 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07007940 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307941 }
7942 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07007943 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307944 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307945 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07007946 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307947 WLAN_VENDOR_ACS_WAIT_TIME);
7948 if (qdf_status != QDF_STATUS_SUCCESS) {
7949 hdd_err("failed to start external acs timer");
7950 return -ENOSPC;
7951 }
7952 /* Update config to application */
7953 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07007954 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307955
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307956 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307957}
7958
Nirav Shaheb017be2018-02-15 11:20:58 +05307959#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05307960/**
7961 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
7962 * @hdd_ctx: hdd context pointer
7963 *
7964 * hdd_unsafe_channel_restart_sap check all unsafe channel list
7965 * and if ACS is enabled, driver will ask userspace to restart the
7966 * sap. User space on LTE coex indication restart driver.
7967 *
7968 * Return - none
7969 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007970void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05307971{
Dustin Brown920397d2017-12-13 16:27:50 -08007972 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307973 uint32_t i;
7974 bool found = false;
7975 uint8_t restart_chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007976
Dustin Brown920397d2017-12-13 16:27:50 -08007977 hdd_for_each_adapter(hdd_ctxt, adapter) {
7978 if (!(adapter->device_mode == QDF_SAP_MODE &&
7979 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007980 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08007981 adapter->device_mode,
7982 adapter->session.ap.sap_config.
7983 acs_cfg.acs_mode);
7984 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307985 }
7986
7987 found = false;
7988 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
Dustin Brown920397d2017-12-13 16:27:50 -08007989 if (adapter->session.ap.operating_channel ==
Agrawal Ashish467dde42016-09-08 18:44:22 +05307990 hdd_ctxt->unsafe_channel_list[i]) {
7991 found = true;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007992 hdd_debug("operating ch:%d is unsafe",
Dustin Brown920397d2017-12-13 16:27:50 -08007993 adapter->session.ap.operating_channel);
Agrawal Ashish467dde42016-09-08 18:44:22 +05307994 break;
7995 }
7996 }
7997
7998 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007999 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08008000 adapter->session.ap.operating_channel);
8001 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308002 }
8003
Kapil Gupta8878ad92017-02-13 11:56:04 +05308004 if (hdd_ctxt->config->vendor_acs_support &&
8005 hdd_ctxt->config->acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08008006 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05308007 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08008008 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308009 } else
8010 restart_chan =
8011 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08008012 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308013 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008014 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308015 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008016 /*
8017 * SAP restart due to unsafe channel. While
8018 * restarting the SAP, make sure to clear
8019 * acs_channel, channel to reset to
8020 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308021 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008022 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308023 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown920397d2017-12-13 16:27:50 -08008024 adapter->session.ap.sap_config.channel =
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308025 AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008026 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308027 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
8028 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Liangwei Dong6663d162017-07-10 03:29:36 -04008029 hdd_debug("driver to start sap: %d",
8030 hdd_ctxt->config->sap_internal_restart);
8031 if (hdd_ctxt->config->sap_internal_restart)
Min Liu2fef5792018-01-19 17:59:42 +08008032 hdd_switch_sap_channel(adapter, restart_chan,
8033 true);
Liangwei Dong6663d162017-07-10 03:29:36 -04008034 else
8035 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308036 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308037 }
8038}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05308039
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008040/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008041 * hdd_init_channel_avoidance() - Initialize channel avoidance
8042 * @hdd_ctx: HDD global context
8043 *
8044 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07008045 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008046 * down to the lower layers. Then subscribe to subsequent channel
8047 * avoidance events.
8048 *
8049 * Return: None
8050 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008051static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008052{
8053 uint16_t unsafe_channel_count;
8054 int index;
8055
Yuanyuan Liu13738502016-04-06 17:41:37 -07008056 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
8057 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008058 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08008059 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008060
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008061 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008062 hdd_ctx->unsafe_channel_count);
8063
Anurag Chouhan6d760662016-02-20 16:05:43 +05308064 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08008065 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008066
8067 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008068 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008069 hdd_ctx->unsafe_channel_list[index]);
8070
8071 }
8072
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008073}
Dustin Brown676a2322017-08-15 13:16:13 -07008074
Jeff Johnson9d295242017-08-29 14:39:48 -07008075static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008076 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008077{
8078 uint8_t restart_chan;
8079
8080 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
8081 if (!restart_chan) {
8082 hdd_alert("fail to restart SAP");
8083 return;
8084 }
8085
8086 /* SAP restart due to unsafe channel. While restarting
8087 * the SAP, make sure to clear acs_channel, channel to
8088 * reset to 0. Otherwise these settings will override
8089 * the ACS while restart.
8090 */
8091 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -07008092 adapter->session.ap.sap_config.channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07008093
8094 hdd_debug("sending coex indication");
8095
8096 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8097 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Min Liu2fef5792018-01-19 17:59:42 +08008098 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07008099}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008100
8101int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
8102 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
8103{
8104 uint32_t size;
8105 uint16_t *unsafe_list;
8106 uint16_t chan_count;
8107
8108 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
8109 return -EINVAL;
8110
8111 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
8112 NUM_CHANNELS);
8113 if (chan_count) {
8114 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
8115 unsafe_list = qdf_mem_malloc(size);
8116 if (!unsafe_list) {
8117 hdd_err("No memory for unsafe chan list size%d",
8118 size);
8119 return -ENOMEM;
8120 }
8121 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
8122 } else {
8123 unsafe_list = NULL;
8124 }
8125
8126 *local_unsafe_list = unsafe_list;
8127 *local_unsafe_list_count = chan_count;
8128
8129 return 0;
8130}
8131
8132bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
8133 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
8134{
8135 int i, j;
8136
8137 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
8138 return true;
8139 if (local_unsafe_list_count == 0)
8140 return false;
8141 for (i = 0; i < local_unsafe_list_count; i++) {
8142 for (j = 0; j < local_unsafe_list_count; j++)
8143 if (local_unsafe_list[i] ==
8144 hdd_ctx->unsafe_channel_list[j])
8145 break;
8146 if (j >= local_unsafe_list_count)
8147 break;
8148 }
8149 if (i >= local_unsafe_list_count) {
8150 hdd_info("unsafe chan list same");
8151 return false;
8152 }
8153
8154 return true;
8155}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008156#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008157static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008158{
8159}
Dustin Brown676a2322017-08-15 13:16:13 -07008160
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008161static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008162{
8163}
Dustin Brown676a2322017-08-15 13:16:13 -07008164
Jeff Johnson9d295242017-08-29 14:39:48 -07008165static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008166 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008167{
8168 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
8169}
Yuanyuan Liu13738502016-04-06 17:41:37 -07008170#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008171
8172/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08008173 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
8174 * user space
8175 * @frame_ind: Management frame data to be informed.
8176 *
8177 * This function is used to indicate management frame to
8178 * user space
8179 *
8180 * Return: None
8181 *
8182 */
8183void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
8184{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008185 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07008186 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008187 int i;
8188
Rajeev Kumard004abc2016-02-17 12:09:56 -08008189 /* Get the HDD context.*/
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008190 hdd_ctx = (struct hdd_context *)cds_get_context(QDF_MODULE_ID_HDD);
Rajeev Kumard004abc2016-02-17 12:09:56 -08008191
8192 if (0 != wlan_hdd_validate_context(hdd_ctx))
8193 return;
8194
8195 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
8196 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
8197 adapter =
8198 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
8199 if (adapter)
8200 break;
8201 }
Wu Gaoa0230a62018-01-04 20:56:57 +08008202 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
8203 hdd_for_each_adapter(hdd_ctx, adapter) {
8204 if ((NULL != adapter) &&
8205 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
8206 __hdd_indicate_mgmt_frame(adapter,
8207 frame_ind->frame_len,
8208 frame_ind->frameBuf,
8209 frame_ind->frameType,
8210 frame_ind->rxChan,
8211 frame_ind->rxRssi);
8212 }
8213 }
8214 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008215 } else {
8216 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
8217 frame_ind->sessionId);
8218 }
8219
8220 if ((NULL != adapter) &&
8221 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
8222 __hdd_indicate_mgmt_frame(adapter,
8223 frame_ind->frame_len,
8224 frame_ind->frameBuf,
8225 frame_ind->frameType,
8226 frame_ind->rxChan,
8227 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08008228}
8229
Kapil Gupta8878ad92017-02-13 11:56:04 +05308230void hdd_acs_response_timeout_handler(void *context)
8231{
8232 struct hdd_external_acs_timer_context *timer_context =
8233 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07008234 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008235 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308236 uint8_t reason;
8237
Dustin Brown491d54b2018-03-14 12:39:11 -07008238 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05308239 if (!timer_context) {
8240 hdd_err("invlaid timer context");
8241 return;
8242 }
8243 adapter = timer_context->adapter;
8244 reason = timer_context->reason;
8245
8246
8247 if ((!adapter) ||
8248 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
8249 hdd_err("invalid adapter or adapter has invalid magic");
8250 return;
8251 }
8252 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8253 if (wlan_hdd_validate_context(hdd_ctx))
8254 return;
8255
8256 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
8257 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8258 else
8259 return;
8260
8261 hdd_err("ACS timeout happened for %s reason %d",
8262 adapter->dev->name, reason);
8263 switch (reason) {
8264 /* SAP init case */
8265 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
8266 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
8267 false);
8268 wlan_hdd_cfg80211_start_acs(adapter);
8269 break;
8270 /* DFS detected on current channel */
8271 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
8272 wlan_sap_update_next_channel(
8273 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
8274 sme_update_new_channel_event(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07008275 adapter->session_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308276 break;
8277 /* LTE coex event on current channel */
8278 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
8279 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
8280 break;
8281 default:
8282 hdd_info("invalid reason for timer invoke");
8283
8284 }
8285}
8286
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008287/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008288 * hdd_override_ini_config - Override INI config
8289 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008290 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008291 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008292 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008293 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008294 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008295static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008296{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008297
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008298 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
8299 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008300 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008301 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008302 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008303 if (0 == enable_11d || 1 == enable_11d) {
8304 hdd_ctx->config->Is11dSupportEnabled = enable_11d;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008305 hdd_debug("Module enable_11d set to %d", enable_11d);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008306 }
Leo Chang11545d62016-10-17 14:53:50 -07008307
Yun Park45d35972018-03-02 09:57:54 -08008308 if (!hdd_ipa_is_present()) {
Leo Chang11545d62016-10-17 14:53:50 -07008309 hdd_ctx->config->IpaConfig = 0;
Jingxiang Ge7a040dc2018-02-02 11:07:59 +08008310 hdd_debug("IpaConfig override to %d",
8311 hdd_ctx->config->IpaConfig);
8312 }
Yeshwanth Sriram Guntuka2ba6fe92017-10-04 14:40:45 +05308313
8314 if (!hdd_ctx->config->rssi_assoc_reject_enabled ||
8315 !hdd_ctx->config->enable_bcast_probe_rsp) {
8316 hdd_debug("OCE disabled, rssi_assoc_reject_enabled: %d enable_bcast_probe_rsp: %d",
8317 hdd_ctx->config->rssi_assoc_reject_enabled,
8318 hdd_ctx->config->enable_bcast_probe_rsp);
8319 hdd_ctx->config->oce_sta_enabled = 0;
8320 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008321}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008322
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008323/**
8324 * hdd_set_trace_level_for_each - Set trace level for each INI config
8325 * @hdd_ctx - HDD context
8326 *
8327 * Set trace level for each module based on INI config.
8328 *
8329 * Return: None
8330 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008331static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008332{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308333 hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
8334 hdd_ctx->config->qdf_trace_enable_wdi);
8335 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
8336 hdd_ctx->config->qdf_trace_enable_hdd);
8337 hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
8338 hdd_ctx->config->qdf_trace_enable_sme);
8339 hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
8340 hdd_ctx->config->qdf_trace_enable_pe);
8341 hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
8342 hdd_ctx->config->qdf_trace_enable_wma);
8343 hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
8344 hdd_ctx->config->qdf_trace_enable_sys);
8345 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
8346 hdd_ctx->config->qdf_trace_enable_qdf);
8347 hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
8348 hdd_ctx->config->qdf_trace_enable_sap);
8349 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
8350 hdd_ctx->config->qdf_trace_enable_hdd_sap);
8351 hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
8352 hdd_ctx->config->qdf_trace_enable_bmi);
8353 hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
8354 hdd_ctx->config->qdf_trace_enable_cfg);
8355 hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
8356 hdd_ctx->config->qdf_trace_enable_epping);
8357 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
8358 hdd_ctx->config->qdf_trace_enable_qdf_devices);
8359 hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
Houston Hoffmanfbf05102017-08-28 11:37:01 -07008360 hdd_ctx->config->qdf_trace_enable_txrx);
8361 hdd_qdf_trace_enable(QDF_MODULE_ID_DP,
8362 hdd_ctx->config->qdf_trace_enable_dp);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308363 hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
8364 hdd_ctx->config->qdf_trace_enable_htc);
8365 hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
8366 hdd_ctx->config->qdf_trace_enable_hif);
8367 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
8368 hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
8369 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
8370 hdd_ctx->config->qdf_trace_enable_hdd_data);
Naveen Rawat7df31862017-03-01 17:09:30 -08008371 hdd_qdf_trace_enable(QDF_MODULE_ID_WIFIPOS,
8372 hdd_ctx->config->qdf_trace_enable_wifi_pos);
Naveen Rawatf2b0dbd2017-03-27 10:00:15 -07008373 hdd_qdf_trace_enable(QDF_MODULE_ID_NAN,
8374 hdd_ctx->config->qdf_trace_enable_nan);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07008375 hdd_qdf_trace_enable(QDF_MODULE_ID_REGULATORY,
8376 hdd_ctx->config->qdf_trace_enable_regulatory);
8377
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008378 hdd_cfg_print(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008379}
8380
8381/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008382 * hdd_context_init() - Initialize HDD context
8383 * @hdd_ctx: HDD context.
8384 *
8385 * Initialize HDD context along with all the feature specific contexts.
8386 *
8387 * return: 0 on success and errno on failure.
8388 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008389static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008390{
8391 int ret;
8392
8393 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
8394 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
8395
8396 hdd_init_ll_stats_ctx();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +05308397 hdd_init_nud_stats_ctx(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008398
8399 init_completion(&hdd_ctx->mc_sus_event_var);
8400 init_completion(&hdd_ctx->ready_to_suspend);
8401
8402 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308403 qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008404 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308405
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008406 qdf_list_create(&hdd_ctx->hdd_adapters, MAX_NUMBER_OF_ADAPTERS);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008407
8408 init_completion(&hdd_ctx->set_antenna_mode_cmpl);
8409
8410 ret = hdd_scan_context_init(hdd_ctx);
8411 if (ret)
8412 goto list_destroy;
8413
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008414 hdd_rx_wake_lock_create(hdd_ctx);
8415
8416 ret = hdd_sap_context_init(hdd_ctx);
8417 if (ret)
8418 goto scan_destroy;
8419
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008420 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
8421
8422 hdd_init_offloaded_packets_ctx(hdd_ctx);
8423
8424 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
8425 hdd_ctx->config);
8426 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08008427 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008428
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05308429 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
8430 "monitor_mode_wakelock");
8431
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008432 return 0;
8433
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008434sap_destroy:
8435 hdd_sap_context_destroy(hdd_ctx);
8436
8437scan_destroy:
8438 hdd_scan_context_destroy(hdd_ctx);
8439 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008440list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008441 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08008442
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008443 return ret;
8444}
8445
8446/**
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308447 * ie_whitelist_attrs_init() - initialize ie whitelisting attributes
8448 * @hdd_ctx: pointer to hdd context
8449 *
8450 * Return: status of initialization
8451 * 0 - success
8452 * negative value - failure
8453 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008454static int ie_whitelist_attrs_init(struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308455{
8456 int ret;
8457
8458 if (!hdd_ctx->config->probe_req_ie_whitelist)
8459 return 0;
8460
8461 if (!hdd_validate_prb_req_ie_bitmap(hdd_ctx)) {
8462 hdd_err("invalid ie bitmap and ouis: disable ie whitelisting");
8463 hdd_ctx->config->probe_req_ie_whitelist = false;
8464 return -EINVAL;
8465 }
8466
8467 /* parse ini string probe req oui */
8468 ret = hdd_parse_probe_req_ouis(hdd_ctx);
8469 if (ret) {
8470 hdd_err("parsing error: disable ie whitelisting");
8471 hdd_ctx->config->probe_req_ie_whitelist = false;
8472 }
8473
8474 return ret;
8475}
8476
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308477/**
8478 * hdd_iface_change_callback() - Function invoked when stop modules expires
8479 * @priv: pointer to hdd context
8480 *
8481 * This function is invoked when the timer waiting for the interface change
8482 * expires, it shall cut-down the power to wlan and stop all the modules.
8483 *
8484 * Return: void
8485 */
8486static void hdd_iface_change_callback(void *priv)
8487{
8488 struct hdd_context *hdd_ctx = (struct hdd_context *) priv;
8489 int ret;
8490 int status = wlan_hdd_validate_context(hdd_ctx);
8491
8492 if (status)
8493 return;
8494
Dustin Brown491d54b2018-03-14 12:39:11 -07008495 hdd_enter();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308496 hdd_debug("Interface change timer expired close the modules!");
8497 ret = hdd_wlan_stop_modules(hdd_ctx, false);
8498 if (ret)
8499 hdd_err("Failed to stop modules");
Dustin Browne74003f2018-03-14 12:51:58 -07008500 hdd_exit();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308501}
8502
Nirav Shaheb017be2018-02-15 11:20:58 +05308503#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8504static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
8505{
8506 wlan_logging_set_log_to_console(hdd_ctx->config->
8507 wlan_logging_to_console);
8508 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
8509}
8510#else
8511static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
8512{ }
8513#endif
8514
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308515/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008516 * hdd_context_create() - Allocate and inialize HDD context.
Arun Khandavallifae92942016-08-01 13:31:08 +05308517 * @dev: Device Pointer to the underlying device
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008518 *
8519 * Allocate and initialize HDD context. HDD context is allocated as part of
8520 * wiphy allocation and then context is initialized.
8521 *
8522 * Return: HDD context on success and ERR_PTR on failure
8523 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008524static struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008525{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308526 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008527 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008528 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008529
Dustin Brown491d54b2018-03-14 12:39:11 -07008530 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008531
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008532 hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(struct hdd_context));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008533 if (hdd_ctx == NULL) {
8534 ret = -ENOMEM;
8535 goto err_out;
8536 }
8537
Dustin Brown6f427922017-09-19 12:19:00 -07008538 qdf_create_delayed_work(&hdd_ctx->iface_idle_work,
8539 hdd_iface_change_callback,
8540 (void *)hdd_ctx);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308541
8542 mutex_init(&hdd_ctx->iface_change_lock);
8543
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008544 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05308545 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008546
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308547 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008548 if (hdd_ctx->config == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008549 hdd_err("Failed to alloc memory for HDD config!");
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008550 ret = -ENOMEM;
8551 goto err_free_hdd_context;
8552 }
8553
8554 /* Read and parse the qcom_cfg.ini file */
8555 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308556 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05308557 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008558 WLAN_INI_FILE);
8559 ret = -EINVAL;
8560 goto err_free_config;
8561 }
8562
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308563 ie_whitelist_attrs_init(hdd_ctx);
8564
Dustin Brown7f939932017-05-18 15:02:17 -07008565 hdd_debug("setting timer multiplier: %u",
8566 hdd_ctx->config->timer_multiplier);
8567 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
8568
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008569
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308570 if (hdd_ctx->config->fhostNSOffload)
8571 hdd_ctx->ns_offload_enable = true;
8572
Abhishek Singh5ea86532016-04-27 14:10:53 +05308573 cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
8574
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008575 hdd_override_ini_config(hdd_ctx);
8576
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008577 ret = hdd_context_init(hdd_ctx);
8578
8579 if (ret)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008580 goto err_free_config;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008581
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008582 /* Uses to enabled logging after SSR */
Komal Seelamc11bb222016-01-27 18:57:10 +05308583 hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008584
Anurag Chouhan6d760662016-02-20 16:05:43 +05308585 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008586 goto skip_multicast_logging;
8587
8588 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
8589
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008590 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
8591 if (ret)
8592 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05308593
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008594 ret = hdd_init_netlink_services(hdd_ctx);
8595 if (ret)
8596 goto err_deinit_txrx_histogram;
8597
Nirav Shaheb017be2018-02-15 11:20:58 +05308598 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +05308599
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008600skip_multicast_logging:
8601 hdd_set_trace_level_for_each(hdd_ctx);
8602
Rajeev Kumar493a31b2017-09-29 14:01:24 -07008603 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
8604
Dustin Browne74003f2018-03-14 12:51:58 -07008605 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07008606
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008607 return hdd_ctx;
8608
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008609err_deinit_txrx_histogram:
8610 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
8611
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008612err_deinit_hdd_context:
8613 hdd_context_deinit(hdd_ctx);
8614
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008615err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308616 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008617
8618err_free_hdd_context:
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308619 mutex_destroy(&hdd_ctx->iface_change_lock);
Rajeev Kumarfa55a692018-01-09 14:12:41 -08008620 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008621
8622err_out:
8623 return ERR_PTR(ret);
8624}
8625
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008626#ifdef WLAN_OPEN_P2P_INTERFACE
8627/**
8628 * hdd_open_p2p_interface - Open P2P interface
8629 * @hdd_ctx: HDD context
8630 * @rtnl_held: True if RTNL lock held
8631 *
8632 * Open P2P interface during probe. This function called to open the P2P
8633 * interface at probe along with STA interface.
8634 *
8635 * Return: 0 on success and errno on failure
8636 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008637static int hdd_open_p2p_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008638{
Jeff Johnson9d295242017-08-29 14:39:48 -07008639 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008640 uint8_t *p2p_dev_addr;
8641
8642 if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
8643 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008644 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008645 hdd_ctx->config->intfMacAddr[0].bytes,
8646 sizeof(tSirMacAddr));
8647
8648 /*
8649 * Generate the P2P Device Address. This consists of
8650 * the device's primary MAC address with the locally
8651 * administered bit set.
8652 */
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008653 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008654 } else {
8655 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
8656 if (p2p_dev_addr == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008657 hdd_err("Failed to allocate mac_address for p2p_device");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008658 return -ENOSPC;
8659 }
8660
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008661 qdf_mem_copy(&hdd_ctx->p2p_device_address.bytes[0],
8662 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008663 }
8664
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008665 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008666 &hdd_ctx->p2p_device_address.bytes[0],
Ryan Hsu07495ea2016-01-21 15:25:39 -08008667 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008668
8669 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008670 hdd_err("Failed to do hdd_open_adapter for P2P Device Interface");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008671 return -ENOSPC;
8672 }
8673
8674 return 0;
8675}
8676#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008677static inline int hdd_open_p2p_interface(struct hdd_context *hdd_ctx,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008678 bool rtnl_held)
8679{
8680 return 0;
8681}
8682#endif
8683
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008684static int hdd_open_ocb_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Jeff Johnson957bc272017-02-02 08:54:48 -08008685{
Jeff Johnson9d295242017-08-29 14:39:48 -07008686 struct hdd_adapter *adapter;
Jeff Johnson957bc272017-02-02 08:54:48 -08008687 int ret = 0;
8688
8689 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
8690 wlan_hdd_get_intf_addr(hdd_ctx),
8691 NET_NAME_UNKNOWN, rtnl_held);
8692 if (adapter == NULL) {
8693 hdd_err("Failed to open 802.11p interface");
8694 ret = -ENOSPC;
8695 }
8696
8697 return ret;
8698}
8699
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008700/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308701 * hdd_start_station_adapter()- Start the Station Adapter
8702 * @adapter: HDD adapter
8703 *
8704 * This function initializes the adapter for the station mode.
8705 *
8706 * Return: 0 on success or errno on failure.
8707 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008708int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308709{
8710 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08008711 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308712
Dustin Brownfdf17c12018-03-14 12:55:34 -07008713 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08008714 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8715 hdd_err("session is already opened, %d",
8716 adapter->session_id);
8717 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8718 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308719
Krunal Sonib51eec72017-11-20 21:53:01 -08008720 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
8721 if (ret) {
8722 hdd_err("failed to create vdev: %d", ret);
8723 return ret;
8724 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308725 status = hdd_init_station_mode(adapter);
8726
8727 if (QDF_STATUS_SUCCESS != status) {
8728 hdd_err("Error Initializing station mode: %d", status);
8729 return qdf_status_to_os_return(status);
8730 }
8731
Arun Khandavallifae92942016-08-01 13:31:08 +05308732 hdd_register_tx_flow_control(adapter,
8733 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008734 hdd_tx_resume_cb,
8735 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308736
Dustin Browne74003f2018-03-14 12:51:58 -07008737 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308738 return 0;
8739}
8740
8741/**
8742 * hdd_start_ap_adapter()- Start AP Adapter
8743 * @adapter: HDD adapter
8744 *
8745 * This function initializes the adapter for the AP mode.
8746 *
8747 * Return: 0 on success errno on failure.
8748 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008749int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308750{
8751 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008752 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08008753 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -08008754 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308755
Dustin Brown491d54b2018-03-14 12:39:11 -07008756 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308757
Krunal Sonib51eec72017-11-20 21:53:01 -08008758 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8759 hdd_err("session is already opened, %d",
8760 adapter->session_id);
8761 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8762 }
8763 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008764 * In SSR case no need to create new sap context.
8765 * Otherwise create sap context first and then create
8766 * vdev as while creating the vdev, driver needs to
8767 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08008768 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008769 if (adapter->session.ap.sap_context) {
8770 is_ssr = true;
8771 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08008772 hdd_err("sap creation failed");
8773 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
8774 }
8775
8776 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
8777 adapter->session.ap.sap_context);
8778 if (ret) {
8779 hdd_err("failed to create vdev, status:%d", ret);
8780 hdd_sap_destroy_ctx(adapter);
8781 return ret;
8782 }
Naveen Rawat1af09392018-01-03 17:28:21 -08008783
8784 if (adapter->device_mode == QDF_SAP_MODE)
8785 sme_cli_set_command(adapter->session_id,
8786 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
8787 (bool)(hdd_ctx->config->fine_time_meas_cap &
8788 WMI_FW_AP_RTT_RESPR),
8789 VDEV_CMD);
8790
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008791 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308792
8793 if (QDF_STATUS_SUCCESS != status) {
8794 hdd_err("Error Initializing the AP mode: %d", status);
8795 return qdf_status_to_os_return(status);
8796 }
8797
Arun Khandavallifae92942016-08-01 13:31:08 +05308798 hdd_register_tx_flow_control(adapter,
8799 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008800 hdd_softap_tx_resume_cb,
8801 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308802
Dustin Browne74003f2018-03-14 12:51:58 -07008803 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308804 return 0;
8805}
8806
Sourav Mohapatra57006c72017-11-19 16:15:55 +05308807static int hdd_open_concurrent_interface(struct hdd_context *hdd_ctx,
8808 bool rtnl_held)
8809{
8810 struct hdd_adapter *adapter;
8811
8812 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
8813 hdd_ctx->config->enableConcurrentSTA,
8814 wlan_hdd_get_intf_addr(hdd_ctx),
8815 NET_NAME_UNKNOWN, rtnl_held);
8816
8817 if (!adapter)
8818 return -ENOSPC;
8819
8820 return 0;
8821}
8822
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308823/**
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008824 * hdd_open_interfaces - Open all required interfaces
8825 * hdd_ctx: HDD context
8826 * rtnl_held: True if RTNL lock is held
8827 *
8828 * Open all the interfaces like STA, P2P and OCB based on the configuration.
8829 *
Jeff Johnson957bc272017-02-02 08:54:48 -08008830 * Return: 0 if all interfaces were created, otherwise negative errno
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008831 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008832static int hdd_open_interfaces(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008833{
Jeff Johnson9d295242017-08-29 14:39:48 -07008834 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008835 int ret;
8836
Ravi Joshia307f632017-07-17 23:41:41 -07008837 /* open monitor mode adapter if con_mode is monitor mode */
Lin Bai1c678482017-12-18 18:29:11 +08008838 if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
8839 con_mode == QDF_GLOBAL_FTM_MODE) {
8840 uint8_t session_type = (con_mode == QDF_GLOBAL_MONITOR_MODE) ?
8841 QDF_MONITOR_MODE : QDF_FTM_MODE;
8842
8843 adapter = hdd_open_adapter(hdd_ctx, session_type, "wlan%d",
8844 wlan_hdd_get_intf_addr(hdd_ctx),
8845 NET_NAME_UNKNOWN, rtnl_held);
Ravi Joshia307f632017-07-17 23:41:41 -07008846 if (!adapter) {
8847 hdd_err("open adapter failed");
8848 return -ENOSPC;
8849 }
Lin Bai1c678482017-12-18 18:29:11 +08008850
Ravi Joshia307f632017-07-17 23:41:41 -07008851 return 0;
8852 }
8853
Jeff Johnson957bc272017-02-02 08:54:48 -08008854 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE)
Arun Khandavallifae92942016-08-01 13:31:08 +05308855 /* Create only 802.11p interface */
Jeff Johnson957bc272017-02-02 08:54:48 -08008856 return hdd_open_ocb_interface(hdd_ctx, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008857
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008858 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008859 wlan_hdd_get_intf_addr(hdd_ctx),
Ryan Hsu07495ea2016-01-21 15:25:39 -08008860 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008861
8862 if (adapter == NULL)
Jeff Johnson957bc272017-02-02 08:54:48 -08008863 return -ENOSPC;
8864
Sourav Mohapatra57006c72017-11-19 16:15:55 +05308865 if (strlen(hdd_ctx->config->enableConcurrentSTA) != 0) {
8866 ret = hdd_open_concurrent_interface(hdd_ctx, rtnl_held);
8867 if (ret)
8868 hdd_err("Cannot create concurrent STA interface");
8869 }
8870
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008871 ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
8872 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -08008873 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008874
8875 /* Open 802.11p Interface */
8876 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
Jeff Johnson957bc272017-02-02 08:54:48 -08008877 ret = hdd_open_ocb_interface(hdd_ctx, rtnl_held);
8878 if (ret)
8879 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008880 }
8881
Jeff Johnson957bc272017-02-02 08:54:48 -08008882 return 0;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008883
Jeff Johnson957bc272017-02-02 08:54:48 -08008884err_close_adapters:
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008885 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Jeff Johnson957bc272017-02-02 08:54:48 -08008886 return ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008887}
8888
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008889
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308890#ifdef QCA_LL_TX_FLOW_CONTROL_V2
8891/**
8892 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
8893 * @cds_cfg: CDS Configuration
8894 * @hdd_ctx: Pointer to hdd context
8895 *
8896 * Return: none
8897 */
8898static inline void hdd_txrx_populate_cds_config(struct cds_config_info
8899 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008900 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308901{
8902 cds_cfg->tx_flow_stop_queue_th =
8903 hdd_ctx->config->TxFlowStopQueueThreshold;
8904 cds_cfg->tx_flow_start_queue_offset =
8905 hdd_ctx->config->TxFlowStartQueueOffset;
8906}
8907#else
8908static inline void hdd_txrx_populate_cds_config(struct cds_config_info
8909 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008910 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308911{
8912}
8913#endif
8914
8915#ifdef FEATURE_WLAN_RA_FILTERING
8916/**
8917 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
8918 * @cds_cfg: CDS Configuration
8919 * @hdd_ctx: Pointer to hdd context
8920 *
8921 * Return: none
8922 */
Anand Kumar3b92a912016-12-05 12:01:26 +05308923static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008924 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308925{
8926 cds_cfg->ra_ratelimit_interval =
8927 hdd_ctx->config->RArateLimitInterval;
8928 cds_cfg->is_ra_ratelimit_enabled =
8929 hdd_ctx->config->IsRArateLimitEnabled;
8930}
8931#else
Anand Kumar3b92a912016-12-05 12:01:26 +05308932static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008933 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308934{
8935}
8936#endif
8937
8938/**
8939 * hdd_update_cds_config() - API to update cds configuration parameters
8940 * @hdd_ctx: HDD Context
8941 *
8942 * Return: 0 for Success, errno on failure
8943 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008944static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308945{
8946 struct cds_config_info *cds_cfg;
8947
8948 cds_cfg = (struct cds_config_info *)qdf_mem_malloc(sizeof(*cds_cfg));
8949 if (!cds_cfg) {
8950 hdd_err("failed to allocate cds config");
8951 return -ENOMEM;
8952 }
8953
Srinivas Girigowda35b00312017-06-27 21:52:03 -07008954 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -08008955 if (!hdd_ctx->config->nMaxPsPoll ||
8956 !hdd_ctx->config->enablePowersaveOffload) {
8957 cds_cfg->powersave_offload_enabled =
8958 hdd_ctx->config->enablePowersaveOffload;
8959 } else {
8960 if ((hdd_ctx->config->enablePowersaveOffload ==
8961 PS_QPOWER_NODEEPSLEEP) ||
8962 (hdd_ctx->config->enablePowersaveOffload ==
8963 PS_LEGACY_NODEEPSLEEP))
8964 cds_cfg->powersave_offload_enabled =
8965 PS_LEGACY_NODEEPSLEEP;
8966 else
8967 cds_cfg->powersave_offload_enabled =
8968 PS_LEGACY_DEEPSLEEP;
8969 hdd_info("Qpower disabled in cds config, %d",
8970 cds_cfg->powersave_offload_enabled);
8971 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308972 cds_cfg->sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
8973 cds_cfg->sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
8974 cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
8975 cds_cfg->wow_enable = hdd_ctx->config->wowEnable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308976
8977 /*
8978 * Copy the DFS Phyerr Filtering Offload status.
8979 * This parameter reflects the value of the
8980 * dfs_phyerr_filter_offload flag as set in the ini.
8981 */
8982 cds_cfg->dfs_phyerr_filter_offload =
8983 hdd_ctx->config->fDfsPhyerrFilterOffload;
8984 if (hdd_ctx->config->ssdp)
8985 cds_cfg->ssdp = hdd_ctx->config->ssdp;
8986
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05308987 cds_cfg->force_target_assert_enabled =
8988 hdd_ctx->config->crash_inject_enabled;
8989
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308990 cds_cfg->enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
8991 cds_cfg->ap_maxoffload_peers = hdd_ctx->config->apMaxOffloadPeers;
8992
8993 cds_cfg->ap_maxoffload_reorderbuffs =
8994 hdd_ctx->config->apMaxOffloadReorderBuffs;
8995
8996 cds_cfg->ap_disable_intrabss_fwd =
8997 hdd_ctx->config->apDisableIntraBssFwd;
8998
8999 cds_cfg->dfs_pri_multiplier =
9000 hdd_ctx->config->dfsRadarPriMultiplier;
9001 cds_cfg->reorder_offload =
9002 hdd_ctx->config->reorderOffloadSupport;
9003
9004 /* IPA micro controller data path offload resource config item */
9005 cds_cfg->uc_offload_enabled = hdd_ipa_uc_is_enabled(hdd_ctx);
Yun Parkde380782016-08-17 16:26:54 -07009006 if (!is_power_of_2(hdd_ctx->config->IpaUcTxBufCount)) {
9007 /* IpaUcTxBufCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009008 hdd_debug("Round down IpaUcTxBufCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07009009 hdd_ctx->config->IpaUcTxBufCount);
9010 hdd_ctx->config->IpaUcTxBufCount =
9011 rounddown_pow_of_two(
9012 hdd_ctx->config->IpaUcTxBufCount);
9013 if (!hdd_ctx->config->IpaUcTxBufCount) {
9014 hdd_err("Failed to round down IpaUcTxBufCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309015 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07009016 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009017 hdd_debug("IpaUcTxBufCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07009018 hdd_ctx->config->IpaUcTxBufCount);
9019 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309020 cds_cfg->uc_txbuf_count = hdd_ctx->config->IpaUcTxBufCount;
9021 cds_cfg->uc_txbuf_size = hdd_ctx->config->IpaUcTxBufSize;
Yun Parkde380782016-08-17 16:26:54 -07009022 if (!is_power_of_2(hdd_ctx->config->IpaUcRxIndRingCount)) {
9023 /* IpaUcRxIndRingCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009024 hdd_debug("Round down IpaUcRxIndRingCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07009025 hdd_ctx->config->IpaUcRxIndRingCount);
9026 hdd_ctx->config->IpaUcRxIndRingCount =
9027 rounddown_pow_of_two(
9028 hdd_ctx->config->IpaUcRxIndRingCount);
9029 if (!hdd_ctx->config->IpaUcRxIndRingCount) {
9030 hdd_err("Failed to round down IpaUcRxIndRingCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309031 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07009032 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009033 hdd_debug("IpaUcRxIndRingCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07009034 hdd_ctx->config->IpaUcRxIndRingCount);
9035 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309036 cds_cfg->uc_rxind_ringcount =
Yun Parkde380782016-08-17 16:26:54 -07009037 hdd_ctx->config->IpaUcRxIndRingCount;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309038 cds_cfg->uc_tx_partition_base =
9039 hdd_ctx->config->IpaUcTxPartitionBase;
9040 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
9041
9042 cds_cfg->ip_tcp_udp_checksum_offload =
9043 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07009044 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309045 cds_cfg->ce_classify_enabled =
9046 hdd_ctx->config->ce_classify_enabled;
Dustin Brownd3fc9ee2016-09-14 13:57:27 -07009047 cds_cfg->bpf_packet_filter_enable =
9048 hdd_ctx->config->bpf_packet_filter_enable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309049 cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
9050 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
9051 cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
Naveen Rawat64e477e2016-05-20 10:34:56 -07009052 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Manjunathappa Prakashfff753c2016-09-01 19:34:56 -07009053 cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07009054 cds_cfg->max_msdus_per_rxinorderind =
9055 hdd_ctx->config->max_msdus_per_rxinorderind;
Naveen Rawat91df30a2016-10-12 21:26:18 -07009056 cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
Sandeep Puligillaafa52892016-10-26 19:03:16 -07009057 cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05309058 cds_cfg->active_uc_bpf_mode = hdd_ctx->config->active_uc_bpf_mode;
9059 cds_cfg->active_mc_bc_bpf_mode = hdd_ctx->config->active_mc_bc_bpf_mode;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05309060 cds_cfg->auto_power_save_fail_mode =
9061 hdd_ctx->config->auto_pwr_save_fail_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309062
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309063 cds_cfg->ito_repeat_count = hdd_ctx->config->ito_repeat_count;
Sandeep Puligilla819d94f2017-10-10 18:33:56 -07009064 cds_cfg->bandcapability = hdd_ctx->config->nBandCapability;
Zhu Jianmina2f8e8d2018-02-11 16:37:10 +08009065 cds_cfg->delay_before_vdev_stop =
9066 hdd_ctx->config->delay_before_vdev_stop;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309067
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309068 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
9069 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
9070 hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07009071 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309072 cds_init_ini_config(cds_cfg);
9073 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309074
9075exit:
9076 qdf_mem_free(cds_cfg);
9077 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309078}
9079
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009080/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009081 * hdd_update_user_config() - API to update user configuration
9082 * parameters to obj mgr which are used by multiple components
9083 * @hdd_ctx: HDD Context
9084 *
9085 * Return: 0 for Success, errno on failure
9086 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009087static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009088{
9089 struct wlan_objmgr_psoc_user_config *user_config;
9090
9091 user_config = qdf_mem_malloc(sizeof(*user_config));
9092 if (user_config == NULL) {
9093 hdd_alert("Failed to alloc memory for user_config!");
9094 return -ENOMEM;
9095 }
9096
9097 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
9098 user_config->dual_mac_feature_disable =
9099 hdd_ctx->config->dual_mac_feature_disable;
9100 user_config->indoor_channel_support =
9101 hdd_ctx->config->indoor_channel_support;
9102 user_config->is_11d_support_enabled =
9103 hdd_ctx->config->Is11dSupportEnabled;
9104 user_config->is_11h_support_enabled =
9105 hdd_ctx->config->Is11hSupportEnabled;
9106 user_config->optimize_chan_avoid_event =
9107 hdd_ctx->config->goptimize_chan_avoid_event;
9108 user_config->skip_dfs_chnl_in_p2p_search =
9109 hdd_ctx->config->skipDfsChnlInP2pSearch;
Naveen Rawat222b2e92017-03-16 09:52:21 -07009110 user_config->band_capability = hdd_ctx->config->nBandCapability;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009111 wlan_objmgr_psoc_set_user_config(hdd_ctx->hdd_psoc, user_config);
9112
9113 qdf_mem_free(user_config);
9114 return 0;
9115}
9116
9117/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009118 * hdd_init_thermal_info - Initialize thermal level
9119 * @hdd_ctx: HDD context
9120 *
9121 * Initialize thermal level at SME layer and set the thermal level callback
9122 * which would be called when a configured thermal threshold is hit.
9123 *
9124 * Return: 0 on success and errno on failure
9125 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009126static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009127{
9128 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309129 QDF_STATUS status;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009130
9131 thermal_param.smeThermalMgmtEnabled =
9132 hdd_ctx->config->thermalMitigationEnable;
9133 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
9134
Poddar, Siddarth83905022016-04-16 17:56:08 -07009135 thermal_param.sme_throttle_duty_cycle_tbl[0] =
9136 hdd_ctx->config->throttle_dutycycle_level0;
9137 thermal_param.sme_throttle_duty_cycle_tbl[1] =
9138 hdd_ctx->config->throttle_dutycycle_level1;
9139 thermal_param.sme_throttle_duty_cycle_tbl[2] =
9140 hdd_ctx->config->throttle_dutycycle_level2;
9141 thermal_param.sme_throttle_duty_cycle_tbl[3] =
9142 hdd_ctx->config->throttle_dutycycle_level3;
9143
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009144 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
9145 hdd_ctx->config->thermalTempMinLevel0;
9146 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
9147 hdd_ctx->config->thermalTempMaxLevel0;
9148 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
9149 hdd_ctx->config->thermalTempMinLevel1;
9150 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
9151 hdd_ctx->config->thermalTempMaxLevel1;
9152 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
9153 hdd_ctx->config->thermalTempMinLevel2;
9154 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
9155 hdd_ctx->config->thermalTempMaxLevel2;
9156 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
9157 hdd_ctx->config->thermalTempMinLevel3;
9158 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
9159 hdd_ctx->config->thermalTempMaxLevel3;
9160
9161 status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);
9162
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309163 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05309164 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009165
9166 sme_add_set_thermal_level_callback(hdd_ctx->hHal,
9167 hdd_set_thermal_level_cb);
9168
9169 return 0;
9170
9171}
9172
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009173#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
9174/**
9175 * hdd_hold_rtnl_lock - Hold RTNL lock
9176 *
9177 * Hold RTNL lock
9178 *
9179 * Return: True if held and false otherwise
9180 */
9181static inline bool hdd_hold_rtnl_lock(void)
9182{
9183 rtnl_lock();
9184 return true;
9185}
9186
9187/**
9188 * hdd_release_rtnl_lock - Release RTNL lock
9189 *
9190 * Release RTNL lock
9191 *
9192 * Return: None
9193 */
9194static inline void hdd_release_rtnl_lock(void)
9195{
9196 rtnl_unlock();
9197}
9198#else
9199static inline bool hdd_hold_rtnl_lock(void) { return false; }
9200static inline void hdd_release_rtnl_lock(void) { }
9201#endif
9202
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009203#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009204
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309205/* MAX iwpriv command support */
9206#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309207#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309208#define MAX_PKTLOG_SIZE 16
9209
9210/**
9211 * hdd_pktlog_set_buff_size() - set pktlog buffer size
9212 * @hdd_ctx: hdd context
9213 * @set_value2: pktlog buffer size value
9214 *
9215 *
9216 * Return: 0 for success or error.
9217 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009218static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309219{
9220 struct sir_wifi_start_log start_log = { 0 };
9221 QDF_STATUS status;
9222
9223 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9224 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
9225 start_log.ini_triggered = cds_is_packet_log_enabled();
9226 start_log.user_triggered = 1;
9227 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309228 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309229
9230 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9231 if (!QDF_IS_STATUS_SUCCESS(status)) {
9232 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009233 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309234 return -EINVAL;
9235 }
9236
9237 return 0;
9238}
9239
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009240/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309241 * hdd_pktlog_clear_buff() - clear pktlog buffer
9242 * @hdd_ctx: hdd context
9243 *
9244 * Return: 0 for success or error.
9245 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009246static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309247{
9248 struct sir_wifi_start_log start_log;
9249 QDF_STATUS status;
9250
9251 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9252 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
9253 start_log.ini_triggered = cds_is_packet_log_enabled();
9254 start_log.user_triggered = 1;
9255 start_log.size = 0;
9256 start_log.is_pktlog_buff_clear = true;
9257
9258 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9259 if (!QDF_IS_STATUS_SUCCESS(status)) {
9260 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009261 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309262 return -EINVAL;
9263 }
9264
9265 return 0;
9266}
9267
9268
9269/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009270 * hdd_process_pktlog_command() - process pktlog command
9271 * @hdd_ctx: hdd context
9272 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309273 * @set_value2: pktlog buffer size value
9274 *
9275 * This function process pktlog command.
9276 * set_value2 only matters when set_value is 3 (set buff size)
9277 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009278 *
9279 * Return: 0 for success or error.
9280 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009281int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309282 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009283{
9284 int ret;
9285 bool enable;
9286 uint8_t user_triggered = 0;
9287
9288 ret = wlan_hdd_validate_context(hdd_ctx);
9289 if (0 != ret)
9290 return ret;
9291
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009292 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009293
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309294 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009295 hdd_err("invalid pktlog value %d", set_value);
9296 return -EINVAL;
9297 }
9298
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309299 if (set_value == PKTLOG_SET_BUFF_SIZE) {
9300 if (set_value2 <= 0) {
9301 hdd_err("invalid pktlog size %d", set_value2);
9302 return -EINVAL;
9303 } else if (set_value2 > MAX_PKTLOG_SIZE) {
9304 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
9305 return -EINVAL;
9306 }
9307 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309308 } else if (set_value == PKTLOG_CLEAR_BUFF) {
9309 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309310 }
9311
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009312 /*
9313 * set_value = 0 then disable packetlog
9314 * set_value = 1 enable packetlog forcefully
9315 * set_vlaue = 2 then disable packetlog if disabled through ini or
9316 * enable packetlog with AUTO type.
9317 */
9318 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
9319 true : false;
9320
9321 if (1 == set_value) {
9322 enable = true;
9323 user_triggered = 1;
9324 }
9325
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309326 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009327}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07009328
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009329/**
9330 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
9331 * @hdd_ctx: HDD context
9332 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309333 * @user_triggered: triggered through iwpriv
9334 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009335 *
9336 * Return: 0 on success; error number otherwise
9337 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009338int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309339 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009340{
9341 struct sir_wifi_start_log start_log;
9342 QDF_STATUS status;
9343
9344 start_log.ring_id = RING_ID_PER_PACKET_STATS;
9345 start_log.verbose_level =
9346 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009347 start_log.ini_triggered = cds_is_packet_log_enabled();
9348 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309349 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309350 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +05309351 /*
9352 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
9353 * commands. Host uses this flag to decide whether to send pktlog
9354 * disable command to fw without sending pktlog enable command
9355 * previously. For eg, If vendor sends pktlog disable command without
9356 * sending pktlog enable command, then host discards the packet
9357 * but for iwpriv command, host will send it to fw.
9358 */
9359 start_log.is_iwpriv_command = 1;
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009360 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
9361 if (!QDF_IS_STATUS_SUCCESS(status)) {
9362 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -07009363 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009364 return -EINVAL;
9365 }
9366
Poddar, Siddarth61fbc932017-12-19 14:27:55 +05309367 if (enable == true)
9368 hdd_ctx->is_pktlog_enabled = 1;
9369 else
9370 hdd_ctx->is_pktlog_enabled = 0;
9371
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009372 return 0;
9373}
9374#endif /* REMOVE_PKT_LOG */
9375
Komal Seelam92fff912016-03-24 11:51:41 +05309376/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009377 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
9378 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +05309379 * @dev: Device Pointer
9380 * @num: Number of Valid Mac address
9381 *
9382 * Return: Pointer to MAC address buffer
9383 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009384static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
9385 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +05309386{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009387 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +05309388}
Komal Seelam92fff912016-03-24 11:51:41 +05309389
9390/**
9391 * hdd_populate_random_mac_addr() - API to populate random mac addresses
9392 * @hdd_ctx: HDD Context
9393 * @num: Number of random mac addresses needed
9394 *
9395 * Generate random addresses using bit manipulation on the base mac address
9396 *
9397 * Return: None
9398 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009399void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +05309400{
9401 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
9402 uint32_t iter;
9403 struct hdd_config *ini = hdd_ctx->config;
9404 uint8_t *buf = NULL;
9405 uint8_t macaddr_b3, tmp_br3;
9406 uint8_t *src = ini->intfMacAddr[0].bytes;
9407
9408 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
9409 buf = ini->intfMacAddr[iter].bytes;
9410 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
9411 macaddr_b3 = buf[3];
9412 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
9413 INTF_MACADDR_MASK;
9414 macaddr_b3 += tmp_br3;
9415 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
9416 buf[0] |= 0x02;
9417 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009418 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309419 }
9420}
9421
9422/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009423 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +05309424 * @hdd_ctx: HDD Context
9425 *
9426 * API to get mac addresses from platform driver and update the driver
9427 * structures and configure FW with the base mac address.
9428 * Return: int
9429 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009430static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309431{
9432 uint32_t no_of_mac_addr, iter;
9433 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
9434 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
9435 uint8_t *addr, *buf;
9436 struct device *dev = hdd_ctx->parent_dev;
9437 struct hdd_config *ini = hdd_ctx->config;
9438 tSirMacAddr mac_addr;
9439 QDF_STATUS status;
9440
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009441 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +05309442
9443 if (no_of_mac_addr == 0 || !addr) {
9444 hdd_warn("Platform Driver Doesn't have wlan mac addresses");
9445 return -EINVAL;
9446 }
9447
9448 if (no_of_mac_addr > max_mac_addr)
9449 no_of_mac_addr = max_mac_addr;
9450
9451 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
9452
9453 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
9454 buf = ini->intfMacAddr[iter].bytes;
9455 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009456 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309457 }
9458
9459 status = sme_set_custom_mac_addr(mac_addr);
9460
9461 if (!QDF_IS_STATUS_SUCCESS(status))
9462 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009463
Komal Seelam92fff912016-03-24 11:51:41 +05309464 if (no_of_mac_addr < max_mac_addr)
9465 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
9466 no_of_mac_addr);
9467 return 0;
9468}
9469
9470/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009471 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
9472 * @hdd_ctx: HDD Context
9473 *
9474 * Update MAC address to FW. If MAC address passed by FW is invalid, host
9475 * will generate its own MAC and update it to FW.
9476 *
9477 * Return: 0 for success
9478 * Non-zero error code for failure
9479 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009480static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009481{
9482 tSirMacAddr customMacAddr;
9483 QDF_STATUS status;
9484
9485 qdf_mem_copy(&customMacAddr,
9486 &hdd_ctx->config->intfMacAddr[0].bytes[0],
9487 sizeof(tSirMacAddr));
9488 status = sme_set_custom_mac_addr(customMacAddr);
9489 if (!QDF_IS_STATUS_SUCCESS(status))
9490 return -EAGAIN;
9491 return 0;
9492}
9493
9494/**
Komal Seelam92fff912016-03-24 11:51:41 +05309495 * hdd_initialize_mac_address() - API to get wlan mac addresses
9496 * @hdd_ctx: HDD Context
9497 *
9498 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
9499 * is provisioned with mac addresses, driver uses it, else it will use
9500 * wlan_mac.bin to update HW MAC addresses.
9501 *
9502 * Return: None
9503 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009504static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309505{
9506 QDF_STATUS status;
9507 int ret;
9508
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009509 ret = hdd_platform_wlan_mac(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +05309510 if (ret == 0)
9511 return;
9512
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009513 hdd_info("MAC is not programmed in platform driver ret: %d, use wlan_mac.bin",
9514 ret);
Komal Seelam92fff912016-03-24 11:51:41 +05309515
9516 status = hdd_update_mac_config(hdd_ctx);
9517
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009518 if (QDF_IS_STATUS_SUCCESS(status))
9519 return;
9520
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009521 hdd_info("MAC is not programmed in wlan_mac.bin ret %d, use default MAC",
9522 status);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009523
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009524 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009525 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009526 if (ret != 0) {
9527 hdd_err("MAC address out-of-sync, ret:%d", ret);
9528 QDF_ASSERT(ret);
9529 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009530 }
Komal Seelam92fff912016-03-24 11:51:41 +05309531}
9532
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009533static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009534{
9535 int vdev_id = 0;
9536 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
9537 int value = hdd_ctx->config->smart_chainmask_enabled;
9538 int vpdev = PDEV_CMD;
9539 int ret;
9540
Naveen Rawat247a8682017-06-05 15:00:31 -07009541 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009542 if (ret)
9543 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
9544
9545 return ret;
9546}
9547
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009548static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009549{
9550 int vdev_id = 0;
9551 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
9552 int value = hdd_ctx->config->alternative_chainmask_enabled;
9553 int vpdev = PDEV_CMD;
9554 int ret;
9555
Naveen Rawat247a8682017-06-05 15:00:31 -07009556 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009557 if (ret)
9558 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
9559 ret);
9560
9561 return ret;
9562}
9563
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009564static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -07009565{
9566 int vdev_id = 0;
9567 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
9568 int value = hdd_ctx->config->ani_enabled;
9569 int vpdev = PDEV_CMD;
9570 int ret;
9571
Naveen Rawat247a8682017-06-05 15:00:31 -07009572 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -07009573 if (ret)
9574 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
9575
9576 return ret;
9577}
9578
Jeff Johnson89c66ff2016-04-22 15:21:37 -07009579/**
Prashanth Bhatta07998752016-04-28 12:35:33 -07009580 * hdd_pre_enable_configure() - Configurations prior to cds_enable
9581 * @hdd_ctx: HDD context
9582 *
9583 * Pre configurations to be done at lower layer before calling cds enable.
9584 *
9585 * Return: 0 on success and errno on failure.
9586 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009587static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -07009588{
9589 int ret;
9590 QDF_STATUS status;
9591 tSirRetStatus hal_status;
Leo Changfdb45c32016-10-28 11:09:23 -07009592 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009593
Leo Changfdb45c32016-10-28 11:09:23 -07009594 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009595 /*
9596 * Set 802.11p config
9597 * TODO-OCB: This has been temporarily added here to ensure this
9598 * parameter is set in CSR when we init the channel list. This should
9599 * be removed once the 5.9 GHz channels are added to the regulatory
9600 * domain.
9601 */
9602 hdd_set_dot11p_config(hdd_ctx);
9603
9604 /*
9605 * Note that the cds_pre_enable() sequence triggers the cfg download.
9606 * The cfg download must occur before we update the SME config
9607 * since the SME config operation must access the cfg database
9608 */
9609 status = hdd_set_sme_config(hdd_ctx);
9610
9611 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009612 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009613 ret = qdf_status_to_os_return(status);
9614 goto out;
9615 }
9616
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -07009617 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
9618 if (QDF_STATUS_SUCCESS != status) {
9619 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
9620 ret = qdf_status_to_os_return(status);
9621 goto out;
9622 }
9623
Naveen Rawat247a8682017-06-05 15:00:31 -07009624 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
Prashanth Bhatta07998752016-04-28 12:35:33 -07009625 hdd_ctx->config->tx_chain_mask_1ss,
9626 PDEV_CMD);
9627 if (0 != ret) {
9628 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
9629 goto out;
9630 }
9631
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009632 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
9633 if (ret)
9634 goto out;
9635
9636 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
9637 if (ret)
9638 goto out;
9639
Jeff Johnson12a744b2017-04-04 08:19:37 -07009640 ret = hdd_set_ani_enabled(hdd_ctx);
9641 if (ret)
9642 goto out;
9643
Naveen Rawat247a8682017-06-05 15:00:31 -07009644 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -08009645 hdd_ctx->config->arp_ac_category,
9646 PDEV_CMD);
9647 if (0 != ret) {
9648 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
9649 hdd_ctx->config->arp_ac_category, ret);
9650 goto out;
9651 }
9652
Prashanth Bhatta07998752016-04-28 12:35:33 -07009653 status = hdd_set_sme_chan_list(hdd_ctx);
9654 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009655 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009656 ret = qdf_status_to_os_return(status);
9657 goto out;
9658 }
9659
9660 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -07009661 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009662 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -07009663 ret = -EINVAL;
9664 goto out;
9665 }
9666
Prashanth Bhatta07998752016-04-28 12:35:33 -07009667 /*
9668 * Set the MAC Address Currently this is used by HAL to add self sta.
9669 * Remove this once self sta is added as part of session open.
9670 */
9671 hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
9672 hdd_ctx->config->intfMacAddr[0].bytes,
9673 sizeof(hdd_ctx->config->intfMacAddr[0]));
9674
9675 if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
9676 hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
9677 hal_status, hal_status);
9678 ret = -EINVAL;
9679 goto out;
9680 }
9681
9682 hdd_init_channel_avoidance(hdd_ctx);
9683
Ganesh Kondabattini408fb8d2017-08-08 22:00:20 +05309684 /* update enable sap mandatory chan list */
9685 policy_mgr_enable_disable_sap_mandatory_chan_list(hdd_ctx->hdd_psoc,
9686 hdd_ctx->config->enable_sap_mandatory_chan_list);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009687out:
9688 return ret;
9689}
9690
9691/**
Peng Xu8fdaa492016-06-22 10:20:47 -07009692 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
9693 * @context_ptr - hdd context pointer
9694 * @event_ptr - event structure pointer
9695 *
9696 * This is the p2p listen offload stop event handler, it sends vendor
9697 * event back to supplicant to notify the stop reason.
9698 *
9699 * Return: None
9700 */
9701static void wlan_hdd_p2p_lo_event_callback(void *context_ptr,
9702 void *event_ptr)
9703{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009704 struct hdd_context *hdd_ctx = (struct hdd_context *)context_ptr;
Peng Xu8fdaa492016-06-22 10:20:47 -07009705 struct sir_p2p_lo_event *evt = event_ptr;
9706 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -07009707 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -07009708
Dustin Brown491d54b2018-03-14 12:39:11 -07009709 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -07009710
9711 if (hdd_ctx == NULL) {
9712 hdd_err("Invalid HDD context pointer");
9713 return;
9714 }
9715
Peng Xu5c682812017-08-06 07:39:13 -07009716 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
9717 if (!adapter) {
9718 hdd_err("Cannot find adapter by vdev_id = %d",
9719 evt->vdev_id);
9720 return;
9721 }
9722
Peng Xu8fdaa492016-06-22 10:20:47 -07009723 vendor_event =
9724 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -07009725 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -07009726 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
9727 GFP_KERNEL);
9728
9729 if (!vendor_event) {
9730 hdd_err("cfg80211_vendor_event_alloc failed");
9731 return;
9732 }
9733
9734 if (nla_put_u32(vendor_event,
9735 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
9736 evt->reason_code)) {
9737 hdd_err("nla put failed");
9738 kfree_skb(vendor_event);
9739 return;
9740 }
9741
9742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -07009743 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
9744 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -07009745}
9746
9747/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309748 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
9749 * @hdd_ctx: HDD context
9750 *
9751 * This function sends the adaptive dwell time config configuration to the
9752 * firmware via WMA
9753 *
9754 * Return: 0 - success, < 0 - failure
9755 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009756static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309757{
9758 QDF_STATUS status;
9759 struct adaptive_dwelltime_params dwelltime_params;
9760
9761 dwelltime_params.is_enabled =
9762 hdd_ctx->config->adaptive_dwell_mode_enabled;
9763 dwelltime_params.dwelltime_mode =
9764 hdd_ctx->config->global_adapt_dwelltime_mode;
9765 dwelltime_params.lpf_weight =
9766 hdd_ctx->config->adapt_dwell_lpf_weight;
9767 dwelltime_params.passive_mon_intval =
9768 hdd_ctx->config->adapt_dwell_passive_mon_intval;
9769 dwelltime_params.wifi_act_threshold =
9770 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
9771
9772 status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
9773 &dwelltime_params);
9774
9775 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
9776 if (!QDF_IS_STATUS_SUCCESS(status)) {
9777 hdd_err("Failed to send Adaptive Dwelltime configuration!");
9778 return -EAGAIN;
9779 }
9780 return 0;
9781}
9782
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009783int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309784{
9785 QDF_STATUS status;
9786 struct wmi_dbs_scan_sel_params dbs_scan_params;
9787 uint32_t i = 0;
9788 uint8_t count = 0, numentries = 0;
9789 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
9790 * CDS_DBS_SCAN_CLIENTS_MAX];
9791
9792 /* check if DBS is enabled or supported */
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07009793 if (hdd_ctx->config->dual_mac_feature_disable ==
9794 DISABLE_DBS_CXN_AND_SCAN)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309795 return -EINVAL;
9796
9797 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
9798 dbs_scan_config, &numentries,
9799 (CDS_DBS_SCAN_PARAM_PER_CLIENT
9800 * CDS_DBS_SCAN_CLIENTS_MAX));
9801
9802 hdd_info("numentries %hu", numentries);
9803 if (!numentries) {
9804 hdd_info("Donot send scan_selection_config");
9805 return 0;
9806 }
9807
9808 /* hdd_set_fw_log_params */
9809 dbs_scan_params.num_clients = 0;
9810 while (count < (numentries - 2)) {
9811 dbs_scan_params.module_id[i] = dbs_scan_config[count];
9812 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
9813 dbs_scan_params.num_non_dbs_scans[i] =
9814 dbs_scan_config[count + 2];
9815 dbs_scan_params.num_clients++;
9816 hdd_debug("module:%d NDS:%d NNDS:%d",
9817 dbs_scan_params.module_id[i],
9818 dbs_scan_params.num_dbs_scans[i],
9819 dbs_scan_params.num_non_dbs_scans[i]);
9820 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
9821 i++;
9822 }
9823
9824 dbs_scan_params.pdev_id = 0;
9825
9826 hdd_debug("clients:%d pdev:%d",
9827 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
9828
9829 status = sme_set_dbs_scan_selection_config(hdd_ctx->hHal,
9830 &dbs_scan_params);
9831 hdd_debug("Sending DBS Scan Selection Configuration to fw");
9832 if (!QDF_IS_STATUS_SUCCESS(status)) {
9833 hdd_err("Failed to send DBS Scan selection configuration!");
9834 return -EAGAIN;
9835 }
9836 return 0;
9837}
9838
Arun Khandavallid4349a92016-07-25 11:10:43 +05309839#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9840/**
9841 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
9842 * @hdd_ctx: HDD context
9843 *
9844 * Set auto shutdown callback to get indications from firmware to indicate
9845 * userspace to shutdown WLAN after a configured amount of inactivity.
9846 *
9847 * Return: 0 on success and errno on failure.
9848 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009849static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309850{
9851 QDF_STATUS status;
9852
9853 if (!hdd_ctx->config->WlanAutoShutdown)
9854 return 0;
9855
9856 status = sme_set_auto_shutdown_cb(hdd_ctx->hHal,
9857 wlan_hdd_auto_shutdown_cb);
9858 if (status != QDF_STATUS_SUCCESS)
9859 hdd_err("Auto shutdown feature could not be enabled: %d",
9860 status);
9861
9862 return qdf_status_to_os_return(status);
9863}
9864#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009865static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309866{
9867 return 0;
9868}
9869#endif
9870
9871/**
9872 * hdd_features_init() - Init features
9873 * @hdd_ctx: HDD context
9874 * @adapter: Primary adapter context
9875 *
9876 * Initialize features and their feature context after WLAN firmware is up.
9877 *
9878 * Return: 0 on success and errno on failure.
9879 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009880static int hdd_features_init(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309881{
9882 tSirTxPowerLimit hddtxlimit;
9883 QDF_STATUS status;
Manjeet Singha9cae432017-02-28 11:58:22 +05309884 struct sme_5g_band_pref_params band_pref_params;
Arun Khandavallid4349a92016-07-25 11:10:43 +05309885 int ret;
9886
Dustin Brown491d54b2018-03-14 12:39:11 -07009887 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +05309888
Arun Khandavallid4349a92016-07-25 11:10:43 +05309889 /* FW capabilities received, Set the Dot11 mode */
9890 sme_setdef_dot11mode(hdd_ctx->hHal);
Kiran Kumar Lokere1aa9c9a2016-10-05 18:50:59 -07009891 sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal,
9892 hdd_ctx->config->sta_prefer_80MHz_over_160MHz);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309893
Arun Khandavallid4349a92016-07-25 11:10:43 +05309894
9895 if (hdd_ctx->config->fIsImpsEnabled)
9896 hdd_set_idle_ps_config(hdd_ctx, true);
9897 else
9898 hdd_set_idle_ps_config(hdd_ctx, false);
9899
Poddar, Siddarth37033032017-10-11 15:47:40 +05309900 /* Send Enable/Disable data stall detection cmd to FW */
9901 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
9902 hdd_ctx->config->enable_data_stall_det, PDEV_CMD);
9903
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05309904 if (hdd_ctx->config->enable_go_cts2self_for_sta)
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009905 sme_set_cts2self_for_p2p_go(hdd_ctx->hHal);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05309906
Nachiket Kukade8983cf62017-10-12 18:14:48 +05309907 if (sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap))
9908 hdd_warn("Error in setting Voltage Corner mode config to FW");
9909
Arun Khandavallid4349a92016-07-25 11:10:43 +05309910 if (hdd_lro_init(hdd_ctx))
9911 hdd_err("Unable to initialize LRO in fw");
9912
9913 if (hdd_adaptive_dwelltime_init(hdd_ctx))
9914 hdd_err("Unable to send adaptive dwelltime setting to FW");
9915
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309916 if (hdd_dbs_scan_selection_init(hdd_ctx))
9917 hdd_err("Unable to send DBS scan selection setting to FW");
9918
Arun Khandavallid4349a92016-07-25 11:10:43 +05309919 ret = hdd_init_thermal_info(hdd_ctx);
9920 if (ret) {
9921 hdd_err("Error while initializing thermal information");
9922 goto deregister_frames;
9923 }
9924
Poddar, Siddarth61fbc932017-12-19 14:27:55 +05309925 /**
9926 * In case of SSR/PDR, if pktlog was enabled manually before
9927 * SSR/PDR, Then enabled it again automatically after Wlan
9928 * device up.
9929 */
9930 if (cds_is_driver_recovering()) {
9931 if (hdd_ctx->is_pktlog_enabled)
9932 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Tiger Yuf3d5d7f2018-03-15 14:48:11 +08009933 }
Poddar, Siddarth66a46592017-02-22 11:44:44 +05309934
Arun Khandavallid4349a92016-07-25 11:10:43 +05309935 hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
9936 hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
9937 status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
9938 if (!QDF_IS_STATUS_SUCCESS(status))
9939 hdd_err("Error setting txlimit in sme: %d", status);
9940
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009941 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309942
Arun Khandavallid4349a92016-07-25 11:10:43 +05309943 ret = hdd_register_cb(hdd_ctx);
9944 if (ret) {
9945 hdd_err("Failed to register HDD callbacks!");
9946 goto deregister_frames;
9947 }
9948
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +05309949 if (hdd_ctx->config->goptimize_chan_avoid_event) {
9950 status = sme_enable_disable_chanavoidind_event(
9951 hdd_ctx->hHal, 0);
9952 if (!QDF_IS_STATUS_SUCCESS(status)) {
9953 hdd_err("Failed to disable Chan Avoidance Indication");
9954 goto deregister_cb;
9955 }
9956 }
Arun Khandavallid4349a92016-07-25 11:10:43 +05309957
Manjeet Singha9cae432017-02-28 11:58:22 +05309958 if (hdd_ctx->config->enable_5g_band_pref) {
9959 band_pref_params.rssi_boost_threshold_5g =
9960 hdd_ctx->config->rssi_boost_threshold_5g;
9961 band_pref_params.rssi_boost_factor_5g =
9962 hdd_ctx->config->rssi_boost_factor_5g;
9963 band_pref_params.max_rssi_boost_5g =
9964 hdd_ctx->config->max_rssi_boost_5g;
9965 band_pref_params.rssi_penalize_threshold_5g =
9966 hdd_ctx->config->rssi_penalize_threshold_5g;
9967 band_pref_params.rssi_penalize_factor_5g =
9968 hdd_ctx->config->rssi_penalize_factor_5g;
9969 band_pref_params.max_rssi_penalize_5g =
9970 hdd_ctx->config->max_rssi_penalize_5g;
9971 sme_set_5g_band_pref(hdd_ctx->hHal, &band_pref_params);
9972 }
9973
Arun Khandavallid4349a92016-07-25 11:10:43 +05309974 /* register P2P Listen Offload event callback */
9975 if (wma_is_p2p_lo_capable())
9976 sme_register_p2p_lo_event(hdd_ctx->hHal, hdd_ctx,
9977 wlan_hdd_p2p_lo_event_callback);
9978
9979 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
9980
9981 if (ret)
9982 goto deregister_cb;
9983
Dustin Brown11638b72018-01-25 17:37:25 +05309984 wlan_hdd_init_chan_info(hdd_ctx);
9985
Dustin Browne74003f2018-03-14 12:51:58 -07009986 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +05309987 return 0;
9988
9989deregister_cb:
9990 hdd_deregister_cb(hdd_ctx);
9991deregister_frames:
9992 wlan_hdd_cfg80211_deregister_frames(adapter);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309993 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +05309994}
9995
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009996/**
9997 * hdd_features_deinit() - Deinit features
9998 * @hdd_ctx: HDD context
9999 *
10000 * De-Initialize features and their feature context.
10001 *
10002 * Return: none.
10003 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010004static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010005{
Dustin Brown11638b72018-01-25 17:37:25 +053010006 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010007 wlan_hdd_tsf_deinit(hdd_ctx);
10008}
10009
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010010/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010011 * hdd_register_bcn_cb() - register scan beacon callback
10012 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010013 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010014 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010015 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010016static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010017{
10018 QDF_STATUS status;
10019
10020 status = ucfg_scan_register_bcn_cb(hdd_ctx->hdd_psoc,
10021 wlan_cfg80211_inform_bss_frame,
10022 SCAN_CB_TYPE_INFORM_BCN);
10023 if (!QDF_IS_STATUS_SUCCESS(status)) {
10024 hdd_err("failed with status code %08d [x%08x]",
10025 status, status);
10026 return status;
10027 }
10028
10029 return QDF_STATUS_SUCCESS;
10030}
Arun Khandavallid4349a92016-07-25 11:10:43 +053010031
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010032/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010033 * hdd_configure_cds() - Configure cds modules
10034 * @hdd_ctx: HDD context
10035 * @adapter: Primary adapter context
10036 *
10037 * Enable Cds modules after WLAN firmware is up.
10038 *
10039 * Return: 0 on success and errno on failure.
10040 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010041int hdd_configure_cds(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +053010042{
10043 int ret;
10044 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010045 int set_value;
10046 uint32_t num_abg_tx_chains = 0;
10047 uint32_t num_11b_tx_chains = 0;
10048 uint32_t num_11ag_tx_chains = 0;
Yun Parkff6a16a2017-09-26 16:38:18 -070010049 struct policy_mgr_dp_cbacks dp_cbs;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010050
10051 if (hdd_ctx->config->sifs_burst_duration) {
10052 set_value = (SIFS_BURST_DUR_MULTIPLIER) *
10053 hdd_ctx->config->sifs_burst_duration;
10054
10055 if ((set_value > 0) && (set_value <= SIFS_BURST_DUR_MAX))
10056 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_BURST_DUR,
10057 set_value, PDEV_CMD);
10058 }
10059
10060 if (hdd_ctx->config->is_force_1x1)
10061 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
10062 1, PDEV_CMD);
10063 /* set chip power save failure detected callback */
10064 sme_set_chip_pwr_save_fail_cb(hdd_ctx->hHal,
10065 hdd_chip_pwr_save_fail_detected_cb);
10066
10067 if (hdd_ctx->config->max_mpdus_inampdu) {
10068 set_value = hdd_ctx->config->max_mpdus_inampdu;
10069 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
10070 set_value, PDEV_CMD);
10071 }
10072
10073 if (hdd_ctx->config->enable_rts_sifsbursting) {
10074 set_value = hdd_ctx->config->enable_rts_sifsbursting;
10075 sme_cli_set_command(0,
10076 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
10077 set_value, PDEV_CMD);
10078 }
10079
10080 if (hdd_ctx->config->sap_get_peer_info) {
10081 set_value = hdd_ctx->config->sap_get_peer_info;
10082 sme_cli_set_command(0,
10083 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
10084 set_value, PDEV_CMD);
10085 }
10086
10087 num_11b_tx_chains = hdd_ctx->config->num_11b_tx_chains;
10088 num_11ag_tx_chains = hdd_ctx->config->num_11ag_tx_chains;
10089 if (!hdd_ctx->config->enable2x2) {
10090 if (num_11b_tx_chains > 1)
10091 num_11b_tx_chains = 1;
10092 if (num_11ag_tx_chains > 1)
10093 num_11ag_tx_chains = 1;
10094 }
10095 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
10096 num_11b_tx_chains);
10097 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
10098 num_11ag_tx_chains);
10099 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
10100 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053010101
10102 ret = hdd_pre_enable_configure(hdd_ctx);
10103 if (ret) {
10104 hdd_err("Failed to pre-configure cds");
10105 goto out;
10106 }
10107
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080010108 /* Always get latest IPA resources allocated from cds_open and configure
10109 * IPA module before configuring them to FW. Sequence required as crash
10110 * observed otherwise.
10111 */
Manikandan Mohan2e803a02017-02-14 14:57:53 -080010112 if (hdd_ipa_uc_ol_init(hdd_ctx)) {
10113 hdd_err("Failed to setup pipes");
10114 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080010115 }
10116
Arun Khandavallifae92942016-08-01 13:31:08 +053010117 /*
10118 * Start CDS which starts up the SME/MAC/HAL modules and everything
10119 * else
10120 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -070010121 status = cds_enable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010122
10123 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010124 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053010125 goto out;
10126 }
10127
10128 status = hdd_post_cds_enable_config(hdd_ctx);
10129 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010130 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010131 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053010132 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010133 status = hdd_register_bcn_cb(hdd_ctx);
10134 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080010135 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010136 goto cds_disable;
10137 }
Arun Khandavallifae92942016-08-01 13:31:08 +053010138
10139 ret = hdd_features_init(hdd_ctx, adapter);
10140 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010141 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053010142
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010143 dp_cbs.hdd_disable_lro_in_concurrency = hdd_disable_lro_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070010144 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010145 status = policy_mgr_register_dp_cb(hdd_ctx->hdd_psoc, &dp_cbs);
10146 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070010147 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010148 goto cds_disable;
10149 }
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053010150 status = policy_mgr_register_mode_change_cb(hdd_ctx->hdd_psoc,
10151 wlan_hdd_send_mode_change_event);
10152 if (!QDF_IS_STATUS_SUCCESS(status)) {
10153 hdd_debug("Failed to register mode change cb with Policy Manager");
10154 goto cds_disable;
10155 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070010156
Himanshu Agarwalb229a142017-12-21 10:16:45 +053010157 if (ucfg_green_ap_enable_egap(hdd_ctx->hdd_pdev))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053010158 hdd_debug("enhance green ap is not enabled");
10159
Nachiket Kukadedd302662017-07-13 17:31:44 +053010160 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
10161 hdd_debug("Failed to set wow pulse");
10162
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053010163 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
10164 hdd_ctx->config->gcmp_enabled, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053010165 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
10166 hdd_ctx->config->auto_pwr_save_fail_mode, PDEV_CMD);
10167
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053010168
10169 if (hdd_ctx->config->enable_phy_reg_retention)
10170 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
10171 hdd_ctx->config->enable_phy_reg_retention, PDEV_CMD);
10172
Arun Khandavallifae92942016-08-01 13:31:08 +053010173 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010174
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010175cds_disable:
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -070010176 cds_disable(hdd_ctx->hdd_psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070010177
Arun Khandavallifae92942016-08-01 13:31:08 +053010178out:
10179 return -EINVAL;
10180}
10181
10182/**
10183 * hdd_deconfigure_cds() -De-Configure cds
10184 * @hdd_ctx: HDD context
10185 *
10186 * Deconfigure Cds modules before WLAN firmware is down.
10187 *
10188 * Return: 0 on success and errno on failure.
10189 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010190static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053010191{
10192 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070010193 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053010194
Dustin Brown491d54b2018-03-14 12:39:11 -070010195 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010196
10197 /* De-init features */
10198 hdd_features_deinit(hdd_ctx);
10199
Arun Khandavallifae92942016-08-01 13:31:08 +053010200 /* De-register the SME callbacks */
10201 hdd_deregister_cb(hdd_ctx);
10202
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053010203 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->hdd_psoc);
10204 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10205 hdd_debug("Failed to deregister mode change cb with Policy Manager");
10206 }
10207
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -070010208 qdf_status = cds_disable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010209 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10210 hdd_err("Failed to Disable the CDS Modules! :%d",
10211 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070010212 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010213 }
10214
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053010215 if (hdd_ipa_uc_ol_deinit(hdd_ctx)) {
10216 hdd_err("Failed to disconnect pipes");
10217 ret = -EINVAL;
10218 }
10219
Dustin Browne74003f2018-03-14 12:51:58 -070010220 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070010221 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053010222}
10223
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070010224#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
10225static void hdd_deregister_policy_manager_callback(
10226 struct wlan_objmgr_psoc *psoc)
10227{
10228 if (QDF_STATUS_SUCCESS !=
10229 policy_mgr_deregister_hdd_cb(psoc)) {
10230 hdd_err("HDD callback deregister with policy manager failed");
10231 }
10232}
10233#else
10234static void hdd_deregister_policy_manager_callback(
10235 struct wlan_objmgr_psoc *psoc)
10236{
10237}
10238#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053010239
10240/**
10241 * hdd_wlan_stop_modules - Single driver state machine for stoping modules
10242 * @hdd_ctx: HDD context
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010243 * @ftm_mode: ftm mode
Arun Khandavallifae92942016-08-01 13:31:08 +053010244 *
10245 * This function maintains the driver state machine it will be invoked from
10246 * exit, shutdown and con_mode change handler. Depending on the driver state
10247 * shall perform the stopping/closing of the modules.
10248 *
10249 * Return: 0 for success; non-zero for failure
10250 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010251int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053010252{
10253 void *hif_ctx;
10254 qdf_device_t qdf_ctx;
10255 QDF_STATUS qdf_status;
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010256 int ret = 0;
Dustin Brown4bc0a622017-12-06 15:56:50 -080010257 bool is_recovery_stop = cds_is_driver_recovering();
Liangwei Donga78cc1d2018-02-01 02:19:30 -050010258 bool is_idle_stop = !cds_is_driver_unloading() && !is_recovery_stop &&
10259 !cds_is_driver_loading();
Dustin Brown70111822017-03-30 15:31:40 -070010260 int active_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053010261 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053010262
Dustin Brown491d54b2018-03-14 12:39:11 -070010263 hdd_enter();
Yun Parkfec73dc2017-09-06 10:40:07 -070010264 hdd_alert("stop WLAN module: entering driver status=%d",
10265 hdd_ctx->driver_status);
Arun Khandavallifae92942016-08-01 13:31:08 +053010266
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070010267 hdd_deregister_policy_manager_callback(hdd_ctx->hdd_psoc);
10268
Arun Khandavallifae92942016-08-01 13:31:08 +053010269 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
10270 if (!qdf_ctx) {
10271 hdd_err("QDF device context NULL");
10272 return -EINVAL;
10273 }
10274
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010275 mutex_lock(&hdd_ctx->iface_change_lock);
10276 hdd_ctx->stop_modules_in_progress = true;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010277 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053010278
Dustin Brown70111822017-03-30 15:31:40 -070010279 active_threads = cds_return_external_threads_count();
Jeff Johnson214671b2017-10-30 19:45:23 -070010280 if (active_threads > 0 || hdd_ctx->is_wiphy_suspended) {
Rajeev Kumar86177c22017-03-16 19:44:39 -070010281 hdd_warn("External threads %d wiphy suspend %d",
Jeff Johnson214671b2017-10-30 19:45:23 -070010282 active_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -070010283
10284 cds_print_external_threads();
10285
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010286 if (is_idle_stop && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -070010287 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown6f427922017-09-19 12:19:00 -070010288 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
10289 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +053010290 hdd_prevent_suspend_timeout(
10291 hdd_ctx->config->iface_change_wait_time,
10292 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010293 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010294 cds_set_module_stop_in_progress(false);
Dustin Brown70111822017-03-30 15:31:40 -070010295 return 0;
10296 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070010297 }
10298
Arun Khandavallifae92942016-08-01 13:31:08 +053010299 hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
10300
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080010301 /* free user wowl patterns */
10302 hdd_free_user_wowl_ptrns();
10303
Arun Khandavallifae92942016-08-01 13:31:08 +053010304 switch (hdd_ctx->driver_status) {
10305 case DRIVER_MODULES_UNINITIALIZED:
10306 hdd_info("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010307 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010308 case DRIVER_MODULES_CLOSED:
10309 hdd_info("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010310 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010311 case DRIVER_MODULES_ENABLED:
Dustin Brown550f6d22017-12-14 15:44:01 -080010312 hdd_info("Wlan transitioning (OPENED <- ENABLED)");
10313
Komal Seelamf2136bb2016-09-28 18:30:44 +053010314 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053010315 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010316 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053010317 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010318 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010319 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010320 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080010321
Arun Khandavallifae92942016-08-01 13:31:08 +053010322 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -080010323 hdd_info("Wlan transitioned (now OPENED)");
10324
10325 /* fall through */
Arun Khandavallifae92942016-08-01 13:31:08 +053010326 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -080010327 hdd_info("Wlan transitioning (CLOSED <- OPENED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053010328 break;
10329 default:
10330 hdd_err("Trying to stop wlan in a wrong state: %d",
10331 hdd_ctx->driver_status);
10332 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010333 ret = -EINVAL;
10334 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053010335 }
10336
Amar Singhal18081642018-01-26 16:04:13 -080010337 hdd_sysfs_destroy_version_interface();
Dustin Brown550f6d22017-12-14 15:44:01 -080010338 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080010339
Rajeev Kumarbe021242017-02-16 16:12:23 -080010340 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +053010341 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10342 hdd_err("Failed to process post CDS disable Modules! :%d",
10343 qdf_status);
10344 ret = -EINVAL;
10345 QDF_ASSERT(0);
10346 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010347
psimhadeea0a12017-12-18 14:50:02 -080010348 hdd_runtime_suspend_context_deinit(hdd_ctx);
10349
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010350 qdf_status = cds_dp_close(hdd_ctx->hdd_psoc);
10351 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10352 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
10353 ret = -EINVAL;
10354 QDF_ASSERT(0);
10355 }
10356
Jeff Johnsone4b14592017-09-13 14:23:33 -070010357 qdf_status = cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010358 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010359 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +053010360 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010361 QDF_ASSERT(0);
10362 }
Krunal Sonid32c6bc2016-10-18 18:00:21 -070010363
Amar Singhal410675c2018-01-10 12:14:21 -080010364 dispatcher_pdev_close(hdd_ctx->hdd_pdev);
Liangwei Dong50a64a72018-01-11 01:17:00 -050010365 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
10366 if (ret) {
10367 hdd_err("Failed to destroy pdev; errno:%d", ret);
10368 QDF_ASSERT(0);
10369 }
10370
10371 /*
10372 * Reset total mac phy during module stop such that during
10373 * next module start same psoc is used to populate new service
10374 * ready data
10375 */
Arunk Khandavallia6305a32018-01-25 11:19:18 +053010376 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->hdd_psoc);
10377 if (tgt_hdl)
10378 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
10379
Liangwei Dong50a64a72018-01-11 01:17:00 -050010380
Arun Khandavallifae92942016-08-01 13:31:08 +053010381 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
10382 if (!hif_ctx) {
10383 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010384 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010385 }
10386
Arunk Khandavalli4b404332017-09-26 12:46:00 +053010387 if (hdd_ctx->target_hw_name) {
10388 qdf_mem_free(hdd_ctx->target_hw_name);
10389 hdd_ctx->target_hw_name = NULL;
10390 }
10391
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053010392 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053010393
10394 ol_cds_free();
10395
Dustin Brown70111822017-03-30 15:31:40 -070010396 if (is_idle_stop) {
Arun Khandavallifae92942016-08-01 13:31:08 +053010397 ret = pld_power_off(qdf_ctx->dev);
10398 if (ret)
10399 hdd_err("CNSS power down failed put device into Low power mode:%d",
10400 ret);
10401 }
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010402
Dustin Brown4bc0a622017-12-06 15:56:50 -080010403 /* many adapter resources are not freed by design in SSR case */
10404 if (!is_recovery_stop)
10405 hdd_check_for_leaks();
Dustin Brown26b3d042017-12-21 11:13:27 -080010406 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080010407
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010408 /* Once the firmware sequence is completed reset this flag */
10409 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053010410 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080010411 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053010412
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010413done:
10414 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010415 cds_set_module_stop_in_progress(false);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010416 mutex_unlock(&hdd_ctx->iface_change_lock);
Yun Parkfec73dc2017-09-06 10:40:07 -070010417 hdd_alert("stop WLAN module: exit driver status=%d",
10418 hdd_ctx->driver_status);
Dustin Brown4bc0a622017-12-06 15:56:50 -080010419
Dustin Browne74003f2018-03-14 12:51:58 -070010420 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053010421
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010422 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053010423}
10424
Arun Khandavallifae92942016-08-01 13:31:08 +053010425
10426/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010427 * hdd_state_info_dump() - prints state information of hdd layer
10428 * @buf: buffer pointer
10429 * @size: size of buffer to be filled
10430 *
10431 * This function is used to dump state information of hdd layer
10432 *
10433 * Return: None
10434 */
10435static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
10436{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010437 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070010438 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070010439 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010440 uint16_t len = 0;
10441 char *buf = *buf_ptr;
10442
10443 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10444 if (!hdd_ctx) {
10445 hdd_err("Failed to get hdd context ");
10446 return;
10447 }
10448
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010449 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010450
10451 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070010452 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010453 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080010454 "\n is_scheduler_suspended %d",
10455 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010456
Dustin Brown920397d2017-12-13 16:27:50 -080010457 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010458 if (adapter->dev)
10459 len += scnprintf(buf + len, *size - len,
10460 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080010461 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010462 "\n device_mode: %d", adapter->device_mode);
10463 switch (adapter->device_mode) {
10464 case QDF_STA_MODE:
10465 case QDF_P2P_CLIENT_MODE:
10466 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
10467 len += scnprintf(buf + len, *size - len,
10468 "\n connState: %d",
10469 hdd_sta_ctx->conn_info.connState);
10470 break;
10471
10472 default:
10473 break;
10474 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010475 }
10476
10477 *size -= len;
10478 *buf_ptr += len;
10479}
10480
10481/**
10482 * hdd_register_debug_callback() - registration function for hdd layer
10483 * to print hdd state information
10484 *
10485 * Return: None
10486 */
10487static void hdd_register_debug_callback(void)
10488{
10489 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
10490}
10491
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053010492/*
10493 * wlan_init_bug_report_lock() - Initialize bug report lock
10494 *
10495 * This function is used to create bug report lock
10496 *
10497 * Return: None
10498 */
10499static void wlan_init_bug_report_lock(void)
10500{
10501 p_cds_contextType p_cds_context;
10502
10503 p_cds_context = cds_get_global_context();
10504 if (!p_cds_context) {
10505 hdd_err("cds context is NULL");
10506 return;
10507 }
10508
10509 qdf_spinlock_create(&p_cds_context->bug_report_lock);
10510}
10511
Mohit Khannaf8f96822017-05-17 17:11:59 -070010512void hdd_dp_trace_init(struct hdd_config *config)
10513{
10514
10515 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
10516 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
10517 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
10518 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
10519 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
10520 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
10521 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080010522 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070010523
10524 hdd_string_to_u8_array(config->dp_trace_config, config_params,
10525 &num_entries, sizeof(config_params));
10526
10527 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080010528 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010529 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080010530 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010531 else if (bw_compute_interval > 1000) {
10532 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
10533 thresh_time_limit = 1;
10534 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070010535 hdd_err("busBandwidthComputeInterval is 0, using defaults");
10536
10537 switch (num_entries) {
10538 case 4:
10539 proto_bitmap = config_params[3];
10540 case 3:
10541 verbosity = config_params[2];
10542 case 2:
10543 thresh = config_params[1];
10544 case 1:
10545 live_mode = config_params[0];
10546 default:
Rajeev Kumar3887f9b2018-01-10 11:24:01 -080010547 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
Mohit Khannaf8f96822017-05-17 17:11:59 -070010548 live_mode, thresh, thresh_time_limit,
10549 verbosity, proto_bitmap);
10550 };
10551
10552 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
10553 verbosity, proto_bitmap);
10554
10555}
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010556/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010557 * hdd_wlan_startup() - HDD init function
10558 * @dev: Pointer to the underlying device
10559 *
10560 * This is the driver startup code executed once a WLAN device has been detected
10561 *
10562 * Return: 0 for success, < 0 for failure
10563 */
Arun Khandavallifae92942016-08-01 13:31:08 +053010564int hdd_wlan_startup(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010565{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010566 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010567 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010568 int ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010569 bool rtnl_held;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010570
Dustin Brown491d54b2018-03-14 12:39:11 -070010571 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010572
Arun Khandavallifae92942016-08-01 13:31:08 +053010573 hdd_ctx = hdd_context_create(dev);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010574
10575 if (IS_ERR(hdd_ctx))
10576 return PTR_ERR(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010577
Abhishek Singhe9068f12017-03-31 14:14:52 +053010578 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx,
10579 DEFAULT_PSOC_ID);
10580 if (ret) {
10581 hdd_err("Psoc creation fails!");
10582 QDF_BUG(0);
10583 goto err_hdd_free_context;
10584 }
10585
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010586 qdf_nbuf_init_replenish_timer();
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053010587#ifdef FEATURE_WLAN_CH_AVOID
10588 mutex_init(&hdd_ctx->avoid_freq_lock);
10589#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053010590
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010591 hdd_request_manager_init();
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053010592 qdf_atomic_init(&hdd_ctx->con_mode_flag);
Arun Khandavallifae92942016-08-01 13:31:08 +053010593
Dustin Brown021cecd2017-12-11 13:56:43 -080010594 hdd_driver_memdump_init();
10595
Jeff Johnson957bc272017-02-02 08:54:48 -080010596 ret = hdd_wlan_start_modules(hdd_ctx, NULL, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010597 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010598 hdd_err("Failed to start modules: %d", ret);
Dustin Brown021cecd2017-12-11 13:56:43 -080010599 goto err_memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010600 }
10601
Yingying Tang80e15f32016-09-27 18:23:01 +080010602 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010603
Anurag Chouhan6d760662016-02-20 16:05:43 +053010604 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010605
10606 if (NULL == hdd_ctx->hHal) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010607 hdd_err("HAL context is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053010608 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010609 }
10610
Prashanth Bhatta07998752016-04-28 12:35:33 -070010611 ret = hdd_wiphy_init(hdd_ctx);
10612 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010613 hdd_err("Failed to initialize wiphy: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053010614 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010615 }
10616
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053010617 if (hdd_ctx->config->enable_dp_trace)
Mohit Khannaf8f96822017-05-17 17:11:59 -070010618 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053010619
jiad195f7032018-01-31 15:18:09 +080010620 ret = hdd_ipa_init(hdd_ctx);
10621 if (ret == QDF_STATUS_E_FAILURE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010622 goto err_wiphy_unregister;
10623
Yuanyuan Liuc98370e2016-10-13 11:22:13 -070010624 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080010625
Paul Zhangfb02f452017-12-22 11:58:43 +080010626 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10627 if (ret) {
10628 hdd_err("register_netdevice_notifier failed: %d", ret);
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010629 goto err_ipa_cleanup;
Paul Zhangfb02f452017-12-22 11:58:43 +080010630 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010631
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010632 rtnl_held = hdd_hold_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010633
Jeff Johnson957bc272017-02-02 08:54:48 -080010634 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
10635 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010636 hdd_err("Failed to open interfaces: %d", ret);
Jeff Johnson46bde382017-02-01 15:31:16 -080010637 goto err_release_rtnl_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010638 }
10639
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010640 hdd_release_rtnl_lock();
10641 rtnl_held = false;
10642
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080010643 wlan_hdd_update_11n_mode(hdd_ctx->config);
10644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010645#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +053010646 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +053010647 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010648 hdd_skip_acs_scan_timer_handler,
10649 (void *)hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010650 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -070010651 hdd_err("Failed to init ACS Skip timer");
Liangwei Dongaef84342016-10-21 05:28:00 -040010652 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010653#endif
10654
Prashanth Bhattaab004382016-10-11 16:08:11 -070010655 hdd_bus_bandwidth_init(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010656
Jeff Johnson9afc5012016-09-23 13:56:27 -070010657 hdd_lpass_notify_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010658
Nirav Shahbd36b062016-07-18 11:12:59 +053010659 if (hdd_ctx->rps)
10660 hdd_set_rps_cpu_mask(hdd_ctx);
Peng Xu8fdaa492016-06-22 10:20:47 -070010661
Paul Zhangfb02f452017-12-22 11:58:43 +080010662 ret = hdd_register_notifiers(hdd_ctx);
10663 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -080010664 goto err_close_adapters;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070010665
Paul Zhangfb02f452017-12-22 11:58:43 +080010666 status = wlansap_global_init();
10667 if (QDF_IS_STATUS_ERROR(status)) {
10668 hdd_unregister_notifiers(hdd_ctx);
10669 goto err_close_adapters;
10670 }
10671
Arun Khandavallifae92942016-08-01 13:31:08 +053010672 if (hdd_ctx->config->fIsImpsEnabled)
10673 hdd_set_idle_ps_config(hdd_ctx, true);
Kiran Kumar Lokereb0f19c32017-10-13 12:23:26 -070010674 else
10675 hdd_set_idle_ps_config(hdd_ctx, false);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010676
Mukul Sharma07bd8752017-10-10 16:58:14 +053010677 if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
Dustin Brown6f427922017-09-19 12:19:00 -070010678 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
10679 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +053010680 hdd_prevent_suspend_timeout(
10681 hdd_ctx->config->iface_change_wait_time,
10682 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
10683 }
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053010684
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010685 goto success;
10686
Jeff Johnson957bc272017-02-02 08:54:48 -080010687err_close_adapters:
Jeff Johnson46bde382017-02-01 15:31:16 -080010688 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010689
Jeff Johnson46bde382017-02-01 15:31:16 -080010690err_release_rtnl_lock:
Arun Khandavallid4349a92016-07-25 11:10:43 +053010691 if (rtnl_held)
10692 hdd_release_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010693
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010694 unregister_netdevice_notifier(&hdd_netdev_notifier);
10695
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010696err_ipa_cleanup:
Anurag Chouhance6a4052016-09-14 18:20:42 +053010697 hdd_ipa_cleanup(hdd_ctx);
Yun Park6a46ad82016-01-04 16:48:19 -080010698
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010699err_wiphy_unregister:
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010700 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010701
Arun Khandavallifae92942016-08-01 13:31:08 +053010702err_stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010703 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010704
Dustin Brown021cecd2017-12-11 13:56:43 -080010705err_memdump_deinit:
10706 hdd_driver_memdump_deinit();
Dustin Brown021cecd2017-12-11 13:56:43 -080010707
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010708 hdd_request_manager_deinit();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070010709 hdd_exit_netlink_services(hdd_ctx);
10710
Dustin Brown20912462017-06-07 13:48:25 -070010711 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10712
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010713err_hdd_free_context:
Nachiket Kukade8003d252017-03-30 15:55:58 +053010714 if (cds_is_fw_down())
10715 hdd_err("Not setting the complete event as fw is down");
10716 else
10717 hdd_start_complete(ret);
10718
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010719 qdf_nbuf_deinit_replenish_timer();
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010720 hdd_context_destroy(hdd_ctx);
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -070010721 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010722
10723success:
Dustin Browne74003f2018-03-14 12:51:58 -070010724 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010725 return 0;
10726}
10727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010728/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010729 * hdd_wlan_update_target_info() - update target type info
10730 * @hdd_ctx: HDD context
10731 * @context: hif context
10732 *
10733 * Update target info received from firmware in hdd context
10734 * Return:None
10735 */
10736
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010737void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053010738{
10739 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
10740
10741 if (!tgt_info) {
10742 hdd_err("Target info is Null");
10743 return;
10744 }
10745
10746 hdd_ctx->target_type = tgt_info->target_type;
10747}
10748
10749/**
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010750 * hdd_get_nud_stats_cb() - callback api to update the stats
10751 * received from the firmware
10752 * @data: pointer to adapter.
10753 * @rsp: pointer to data received from FW.
10754 *
10755 * This is called when wlan driver received response event for
10756 * get arp stats to firmware.
10757 *
10758 * Return: None
10759 */
10760static void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp)
10761{
10762 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
10763 struct hdd_nud_stats_context *context;
10764 int status;
10765 struct hdd_adapter *adapter = NULL;
10766
Dustin Brown491d54b2018-03-14 12:39:11 -070010767 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010768
10769 if (!rsp) {
10770 hdd_err("data is null");
10771 return;
10772 }
10773
10774 status = wlan_hdd_validate_context(hdd_ctx);
10775 if (0 != status)
10776 return;
10777
10778 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
10779 if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
10780 hdd_err("Invalid adapter or adapter has invalid magic");
10781 return;
10782 }
10783
Dustin Brown5e89ef82018-03-14 11:50:23 -070010784 hdd_info("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
10785 hdd_info("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
10786 hdd_info("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
10787 hdd_info("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
10788 hdd_info("rsp->out_of_order_arp_rsp_drop_cnt :%x",
10789 rsp->out_of_order_arp_rsp_drop_cnt);
10790 hdd_info("rsp->dad_detected :%x", rsp->dad_detected);
10791 hdd_info("rsp->connect_status :%x", rsp->connect_status);
10792 hdd_info("rsp->ba_session_establishment_status :%x",
10793 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010794
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010795 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010796 adapter->dad |= rsp->dad_detected;
10797 adapter->con_status = rsp->connect_status;
10798
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053010799 /* Flag true indicates connectivity check stats present. */
10800 if (rsp->connect_stats_present) {
10801 hdd_info("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
10802 hdd_info("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
10803 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
10804 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
10805 rsp->icmpv4_rsp_recvd;
10806 }
10807
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010808 spin_lock(&hdd_context_lock);
10809 context = &hdd_ctx->nud_stats_context;
10810 complete(&context->response_event);
10811 spin_unlock(&hdd_context_lock);
10812
Dustin Browne74003f2018-03-14 12:51:58 -070010813 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010814}
10815
10816/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010817 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010818 * @hdd_ctx: HDD context
10819 *
10820 * Register the HDD callbacks to CDS/SME.
10821 *
10822 * Return: 0 for success or Error code for failure
10823 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010824int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010825{
10826 QDF_STATUS status;
10827 int ret = 0;
10828
Dustin Brown491d54b2018-03-14 12:39:11 -070010829 hdd_enter();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010830
10831 sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);
10832
10833 sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
10834 hdd_send_oem_data_rsp_msg);
10835
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053010836 sme_register_mgmt_frame_ind_callback(hdd_ctx->hHal,
10837 hdd_indicate_mgmt_frame);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010838 sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
10839 sme_nan_register_callback(hdd_ctx->hHal,
10840 wlan_hdd_cfg80211_nan_callback);
10841 sme_stats_ext_register_callback(hdd_ctx->hHal,
10842 wlan_hdd_cfg80211_stats_ext_callback);
10843
10844 sme_ext_scan_register_callback(hdd_ctx->hHal,
10845 wlan_hdd_cfg80211_extscan_callback);
lifeng66831662017-05-19 16:01:35 +080010846 sme_stats_ext2_register_callback(hdd_ctx->hHal,
10847 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010848
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010849 sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
10850 hdd_rssi_threshold_breached);
10851
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010852 sme_set_nud_debug_stats_cb(hdd_ctx->hHal, hdd_get_nud_stats_cb);
10853
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010854 sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
10855 wlan_hdd_cfg80211_link_layer_stats_callback);
10856
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010857 sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb);
10858
Zhang Qianca38fb12016-12-23 11:10:48 +080010859 sme_set_link_layer_ext_cb(hdd_ctx->hHal,
10860 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
10861
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053010862 status = sme_set_lost_link_info_cb(hdd_ctx->hHal,
10863 hdd_lost_link_info_cb);
10864 /* print error and not block the startup process */
10865 if (!QDF_IS_STATUS_SUCCESS(status))
10866 hdd_err("set lost link info callback failed");
10867
Poddar, Siddarth34872782017-08-10 14:08:51 +053010868 ret = hdd_register_data_stall_detect_cb();
10869 if (ret) {
10870 hdd_err("Register data stall detect detect callback failed.");
10871 return ret;
10872 }
10873
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010874 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
10875
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080010876 sme_register_set_connection_info_cb(hdd_ctx->hHal,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010877 hdd_set_connection_in_progress,
10878 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053010879
10880 status = sme_congestion_register_callback(hdd_ctx->hHal,
10881 hdd_update_cca_info_cb);
10882 if (!QDF_IS_STATUS_SUCCESS(status))
10883 hdd_err("set congestion callback failed");
10884
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053010885 status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
10886 hdd_bt_activity_cb);
10887 if (!QDF_IS_STATUS_SUCCESS(status))
10888 hdd_err("set bt activity info callback failed");
10889
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080010890 status = sme_register_tx_queue_cb(hdd_ctx->hHal,
10891 hdd_tx_queue_cb);
10892 if (!QDF_IS_STATUS_SUCCESS(status))
10893 hdd_err("Register tx queue callback failed");
10894
Dustin Browne74003f2018-03-14 12:51:58 -070010895 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010896
10897 return ret;
10898}
10899
10900/**
10901 * hdd_deregister_cb() - De-Register HDD callbacks.
10902 * @hdd_ctx: HDD context
10903 *
10904 * De-Register the HDD callbacks to CDS/SME.
10905 *
10906 * Return: void
10907 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010908void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010909{
10910 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053010911 int ret;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010912
Dustin Brown491d54b2018-03-14 12:39:11 -070010913 hdd_enter();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010914
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080010915 sme_deregister_tx_queue_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010916 status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
10917 if (!QDF_IS_STATUS_SUCCESS(status))
10918 hdd_err("De-register of dcc stats callback failed: %d",
10919 status);
10920
10921 sme_reset_link_layer_stats_ind_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010922 sme_reset_rssi_threshold_breached_cb(hdd_ctx->hHal);
10923
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010924 sme_stats_ext_register_callback(hdd_ctx->hHal,
10925 wlan_hdd_cfg80211_stats_ext_callback);
10926
10927 sme_nan_deregister_callback(hdd_ctx->hHal);
10928 status = sme_reset_tsfcb(hdd_ctx->hHal);
10929 if (!QDF_IS_STATUS_SUCCESS(status))
10930 hdd_err("Failed to de-register tsfcb the callback:%d",
10931 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010932
Poddar, Siddarth34872782017-08-10 14:08:51 +053010933 ret = hdd_deregister_data_stall_detect_cb();
10934 if (ret)
10935 hdd_err("Failed to de-register data stall detect event callback");
10936
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010937 sme_deregister_oem_data_rsp_callback(hdd_ctx->hHal);
10938 sme_deregister11d_scan_done_callback(hdd_ctx->hHal);
10939
Dustin Browne74003f2018-03-14 12:51:58 -070010940 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010941}
10942
10943/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010944 * hdd_softap_sta_deauth() - handle deauth req from HDD
10945 * @adapter: Pointer to the HDD
10946 * @enable: bool value
10947 *
10948 * This to take counter measure to handle deauth req from HDD
10949 *
10950 * Return: None
10951 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010952QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080010953 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010954{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010955 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010956
Dustin Brown491d54b2018-03-14 12:39:11 -070010957 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010958
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010959 /* Ignore request to deauth bcmc station */
10960 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010961 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010962
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010963 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010964 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
10965 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010966
Dustin Browne74003f2018-03-14 12:51:58 -070010967 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010968 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010969}
10970
10971/**
10972 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
10973 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053010974 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010975 *
10976 * This to take counter measure to handle deauth req from HDD
10977 *
10978 * Return: None
10979 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010980void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080010981 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010982{
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +053010983 struct sir_peer_sta_info peer_sta_info;
10984 struct hdd_station_info *stainfo;
Jeff Johnsone0847ba2018-03-01 12:34:50 -080010985
Dustin Brown491d54b2018-03-14 12:39:11 -070010986 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010987
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010988 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053010989 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010990 return;
10991
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +053010992 wlan_hdd_get_peer_rssi(adapter, &pDelStaParams->peerMacAddr,
10993 &peer_sta_info);
10994 stainfo = hdd_get_stainfo(adapter->cache_sta_info,
10995 pDelStaParams->peerMacAddr);
10996 if (stainfo) {
10997 stainfo->rssi = peer_sta_info.info[0].rssi;
10998 stainfo->tx_rate = peer_sta_info.info[0].tx_rate;
10999 stainfo->rx_rate = peer_sta_info.info[0].rx_rate;
Jiachao Wuf610d912018-01-23 17:47:32 +080011000 stainfo->reason_code = pDelStaParams->reason_code;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +053011001 }
11002
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011003 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053011004 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011005}
11006
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011007/**
11008 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
11009 * @hdd_ctx: HDD Context
11010 *
11011 * API to find if there is any STA or P2P-Client is connected
11012 *
11013 * Return: true if connected; false otherwise
11014 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011015QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011016{
11017 return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
11018}
11019
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011020/**
11021 * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
11022 * @adapter: HDD adapter pointer
11023 *
11024 * This function loop through each adapter and disable roaming on each STA
11025 * device mode except the input adapter.
11026 *
11027 * Note: On the input adapter roaming is not enabled yet hence no need to
11028 * disable.
11029 *
11030 * Return: None
11031 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011032void wlan_hdd_disable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011033{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011034 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011035 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011036
11037 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011038 hdd_ctx->config->isRoamOffloadScanEnabled &&
11039 QDF_STA_MODE == adapter->device_mode &&
11040 policy_mgr_is_sta_active_connection_exists(
11041 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011042 hdd_debug("Connect received on STA session Id(%d)",
11043 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011044 /*
11045 * Loop through adapter and disable roaming for each STA device
11046 * mode except the input adapter.
11047 */
Dustin Brown920397d2017-12-13 16:27:50 -080011048 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011049 if (QDF_STA_MODE == adapterIdx->device_mode &&
11050 adapter->session_id != adapterIdx->session_id) {
11051 hdd_debug("Disable Roaming on session Id(%d)",
11052 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011053 sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
11054 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070011055 adapterIdx->session_id, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011056 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011057 }
11058 }
11059}
11060
11061/**
11062 * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
11063 * @adapter: HDD adapter pointer
11064 *
11065 * This function loop through each adapter and enable roaming on each STA
11066 * device mode except the input adapter.
11067 * Note: On the input adapter no need to enable roaming because link got
11068 * disconnected on this.
11069 *
11070 * Return: None
11071 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011072void wlan_hdd_enable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011073{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011074 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011075 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011076
11077 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011078 hdd_ctx->config->isRoamOffloadScanEnabled &&
11079 QDF_STA_MODE == adapter->device_mode &&
11080 policy_mgr_is_sta_active_connection_exists(
11081 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011082 hdd_debug("Disconnect received on STA session Id(%d)",
11083 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011084 /*
11085 * Loop through adapter and enable roaming for each STA device
11086 * mode except the input adapter.
11087 */
Dustin Brown920397d2017-12-13 16:27:50 -080011088 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070011089 if (QDF_STA_MODE == adapterIdx->device_mode &&
11090 adapter->session_id != adapterIdx->session_id) {
11091 hdd_debug("Enabling Roaming on session Id(%d)",
11092 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011093 sme_start_roaming(WLAN_HDD_GET_HAL_CTX
11094 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070011095 adapterIdx->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011096 REASON_CONNECT);
11097 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011098 }
11099 }
11100}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011101
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053011102/**
11103 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
11104 * @skb: sk buffer pointer
11105 *
11106 * Sends the bcast message to SVC multicast group with generic nl socket
11107 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
11108 *
11109 * Return: None
11110 */
11111static void nl_srv_bcast_svc(struct sk_buff *skb)
11112{
11113#ifdef CNSS_GENL
11114 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
11115#else
11116 nl_srv_bcast(skb);
11117#endif
11118}
11119
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011120void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011121{
11122 struct sk_buff *skb;
11123 struct nlmsghdr *nlh;
11124 tAniMsgHdr *ani_hdr;
11125 void *nl_data = NULL;
11126 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011127 struct radio_index_tlv *radio_info;
11128 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011129
11130 if (in_interrupt() || irqs_disabled() || in_atomic())
11131 flags = GFP_ATOMIC;
11132
11133 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
11134
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011135 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011136 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011137
11138 nlh = (struct nlmsghdr *)skb->data;
11139 nlh->nlmsg_pid = 0; /* from kernel */
11140 nlh->nlmsg_flags = 0;
11141 nlh->nlmsg_seq = 0;
11142 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
11143
11144 ani_hdr = NLMSG_DATA(nlh);
11145 ani_hdr->type = type;
11146
11147 switch (type) {
11148 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053011149 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011150 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011151 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070011152 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011153 ani_hdr->length = 0;
11154 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011155 break;
11156 case WLAN_SVC_WLAN_STATUS_IND:
11157 case WLAN_SVC_WLAN_VERSION_IND:
11158 case WLAN_SVC_DFS_CAC_START_IND:
11159 case WLAN_SVC_DFS_CAC_END_IND:
11160 case WLAN_SVC_DFS_RADAR_DETECT_IND:
11161 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
11162 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080011163 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053011164 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080011165 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011166 ani_hdr->length = len;
11167 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
11168 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11169 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011170 break;
11171
11172 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070011173 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011174 type);
11175 kfree_skb(skb);
11176 return;
11177 }
11178
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011179 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080011180 * Add radio index at the end of the svc event in TLV format
11181 * to maintain the backward compatibility with userspace
11182 * applications.
11183 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011184
11185 tlv_len = 0;
11186
11187 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
11188 < WLAN_NL_MAX_PAYLOAD) {
11189 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
11190 sizeof(*ani_hdr) + len);
11191 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
11192 radio_info->length = (unsigned short) sizeof(radio_info->radio);
11193 radio_info->radio = radio;
11194 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070011195 hdd_debug("Added radio index tlv - radio index %d",
11196 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011197 }
11198
11199 nlh->nlmsg_len += tlv_len;
11200 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
11201
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053011202 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011203}
11204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011205#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
11206void wlan_hdd_auto_shutdown_cb(void)
11207{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011208 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011209
11210 if (!hdd_ctx)
11211 return;
11212
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011213 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011214 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
11215 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011216}
11217
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011218void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011219{
Jeff Johnson9d295242017-08-29 14:39:48 -070011220 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011221 bool ap_connected = false, sta_connected = false;
11222 tHalHandle hal_handle;
11223
11224 hal_handle = hdd_ctx->hHal;
11225 if (hal_handle == NULL)
11226 return;
11227
11228 if (hdd_ctx->config->WlanAutoShutdown == 0)
11229 return;
11230
11231 if (enable == false) {
11232 if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011233 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011234 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011235 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053011236 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070011237 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011238 return;
11239 }
11240
11241 /* To enable shutdown timer check conncurrency */
Dustin Brown920397d2017-12-13 16:27:50 -080011242 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->hdd_psoc)) {
11243 hdd_for_each_adapter(hdd_ctx, adapter) {
11244 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011245 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
11246 conn_info.connState ==
11247 eConnectionState_Associated) {
11248 sta_connected = true;
11249 break;
11250 }
11251 }
Dustin Brown920397d2017-12-13 16:27:50 -080011252
11253 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011254 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070011255 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011256 ap_connected = true;
11257 break;
11258 }
11259 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011260 }
11261 }
11262
11263 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011264 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011265 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011266 }
Jeff Johnson68755312017-02-10 11:46:55 -080011267
11268 if (sme_set_auto_shutdown_timer(hal_handle,
11269 hdd_ctx->config->WlanAutoShutdown)
11270 != QDF_STATUS_SUCCESS)
11271 hdd_err("Failed to start wlan auto shutdown timer");
11272 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070011273 hdd_info("Auto Shutdown timer for %d seconds enabled",
11274 hdd_ctx->config->WlanAutoShutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011275}
11276#endif
11277
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011278struct hdd_adapter *
11279hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
11280 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011281{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011282 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070011283 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011284
11285 con_sap_adapter = NULL;
11286
Dustin Brown920397d2017-12-13 16:27:50 -080011287 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011288 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
11289 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011290 adapter != this_sap_adapter) {
11291 if (check_start_bss) {
11292 if (test_bit(SOFTAP_BSS_STARTED,
11293 &adapter->event_flags)) {
11294 con_sap_adapter = adapter;
11295 break;
11296 }
11297 } else {
11298 con_sap_adapter = adapter;
11299 break;
11300 }
11301 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011302 }
11303
11304 return con_sap_adapter;
11305}
11306
11307#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070011308static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011309{
Dustin Brown5ec6b552017-03-31 12:11:40 -070011310 return adapter->device_mode == QDF_STA_MODE ||
11311 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011312}
11313
Jeff Johnson9d295242017-08-29 14:39:48 -070011314static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011315{
Dustin Brown5ec6b552017-03-31 12:11:40 -070011316 return adapter->device_mode == QDF_SAP_MODE ||
11317 adapter->device_mode == QDF_P2P_GO_MODE;
11318}
11319
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011320static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011321{
Dustin Brown920397d2017-12-13 16:27:50 -080011322 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070011323
Dustin Brown920397d2017-12-13 16:27:50 -080011324 hdd_for_each_adapter(hdd_ctx, adapter) {
11325 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070011326 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
11327 conn_info.connState == eConnectionState_Associated) {
11328 return true;
11329 }
11330
Dustin Brown920397d2017-12-13 16:27:50 -080011331 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070011332 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070011333 return true;
11334 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070011335 }
11336
11337 return false;
11338}
11339
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011340static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011341{
11342 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011343
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053011344 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070011345 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053011346 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011347
Dustin Brown5ec6b552017-03-31 12:11:40 -070011348 return is_running;
11349}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011350
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011351static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011352{
11353 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
11354 hdd_ctx->bus_bw_timer_running = true;
11355 qdf_timer_start(&hdd_ctx->bus_bw_timer,
11356 hdd_ctx->config->busBandwidthComputeInterval);
11357 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
11358}
11359
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011360void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011361{
Dustin Brown491d54b2018-03-14 12:39:11 -070011362 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011363
11364 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11365 hdd_debug("Bandwidth compute timer already started");
11366 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011367 }
11368
Dustin Brown5ec6b552017-03-31 12:11:40 -070011369 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11370
Dustin Browne74003f2018-03-14 12:51:58 -070011371 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011372}
11373
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011374void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011375{
Dustin Brown491d54b2018-03-14 12:39:11 -070011376 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011377
11378 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11379 hdd_debug("Bandwidth compute timer already started");
11380 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070011381 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070011382
11383 if (hdd_any_adapter_is_assoc(hdd_ctx))
11384 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11385
Dustin Browne74003f2018-03-14 12:51:58 -070011386 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011387}
11388
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011389static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011390{
Sravan Kumar Kairam9e99e9a2018-03-12 19:09:45 +053011391 ucfg_ipa_set_perf_level(hdd_ctx->hdd_pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070011392
11393 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
11394 qdf_timer_stop(&hdd_ctx->bus_bw_timer);
11395 hdd_ctx->bus_bw_timer_running = false;
11396 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
11397
11398 hdd_reset_tcp_delack(hdd_ctx);
11399}
11400
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011401void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011402{
Dustin Brown491d54b2018-03-14 12:39:11 -070011403 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011404
11405 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11406 hdd_debug("Bandwidth compute timer already stopped");
11407 return;
11408 }
11409
11410 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11411
Dustin Browne74003f2018-03-14 12:51:58 -070011412 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011413}
11414
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011415void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011416{
Dustin Brown491d54b2018-03-14 12:39:11 -070011417 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070011418
11419 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11420 hdd_debug("Bandwidth compute timer already stopped");
11421 return;
11422 }
11423
11424 if (!hdd_any_adapter_is_assoc(hdd_ctx))
11425 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11426
Dustin Browne74003f2018-03-14 12:51:58 -070011427 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011428}
11429#endif
11430
11431/**
11432 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
11433 * and sta's operating channel.
11434 * @sta_adapter: Describe the first argument to foobar.
11435 * @ap_adapter: Describe the second argument to foobar.
11436 * @roam_profile: Roam profile of AP to which STA wants to connect.
11437 * @concurrent_chnl_same: If both SAP and STA channels are same then
11438 * set this flag to true else false.
11439 *
11440 * This function checks the sap's operating channel and sta's operating channel.
11441 * if both are same then it will return false else it will restart the sap in
11442 * sta's channel and return true.
11443 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011444 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011445 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011446QDF_STATUS
11447wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
11448 struct hdd_adapter *ap_adapter,
Jeff Johnson61b5e982018-03-15 11:33:31 -070011449 struct csr_roam_profile *roam_profile,
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011450 tScanResultHandle *scan_cache,
11451 bool *concurrent_chnl_same)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011452{
Jeff Johnson87251032017-08-29 13:31:11 -070011453 struct hdd_ap_ctx *hdd_ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011454 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011455 QDF_STATUS status;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080011456 enum QDF_OPMODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011457 *concurrent_chnl_same = true;
11458
11459 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11460 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070011461 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011462 scan_cache,
11463 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011464 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011465 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011466 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011467 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011468 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011469 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011470 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011471 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011472 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011473 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011474 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011475 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011476 }
11477 }
11478 } else {
11479 /*
11480 * Lets handle worst case scenario here, Scan cache lookup is
11481 * failed so we have to stop the SAP to avoid any channel
11482 * discrepancy between SAP's channel and STA's channel.
11483 * Return the status as failure so caller function could know
11484 * that scan look up is failed.
11485 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070011486 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011487 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011488 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011489 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011490}
11491
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011492/**
11493 * wlan_hdd_stop_sap() - This function stops bss of SAP.
11494 * @ap_adapter: SAP adapter
11495 *
11496 * This function will process the stopping of sap adapter.
11497 *
11498 * Return: None
11499 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011500void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011501{
Jeff Johnson87251032017-08-29 13:31:11 -070011502 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011503 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011504 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011505 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011506
11507 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011508 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011509 return;
11510 }
11511
11512 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11513 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011514 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011515 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011516
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011517 mutex_lock(&hdd_ctx->sap_lock);
11518 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080011519 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011520 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011521 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011522 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011523 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011524 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053011525 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080011526 qdf_stop_bss_event,
11527 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011528 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011529 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070011530 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011531 return;
11532 }
11533 }
11534 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011535 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
11536 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011537 ap_adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011538 hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
11539 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011540 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011541 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011542 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011543 }
11544 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011545}
11546
11547/**
11548 * wlan_hdd_start_sap() - this function starts bss of SAP.
11549 * @ap_adapter: SAP adapter
11550 *
11551 * This function will process the starting of sap adapter.
11552 *
11553 * Return: None
11554 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011555void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011556{
Jeff Johnson87251032017-08-29 13:31:11 -070011557 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011558 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011559 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011560 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011561 tsap_Config_t *sap_config;
11562
11563 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011564 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011565 return;
11566 }
11567
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011568 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070011569 hdd_err("SoftAp role has not been enabled");
11570 return;
11571 }
11572
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011573 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
11574 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11575 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070011576 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011577
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011578 mutex_lock(&hdd_ctx->sap_lock);
11579 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
11580 goto end;
11581
11582 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011583 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011584 goto end;
11585 }
11586
Wei Song2f76f642016-11-18 16:32:53 +080011587 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011588 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070011589 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011590 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011591 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011592 goto end;
11593
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011594 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053011595 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -080011596 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011597 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011598 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011599 goto end;
11600 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070011601 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053011602 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011603 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011604 if (hostapd_state->bss_state == BSS_START) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011605 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
11606 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011607 ap_adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053011608 hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
11609 true);
11610 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053011611 mutex_unlock(&hdd_ctx->sap_lock);
11612
11613 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011614end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053011615 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011616 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070011617 /* SAP context and beacon cleanup will happen during driver unload
11618 * in hdd_stop_adapter
11619 */
11620 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
11621
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011622}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011623
11624/**
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011625 * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual
11626 * mac scan config
11627 * @status: Status of set antenna mode
11628 *
11629 * Callback on setting the dual mac configuration
11630 *
11631 * Return: None
11632 */
11633void wlan_hdd_soc_set_antenna_mode_cb(
11634 enum set_antenna_mode_status status)
11635{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011636 struct hdd_context *hdd_ctx;
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011637
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011638 hdd_debug("Status: %d", status);
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011639
11640 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11641 if (0 != wlan_hdd_validate_context(hdd_ctx))
11642 return;
11643
11644 /* Signal the completion of set dual mac config */
11645 complete(&hdd_ctx->set_antenna_mode_cmpl);
11646}
11647
11648/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011649 * hdd_get_fw_version() - Get FW version
11650 * @hdd_ctx: pointer to HDD context.
11651 * @major_spid: FW version - major spid.
11652 * @minor_spid: FW version - minor spid
11653 * @ssid: FW version - ssid
11654 * @crmid: FW version - crmid
11655 *
11656 * This function is called to get the firmware build version stored
11657 * as part of the HDD context
11658 *
11659 * Return: None
11660 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011661void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011662 uint32_t *major_spid, uint32_t *minor_spid,
11663 uint32_t *siid, uint32_t *crmid)
11664{
11665 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
11666 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
11667 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
11668 *crmid = hdd_ctx->target_fw_version & 0x7fff;
11669}
11670
11671#ifdef QCA_CONFIG_SMP
11672/**
11673 * wlan_hdd_get_cpu() - get cpu_index
11674 *
11675 * Return: cpu_index
11676 */
11677int wlan_hdd_get_cpu(void)
11678{
11679 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011680
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011681 put_cpu();
11682 return cpu_index;
11683}
11684#endif
11685
11686/**
11687 * hdd_get_fwpath() - get framework path
11688 *
11689 * This function is used to get the string written by
11690 * userspace to start the wlan driver
11691 *
11692 * Return: string
11693 */
11694const char *hdd_get_fwpath(void)
11695{
11696 return fwpath.string;
11697}
11698
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011699static int hdd_qdf_print_init(void)
11700{
11701 int qdf_print_idx;
11702 QDF_STATUS status;
11703
11704 status = qdf_print_setup();
11705 if (status != QDF_STATUS_SUCCESS) {
11706 pr_err("qdf_print_setup failed\n");
11707 return -EINVAL;
11708 }
11709
11710 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
11711
11712 if (qdf_print_idx < 0) {
11713 pr_err("qdf_print_ctrl_register failed, ret = %d\n",
11714 qdf_print_idx);
11715 return -EINVAL;
11716 }
11717
11718 qdf_set_pidx(qdf_print_idx);
11719
11720 return 0;
11721}
11722
11723static void hdd_qdf_print_deinit(void)
11724{
11725 int qdf_print_idx;
11726
11727 qdf_print_idx = qdf_get_pidx();
11728 qdf_print_ctrl_cleanup(qdf_print_idx);
11729}
11730
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011731/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011732 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011733 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011734 * This function initilizes CDS global context with the help of cds_init. This
11735 * has to be the first function called after probe to get a valid global
11736 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011737 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011738 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011739 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011740int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011741{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011742 QDF_STATUS status;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011743 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011744
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011745 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080011746 if (QDF_IS_STATUS_ERROR(status)) {
11747 hdd_err("Failed to allocate CDS context");
11748 ret = -ENOMEM;
11749 goto err_out;
11750 }
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053011751
11752 wlan_init_bug_report_lock();
11753
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011754#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11755 wlan_logging_sock_init_svc();
11756#endif
11757
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011758 qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
11759 (void *)hdd_drv_ops_inactivity_handler, NULL,
11760 QDF_TIMER_TYPE_SW);
11761
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011762 hdd_trace_init();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011763 hdd_qdf_print_init();
11764
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011765 hdd_register_debug_callback();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011766
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011767err_out:
11768 return ret;
11769}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011770
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011771/**
11772 * hdd_deinit() - Deinitialize Driver
11773 *
11774 * This function frees CDS global context with the help of cds_deinit. This
11775 * has to be the last function call in remove callback to free the global
11776 * context.
11777 */
11778void hdd_deinit(void)
11779{
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011780 qdf_timer_free(&hdd_drv_ops_inactivity_timer);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011781
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070011782 wlan_destroy_bug_report_lock();
11783 cds_deinit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011784
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070011785 hdd_qdf_print_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011786#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11787 wlan_logging_sock_deinit_svc();
11788#endif
11789}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011790
Yue Ma6e7b1a02017-04-03 14:17:46 -070011791#ifdef QCA_WIFI_NAPIER_EMULATION
11792#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
11793#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011794#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070011795#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011796
Sachin Ahujadddd2632017-03-07 19:07:24 +053011797static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
11798 struct file *file)
11799{
11800 return 0;
11801}
11802
11803static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
11804 const char __user *user_buf,
11805 size_t count,
11806 loff_t *f_pos)
11807{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011808 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053011809 static const char wlan_off_str[] = "OFF";
11810 static const char wlan_on_str[] = "ON";
11811 int ret;
11812 unsigned long rc;
11813
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011814 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011815 pr_err("Failed to read buffer\n");
11816 return -EINVAL;
11817 }
11818
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011819 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011820 pr_debug("Wifi turning off from UI\n");
11821 goto exit;
11822 }
11823
Sachin Ahuja16904db2017-12-13 19:56:57 +053011824 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0) {
11825 pr_info("Wifi Turning On from UI\n");
11826 }
11827
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011828 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011829 pr_err("Invalid value received from framework");
11830 goto exit;
11831 }
11832
11833 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053011834 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053011835 rc = wait_for_completion_timeout(&wlan_start_comp,
11836 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
11837 if (!rc) {
11838 hdd_alert("Timed-out waiting in wlan_hdd_state_ctrl_param_write");
11839 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053011840 return ret;
11841 }
11842
11843 hdd_start_complete(0);
11844 }
11845
11846exit:
11847 return count;
11848}
11849
11850
11851const struct file_operations wlan_hdd_state_fops = {
11852 .owner = THIS_MODULE,
11853 .open = wlan_hdd_state_ctrl_param_open,
11854 .write = wlan_hdd_state_ctrl_param_write,
11855};
11856
11857static int wlan_hdd_state_ctrl_param_create(void)
11858{
11859 unsigned int wlan_hdd_state_major = 0;
11860 int ret;
11861 struct device *dev;
11862
11863 device = MKDEV(wlan_hdd_state_major, 0);
11864
11865 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
11866 if (ret) {
11867 pr_err("Failed to register qcwlanstate");
11868 goto dev_alloc_err;
11869 }
11870 wlan_hdd_state_major = MAJOR(device);
11871
11872 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
11873 if (IS_ERR(class)) {
11874 pr_err("wlan_hdd_state class_create error");
11875 goto class_err;
11876 }
11877
11878 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
11879 if (IS_ERR(dev)) {
11880 pr_err("wlan_hdd_statedevice_create error");
11881 goto err_class_destroy;
11882 }
11883
11884 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
11885 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
11886 if (ret) {
11887 pr_err("Failed to add cdev error");
11888 goto cdev_add_err;
11889 }
11890
11891 pr_info("wlan_hdd_state %s major(%d) initialized",
11892 WLAN_MODULE_NAME, wlan_hdd_state_major);
11893
11894 return 0;
11895
11896cdev_add_err:
11897 device_destroy(class, device);
11898err_class_destroy:
11899 class_destroy(class);
11900class_err:
11901 unregister_chrdev_region(device, dev_num);
11902dev_alloc_err:
11903 return -ENODEV;
11904}
11905
11906static void wlan_hdd_state_ctrl_param_destroy(void)
11907{
11908 cdev_del(&wlan_hdd_state_cdev);
11909 device_destroy(class, device);
11910 class_destroy(class);
11911 unregister_chrdev_region(device, dev_num);
11912
11913 pr_info("Device node unregistered");
11914}
11915
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011916/**
Mukul Sharmad75a6672017-06-22 15:40:53 +053011917 * component_init - API to init cld component's
11918 *
11919 * Return: None
11920 */
11921static void component_init(void)
11922{
11923 pmo_init();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011924 disa_init();
Zhang Qian47e22ce2018-01-04 15:38:38 +080011925 ucfg_ocb_init();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053011926 ipa_init();
Mukul Sharmad75a6672017-06-22 15:40:53 +053011927}
11928
11929/**
11930 * component_deinit - API to deinit cld component's
11931 *
11932 * Return: None
11933 */
11934static void component_deinit(void)
11935{
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053011936 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080011937 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053011938 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011939 disa_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011940}
11941
11942void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
11943{
Zhang Qian47e22ce2018-01-04 15:38:38 +080011944 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011945 disa_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011946}
11947
11948void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
11949{
Nachiket Kukade98f562a2017-12-15 12:18:07 +053011950 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080011951 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053011952}
11953
11954/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011955 * __hdd_module_init - Module init helper
11956 *
11957 * Module init helper function used by both module and static driver.
11958 *
11959 * Return: 0 for success, errno on failure
11960 */
11961static int __hdd_module_init(void)
11962{
11963 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011964
Dustin Brown96cd9632017-11-13 12:45:04 -080011965 pr_err("%s: Loading driver v%s (%s)\n",
Dustin Brownab482ac2017-06-09 17:00:44 -070011966 WLAN_MODULE_NAME,
Dustin Brown96cd9632017-11-13 12:45:04 -080011967 g_wlan_driver_version,
Dustin Brownc1034df2018-02-07 14:51:32 -080011968 TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011969
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070011970 pld_init();
11971
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011972 ret = hdd_init();
11973 if (ret) {
11974 pr_err("hdd_init failed %x\n", ret);
11975 goto err_hdd_init;
11976 }
11977
Rajeev Kumar97767a02016-11-30 11:20:40 -080011978 dispatcher_init();
11979
Mukul Sharmad75a6672017-06-22 15:40:53 +053011980 /* Ensure to call post objmgr init */
11981 component_init();
11982
Anurag Chouhana37b5b72016-02-21 14:53:42 +053011983 qdf_wake_lock_create(&wlan_wake_lock, "wlan");
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011984
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011985 hdd_set_conparam((uint32_t) con_mode);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011986
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011987 ret = wlan_hdd_register_driver();
11988 if (ret) {
Mohit Khannafa99aea2016-05-12 21:43:13 -070011989 pr_err("%s: driver load failure, err %d\n", WLAN_MODULE_NAME,
11990 ret);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011991 goto out;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011992 }
11993
Sachin Ahuja16904db2017-12-13 19:56:57 +053011994 ret = wlan_hdd_state_ctrl_param_create();
11995 if (ret) {
11996 pr_err("wlan_hdd_state_create:%x\n", ret);
11997 goto out;
11998 }
11999
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053012000 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012001
12002 return 0;
12003out:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053012004 qdf_wake_lock_destroy(&wlan_wake_lock);
Liangwei Dong9fcc7212017-10-24 13:43:52 +080012005 component_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080012006 dispatcher_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012007 hdd_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080012008
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012009err_hdd_init:
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070012010 pld_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012011 return ret;
12012}
12013
12014/**
12015 * __hdd_module_exit - Module exit helper
12016 *
12017 * Module exit helper function used by both module and static driver.
12018 */
12019static void __hdd_module_exit(void)
12020{
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053012021
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012022 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
12023 QWLAN_VERSIONSTR);
12024
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053012025 hdd_wait_for_recovery_completion();
12026
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012027 wlan_hdd_unregister_driver();
12028
Anurag Chouhana37b5b72016-02-21 14:53:42 +053012029 qdf_wake_lock_destroy(&wlan_wake_lock);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012030
Mukul Sharmad75a6672017-06-22 15:40:53 +053012031 /* Ensure to call prior to objmgr deinit */
12032 component_deinit();
12033
Rajeev Kumar97767a02016-11-30 11:20:40 -080012034 dispatcher_deinit();
Amar Singhal0928b192017-12-01 10:50:54 -080012035
12036 hdd_sysfs_destroy_version_interface();
12037
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012038 hdd_deinit();
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070012039 pld_deinit();
12040
Sachin Ahujadddd2632017-03-07 19:07:24 +053012041 wlan_hdd_state_ctrl_param_destroy();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012042}
12043
Arun Khandavallifae92942016-08-01 13:31:08 +053012044#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012045/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012046 * wlan_boot_cb() - Wlan boot callback
12047 * @kobj: object whose directory we're creating the link in.
12048 * @attr: attribute the user is interacting with
12049 * @buff: the buffer containing the user data
12050 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012051 *
Arun Khandavallifae92942016-08-01 13:31:08 +053012052 * This callback is invoked when the fs is ready to start the
12053 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012054 *
Arun Khandavallifae92942016-08-01 13:31:08 +053012055 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012056 */
Arun Khandavallifae92942016-08-01 13:31:08 +053012057static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012058 struct kobj_attribute *attr,
12059 const char *buf,
12060 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012061{
Arun Khandavallifae92942016-08-01 13:31:08 +053012062
Arun Khandavallifae92942016-08-01 13:31:08 +053012063 if (wlan_loader->loaded_state) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012064 pr_err("%s: wlan driver already initialized\n", __func__);
12065 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053012066 }
12067
Arun Khandavallifae92942016-08-01 13:31:08 +053012068 if (__hdd_module_init()) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012069 pr_err("%s: wlan driver initialization failed\n", __func__);
12070 return -EIO;
12071 }
12072
12073 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053012074
12075 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012076}
Arun Khandavallifae92942016-08-01 13:31:08 +053012077
12078/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012079 * hdd_sysfs_cleanup() - cleanup sysfs
12080 *
12081 * Return: None
12082 *
12083 */
12084static void hdd_sysfs_cleanup(void)
12085{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012086 /* remove from group */
12087 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
12088 sysfs_remove_group(wlan_loader->boot_wlan_obj,
12089 wlan_loader->attr_group);
12090
12091 /* unlink the object from parent */
12092 kobject_del(wlan_loader->boot_wlan_obj);
12093
12094 /* free the object */
12095 kobject_put(wlan_loader->boot_wlan_obj);
12096
12097 kfree(wlan_loader->attr_group);
12098 kfree(wlan_loader);
12099
12100 wlan_loader = NULL;
12101}
12102
12103/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012104 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
12105 * ready
12106 *
12107 * This is creates the syfs entry boot_wlan. Which shall be invoked
12108 * when the filesystem is ready.
12109 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012110 * QDF API cannot be used here since this function is called even before
12111 * initializing WLAN driver.
12112 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070012113 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053012114 */
12115static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012116{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012117 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053012118
12119 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012120 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012121 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053012122
12123 wlan_loader->boot_wlan_obj = NULL;
12124 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
12125 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012126 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053012127 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053012128
12129 wlan_loader->loaded_state = 0;
12130 wlan_loader->attr_group->attrs = attrs;
12131
12132 wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
12133 kernel_kobj);
12134 if (!wlan_loader->boot_wlan_obj) {
12135 pr_err("%s: sysfs create and add failed\n", __func__);
Arun Khandavallifae92942016-08-01 13:31:08 +053012136 goto error_return;
12137 }
12138
12139 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
12140 wlan_loader->attr_group);
12141 if (ret) {
12142 pr_err("%s: sysfs create group failed %d\n", __func__, ret);
12143 goto error_return;
12144 }
12145
12146 return 0;
12147
12148error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012149 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053012150
12151 return ret;
12152}
12153
12154/**
12155 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
12156 *
12157 * Return: 0 on success or errno on failure
12158 */
12159static int wlan_deinit_sysfs(void)
12160{
Arun Khandavallifae92942016-08-01 13:31:08 +053012161 if (!wlan_loader) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012162 hdd_err("wlan loader context is Null!");
Arun Khandavallifae92942016-08-01 13:31:08 +053012163 return -EINVAL;
12164 }
12165
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012166 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012167 return 0;
12168}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012169
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070012170#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053012171
12172#ifdef MODULE
12173/**
12174 * __hdd_module_init - Module init helper
12175 *
12176 * Module init helper function used by both module and static driver.
12177 *
12178 * Return: 0 for success, errno on failure
12179 */
12180static int hdd_module_init(void)
12181{
Arun Khandavallifae92942016-08-01 13:31:08 +053012182 if (__hdd_module_init()) {
12183 pr_err("%s: Failed to register handler\n", __func__);
Dustin Brownab482ac2017-06-09 17:00:44 -070012184 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012185 }
12186
Dustin Brownab482ac2017-06-09 17:00:44 -070012187 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053012188}
12189#else
12190static int __init hdd_module_init(void)
12191{
12192 int ret = -EINVAL;
12193
12194 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070012195 if (ret)
Arun Khandavallifae92942016-08-01 13:31:08 +053012196 pr_err("Failed to create sysfs entry for loading wlan");
12197
12198 return ret;
12199}
12200#endif
12201
12202
12203#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012204/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012205 * hdd_module_exit() - Exit function
12206 *
12207 * This is the driver exit point (invoked when module is unloaded using rmmod)
12208 *
12209 * Return: None
12210 */
12211static void __exit hdd_module_exit(void)
12212{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012213 __hdd_module_exit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012214}
Arun Khandavallifae92942016-08-01 13:31:08 +053012215#else
12216static void __exit hdd_module_exit(void)
12217{
12218 __hdd_module_exit();
12219 wlan_deinit_sysfs();
12220}
12221#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012222
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012223static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
12224{
12225 return param_set_copystring(kmessage, kp);
12226}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012227
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012228/**
12229 * is_con_mode_valid() check con mode is valid or not
12230 * @mode: global con mode
12231 *
12232 * Return: TRUE on success FALSE on failure
12233 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080012234static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012235{
12236 switch (mode) {
12237 case QDF_GLOBAL_MONITOR_MODE:
12238 case QDF_GLOBAL_FTM_MODE:
12239 case QDF_GLOBAL_EPPING_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012240 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012241 return true;
12242 default:
12243 return false;
12244 }
12245}
12246
12247/**
12248 * hdd_get_adpter_mode() - returns adapter mode based on global con mode
12249 * @mode: global con mode
12250 *
12251 * Return: adapter mode
12252 */
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012253static enum QDF_OPMODE hdd_get_adpter_mode(
Jeff Johnson876c1a62017-12-12 10:43:07 -080012254 enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012255{
12256
12257 switch (mode) {
12258 case QDF_GLOBAL_MISSION_MODE:
12259 return QDF_STA_MODE;
12260 case QDF_GLOBAL_MONITOR_MODE:
12261 return QDF_MONITOR_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012262 case QDF_GLOBAL_EPPING_MODE:
12263 return QDF_EPPING_MODE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012264 case QDF_GLOBAL_FTM_MODE:
12265 return QDF_FTM_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012266 case QDF_GLOBAL_QVIT_MODE:
12267 return QDF_QVIT_MODE;
12268 default:
12269 return QDF_MAX_NO_OF_MODE;
12270 }
12271}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012272
Dustin Brown27cd9942017-09-27 16:11:44 -070012273static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012274 enum QDF_GLOBAL_MODE curr_mode)
Dustin Brown27cd9942017-09-27 16:11:44 -070012275{
12276 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
12277 return;
12278
12279 switch (curr_mode) {
Dustin Brown27cd9942017-09-27 16:11:44 -070012280 case QDF_GLOBAL_MONITOR_MODE:
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012281 hdd_info("Release wakelock for monitor mode!");
12282 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
12283 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
12284 case QDF_GLOBAL_MISSION_MODE:
Dustin Brown27cd9942017-09-27 16:11:44 -070012285 case QDF_GLOBAL_FTM_MODE:
12286 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Sourav Mohapatra001cfaf2018-02-28 11:30:46 +053012287 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev, NULL);
Dustin Browndb2a8be2017-12-20 11:49:56 -080012288 hdd_stop_all_adapters(hdd_ctx);
Dustin Brown27cd9942017-09-27 16:11:44 -070012289
Dustin Brown27cd9942017-09-27 16:11:44 -070012290 break;
12291 default:
12292 break;
12293 }
12294}
12295
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012296static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012297 enum QDF_GLOBAL_MODE curr_mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012298{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053012299 int driver_status;
12300
12301 driver_status = hdd_ctx->driver_status;
12302
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012303 switch (curr_mode) {
12304 case QDF_GLOBAL_MISSION_MODE:
12305 case QDF_GLOBAL_MONITOR_MODE:
12306 case QDF_GLOBAL_FTM_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012307 hdd_deinit_all_adapters(hdd_ctx, false);
12308 hdd_close_all_adapters(hdd_ctx, false);
12309 break;
12310 case QDF_GLOBAL_EPPING_MODE:
12311 epping_disable();
12312 epping_close();
12313 break;
12314 default:
12315 return;
12316 }
12317}
12318
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012319static int hdd_register_req_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080012320 enum QDF_GLOBAL_MODE mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012321{
Jeff Johnson9d295242017-08-29 14:39:48 -070012322 struct hdd_adapter *adapter;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012323 int ret = 0;
12324 bool rtnl_held;
12325 qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
12326 QDF_STATUS status;
12327
12328 if (!qdf_dev) {
12329 hdd_err("qdf device context is Null return!");
12330 return -EINVAL;
12331 }
12332
12333 rtnl_held = hdd_hold_rtnl_lock();
12334 switch (mode) {
12335 case QDF_GLOBAL_MISSION_MODE:
Jeff Johnson957bc272017-02-02 08:54:48 -080012336 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
12337 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012338 hdd_err("Failed to open interfaces: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012339 break;
12340 case QDF_GLOBAL_FTM_MODE:
12341 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
12342 wlan_hdd_get_intf_addr(hdd_ctx),
12343 NET_NAME_UNKNOWN, rtnl_held);
12344 if (adapter == NULL)
12345 ret = -EINVAL;
12346 break;
12347 case QDF_GLOBAL_MONITOR_MODE:
12348 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
12349 wlan_hdd_get_intf_addr(hdd_ctx),
12350 NET_NAME_UNKNOWN, rtnl_held);
12351 if (adapter == NULL)
12352 ret = -EINVAL;
12353 break;
12354 case QDF_GLOBAL_EPPING_MODE:
12355 status = epping_open();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012356 if (status != QDF_STATUS_SUCCESS) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012357 hdd_err("Failed to open in eeping mode: %d", status);
12358 ret = -EINVAL;
12359 break;
12360 }
12361 ret = epping_enable(qdf_dev->dev);
12362 if (ret) {
12363 hdd_err("Failed to enable in epping mode : %d", ret);
12364 epping_close();
12365 }
12366 break;
12367 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012368 hdd_err("Mode not supported");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012369 ret = -ENOTSUPP;
12370 break;
12371 }
12372 hdd_release_rtnl_lock();
12373 rtnl_held = false;
12374 return ret;
12375}
12376
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012377/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012378 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012379 * @kmessage: con mode name on which driver to be bring up
12380 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012381 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012382 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012383 * This function is invoked when user updates con mode using sys entry,
12384 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012385 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012386 * Return - 0 on success and failure code on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012387 */
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012388static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012389 struct hdd_context *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012390{
12391 int ret;
Jeff Johnson9d295242017-08-29 14:39:48 -070012392 struct hdd_adapter *adapter;
Jeff Johnson876c1a62017-12-12 10:43:07 -080012393 enum QDF_GLOBAL_MODE curr_mode;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012394 enum QDF_OPMODE adapter_mode;
Dustin Brown20024e32018-01-03 12:34:58 -080012395 int new_con_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012396
Dustin Brownab6029b2017-05-24 13:04:19 -070012397 hdd_info("con_mode handler: %s", kmessage);
12398
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012399 ret = wlan_hdd_validate_context(hdd_ctx);
12400 if (ret)
12401 return ret;
12402
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012403 qdf_atomic_set(&hdd_ctx->con_mode_flag, 1);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012404 cds_set_load_in_progress(true);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012405
Dustin Brown20024e32018-01-03 12:34:58 -080012406 ret = kstrtoint(kmessage, 0, &new_con_mode);
12407 if (ret) {
12408 hdd_err("Failed to parse con_mode '%s'", kmessage);
12409 goto reset_flags;
12410 }
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012411 mutex_lock(&hdd_init_deinit_lock);
Arun Khandavallifae92942016-08-01 13:31:08 +053012412
Dustin Brown20024e32018-01-03 12:34:58 -080012413 if (!is_con_mode_valid(new_con_mode)) {
12414 hdd_err("invalid con_mode %d", new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012415 ret = -EINVAL;
12416 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012417 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012418
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012419 curr_mode = hdd_get_conparam();
Dustin Brown20024e32018-01-03 12:34:58 -080012420 if (curr_mode == new_con_mode) {
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012421 hdd_err("curr mode: %d is same as user triggered mode %d",
Dustin Brown20024e32018-01-03 12:34:58 -080012422 curr_mode, new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012423 ret = 0;
12424 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012425 }
12426
Dustin Brown27cd9942017-09-27 16:11:44 -070012427 /* ensure adapters are stopped */
12428 hdd_stop_present_mode(hdd_ctx, curr_mode);
12429
Frank Liu6666f832018-01-04 10:06:05 +080012430 /* Cleanup present mode before switching to new mode */
12431 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
12432
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012433 ret = hdd_wlan_stop_modules(hdd_ctx, true);
Arun Khandavallifae92942016-08-01 13:31:08 +053012434 if (ret) {
12435 hdd_err("Stop wlan modules failed");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012436 goto reset_flags;
12437 }
12438
Ashish Kumar Dhanotiyacda57662017-08-14 14:45:25 +053012439
Dustin Brown20024e32018-01-03 12:34:58 -080012440 hdd_set_conparam(new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012441
Frank Liu6666f832018-01-04 10:06:05 +080012442 /*
12443 * Set ACTIVE domain before adapters created, otherwise check domain
12444 * match will fail when cleanup adapters.
12445 */
12446 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012447 /* Register for new con_mode & then kick_start modules again */
Dustin Brown20024e32018-01-03 12:34:58 -080012448 ret = hdd_register_req_mode(hdd_ctx, new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012449 if (ret) {
12450 hdd_err("Failed to register for new mode");
12451 goto reset_flags;
12452 }
12453
Dustin Brown20024e32018-01-03 12:34:58 -080012454 adapter_mode = hdd_get_adpter_mode(new_con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012455 if (adapter_mode == QDF_MAX_NO_OF_MODE) {
12456 hdd_err("invalid adapter");
12457 ret = -EINVAL;
12458 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012459 }
12460
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012461 adapter = hdd_get_adapter(hdd_ctx, adapter_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +053012462 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012463 hdd_err("Failed to get adapter:%d", adapter_mode);
12464 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012465 }
12466
12467 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
12468 if (ret) {
12469 hdd_err("Start wlan modules failed: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012470 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012471 }
12472
Dustin Brown20024e32018-01-03 12:34:58 -080012473 if (new_con_mode == QDF_GLOBAL_MONITOR_MODE) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012474 if (hdd_start_adapter(adapter)) {
12475 hdd_err("Failed to start %s adapter", kmessage);
12476 ret = -EINVAL;
12477 goto reset_flags;
12478 }
Arun Khandavallifae92942016-08-01 13:31:08 +053012479
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012480 hdd_info("Acquire wakelock for monitor mode!");
12481 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
12482 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
12483 }
12484
Dustin Brown20024e32018-01-03 12:34:58 -080012485 /* con_mode is a global module parameter */
12486 con_mode = new_con_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012487 hdd_info("Mode successfully changed to %s", kmessage);
12488 ret = 0;
12489
12490reset_flags:
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012491 mutex_unlock(&hdd_init_deinit_lock);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012492 cds_set_load_in_progress(false);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053012493 qdf_atomic_set(&hdd_ctx->con_mode_flag, 0);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012494 return ret;
12495}
12496
12497
12498static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
12499{
12500 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012501 struct hdd_context *hdd_ctx;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012502
12503 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12504 ret = wlan_hdd_validate_context(hdd_ctx);
12505 if (ret)
12506 return ret;
12507
12508 cds_ssr_protect(__func__);
12509 ret = __con_mode_handler(kmessage, kp, hdd_ctx);
12510 cds_ssr_unprotect(__func__);
12511
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012512 return ret;
12513}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012514
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053012515static int con_mode_handler_ftm(const char *kmessage,
12516 struct kernel_param *kp)
12517{
12518 int ret;
12519
12520 ret = param_set_int(kmessage, kp);
12521
12522 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
12523 pr_err("Only FTM mode supported!");
12524 return -ENOTSUPP;
12525 }
12526
12527 hdd_set_conparam(con_mode_ftm);
12528 con_mode = con_mode_ftm;
12529
12530 return ret;
12531}
12532
Ravi Joshia307f632017-07-17 23:41:41 -070012533static int con_mode_handler_monitor(const char *kmessage,
12534 struct kernel_param *kp)
12535{
12536 int ret;
12537
12538 ret = param_set_int(kmessage, kp);
12539
12540 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
12541 pr_err("Only Monitor mode supported!");
12542 return -ENOTSUPP;
12543 }
12544
12545 hdd_set_conparam(con_mode_monitor);
12546 con_mode = con_mode_monitor;
12547
12548 return ret;
12549}
12550
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012551/**
12552 * hdd_get_conparam() - driver exit point
12553 *
12554 * This is the driver exit point (invoked when module is unloaded using rmmod)
12555 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080012556 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012557 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080012558enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012559{
Jeff Johnson876c1a62017-12-12 10:43:07 -080012560 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012561}
12562
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012563void hdd_set_conparam(uint32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012564{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012565 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012566}
12567
Komal Seelamc11bb222016-01-27 18:57:10 +053012568/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012569 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
12570 * @hdd_ctx: HDD context
12571 *
12572 * Cleans up the pre cac interface, if it exists
12573 *
12574 * Return: None
12575 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012576void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012577{
12578 uint8_t session_id;
12579 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070012580 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012581
12582 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->hHal, &session_id);
12583 if (QDF_IS_STATUS_ERROR(status)) {
12584 hdd_err("failed to get pre cac vdev id");
12585 return;
12586 }
12587
12588 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
12589 if (!precac_adapter) {
12590 hdd_err("invalid pre cac adapater");
12591 return;
12592 }
12593
12594 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
12595 wlan_hdd_sap_pre_cac_failure,
12596 (void *)precac_adapter);
12597 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
12598
12599}
12600
12601/**
Komal Seelamec702b02016-02-24 18:42:16 +053012602 * hdd_update_ol_config - API to update ol configuration parameters
12603 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053012604 *
Komal Seelamc11bb222016-01-27 18:57:10 +053012605 * Return: void
12606 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012607static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053012608{
Komal Seelamec702b02016-02-24 18:42:16 +053012609 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012610 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Komal Seelamc11bb222016-01-27 18:57:10 +053012611
Komal Seelamec702b02016-02-24 18:42:16 +053012612 if (!ol_ctx)
12613 return;
12614
12615 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
12616 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
12617 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
12618 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070012619 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053012620
12621 ol_init_ini_config(ol_ctx, &cfg);
12622}
12623
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012624#ifdef FEATURE_RUNTIME_PM
12625/**
12626 * hdd_populate_runtime_cfg() - populate runtime configuration
12627 * @hdd_ctx: hdd context
12628 * @cfg: pointer to the configuration memory being populated
12629 *
12630 * Return: void
12631 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012632static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012633 struct hif_config_info *cfg)
12634{
12635 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
12636 cfg->runtime_pm_delay = hdd_ctx->config->runtime_pm_delay;
12637}
12638#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012639static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012640 struct hif_config_info *cfg)
12641{
12642}
12643#endif
12644
Komal Seelamec702b02016-02-24 18:42:16 +053012645/**
12646 * hdd_update_hif_config - API to update HIF configuration parameters
12647 * @hdd_ctx: HDD Context
12648 *
12649 * Return: void
12650 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012651static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012652{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012653 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053012654 struct hif_config_info cfg;
12655
12656 if (!scn)
12657 return;
12658
12659 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012660 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053012661 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070012662
12663 if (hdd_ctx->config->prevent_link_down)
12664 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053012665}
12666
12667/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012668 * hdd_update_dp_config() - Propagate config parameters to Lithium
12669 * datapath
12670 * @hdd_ctx: HDD Context
12671 *
12672 * Return: 0 for success/errno for failure
12673 */
12674static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
12675{
12676 struct cdp_config_params params;
12677 QDF_STATUS status;
12678
12679 params.tso_enable = hdd_ctx->config->tso_enable;
12680 params.lro_enable = hdd_ctx->config->lro_enable;
12681#ifdef QCA_LL_TX_FLOW_CONTROL_V2
12682 params.tx_flow_stop_queue_threshold =
12683 hdd_ctx->config->TxFlowStopQueueThreshold;
12684 params.tx_flow_start_queue_offset =
12685 hdd_ctx->config->TxFlowStartQueueOffset;
12686#endif
12687 params.flow_steering_enable = hdd_ctx->config->flow_steering_enable;
12688 params.napi_enable = hdd_ctx->napi_enable;
12689 params.tcp_udp_checksumoffload =
12690 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
12691
12692 status = cdp_update_config_parameters(
12693 cds_get_context(QDF_MODULE_ID_SOC),
12694 &params);
12695 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070012696 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012697 return status;
12698 }
12699
12700 return 0;
12701}
12702
12703/**
Komal Seelamec702b02016-02-24 18:42:16 +053012704 * hdd_update_config() - Initialize driver per module ini parameters
12705 * @hdd_ctx: HDD Context
12706 *
12707 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012708 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053012709 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012710int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012711{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012712 int ret;
12713
Komal Seelamec702b02016-02-24 18:42:16 +053012714 hdd_update_ol_config(hdd_ctx);
12715 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012716 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
12717 ret = hdd_update_cds_config_ftm(hdd_ctx);
12718 else
12719 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080012720 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012721
12722 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053012723}
12724
Mukul Sharma9d797a02017-01-05 20:26:03 +053012725#ifdef FEATURE_WLAN_RA_FILTERING
12726/**
12727 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
12728 * @psoc_cfg: pmo psoc Configuration
12729 * @hdd_ctx: Pointer to hdd context
12730 *
12731 * Return: none
12732 */
12733static inline void hdd_ra_populate_pmo_config(
12734 struct pmo_psoc_cfg *psoc_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012735 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012736{
12737 psoc_cfg->ra_ratelimit_interval =
12738 hdd_ctx->config->RArateLimitInterval;
12739 psoc_cfg->ra_ratelimit_enable =
12740 hdd_ctx->config->IsRArateLimitEnabled;
12741}
12742#else
12743static inline void hdd_ra_populate_pmo_config(
12744 struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012745 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012746{
12747}
12748#endif
Will Huang3cd2b7c2017-11-17 13:16:56 +080012749
Mukul Sharma9d797a02017-01-05 20:26:03 +053012750/**
12751 * hdd_update_pmo_config - API to update pmo configuration parameters
12752 * @hdd_ctx: HDD context
12753 *
12754 * Return: void
12755 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012756static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012757{
Mukul Sharma9d797a02017-01-05 20:26:03 +053012758 struct pmo_psoc_cfg psoc_cfg;
12759 QDF_STATUS status;
12760
12761 /*
12762 * Value of hdd_ctx->wowEnable can be,
12763 * 0 - Disable both magic pattern match and pattern byte match.
12764 * 1 - Enable magic pattern match on all interfaces.
12765 * 2 - Enable pattern byte match on all interfaces.
12766 * 3 - Enable both magic patter and pattern byte match on
12767 * all interfaces.
12768 */
12769 psoc_cfg.magic_ptrn_enable =
12770 (hdd_ctx->config->wowEnable & 0x01) ? true : false;
12771 psoc_cfg.ptrn_match_enable_all_vdev =
12772 (hdd_ctx->config->wowEnable & 0x02) ? true : false;
Dustin Brownb9987af2018-03-01 17:15:11 -080012773 psoc_cfg.ptrn_id_per_vdev =
12774 wma_is_service_enabled(wmi_service_unified_wow_capability);
12775 psoc_cfg.apf_enable = hdd_ctx->config->bpf_packet_filter_enable;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012776 psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
Dustin Brown1224e212017-05-12 14:02:12 -070012777 psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode;
Dustin Brownb9987af2018-03-01 17:15:11 -080012778 psoc_cfg.ns_offload_enable_dynamic = hdd_ctx->config->fhostNSOffload;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012779 psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
Dustin Brownb9987af2018-03-01 17:15:11 -080012780 psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012781 psoc_cfg.ssdp = hdd_ctx->config->ssdp;
12782 psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
Dustin Brownb9987af2018-03-01 17:15:11 -080012783 psoc_cfg.active_mode_offload = hdd_ctx->config->active_mode_offload;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012784 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080012785 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Mukul Sharma9223f232017-03-08 18:42:27 +053012786 psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
12787 psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
12788 psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
Dustin Brownb9987af2018-03-01 17:15:11 -080012789 psoc_cfg.power_save_mode = hdd_ctx->config->enablePowersaveOffload;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +053012790 psoc_cfg.auto_power_save_fail_mode =
12791 hdd_ctx->config->auto_pwr_save_fail_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012792
12793 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053012794 hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx);
12795 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053012796
Dustin Brownb9987af2018-03-01 17:15:11 -080012797 status = ucfg_pmo_update_psoc_config(hdd_ctx->hdd_psoc, &psoc_cfg);
12798 if (QDF_IS_STATUS_ERROR(status))
12799 hdd_err("failed pmo psoc configuration; status:%d", status);
12800
12801 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053012802}
12803
Abhishek Singhb20db962017-03-03 21:28:46 +053012804#ifdef FEATURE_WLAN_SCAN_PNO
12805static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
12806 struct hdd_config *cfg)
12807{
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070012808 struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
12809
Abhishek Singhb20db962017-03-03 21:28:46 +053012810 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
12811 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
12812 pno_cfg->stationary_thresh = cfg->stationary_thresh;
12813 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
12814 pno_cfg->channel_prediction_full_scan =
12815 cfg->channel_prediction_full_scan;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070012816 mawc_cfg->enable = cfg->MAWCEnabled && cfg->mawc_nlo_enabled;
12817 mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
12818 mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
12819 mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
Abhishek Singhb20db962017-03-03 21:28:46 +053012820}
12821#else
12822static inline void
12823hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Jeff Johnson33a07922017-10-05 09:08:46 -070012824 struct hdd_config *cfg)
Abhishek Singhb20db962017-03-03 21:28:46 +053012825{
Abhishek Singhb20db962017-03-03 21:28:46 +053012826}
12827#endif
12828
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053012829void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
12830 struct hdd_config *cfg)
12831{
12832 uint8_t i = 0;
12833
12834 ie_whitelist->white_list = cfg->probe_req_ie_whitelist;
12835 if (!ie_whitelist->white_list)
12836 return;
12837
12838 ie_whitelist->ie_bitmap[0] = cfg->probe_req_ie_bitmap_0;
12839 ie_whitelist->ie_bitmap[1] = cfg->probe_req_ie_bitmap_1;
12840 ie_whitelist->ie_bitmap[2] = cfg->probe_req_ie_bitmap_2;
12841 ie_whitelist->ie_bitmap[3] = cfg->probe_req_ie_bitmap_3;
12842 ie_whitelist->ie_bitmap[4] = cfg->probe_req_ie_bitmap_4;
12843 ie_whitelist->ie_bitmap[5] = cfg->probe_req_ie_bitmap_5;
12844 ie_whitelist->ie_bitmap[6] = cfg->probe_req_ie_bitmap_6;
12845 ie_whitelist->ie_bitmap[7] = cfg->probe_req_ie_bitmap_7;
12846
12847 ie_whitelist->num_vendor_oui = cfg->no_of_probe_req_ouis;
12848 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
12849 ie_whitelist->voui[i] = cfg->probe_req_voui[i];
12850}
12851
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053012852uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
12853{
12854 uint8_t i, score;
12855
12856 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
12857 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
12858 if (score > MAX_INDEX_SCORE)
12859 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
12860 MAX_INDEX_SCORE, i);
12861 }
12862
12863 return per_index_score;
12864}
12865
12866/**
12867 * hdd_update_score_config - API to update candidate scoring related params
12868 * configuration parameters
12869 * @score_config: score config to update
12870 * @cfg: config params
12871 *
12872 * Return: 0 if success else err
12873 */
12874static void hdd_update_score_config(
12875 struct scoring_config *score_config, struct hdd_config *cfg)
12876{
12877 int total_weight;
12878
12879 score_config->weight_cfg.rssi_weightage = cfg->rssi_weightage;
12880 score_config->weight_cfg.ht_caps_weightage = cfg->ht_caps_weightage;
12881 score_config->weight_cfg.vht_caps_weightage =
12882 cfg->vht_caps_weightage;
12883 score_config->weight_cfg.he_caps_weightage =
12884 cfg->he_caps_weightage;
12885 score_config->weight_cfg.chan_width_weightage =
12886 cfg->chan_width_weightage;
12887 score_config->weight_cfg.chan_band_weightage =
12888 cfg->chan_band_weightage;
12889 score_config->weight_cfg.nss_weightage = cfg->nss_weightage;
12890 score_config->weight_cfg.beamforming_cap_weightage =
12891 cfg->beamforming_cap_weightage;
12892 score_config->weight_cfg.pcl_weightage = cfg->pcl_weightage;
12893 score_config->weight_cfg.channel_congestion_weightage =
12894 cfg->channel_congestion_weightage;
12895 score_config->weight_cfg.oce_wan_weightage = cfg->oce_wan_weightage;
12896
12897 total_weight = score_config->weight_cfg.rssi_weightage +
12898 score_config->weight_cfg.ht_caps_weightage +
12899 score_config->weight_cfg.vht_caps_weightage +
12900 score_config->weight_cfg.he_caps_weightage +
12901 score_config->weight_cfg.chan_width_weightage +
12902 score_config->weight_cfg.chan_band_weightage +
12903 score_config->weight_cfg.nss_weightage +
12904 score_config->weight_cfg.beamforming_cap_weightage +
12905 score_config->weight_cfg.pcl_weightage +
12906 score_config->weight_cfg.channel_congestion_weightage +
12907 score_config->weight_cfg.oce_wan_weightage;
12908
12909 if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
12910 hdd_err("total weight is greater than %d fallback to default values",
12911 BEST_CANDIDATE_MAX_WEIGHT);
12912
12913 score_config->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE;
12914 score_config->weight_cfg.ht_caps_weightage =
12915 HT_CAPABILITY_WEIGHTAGE;
12916 score_config->weight_cfg.vht_caps_weightage = VHT_CAP_WEIGHTAGE;
12917 score_config->weight_cfg.he_caps_weightage = HE_CAP_WEIGHTAGE;
12918 score_config->weight_cfg.chan_width_weightage =
12919 CHAN_WIDTH_WEIGHTAGE;
12920 score_config->weight_cfg.chan_band_weightage =
12921 CHAN_BAND_WEIGHTAGE;
12922 score_config->weight_cfg.nss_weightage = NSS_WEIGHTAGE;
12923 score_config->weight_cfg.beamforming_cap_weightage =
12924 BEAMFORMING_CAP_WEIGHTAGE;
12925 score_config->weight_cfg.pcl_weightage = PCL_WEIGHT;
12926 score_config->weight_cfg.channel_congestion_weightage =
12927 CHANNEL_CONGESTION_WEIGHTAGE;
12928 score_config->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
12929 }
12930
12931 score_config->bandwidth_weight_per_index =
12932 hdd_limit_max_per_index_score(
12933 cfg->bandwidth_weight_per_index);
12934 score_config->nss_weight_per_index =
12935 hdd_limit_max_per_index_score(cfg->nss_weight_per_index);
12936 score_config->band_weight_per_index =
12937 hdd_limit_max_per_index_score(cfg->band_weight_per_index);
12938
12939 score_config->rssi_score.best_rssi_threshold =
12940 cfg->best_rssi_threshold;
12941 score_config->rssi_score.good_rssi_threshold =
12942 cfg->good_rssi_threshold;
12943 score_config->rssi_score.bad_rssi_threshold =
12944 cfg->bad_rssi_threshold;
12945 score_config->rssi_score.good_rssi_pcnt = cfg->good_rssi_pcnt;
12946 score_config->rssi_score.bad_rssi_pcnt = cfg->bad_rssi_pcnt;
12947 score_config->rssi_score.good_rssi_bucket_size =
12948 cfg->good_rssi_bucket_size;
12949 score_config->rssi_score.bad_rssi_bucket_size =
12950 cfg->bad_rssi_bucket_size;
12951 score_config->rssi_score.rssi_pref_5g_rssi_thresh =
12952 cfg->rssi_pref_5g_rssi_thresh;
12953
12954 score_config->esp_qbss_scoring.num_slot = cfg->num_esp_qbss_slots;
12955 score_config->esp_qbss_scoring.score_pcnt3_to_0 =
12956 hdd_limit_max_per_index_score(
12957 cfg->esp_qbss_score_slots3_to_0);
12958 score_config->esp_qbss_scoring.score_pcnt7_to_4 =
12959 hdd_limit_max_per_index_score(
12960 cfg->esp_qbss_score_slots7_to_4);
12961 score_config->esp_qbss_scoring.score_pcnt11_to_8 =
12962 hdd_limit_max_per_index_score(
12963 cfg->esp_qbss_score_slots11_to_8);
12964 score_config->esp_qbss_scoring.score_pcnt15_to_12 =
12965 hdd_limit_max_per_index_score(
12966 cfg->esp_qbss_score_slots15_to_12);
12967
12968 score_config->oce_wan_scoring.num_slot = cfg->num_oce_wan_slots;
12969 score_config->oce_wan_scoring.score_pcnt3_to_0 =
12970 hdd_limit_max_per_index_score(
12971 cfg->oce_wan_score_slots3_to_0);
12972 score_config->oce_wan_scoring.score_pcnt7_to_4 =
12973 hdd_limit_max_per_index_score(
12974 cfg->oce_wan_score_slots7_to_4);
12975 score_config->oce_wan_scoring.score_pcnt11_to_8 =
12976 hdd_limit_max_per_index_score(
12977 cfg->oce_wan_score_slots11_to_8);
12978 score_config->oce_wan_scoring.score_pcnt15_to_12 =
12979 hdd_limit_max_per_index_score(
12980 cfg->oce_wan_score_slots15_to_12);
12981
12982
12983 score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
12984 score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
12985 score_config->nss = cfg->enable2x2 ? 2 : 1;
12986
12987 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
12988 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
12989 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
12990 score_config->he_cap = 1;
12991
12992 if (score_config->he_cap ||
12993 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
12994 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
12995 score_config->vht_cap = 1;
12996
12997 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
12998 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
12999 score_config->ht_cap = 1;
13000
13001 if (score_config->vht_cap && cfg->enableVhtFor24GHzBand)
13002 score_config->vht_24G_cap = 1;
13003
13004 if (cfg->enableTxBF)
13005 score_config->beamformee_cap = 1;
13006
13007}
13008
Abhishek Singh257a9482017-03-06 16:52:39 +053013009/**
bings81fe50a2017-11-27 14:33:26 +080013010 * hdd_update_dfs_config() - API to update dfs configuration parameters.
13011 * @hdd_ctx: HDD context
13012 *
13013 * Return: 0 if success else err
13014 */
13015static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
13016{
13017 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
13018 struct hdd_config *cfg = hdd_ctx->config;
13019 struct dfs_user_config dfs_cfg;
13020 QDF_STATUS status;
13021
13022 dfs_cfg.dfs_is_phyerr_filter_offload = !!cfg->fDfsPhyerrFilterOffload;
13023 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
13024 if (QDF_IS_STATUS_ERROR(status)) {
13025 hdd_err("failed dfs psoc configuration");
13026 return -EINVAL;
13027 }
13028
13029 return 0;
13030}
13031
13032/**
Abhishek Singh257a9482017-03-06 16:52:39 +053013033 * hdd_update_scan_config - API to update scan configuration parameters
13034 * @hdd_ctx: HDD context
13035 *
13036 * Return: 0 if success else err
13037 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013038static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053013039{
13040 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
13041 struct scan_user_cfg scan_cfg;
13042 struct hdd_config *cfg = hdd_ctx->config;
13043 QDF_STATUS status;
13044
13045 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
13046 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
13047 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
13048 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
13049 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
13050 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
13051 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053013052 /* convert to ms */
13053 scan_cfg.scan_cache_aging_time =
13054 cfg->scanAgingTimeout * 1000;
13055 scan_cfg.prefer_5ghz = cfg->nRoamPrefer5GHz;
13056 scan_cfg.select_5ghz_margin = cfg->nSelect5GHzMargin;
13057 scan_cfg.scan_bucket_threshold = cfg->first_scan_bucket_threshold;
13058 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053013059 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053013060 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Jeff Johnson81c00d02017-11-07 12:34:36 -080013061 scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
13062 scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
Abhishek Singhb58164a2017-07-19 18:47:23 +053013063 scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
Kiran Kumar Lokered547fdd2017-09-13 17:20:55 -070013064 scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
Abhishek Singhc87bb042018-01-30 17:10:42 +053013065 scan_cfg.sta_miracast_mcc_rest_time =
13066 cfg->sta_miracast_mcc_rest_time_val;
Abhishek Singh257a9482017-03-06 16:52:39 +053013067
Abhishek Singhb20db962017-03-03 21:28:46 +053013068 hdd_update_pno_config(&scan_cfg.pno_cfg, cfg);
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053013069 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, cfg);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053013070 hdd_update_score_config(&scan_cfg.score_config, cfg);
Abhishek Singhb20db962017-03-03 21:28:46 +053013071
Abhishek Singh257a9482017-03-06 16:52:39 +053013072 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
13073 if (status != QDF_STATUS_SUCCESS) {
13074 hdd_err("failed pmo psoc configuration");
13075 return -EINVAL;
13076 }
13077
13078 return 0;
13079}
Abhishek Singh257a9482017-03-06 16:52:39 +053013080
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013081int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053013082{
13083 int ret;
13084
13085 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053013086 if (ret)
13087 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013088
Abhishek Singh257a9482017-03-06 16:52:39 +053013089 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080013090 if (ret)
13091 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013092
Frank Liud4b2fa02017-03-29 11:46:48 +080013093 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070013094 if (ret)
13095 return ret;
13096
13097 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080013098 if (ret)
13099 return ret;
13100
13101 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053013102
13103 return ret;
13104}
13105
Agrawal Ashish65634612016-08-18 13:24:32 +053013106/**
13107 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
13108 * @mode : cfg80211 DFS mode
13109 *
13110 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
13111 */
13112enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
13113{
13114 switch (mode) {
13115 case DFS_MODE_ENABLE:
13116 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013117 case DFS_MODE_DISABLE:
13118 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013119 case DFS_MODE_DEPRIORITIZE:
13120 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013121 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013122 hdd_debug("ACS dfs mode is NONE");
13123 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053013124 }
13125}
13126
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013127/**
13128 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
13129 * @hddctx: pointer to hdd context
13130 * @set_value: enable/disable
13131 *
13132 * When Host sends vendor command enable, FW will send *ONE* CA ind to
13133 * Host(even though it is duplicate). When Host send vendor command
13134 * disable,FW doesn't perform any action. Whenever any change in
13135 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
13136 *
13137 * return - 0 on success, appropriate error values on failure.
13138 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013139int hdd_enable_disable_ca_event(struct hdd_context *hddctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013140{
13141 QDF_STATUS status;
13142
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013143 if (0 != wlan_hdd_validate_context(hddctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013144 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053013145
13146 if (!hddctx->config->goptimize_chan_avoid_event) {
13147 hdd_warn("goptimize_chan_avoid_event ini param disabled");
13148 return -EINVAL;
13149 }
13150
13151 status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
13152 if (!QDF_IS_STATUS_SUCCESS(status)) {
13153 hdd_err("Failed to send chan avoid command to SME");
13154 return -EINVAL;
13155 }
13156 return 0;
13157}
Agrawal Ashish65634612016-08-18 13:24:32 +053013158
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013159/**
13160 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
13161 * @value: value to set
13162 *
13163 * This function will set the passed value to roaming in progress flag.
13164 *
13165 * Return: None
13166 */
13167void hdd_set_roaming_in_progress(bool value)
13168{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013169 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013170
13171 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13172 if (!hdd_ctx) {
13173 hdd_err("HDD context is NULL");
13174 return;
13175 }
13176
13177 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013178 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013179}
13180
13181/**
13182 * hdd_is_roaming_in_progress() - check if roaming is in progress
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013183 * @adapter - HDD adapter
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013184 *
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013185 * Return: true if roaming is in progress for STA type, else false
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013186 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013187bool hdd_is_roaming_in_progress(struct hdd_adapter *adapter)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013188{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013189 struct hdd_context *hdd_ctx;
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013190 bool ret_status = false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013191
13192 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13193 if (!hdd_ctx) {
13194 hdd_err("HDD context is NULL");
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013195 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013196 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013197 hdd_debug("dev mode = %d, roaming_in_progress = %d",
13198 adapter->device_mode, hdd_ctx->roaming_in_progress);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080013199 ret_status = ((adapter->device_mode == QDF_STA_MODE) &&
13200 hdd_ctx->roaming_in_progress);
13201
13202 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080013203}
13204
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013205/**
13206 * hdd_is_connection_in_progress() - check if connection is in
13207 * progress
13208 * @session_id: session id
13209 * @reason: scan reject reason
13210 *
13211 * Go through each adapter and check if Connection is in progress
13212 *
13213 * Return: true if connection is in progress else false
13214 */
13215bool hdd_is_connection_in_progress(uint8_t *session_id,
13216 enum scan_reject_states *reason)
13217{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070013218 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070013219 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013220 uint8_t sta_id = 0;
13221 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013222 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013223
13224 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13225 if (!hdd_ctx) {
13226 hdd_err("HDD context is NULL");
13227 return false;
13228 }
13229
Dustin Brown920397d2017-12-13 16:27:50 -080013230 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013231 hdd_info("Adapter with device mode %s(%d) exists",
13232 hdd_device_mode_to_string(adapter->device_mode),
13233 adapter->device_mode);
13234 if (((QDF_STA_MODE == adapter->device_mode)
13235 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
13236 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
13237 && (eConnectionState_Connecting ==
13238 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
13239 conn_info.connState)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013240 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013241 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013242 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013243 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013244 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013245 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013246 }
13247 return true;
13248 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070013249 /*
13250 * sme_neighbor_middle_of_roaming is for LFR2
13251 * hdd_is_roaming_in_progress is for LFR3
13252 */
13253 if (((QDF_STA_MODE == adapter->device_mode) &&
13254 sme_neighbor_middle_of_roaming(
13255 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013256 adapter->session_id)) ||
Archana Ramachandran62886ce2017-03-24 14:46:32 -070013257 hdd_is_roaming_in_progress(adapter)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013258 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013259 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070013260 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013261 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013262 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013263 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013264 }
13265 return true;
13266 }
13267 if ((QDF_STA_MODE == adapter->device_mode) ||
13268 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
13269 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
13270 hdd_sta_ctx =
13271 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
13272 if ((eConnectionState_Associated ==
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053013273 hdd_sta_ctx->conn_info.connState)
13274 && sme_is_sta_key_exchange_in_progress(
13275 hdd_ctx->hHal, adapter->session_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013276 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070013277 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013278 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013279 " is in middle of WPS/EAPOL exchange.",
13280 MAC_ADDR_ARRAY(sta_mac));
13281 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013282 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013283 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013284 }
13285 return true;
13286 }
13287 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
13288 (QDF_P2P_GO_MODE == adapter->device_mode)) {
13289 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
13290 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013291 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013292 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013293 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013294 continue;
13295
13296 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070013297 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070013298 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013299 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013300 " of SAP/GO is in middle of WPS/EAPOL exchange",
13301 MAC_ADDR_ARRAY(sta_mac));
13302 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070013303 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013304 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013305 }
13306 return true;
13307 }
13308 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053013309 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013310 return true;
13311 }
13312 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013313 }
Dustin Brown920397d2017-12-13 16:27:50 -080013314
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013315 return false;
13316}
13317
13318/**
13319 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070013320 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013321 *
13322 * Return: None
13323 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013324void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013325{
Jeff Johnson87251032017-08-29 13:31:11 -070013326 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013327 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013328 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013329 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013330 tsap_Config_t *sap_config;
13331 void *sap_ctx;
13332
13333 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070013334 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013335 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013336
13337 mutex_lock(&hdd_ctx->sap_lock);
13338 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
13339 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013340 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
13341 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
13342 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
13343 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053013344 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013345 qdf_stop_bss_event,
13346 SME_CMD_TIMEOUT_VALUE);
13347
13348 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013349 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013350 goto end;
13351 }
13352 }
13353 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013354 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -070013355 ap_adapter->device_mode, ap_adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013356 hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
13357 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070013358 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013359
13360 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013361 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013362 wlansap_reset_sap_config_add_ie(sap_config,
13363 eUPDATE_IE_ALL);
13364 goto end;
13365 }
13366
13367 qdf_event_reset(&hostapd_state->qdf_event);
13368 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
13369 sap_config,
13370 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013371 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013372 wlansap_reset_sap_config_add_ie(sap_config,
13373 eUPDATE_IE_ALL);
13374 goto end;
13375 }
13376
Jeff Johnson6867ec32017-09-29 20:30:20 -070013377 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013378 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053013379 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013380 SME_CMD_TIMEOUT_VALUE);
13381 wlansap_reset_sap_config_add_ie(sap_config,
13382 eUPDATE_IE_ALL);
13383 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013384 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013385 goto end;
13386 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070013387 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013388 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013389 if (hostapd_state->bss_state == BSS_START) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013390 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
13391 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070013392 ap_adapter->session_id);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013393 hdd_start_green_ap_state_mc(hdd_ctx,
13394 ap_adapter->device_mode,
13395 true);
13396 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013397 }
13398end:
13399 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013400}
13401
13402/**
13403 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
13404 * with non dfs acs
13405 *
13406 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
13407 *
13408 * Return: None
13409 */
13410void hdd_check_and_restart_sap_with_non_dfs_acs(void)
13411{
Jeff Johnson9d295242017-08-29 14:39:48 -070013412 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013413 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013414 cds_context_type *cds_ctx;
13415
13416 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13417 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013418 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013419 return;
13420 }
13421
13422 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
13423 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013424 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013425 return;
13426 }
13427
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013428 if (policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc)
13429 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013430 hdd_info("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013431 return;
13432 }
13433
13434 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070013435 if (ap_adapter != NULL && test_bit(SOFTAP_BSS_STARTED,
13436 &ap_adapter->event_flags) &&
13437 wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Jeff Johnsonb9424862017-10-30 08:49:35 -070013438 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013439
Jeff Johnson6867ec32017-09-29 20:30:20 -070013440 hdd_warn("STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS");
Jeff Johnsonb9424862017-10-30 08:49:35 -070013441 ap_adapter->session.ap.sap_config.channel =
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013442 AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -070013443 ap_adapter->session.ap.sap_config.
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013444 acs_cfg.acs_mode = true;
13445
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013446 hdd_restart_sap(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013447 }
13448}
13449
13450/**
13451 * hdd_set_connection_in_progress() - to set the connection in
13452 * progress flag
13453 * @value: value to set
13454 *
13455 * This function will set the passed value to connection in progress flag.
13456 * If value is previously being set to true then no need to set it again.
13457 *
13458 * Return: true if value is being set correctly and false otherwise.
13459 */
13460bool hdd_set_connection_in_progress(bool value)
13461{
13462 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013463 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013464
13465 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13466 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013467 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013468 return false;
13469 }
13470
13471 qdf_spin_lock(&hdd_ctx->connection_status_lock);
13472 /*
13473 * if the value is set to true previously and if someone is
13474 * trying to make it true again then it could be some race
13475 * condition being triggered. Avoid this situation by returning
13476 * false
13477 */
13478 if (hdd_ctx->connection_in_progress && value)
13479 status = false;
13480 else
13481 hdd_ctx->connection_in_progress = value;
13482 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
13483 return status;
13484}
13485
Jeff Johnson9d295242017-08-29 14:39:48 -070013486int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013487{
13488 if (!adapter) {
13489 hdd_err("Invalid adapter");
13490 return -EINVAL;
13491 }
13492 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013493 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013494 WMA_VDEV_MCC_SET_TIME_QUOTA,
13495 set_value, VDEV_CMD);
13496 return 0;
13497
13498}
13499
Jeff Johnson9d295242017-08-29 14:39:48 -070013500int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013501{
13502 if (!adapter) {
13503 hdd_err("Invalid adapter");
13504 return -EINVAL;
13505 }
13506
13507 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013508 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013509 WMA_VDEV_MCC_SET_TIME_LATENCY,
13510 set_value, VDEV_CMD);
13511 return 0;
13512}
13513
Jeff Johnson9d295242017-08-29 14:39:48 -070013514struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013515 *psoc, uint8_t vdev_id)
13516{
Jeff Johnson9d295242017-08-29 14:39:48 -070013517 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013518 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013519
13520 /*
13521 * Currently PSOC is not being used. But this logic will
13522 * change once we have the converged implementation of
13523 * HDD context per PSOC in place. This would break if
13524 * multiple vdev objects reuse the vdev id.
13525 */
13526 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
13527 if (!adapter)
13528 hdd_err("Get adapter by vdev id failed");
13529
13530 return adapter;
13531}
13532
Jeff Johnson9d295242017-08-29 14:39:48 -070013533int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013534 int8_t *rssi, int8_t *snr)
13535{
13536 QDF_STATUS status;
Jeff Johnson025618c2018-03-18 14:41:00 -070013537 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013538
Jeff Johnson025618c2018-03-18 14:41:00 -070013539 roam_profile = hdd_roam_profile(adapter);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013540 status = sme_get_rssi_snr_by_bssid(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson025618c2018-03-18 14:41:00 -070013541 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013542 if (QDF_STATUS_SUCCESS != status) {
13543 hdd_warn("sme_get_rssi_snr_by_bssid failed");
13544 return -EINVAL;
13545 }
13546
13547 return 0;
13548}
13549
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013550/**
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013551 * hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
13552 * @adapter - HDD adapter
13553 * @tos - type of service
13554 * @status - status of the traffic
13555 *
13556 * Return: 0 on success and non zero value on failure
13557 */
13558
13559int hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter, enum tos tos,
13560 bool is_tos_active)
13561{
13562 int ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013563 struct hdd_context *hdd_ctx;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013564 uint32_t max_off_chan_time = 0;
13565 QDF_STATUS status;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013566 int ret;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013567 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013568
13569 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13570 ret = wlan_hdd_validate_context(hdd_ctx);
13571
13572 if (ret < 0) {
13573 hdd_err("failed to set limit off chan params");
13574 return ret;
13575 }
13576
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013577 ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
13578
13579 if (is_tos_active)
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013580 adapter->active_ac |= ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013581 else
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013582 adapter->active_ac &= ~ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013583
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013584 if (adapter->active_ac) {
13585 if (adapter->active_ac & HDD_AC_VO_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013586 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013587 limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
13588 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13589 PM_LATENCY);
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013590 } else if (adapter->active_ac & HDD_AC_VI_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013591 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013592 limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
13593 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13594 PM_LATENCY);
13595 } else {
13596 /*ignore this command if only BE/BK is active */
13597 is_tos_active = false;
13598 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13599 hdd_ctx->config->conc_system_pref);
13600 }
13601 } else {
13602 /* No active tos */
13603 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13604 hdd_ctx->config->conc_system_pref);
13605 }
13606
Jeff Johnson1b780e42017-10-31 14:11:45 -070013607 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013608 is_tos_active, max_off_chan_time,
13609 hdd_ctx->config->nRestTimeConc, true);
13610 if (!QDF_IS_STATUS_SUCCESS(status)) {
13611 hdd_err("failed to set limit off chan params");
13612 ret = -EINVAL;
13613 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013614
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013615 return ret;
13616}
13617
13618/**
13619 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
13620 * @adapter - HDD adapter
13621 *
13622 * Return: 0 on success and non zero value on failure
13623 */
13624int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
13625{
13626 struct hdd_context *hdd_ctx;
13627 int ret;
13628 QDF_STATUS status;
13629 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
13630
13631 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13632 ret = wlan_hdd_validate_context(hdd_ctx);
13633 if (ret < 0)
13634 return ret;
13635
13636 /* set the system preferece to default */
13637 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13638 hdd_ctx->config->conc_system_pref);
13639
13640 /* clear the bitmap */
13641 adapter->active_ac = 0;
13642
13643 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson1b780e42017-10-31 14:11:45 -070013644 adapter->session_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013645
Jeff Johnson1b780e42017-10-31 14:11:45 -070013646 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013647 false, 0, 0, false);
13648 if (!QDF_IS_STATUS_SUCCESS(status)) {
13649 hdd_err("failed to reset limit off chan params");
13650 ret = -EINVAL;
13651 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013652
13653 return ret;
13654}
13655
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013656/**
13657 * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
13658 * @drv_op: Enum indicating driver op
13659 *
13660 * Return: none
13661 */
13662void hdd_start_driver_ops_timer(int drv_op)
13663{
13664 memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
13665 switch (drv_op) {
13666 case eHDD_DRV_OP_PROBE:
13667 memcpy(drv_ops_string, "probe", sizeof("probe"));
13668 break;
13669 case eHDD_DRV_OP_REMOVE:
13670 memcpy(drv_ops_string, "remove", sizeof("remove"));
13671 break;
13672 case eHDD_DRV_OP_SHUTDOWN:
13673 memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
13674 break;
13675 case eHDD_DRV_OP_REINIT:
13676 memcpy(drv_ops_string, "reinit", sizeof("reinit"));
13677 break;
Arunk Khandavallie9ef42a2017-10-04 14:49:51 +053013678 case eHDD_DRV_OP_IFF_UP:
13679 memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
13680 break;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013681 }
13682
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013683 hdd_drv_ops_task = current;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013684 qdf_timer_start(&hdd_drv_ops_inactivity_timer,
13685 HDD_OPS_INACTIVITY_TIMEOUT);
13686}
13687
13688/**
13689 * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
13690 *
13691 * Return: none
13692 */
13693void hdd_stop_driver_ops_timer(void)
13694{
13695 qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
13696}
13697
13698/**
13699 * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
13700 * inactivity timer
13701 *
13702 * Return: None
13703 */
13704void hdd_drv_ops_inactivity_handler(void)
13705{
13706 hdd_err("%s: %d Sec timer expired while in .%s",
13707 __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
13708
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013709 if (hdd_drv_ops_task) {
13710 printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
13711 qdf_print_thread_trace(hdd_drv_ops_task);
13712 } else {
13713 hdd_err("hdd_drv_ops_task is null");
13714 }
13715
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013716 /* Driver shutdown is stuck, no recovery possible at this point */
13717 if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
13718 sizeof("shutdown")))
13719 QDF_BUG(0);
13720
Rajeev Kumar1e57b9c2018-01-04 16:17:10 -080013721 if (cds_is_fw_down()) {
13722 hdd_err("FW is down");
13723 return;
13724 }
13725
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013726 if (cds_is_self_recovery_enabled())
Anurag Chouhan4085ff72017-10-05 18:09:56 +053013727 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013728 else
13729 QDF_BUG(0);
13730}
13731
Sravan Kumar Kairamd80c7662017-10-03 16:11:05 +053013732void hdd_pld_ipa_uc_shutdown_pipes(void)
13733{
13734 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13735
13736 if (!hdd_ctx)
13737 return;
13738
13739 hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
13740}
13741
Yun Parkff6a16a2017-09-26 16:38:18 -070013742/**
13743 * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
13744 * @struct hdd_context *hdd_ctx
13745 * @struct hdd_adapter *padapter
13746 * @bool enble
13747 *
13748 * Return: none
13749 */
13750void hdd_set_rx_mode_rps(bool enable)
13751{
13752 struct cds_config_info *cds_cfg = cds_get_ini_config();
13753 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13754 struct hdd_adapter *adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
13755
13756 if (adapter && hdd_ctx &&
13757 !hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
13758 if (enable && !cds_cfg->rps_enabled)
13759 hdd_send_rps_ind(adapter);
13760 else if (!enable && cds_cfg->rps_enabled)
13761 hdd_send_rps_disable_ind(adapter);
13762 }
13763}
13764
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +053013765bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx)
13766{
13767 struct hdd_adapter *adapter = NULL;
13768
13769 hdd_for_each_adapter(hdd_ctx, adapter) {
13770 if ((adapter->device_mode == QDF_STA_MODE ||
13771 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
13772 qdf_atomic_test_bit(DEVICE_IFACE_OPENED,
13773 &adapter->event_flags)){
13774 return true;
13775 }
13776 }
13777
13778 return false;
13779}
13780
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013781/* Register the module init/exit functions */
13782module_init(hdd_module_init);
13783module_exit(hdd_module_exit);
13784
13785MODULE_LICENSE("Dual BSD/GPL");
13786MODULE_AUTHOR("Qualcomm Atheros, Inc.");
13787MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
13788
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013789module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
13790 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013791
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013792module_param_call(con_mode_ftm, con_mode_handler_ftm, param_get_int,
13793 &con_mode_ftm, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13794
Ravi Joshia307f632017-07-17 23:41:41 -070013795module_param_call(con_mode_monitor, con_mode_handler_monitor, param_get_int,
13796 &con_mode_monitor, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13797
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013798module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
13799 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13800
13801module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
13802
13803module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
13804
13805module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);