blob: 41d3563dc47e8879c8e789ce3b6d68b5bb1f2659 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Jeff Johnsond9f08602016-12-02 11:31:30 -08002 * Copyright (c) 2012-2017 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"
Anurag Chouhan6d760662016-02-20 16:05:43 +053058#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053059#include "qdf_trace.h"
Dustin Brown4bc0a622017-12-06 15:56:50 -080060#include "qdf_debug_domain.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070061#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080062#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070063#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064
65#include <net/addrconf.h>
66#include <linux/wireless.h>
67#include <net/cfg80211.h>
68#include <linux/inetdevice.h>
69#include <net/addrconf.h>
70#include "wlan_hdd_cfg80211.h"
71#include "wlan_hdd_ext_scan.h"
72#include "wlan_hdd_p2p.h"
73#include <linux/rtnetlink.h>
74#include "sap_api.h"
75#include <linux/semaphore.h>
76#include <linux/ctype.h>
77#include <linux/compat.h>
78#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079#include <soc/qcom/subsystem_restart.h>
80#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081#include <wlan_hdd_hostapd.h>
82#include <wlan_hdd_softap_tx_rx.h>
83#include "cfg_api.h"
84#include "qwlan_version.h"
85#include "wma_types.h"
86#include "wlan_hdd_tdls.h"
87#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053088#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070090#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070091#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080092#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093#include "wlan_hdd_nan.h"
94#include "wlan_hdd_debugfs.h"
95#include "wlan_hdd_driver_ops.h"
96#include "epping_main.h"
97#include "wlan_hdd_memdump.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +053098#include "wlan_hdd_data_stall_detection.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099
100#include <wlan_hdd_ipa.h>
101#include "hif.h"
102#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800103#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700104#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105#include "wlan_hdd_green_ap.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530106#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700107#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700108#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530109#include "nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700110#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530111#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800112#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800113#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530114#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800115#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800116#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530117#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530118#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800119#include "os_if_wifi_pos.h"
120#include "wifi_pos_api.h"
121#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800122#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700123#include "os_if_nan.h"
124#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700125#include "wlan_reg_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700126#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530127#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530128#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700129#include <cdp_txrx_cmn_struct.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800130#include "wlan_hdd_sysfs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800131
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530132#ifdef CNSS_GENL
133#include <net/cnss_nl.h>
134#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800135#include "wlan_reg_ucfg_api.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530136
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137#ifdef MODULE
138#define WLAN_MODULE_NAME module_name(THIS_MODULE)
139#else
140#define WLAN_MODULE_NAME "wlan"
141#endif
142
143#ifdef TIMER_MANAGER
144#define TIMER_MANAGER_STR " +TIMER_MANAGER"
145#else
146#define TIMER_MANAGER_STR ""
147#endif
148
149#ifdef MEMORY_DEBUG
150#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
151#else
152#define MEMORY_DEBUG_STR ""
153#endif
154
Sachin Ahujadddd2632017-03-07 19:07:24 +0530155int wlan_start_ret_val;
156static DECLARE_COMPLETION(wlan_start_comp);
157static unsigned int dev_num = 1;
158static struct cdev wlan_hdd_state_cdev;
159static struct class *class;
160static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530161#ifndef MODULE
162static struct gwlan_loader *wlan_loader;
163static ssize_t wlan_boot_cb(struct kobject *kobj,
164 struct kobj_attribute *attr,
165 const char *buf, size_t count);
166struct gwlan_loader {
167 bool loaded_state;
168 struct kobject *boot_wlan_obj;
169 struct attribute_group *attr_group;
170};
171
172static struct kobj_attribute wlan_boot_attribute =
173 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
174
175static struct attribute *attrs[] = {
176 &wlan_boot_attribute.attr,
177 NULL,
178};
179
180#define MODULE_INITIALIZED 1
181#endif
182
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530183#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
184#define MAX_OPS_NAME_STRING_SIZE 20
185
186static qdf_timer_t hdd_drv_ops_inactivity_timer;
Dustin Brown45ed4bb2017-12-18 12:00:13 -0800187static struct task_struct *hdd_drv_ops_task;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530188static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
189
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800190/* the Android framework expects this param even though we don't use it */
191#define BUF_LEN 20
192static char fwpath_buffer[BUF_LEN];
193static struct kparam_string fwpath = {
194 .string = fwpath_buffer,
195 .maxlen = BUF_LEN,
196};
197
198static char *country_code;
199static int enable_11d = -1;
200static int enable_dfs_chan_scan = -1;
201
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202/*
203 * spinlock for synchronizing asynchronous request/response
204 * (full description of use in wlan_hdd_main.h)
205 */
206DEFINE_SPINLOCK(hdd_context_lock);
Arunk Khandavalli16d84252017-06-21 15:26:29 +0530207DEFINE_MUTEX(hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800209#define WLAN_NLINK_CESIUM 30
210
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530211static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212
213#define WOW_MAX_FILTER_LISTS 1
214#define WOW_MAX_FILTERS_PER_LIST 4
215#define WOW_MIN_PATTERN_SIZE 6
216#define WOW_MAX_PATTERN_SIZE 64
217
218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
219static const struct wiphy_wowlan_support wowlan_support_reg_init = {
220 .flags = WIPHY_WOWLAN_ANY |
221 WIPHY_WOWLAN_MAGIC_PKT |
222 WIPHY_WOWLAN_DISCONNECT |
223 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
224 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
225 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
226 WIPHY_WOWLAN_4WAY_HANDSHAKE |
227 WIPHY_WOWLAN_RFKILL_RELEASE,
228 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
229 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
230 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
231};
232#endif
233
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700234static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
235 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
236 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
237 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
238 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
239 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
240 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
241 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
242 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
243 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
244 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
245 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
246 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
247 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
248 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
249 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
250 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
251 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
252 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
253 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
254 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
255 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
256 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
257 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
258 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
259 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
260 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
261 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
262 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
263 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
264 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
265 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
266 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
267 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
268 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700269 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700270 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700271 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700272};
273
Ganesh Kondabattini35739572017-06-21 16:26:39 +0530274int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
275 { HDD_AC_BK_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BK },
276 { HDD_AC_BE_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_BE },
277 { HDD_AC_VI_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VI },
278 { HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
279};
280
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281/* internal function declaration */
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530282struct notifier_block hdd_netdev_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283
284struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700286static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800287#endif
288
Sachin Ahujadddd2632017-03-07 19:07:24 +0530289void hdd_start_complete(int ret)
290{
291 wlan_start_ret_val = ret;
292
293 complete(&wlan_start_comp);
294}
295
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800296/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530297 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700298 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530299 *
300 * Return: none
301 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700302static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530303{
Jeff Johnson9d295242017-08-29 14:39:48 -0700304 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530305
Dustin Brown920397d2017-12-13 16:27:50 -0800306 hdd_for_each_adapter(hdd_ctx, adapter)
307 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530308}
309
310/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
312 * @vdev_id: vdev_id
313 * @action: action type
314 * @reason: reason type
315 *
316 * Return: none
317 */
318void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
319 enum netif_action_type action, enum netif_reason_type reason)
320{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700321 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700322 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323
324 if (!hdd_ctx) {
325 hdd_err("hdd ctx is NULL");
326 return;
327 }
328 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
329
330 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331}
332
333/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700334 * Store WLAN driver version and timestamp info in global variables such that
335 * crash debugger can extract them from driver debug symbol and crashdump for
336 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800337 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800338#ifdef BUILD_TAG
339uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR "; " BUILD_TAG;
340#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;
Naveen Rawat93836252017-06-20 16:30:59 -0700342#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343
344/**
345 * hdd_device_mode_to_string() - return string conversion of device mode
346 * @device_mode: device mode
347 *
348 * This utility function helps log string conversion of device mode.
349 *
350 * Return: string conversion of device mode, if match found;
351 * "Unknown" otherwise.
352 */
353const char *hdd_device_mode_to_string(uint8_t device_mode)
354{
355 switch (device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -0800356 CASE_RETURN_STRING(QDF_STA_MODE);
357 CASE_RETURN_STRING(QDF_SAP_MODE);
358 CASE_RETURN_STRING(QDF_P2P_CLIENT_MODE);
359 CASE_RETURN_STRING(QDF_P2P_GO_MODE);
360 CASE_RETURN_STRING(QDF_FTM_MODE);
361 CASE_RETURN_STRING(QDF_IBSS_MODE);
362 CASE_RETURN_STRING(QDF_P2P_DEVICE_MODE);
363 CASE_RETURN_STRING(QDF_OCB_MODE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700364 CASE_RETURN_STRING(QDF_NDI_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800365 default:
366 return "Unknown";
367 }
368}
369
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530370/**
371 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
372 * @adapter: HDD adapter
373 * @chan_number: Channel number
374 * @chan_bw: Bandwidth
375 *
376 * Checks if the given bandwidth is valid for the given channel number.
377 *
378 * Return: 0 for success, non-zero for failure
379 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700380int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530381 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800382 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530383{
384 uint8_t chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
385 uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN, i;
386 bool found = false;
387 tHalHandle hal;
388
389 hal = WLAN_HDD_GET_HAL_CTX(adapter);
390 if (!hal) {
391 hdd_err("Invalid HAL context");
392 return -EINVAL;
393 }
394
395 if (0 != sme_cfg_get_str(hal, WNI_CFG_VALID_CHANNEL_LIST, chan, &len)) {
396 hdd_err("No valid channel list");
397 return -EOPNOTSUPP;
398 }
399
400 for (i = 0; i < len; i++) {
401 if (chan[i] == chan_number) {
402 found = true;
403 break;
404 }
405 }
406
407 if (found == false) {
408 hdd_err("Channel not in driver's valid channel list");
409 return -EOPNOTSUPP;
410 }
411
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700412 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
413 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530414 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
415 return -EINVAL;
416 }
417
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700418 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530419 if (chan_bw == CH_WIDTH_80MHZ) {
420 hdd_err("BW80 not possible in 2.4GHz band");
421 return -EINVAL;
422 }
423 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
424 (chan_bw != CH_WIDTH_MAX)) {
425 hdd_err("Only BW20 possible on channel 14");
426 return -EINVAL;
427 }
428 }
429
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700430 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530431 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
432 (chan_bw != CH_WIDTH_MAX)) {
433 hdd_err("Only BW20 possible on channel 165");
434 return -EINVAL;
435 }
436 }
437
438 return 0;
439}
440
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530441/**
442 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
443 *
444 * Block the unloading of the driver (or) interface up until the
445 * cds recovery is completed
446 *
447 * Return: true for recovery completion else false
448 */
449static bool hdd_wait_for_recovery_completion(void)
450{
451 int retry = 0;
452
453 /* Wait for recovery to complete */
454 while (cds_is_driver_recovering()) {
455 if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
456 hdd_err("Recovery in progress; wait here!!!");
457 msleep(1000);
458 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
459 hdd_err("SSR never completed, error");
460 /*
461 * Trigger the bug_on in the internal builds, in the
462 * customer builds self-recovery will be enabled
463 * in those cases just return error.
464 */
465 if (cds_is_self_recovery_enabled())
466 return false;
467 QDF_BUG(0);
468 }
469 }
470
471 hdd_info("Recovery completed successfully!");
472 return true;
473}
474
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800475static int __hdd_netdev_notifier_call(struct notifier_block *nb,
476 unsigned long state, void *data)
477{
478#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
479 struct netdev_notifier_info *dev_notif_info = data;
480 struct net_device *dev = dev_notif_info->dev;
481#else
482 struct net_device *dev = data;
483#endif
Jeff Johnson9d295242017-08-29 14:39:48 -0700484 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700485 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800487 ENTER_DEV(dev);
488
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 /* Make sure that this callback corresponds to our device. */
490 if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
491 return NOTIFY_DONE;
492
Samuel Ahnc9c48ca2016-09-19 15:46:36 +0530493 if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494 (adapter->dev != dev)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700495 hdd_err("device adapter is not matching!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 return NOTIFY_DONE;
497 }
498
499 if (!dev->ieee80211_ptr) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700500 hdd_err("ieee80211_ptr is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800501 return NOTIFY_DONE;
502 }
503
504 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
505 if (NULL == hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800506 hdd_err("HDD Context Null Pointer");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530507 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 return NOTIFY_DONE;
509 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800510
511 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
512 hdd_err("%s: Driver module is closed", __func__);
513 return NOTIFY_DONE;
514 }
515
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530516 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state())
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 return NOTIFY_DONE;
518
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800519 hdd_debug("%s New Net Device State = %lu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 dev->name, state);
521
522 switch (state) {
523 case NETDEV_REGISTER:
524 break;
525
526 case NETDEV_UNREGISTER:
527 break;
528
529 case NETDEV_UP:
530 sme_ch_avoid_update_req(hdd_ctx->hHal);
531 break;
532
533 case NETDEV_DOWN:
534 break;
535
536 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700537 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538 complete(&adapter->linkup_event_var);
539 break;
540
541 case NETDEV_GOING_DOWN:
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700542 if (ucfg_scan_get_vdev_status(adapter->hdd_vdev) !=
543 SCAN_NOT_IN_PROGRESS) {
Abhishek Singh69ccb512017-04-25 11:58:16 +0530544 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -0700545 adapter->session_id, INVALID_SCAN_ID, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 } else {
hqueaa33ee2017-05-04 17:56:35 +0800547 cds_flush_work(&adapter->scan_block_work);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800548 hdd_debug("Scan is not Pending from user");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 }
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530550 /*
551 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
552 * of return status of hdd_stop call, kernel resets the IFF_UP
553 * flag after which driver does not send the cfg80211_scan_done.
554 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
555 */
556 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557 break;
558
559 default:
560 break;
561 }
562
563 return NOTIFY_DONE;
564}
565
566/**
567 * hdd_netdev_notifier_call() - netdev notifier callback function
568 * @nb: pointer to notifier block
569 * @state: state
570 * @ndev: ndev pointer
571 *
572 * Return: 0 on success, error number otherwise.
573 */
574static int hdd_netdev_notifier_call(struct notifier_block *nb,
575 unsigned long state,
576 void *ndev)
577{
578 int ret;
579
580 cds_ssr_protect(__func__);
581 ret = __hdd_netdev_notifier_call(nb, state, ndev);
582 cds_ssr_unprotect(__func__);
583
584 return ret;
585}
586
587struct notifier_block hdd_netdev_notifier = {
588 .notifier_call = hdd_netdev_notifier_call,
589};
590
591/* variable to hold the insmod parameters */
592static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800593
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530594static int con_mode_ftm;
Ravi Joshia307f632017-07-17 23:41:41 -0700595int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530596
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800597/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530600/**
601 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
602 * @ch_width: NL channel width
603 *
604 * Converts the NL channel width to the driver's internal representation
605 *
606 * Return: Converted channel width. In case of non matching NL channel width,
607 * CH_WIDTH_MAX will be returned.
608 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800609enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530610{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800611 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700612
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800613 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530614 switch (ch_width) {
615 case NL80211_CHAN_WIDTH_20_NOHT:
616 case NL80211_CHAN_WIDTH_20:
617 return CH_WIDTH_20MHZ;
618 case NL80211_CHAN_WIDTH_40:
619 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530620 case NL80211_CHAN_WIDTH_80:
621 return CH_WIDTH_80MHZ;
622 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800623 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
624 return CH_WIDTH_80P80MHZ;
625 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
626 return CH_WIDTH_160MHZ;
627 else
628 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530629 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800630 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
631 return CH_WIDTH_160MHZ;
632 else
633 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530634 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800635 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530636 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800637 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530638 default:
639 hdd_err("Invalid channel width %d, setting to default",
640 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800641 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530642 }
643}
644
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530645/* wlan_hdd_find_opclass() - Find operating class for a channel
646 * @hal: handler to HAL
647 * @channel: channel id
648 * @bw_offset: bandwidth offset
649 *
650 * Function invokes sme api to find the operating class
651 *
652 * Return: operating class
653 */
654uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
655 uint8_t bw_offset)
656{
657 uint8_t opclass = 0;
658
659 sme_get_opclass(hal, channel, bw_offset, &opclass);
660 return opclass;
661}
662
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530664 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530665 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 * @bitmask: Bitmask of log levels to be enabled
667 *
668 * Called immediately after the cfg.ini is read in order to configure
669 * the desired trace levels.
670 *
671 * Return: None
672 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530673int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530675 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530676 int qdf_print_idx = -1;
677 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 /*
679 * if the bitmask is the default value, then a bitmask was not
680 * specified in cfg.ini, so leave the logging level alone (it
681 * will remain at the "compiled in" default value)
682 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700683 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530684 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530686 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530688 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530689 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530690 QDF_TRACE_LEVEL_NONE, 0);
691
692 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530693 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +0530695 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 while (0 != bitmask) {
697 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530698 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530699 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530700 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530701 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700703
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 level++;
705 bitmask >>= 1;
706 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530707 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708}
709
710/**
Chris Guo1751acf2017-07-03 14:09:01 +0800711 * wlan_hdd_validate_context_in_loading() - check the HDD context in loading
712 * @hdd_ctx: HDD context pointer
713 *
714 * Return: 0 if the context is valid. Error code otherwise
715 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700716int wlan_hdd_validate_context_in_loading(struct hdd_context *hdd_ctx)
Chris Guo1751acf2017-07-03 14:09:01 +0800717{
718 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
719 hdd_info("%pS HDD context is Null", (void *)_RET_IP_);
720 return -ENODEV;
721 }
722
723 if (cds_is_driver_recovering()) {
724 hdd_info("%pS Recovery in Progress. State: 0x%x Ignore!!!",
725 (void *)_RET_IP_, cds_get_driver_state());
726 return -EAGAIN;
727 }
728
729 if (hdd_ctx->start_modules_in_progress ||
730 hdd_ctx->stop_modules_in_progress) {
731 hdd_info("%pS Start/Stop Modules in progress. Ignore!!!",
732 (void *)_RET_IP_);
733 return -EAGAIN;
734 }
735
736 return 0;
737}
738
739
740/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741 * wlan_hdd_validate_context() - check the HDD context
742 * @hdd_ctx: HDD context pointer
743 *
744 * Return: 0 if the context is valid. Error code otherwise
745 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700746int wlan_hdd_validate_context(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530749 hdd_err("%pS HDD context is Null", (void *)_RET_IP_);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750 return -ENODEV;
751 }
752
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800753 if (cds_is_driver_recovering()) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800754 hdd_debug("%pS Recovery in Progress. State: 0x%x Ignore!!!",
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530755 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 return -EAGAIN;
757 }
758
Yue Ma9f275d92017-09-14 16:58:41 -0700759 if (cds_is_load_or_unload_in_progress()) {
760 hdd_debug("%pS Load or unload in progress, state: 0x%x, ignore!",
761 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -0700763 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530764
765 if (hdd_ctx->start_modules_in_progress ||
766 hdd_ctx->stop_modules_in_progress) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800767 hdd_debug("%pS Start/Stop Modules in progress. Ignore!!!",
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530768 (void *)_RET_IP_);
769 return -EAGAIN;
770 }
771
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530772 if (cds_is_driver_in_bad_state()) {
773 hdd_debug("%pS driver in bad State: 0x%x Ignore!!!",
774 (void *)_RET_IP_, cds_get_driver_state());
775 return -ENODEV;
776 }
777
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 return 0;
779}
780
Jeff Johnson9d295242017-08-29 14:39:48 -0700781int hdd_validate_adapter(struct hdd_adapter *adapter)
Dustin Brownf13b8c32017-05-19 17:23:08 -0700782{
783 if (!adapter) {
784 hdd_err("adapter is null");
785 return -EINVAL;
786 }
787
788 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
789 hdd_err("bad adapter magic: 0x%x (should be 0x%x)",
790 adapter->magic, WLAN_HDD_ADAPTER_MAGIC);
791 return -EINVAL;
792 }
793
794 if (!adapter->dev) {
795 hdd_err("adapter net_device is null");
796 return -EINVAL;
797 }
798
799 if (!(adapter->dev->flags & IFF_UP)) {
800 hdd_info("adapter net_device is not up");
801 return -EAGAIN;
802 }
803
Jeff Johnson1b780e42017-10-31 14:11:45 -0700804 if (wlan_hdd_validate_session_id(adapter->session_id)) {
Dustin Brownf13b8c32017-05-19 17:23:08 -0700805 hdd_info("adapter session is not open");
806 return -EAGAIN;
807 }
808
Jeff Johnson1b780e42017-10-31 14:11:45 -0700809 if (adapter->session_id >= MAX_NUMBER_OF_ADAPTERS) {
810 hdd_err("bad adapter session Id: %u", adapter->session_id);
Dustin Brownf13b8c32017-05-19 17:23:08 -0700811 return -EINVAL;
812 }
813
814 return 0;
815}
816
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817/**
Arun Khandavallica892f62017-05-26 14:25:50 +0530818 * wlan_hdd_validate_modules_state() - Check modules status
819 * @hdd_ctx: HDD context pointer
820 *
821 * Check's the driver module's state and returns true if the
822 * modules are enabled returns false if modules are closed.
823 *
824 * Return: True if modules are enabled or false.
825 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700826bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +0530827{
828 mutex_lock(&hdd_ctx->iface_change_lock);
829 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
830 mutex_unlock(&hdd_ctx->iface_change_lock);
831 hdd_notice("Modules not enabled, Present status: %d",
832 hdd_ctx->driver_status);
833 return false;
834 }
835 mutex_unlock(&hdd_ctx->iface_change_lock);
836 return true;
837}
838
839/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -0700841 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 *
843 * This function sets the IBSS power save config parameters to WMA
844 * which will send it to firmware if FW supports IBSS power save
845 * before vdev start.
846 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530847 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848 * on failure.
849 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700850QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851{
852 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700853 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854
855 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700856 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530857 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 }
859
Jeff Johnson1b780e42017-10-31 14:11:45 -0700860 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
862 hdd_ctx->config->ibssATIMWinSize,
863 VDEV_CMD);
864 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700865 hdd_err("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530866 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800867 }
868
Jeff Johnson1b780e42017-10-31 14:11:45 -0700869 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
871 hdd_ctx->config->isIbssPowerSaveAllowed,
872 VDEV_CMD);
873 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700874 hdd_err("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d",
875 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530876 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 }
878
Jeff Johnson1b780e42017-10-31 14:11:45 -0700879 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
881 hdd_ctx->config->
882 isIbssPowerCollapseAllowed, VDEV_CMD);
883 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700884 hdd_err("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d",
885 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530886 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 }
888
Jeff Johnson1b780e42017-10-31 14:11:45 -0700889 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
891 hdd_ctx->config->isIbssAwakeOnTxRx,
892 VDEV_CMD);
893 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700894 hdd_err("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530895 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 }
897
Jeff Johnson1b780e42017-10-31 14:11:45 -0700898 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
900 hdd_ctx->config->ibssInactivityCount,
901 VDEV_CMD);
902 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700903 hdd_err("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530904 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 }
906
Jeff Johnson1b780e42017-10-31 14:11:45 -0700907 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
909 hdd_ctx->config->ibssTxSpEndInactivityTime,
910 VDEV_CMD);
911 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700912 hdd_err("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d",
913 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530914 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915 }
916
Jeff Johnson1b780e42017-10-31 14:11:45 -0700917 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
919 hdd_ctx->config->ibssPsWarmupTime,
920 VDEV_CMD);
921 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700922 hdd_err("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d",
923 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530924 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 }
926
Jeff Johnson1b780e42017-10-31 14:11:45 -0700927 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
929 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
930 VDEV_CMD);
931 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700932 hdd_err("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d",
933 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530934 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 }
936
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530937 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938}
939
Yue Macd359b72017-10-03 15:21:00 -0700940#ifdef FEATURE_RUNTIME_PM
941/**
942 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
943 * @hdd_ctx: HDD context
944 *
945 * Return: None
946 */
947static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
948{
949 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
950
Yue Macd359b72017-10-03 15:21:00 -0700951 qdf_runtime_lock_init(&ctx->dfs);
952
953 wlan_scan_runtime_pm_init(hdd_ctx->hdd_pdev);
954}
955
956/**
957 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
958 * @hdd_ctx: HDD Context
959 *
960 * Return: None
961 */
962static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
963{
964 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
965
Yue Macd359b72017-10-03 15:21:00 -0700966 qdf_runtime_lock_deinit(&ctx->dfs);
967
968 wlan_scan_runtime_pm_deinit(hdd_ctx->hdd_pdev);
969}
970
971static void hdd_adapter_runtime_suspend_init(struct hdd_adapter *adapter)
972{
973 struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
974
975 qdf_runtime_lock_init(&ctx->connect);
976}
977
Yue Ma9e89e832017-11-14 11:40:23 -0800978static void hdd_adapter_runtime_suspend_deinit(struct hdd_adapter *adapter)
Yue Macd359b72017-10-03 15:21:00 -0700979{
980 struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
981
982 qdf_runtime_lock_deinit(&ctx->connect);
983}
984#else /* FEATURE_RUNTIME_PM */
985static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
986static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
987static void hdd_adapter_runtime_suspend_init(struct hdd_adapter *adapter) {}
Yue Ma9e89e832017-11-14 11:40:23 -0800988static void hdd_adapter_runtime_suspend_deinit(struct hdd_adapter *adapter) {}
Yue Macd359b72017-10-03 15:21:00 -0700989#endif /* FEATURE_RUNTIME_PM */
990
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991#define INTF_MACADDR_MASK 0x7
992
993/**
994 * hdd_update_macaddr() - update mac address
995 * @config: hdd configuration
996 * @hw_macaddr: mac address
997 *
998 * Mac address for multiple virtual interface is found as following
999 * i) The mac address of the first interface is just the actual hw mac address.
1000 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
1001 * define the mac address for the remaining interfaces and locally
1002 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
1003 * supported virtual interfaces, right now this is 0x07 (meaning 8
1004 * interface).
1005 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
1006 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
1007 *
1008 * Return: None
1009 */
1010void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301011 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012{
1013 int8_t i;
1014 uint8_t macaddr_b3, tmp_br3;
1015
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301016 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301017 QDF_MAC_ADDR_SIZE);
1018 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301019 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301020 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 macaddr_b3 = config->intfMacAddr[i].bytes[3];
1022 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1023 INTF_MACADDR_MASK;
1024 macaddr_b3 += tmp_br3;
1025
1026 /* XOR-ing bit-24 of the mac address. This will give enough
1027 * mac address range before collision
1028 */
1029 macaddr_b3 ^= (1 << 7);
1030
1031 /* Set locally administered bit */
1032 config->intfMacAddr[i].bytes[0] |= 0x02;
1033 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001034 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035 MAC_ADDRESS_STR, i,
1036 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
1037 }
1038}
1039
Kabilan Kannan44a58372017-12-06 18:16:11 -08001040static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1041{
1042 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
1043 struct tdls_start_params tdls_cfg;
1044 struct tdls_user_config *config = &tdls_cfg.config;
1045 struct hdd_config *cfg = hdd_ctx->config;
1046 QDF_STATUS status;
1047
1048 config->tdls_tx_states_period = cfg->fTDLSTxStatsPeriod;
1049 config->tdls_tx_pkt_threshold = cfg->fTDLSTxPacketThreshold;
1050 config->tdls_rx_pkt_threshold = cfg->fTDLSRxFrameThreshold;
1051 config->tdls_max_discovery_attempt = cfg->fTDLSMaxDiscoveryAttempt;
1052 config->tdls_idle_timeout = cfg->tdls_idle_timeout;
1053 config->tdls_idle_pkt_threshold = cfg->fTDLSIdlePacketThreshold;
1054 config->tdls_rssi_trigger_threshold = cfg->fTDLSRSSITriggerThreshold;
1055 config->tdls_rssi_teardown_threshold = cfg->fTDLSRSSITeardownThreshold;
1056 config->tdls_rssi_delta = cfg->fTDLSRSSIDelta;
1057 config->tdls_uapsd_mask = cfg->fTDLSUapsdMask;
1058 config->tdls_uapsd_inactivity_time = cfg->fTDLSPuapsdInactivityTimer;
1059 config->tdls_uapsd_pti_window = cfg->fTDLSPuapsdPTIWindow;
1060 config->tdls_uapsd_ptr_timeout = cfg->fTDLSPuapsdPTRTimeout;
1061 config->tdls_pre_off_chan_num = cfg->fTDLSPrefOffChanNum;
1062 config->tdls_pre_off_chan_bw = cfg->fTDLSPrefOffChanBandwidth;
1063 config->tdls_peer_kickout_threshold = cfg->tdls_peer_kickout_threshold;
1064 config->delayed_trig_framint = cfg->DelayedTriggerFrmInt;
1065 config->tdls_feature_flags = ((cfg->fEnableTDLSOffChannel ?
1066 1 << TDLS_FEATURE_OFF_CHANNEL : 0) |
1067 (cfg->fEnableTDLSWmmMode ? 1 << TDLS_FEATURE_WMM : 0) |
1068 (cfg->fEnableTDLSBufferSta ? 1 << TDLS_FEATURE_BUFFER_STA : 0) |
1069 (cfg->fEnableTDLSSleepSta ? 1 << TDLS_FEATURE_SLEEP_STA : 0) |
1070 (cfg->enable_tdls_scan ? 1 << TDLS_FEATURE_SCAN : 0) |
1071 (cfg->fEnableTDLSSupport ? 1 << TDLS_FEATURE_ENABLE : 0) |
1072 (cfg->fEnableTDLSImplicitTrigger ?
1073 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) |
1074 (cfg->fTDLSExternalControl ?
1075 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0));
1076 config->tdls_vdev_nss_2g = CFG_TDLS_NSS(cfg->vdev_type_nss_2g);
1077 config->tdls_vdev_nss_5g = CFG_TDLS_NSS(cfg->vdev_type_nss_5g);
1078
1079 tdls_cfg.tdls_send_mgmt_req = eWNI_SME_TDLS_SEND_MGMT_REQ;
1080 tdls_cfg.tdls_add_sta_req = eWNI_SME_TDLS_ADD_STA_REQ;
1081 tdls_cfg.tdls_del_sta_req = eWNI_SME_TDLS_DEL_STA_REQ;
1082 tdls_cfg.tdls_update_peer_state = WMA_UPDATE_TDLS_PEER_STATE;
1083 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1084 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1085 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1086 tdls_cfg.tdls_evt_cb_data = psoc;
1087 tdls_cfg.tdls_tl_peer_data = hdd_ctx;
1088 tdls_cfg.tdls_reg_tl_peer = hdd_tdls_register_tdls_peer;
1089 tdls_cfg.tdls_dereg_tl_peer = hdd_tdls_deregister_tdl_peer;
1090 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1091 tdls_cfg.tdls_wmm_cb_data = psoc;
1092 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1093 tdls_cfg.tdls_rx_cb_data = psoc;
1094 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1095
1096 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1097 if (status != QDF_STATUS_SUCCESS) {
1098 hdd_err("failed pmo psoc configuration");
1099 return -EINVAL;
1100 }
1101
1102 hdd_ctx->tdls_umac_comp_active = true;
1103 /* enable napier specific tdls data path */
1104 hdd_ctx->tdls_nap_active = true;
1105
1106 return 0;
1107}
1108
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001109static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001110 struct wma_tgt_services *cfg)
1111{
1112 struct hdd_config *config = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001113
1114 /* Set up UAPSD */
1115 config->apUapsdEnabled &= cfg->uapsd;
1116
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001117 /* 11AX mode support */
1118 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1119 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1120 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1121
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 /* 11AC mode support */
1123 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1124 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1125 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126
1127 /* ARP offload: override user setting if invalid */
1128 config->fhostArpOffload &= cfg->arp_offload;
1129
1130#ifdef FEATURE_WLAN_SCAN_PNO
1131 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001132 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 if (cfg->pno_offload)
1134 config->PnoOffload = true;
1135#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001136#ifdef FEATURE_WLAN_TDLS
1137 config->fEnableTDLSSupport &= cfg->en_tdls;
Manjeet Singhfdd2ac72016-09-02 18:11:43 +05301138 config->fEnableTDLSOffChannel = config->fEnableTDLSOffChannel &&
1139 cfg->en_tdls_offchan;
1140 config->fEnableTDLSBufferSta = config->fEnableTDLSBufferSta &&
1141 cfg->en_tdls_uapsd_buf_sta;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001142 if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143 config->fEnableTDLSSleepSta = true;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001144 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145 config->fEnableTDLSSleepSta = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001146#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001147#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1148 config->isRoamOffloadEnabled &= cfg->en_roam_offload;
1149#endif
Will Huang496b36c2017-07-11 16:38:50 +08001150 config->sap_get_peer_info &= cfg->get_peer_info_enabled;
Varun Reddy Yeturu62c32652017-10-26 15:32:35 -07001151 config->MAWCEnabled &= cfg->is_fw_mawc_capable;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001152 hdd_update_tdls_config(hdd_ctx);
Krishna Kumaar Natarajan052c6e62015-09-28 15:32:55 -07001153 sme_update_tgt_services(hdd_ctx->hHal, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001154
1155}
1156
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001157/**
1158 * hdd_update_vdev_nss() - sets the vdev nss
1159 * @hdd_ctx: HDD context
1160 *
1161 * Sets the Nss per vdev type based on INI
1162 *
1163 * Return: None
1164 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001165static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001166{
1167 struct hdd_config *cfg_ini = hdd_ctx->config;
1168 uint8_t max_supp_nss = 1;
1169
Naveen Rawat10b1c152017-01-18 11:16:06 -08001170 if (cfg_ini->enable2x2 && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001171 max_supp_nss = 2;
1172
1173 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001174 cfg_ini->vdev_type_nss_2g, BAND_2G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001175
1176 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001177 cfg_ini->vdev_type_nss_5g, BAND_5G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001178}
1179
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301180/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301181 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1182 * @hdd_ctx: HDD context
1183 *
1184 * Updates wiphy vhtcap fields
1185 *
1186 * Return: None
1187 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001188static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301189{
1190 struct ieee80211_supported_band *band_5g =
1191 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
1192 uint32_t val;
1193
1194 if (!band_5g) {
1195 hdd_debug("5GHz band disabled, skipping capability population");
1196 return;
1197 }
1198
1199 val = hdd_ctx->config->txBFCsnValue;
1200 band_5g->vht_cap.cap |= (val << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
1201
1202 val = NUM_OF_SOUNDING_DIMENSIONS;
1203 band_5g->vht_cap.cap |=
1204 (val << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
1205
1206 hdd_info("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
1207 band_5g->vht_cap.cap, hdd_ctx->config->txBFCsnValue, val);
1208}
1209
1210/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301211 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
1212 * @hdd_ctx: HDD context
1213 *
1214 * Sets the DBS capability as per INI and firmware capability
1215 *
1216 * Return: None
1217 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001218static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301219{
1220 struct hdd_config *cfg_ini = hdd_ctx->config;
1221 uint8_t hw_dbs_capable = 0;
1222
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07001223 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc) &&
1224 ((cfg_ini->dual_mac_feature_disable ==
1225 ENABLE_DBS_CXN_AND_SCAN) ||
1226 (cfg_ini->dual_mac_feature_disable ==
1227 ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF)))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301228 hw_dbs_capable = 1;
1229
1230 sme_update_hw_dbs_capable(hdd_ctx->hHal, hw_dbs_capable);
1231}
1232
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001233static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 struct wma_tgt_ht_cap *cfg)
1235{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301236 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 uint32_t value, val32;
1238 uint16_t val16;
1239 struct hdd_config *pconfig = hdd_ctx->config;
1240 tSirMacHTCapabilityInfo *phtCapInfo;
1241 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
1242 uint8_t enable_tx_stbc;
1243
1244 /* check and update RX STBC */
1245 if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
1246 pconfig->enableRxSTBC = cfg->ht_rx_stbc;
1247
1248 /* get the MPDU density */
1249 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);
1250
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301251 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001252 hdd_err("could not get MPDU DENSITY");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 value = 0;
1254 }
1255
1256 /*
1257 * MPDU density:
1258 * override user's setting if value is larger
1259 * than the one supported by target
1260 */
1261 if (value > cfg->mpdu_density) {
1262 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
1263 cfg->mpdu_density);
1264
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301265 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001266 hdd_err("could not set MPDU DENSITY to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 }
1268
1269 /* get the HT capability info */
1270 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301271 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001272 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 return;
1274 }
1275 val16 = (uint16_t) val32;
1276 phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;
1277
1278 /* Set the LDPC capability */
1279 phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;
1280
1281 if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
1282 pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;
1283
1284 if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
1285 pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;
1286
1287 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1288 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1289
1290 enable_tx_stbc = pconfig->enableTxSTBC;
1291
1292 if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
1293 pconfig->enable2x2 = 1;
1294 } else {
1295 pconfig->enable2x2 = 0;
1296 enable_tx_stbc = 0;
1297
1298 /* 1x1 */
1299 /* Update Rx Highest Long GI data Rate */
1300 if (sme_cfg_set_int(hdd_ctx->hHal,
1301 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001302 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301303 == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001304 hdd_err("Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 }
1306
1307 /* Update Tx Highest Long GI data Rate */
1308 if (sme_cfg_set_int
1309 (hdd_ctx->hHal,
1310 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001311 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301312 QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001313 hdd_err("VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 }
1315 }
1316 if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
1317 enable_tx_stbc = 0;
1318 phtCapInfo->txSTBC = enable_tx_stbc;
1319
1320 val32 = val16;
1321 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301322 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001323 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001324#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
1325 value = SIZE_OF_SUPPORTED_MCS_SET;
1326 if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301327 &value) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001328 hdd_debug("Read MCS rate set");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329
1330 if (pconfig->enable2x2) {
1331 for (value = 0; value < cfg->num_rf_chains; value++)
1332 mcs_set[value] =
1333 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1334
1335 status =
1336 sme_cfg_set_str(hdd_ctx->hHal,
1337 WNI_CFG_SUPPORTED_MCS_SET,
1338 mcs_set,
1339 SIZE_OF_SUPPORTED_MCS_SET);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301340 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001341 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 }
1343 }
1344#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1345}
1346
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001347static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 struct wma_tgt_vht_cap *cfg)
1349{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301350 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351 uint32_t value = 0;
1352 struct hdd_config *pconfig = hdd_ctx->config;
1353 struct wiphy *wiphy = hdd_ctx->wiphy;
1354 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001355 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001356 uint32_t temp = 0;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001357 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
jiad4a7a33c2017-08-08 15:32:24 +08001358 uint32_t hw_rx_ldpc_enabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359
Dustin Brown5e06bd32016-10-04 12:49:10 -07001360 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001361 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001362 return;
1363 }
1364
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001365 /* Get the current MPDU length */
1366 status =
1367 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
1368 &value);
1369
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301370 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001371 hdd_err("could not get MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372 value = 0;
1373 }
1374
1375 /*
1376 * VHT max MPDU length:
1377 * override if user configured value is too high
1378 * that the target cannot support
1379 */
1380 if (value > cfg->vht_max_mpdu) {
1381 status = sme_cfg_set_int(hdd_ctx->hHal,
1382 WNI_CFG_VHT_MAX_MPDU_LENGTH,
1383 cfg->vht_max_mpdu);
1384
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001385 if (status == QDF_STATUS_E_FAILURE)
1386 hdd_err("could not set VHT MAX MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 }
1388
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001389 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
1390 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1391
1392 if (pconfig->enable2x2)
1393 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1394
1395 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) ==
1396 QDF_STATUS_E_FAILURE) {
1397 hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM");
1398 }
1399
1400 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
1401 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1402 if (pconfig->enable2x2)
1403 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1404
1405 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) ==
1406 QDF_STATUS_E_FAILURE) {
1407 hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM");
1408 }
1409
1410 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
1411 temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
1412 if (pconfig->enable2x2)
1413 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
1414
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001415 hdd_debug("vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001416 pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
1417
1418 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) ==
1419 QDF_STATUS_E_FAILURE) {
1420 hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM");
1421 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422 /* Get the current RX LDPC setting */
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001423 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424 &value);
1425
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301426 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001427 hdd_err("could not get VHT LDPC CODING CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 value = 0;
1429 }
1430
jiad4a7a33c2017-08-08 15:32:24 +08001431 /* Set HW RX LDPC capability */
1432 hw_rx_ldpc_enabled = !!cfg->vht_rx_ldpc;
1433 if (hw_rx_ldpc_enabled != value) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434 status = sme_cfg_set_int(hdd_ctx->hHal,
1435 WNI_CFG_VHT_LDPC_CODING_CAP,
jiad4a7a33c2017-08-08 15:32:24 +08001436 hw_rx_ldpc_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001438 if (status == QDF_STATUS_E_FAILURE)
1439 hdd_err("could not set VHT LDPC CODING CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 }
1441
1442 /* Get current GI 80 value */
1443 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
1444 &value);
1445
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301446 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001447 hdd_err("could not get SHORT GI 80MHZ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448 value = 0;
1449 }
1450
1451 /* set the Guard interval 80MHz */
1452 if (value && !cfg->vht_short_gi_80) {
1453 status = sme_cfg_set_int(hdd_ctx->hHal,
1454 WNI_CFG_VHT_SHORT_GI_80MHZ,
1455 cfg->vht_short_gi_80);
1456
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001457 if (status == QDF_STATUS_E_FAILURE)
1458 hdd_err("could not set SHORT GI 80MHZ to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459 }
1460
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 /* Get VHT TX STBC cap */
1462 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);
1463
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301464 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001465 hdd_err("could not get VHT TX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001466 value = 0;
1467 }
1468
1469 /* VHT TX STBC cap */
1470 if (value && !cfg->vht_tx_stbc) {
1471 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
1472 cfg->vht_tx_stbc);
1473
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001474 if (status == QDF_STATUS_E_FAILURE)
1475 hdd_err("could not set the VHT TX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 }
1477
1478 /* Get VHT RX STBC cap */
1479 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);
1480
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301481 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001482 hdd_err("could not get VHT RX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483 value = 0;
1484 }
1485
1486 /* VHT RX STBC cap */
1487 if (value && !cfg->vht_rx_stbc) {
1488 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
1489 cfg->vht_rx_stbc);
1490
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001491 if (status == QDF_STATUS_E_FAILURE)
1492 hdd_err("could not set the VHT RX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493 }
1494
1495 /* Get VHT SU Beamformer cap */
1496 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1497 &value);
1498
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301499 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001500 hdd_err("could not get VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 value = 0;
1502 }
1503
1504 /* set VHT SU Beamformer cap */
1505 if (value && !cfg->vht_su_bformer) {
1506 status = sme_cfg_set_int(hdd_ctx->hHal,
1507 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1508 cfg->vht_su_bformer);
1509
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001510 if (status == QDF_STATUS_E_FAILURE)
1511 hdd_err("could not set VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 }
1513
1514 /* check and update SU BEAMFORMEE capabality */
1515 if (pconfig->enableTxBF && !cfg->vht_su_bformee)
1516 pconfig->enableTxBF = cfg->vht_su_bformee;
1517
1518 status = sme_cfg_set_int(hdd_ctx->hHal,
1519 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1520 pconfig->enableTxBF);
1521
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001522 if (status == QDF_STATUS_E_FAILURE)
1523 hdd_err("could not set VHT SU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524
1525 /* Get VHT MU Beamformer cap */
1526 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1527 &value);
1528
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301529 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001530 hdd_err("could not get VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 value = 0;
1532 }
1533
1534 /* set VHT MU Beamformer cap */
1535 if (value && !cfg->vht_mu_bformer) {
1536 status = sme_cfg_set_int(hdd_ctx->hHal,
1537 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1538 cfg->vht_mu_bformer);
1539
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001540 if (status == QDF_STATUS_E_FAILURE)
1541 hdd_err("could not set the VHT MU BEAMFORMER CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 }
1543
1544 /* Get VHT MU Beamformee cap */
1545 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1546 &value);
1547
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301548 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001549 hdd_err("could not get VHT MU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550 value = 0;
1551 }
1552
1553 /* set VHT MU Beamformee cap */
1554 if (value && !cfg->vht_mu_bformee) {
1555 status = sme_cfg_set_int(hdd_ctx->hHal,
1556 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1557 cfg->vht_mu_bformee);
1558
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001559 if (status == QDF_STATUS_E_FAILURE)
1560 hdd_err("could not set VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561 }
1562
1563 /* Get VHT MAX AMPDU Len exp */
1564 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1565 &value);
1566
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301567 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001568 hdd_err("could not get VHT AMPDU LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001569 value = 0;
1570 }
1571
1572 /*
1573 * VHT max AMPDU len exp:
1574 * override if user configured value is too high
1575 * that the target cannot support.
1576 * Even though Rome publish ampdu_len=7, it can
1577 * only support 4 because of some h/w bug.
1578 */
1579
1580 if (value > cfg->vht_max_ampdu_len_exp) {
1581 status = sme_cfg_set_int(hdd_ctx->hHal,
1582 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1583 cfg->vht_max_ampdu_len_exp);
1584
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001585 if (status == QDF_STATUS_E_FAILURE)
1586 hdd_err("could not set the VHT AMPDU LEN EXP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 }
1588
1589 /* Get VHT TXOP PS CAP */
1590 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);
1591
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301592 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001593 hdd_err("could not get VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001594 value = 0;
1595 }
1596
1597 /* set VHT TXOP PS cap */
1598 if (value && !cfg->vht_txop_ps) {
1599 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
1600 cfg->vht_txop_ps);
1601
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001602 if (status == QDF_STATUS_E_FAILURE)
1603 hdd_err("could not set the VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 }
1605
1606 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1607 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1608 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1609 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1610 else
1611 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1612
1613
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001614 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
1615 status = sme_cfg_set_int(hdd_ctx->hHal,
1616 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1617 VHT_CAP_160_AND_80P80_SUPP);
1618 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001619 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 band_5g->vht_cap.cap |=
1621 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001622 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1623 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
1624 status = sme_cfg_set_int(hdd_ctx->hHal,
1625 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1626 VHT_CAP_160_SUPP);
1627 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001628 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 band_5g->vht_cap.cap |=
1630 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001631 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1632 }
1633 pconfig->vhtChannelWidth = QDF_MIN(pconfig->vhtChannelWidth,
1634 ch_width);
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301635 /* Get the current GI 160 value */
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001636 status = sme_cfg_get_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301637 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001638 &value);
1639 if (status != QDF_STATUS_SUCCESS) {
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301640 hdd_err("could not get GI 80 & 160");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001641 value = 0;
1642 }
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301643 /* set the Guard interval 160MHz */
1644 if (value && !cfg->vht_short_gi_160) {
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001645 status = sme_cfg_set_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301646 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
1647 cfg->vht_short_gi_160);
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001648
1649 if (status == QDF_STATUS_E_FAILURE)
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301650 hdd_err("failed to set SHORT GI 160MHZ");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001651 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652
1653 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC)
1654 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1655
1656 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1657 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1658 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1659 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1660
1661 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1662 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1663
1664 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1665 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1666 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1667 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1668 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1669 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1670
1671 band_5g->vht_cap.cap |=
1672 (cfg->vht_max_ampdu_len_exp <<
1673 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1674
1675 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1676 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1677 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1678 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1679 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1680 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1681 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1682 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1683
1684 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1685 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1686
1687}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001689/**
1690 * hdd_generate_macaddr_auto() - Auto-generate mac address
1691 * @hdd_ctx: Pointer to the HDD context
1692 *
1693 * Auto-generate mac address using device serial number.
1694 * Keep the first 3 bytes of OUI as before and replace
1695 * the last 3 bytes with the lower 3 bytes of serial number.
1696 *
1697 * Return: 0 for success
1698 * Non zero failure code for errors
1699 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001700static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001701{
1702 unsigned int serialno = 0;
1703 struct qdf_mac_addr mac_addr = {
1704 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1705 };
1706
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001707 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001708 if (serialno == 0)
1709 return -EINVAL;
1710
1711 serialno &= 0x00ffffff;
1712
1713 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1714 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1715 mac_addr.bytes[5] = serialno & 0xff;
1716
1717 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1718 return 0;
1719}
1720
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301721/**
1722 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1723 * configuration to cfg_ini in HDD
1724 * @hdd_ctx: Pointer to hdd_ctx
1725 * @cfg: target configuration
1726 *
1727 * Return: None
1728 */
1729#ifdef FEATURE_WLAN_RA_FILTERING
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001730static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301731 struct wma_tgt_cfg *cfg)
1732{
1733 hdd_ctx->config->IsRArateLimitEnabled = cfg->is_ra_rate_limit_enabled;
1734}
1735#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001736static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301737 struct wma_tgt_cfg *cfg)
1738{
1739}
1740#endif
1741
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742void hdd_update_tgt_cfg(void *context, void *param)
1743{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001744 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001745 struct hdd_context *hdd_ctx = (struct hdd_context *) context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001746 struct wma_tgt_cfg *cfg = param;
1747 uint8_t temp_band_cap;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001748 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301749 uint8_t antenna_mode;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301750
Dustin Brownbd68fe12017-11-21 15:28:52 -08001751 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1752 if (ret) {
1753 hdd_err("Failed to create pdev; errno:%d", ret);
1754 QDF_BUG(0);
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07001755 } else {
Dustin Brownbd68fe12017-11-21 15:28:52 -08001756 hdd_debug("New pdev has been created with pdev_id = %u",
1757 hdd_ctx->hdd_pdev->pdev_objmgr.wlan_pdev_id);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301758 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001759
Naveen Rawat64e477e2016-05-20 10:34:56 -07001760 if (cds_cfg) {
1761 if (hdd_ctx->config->enable_sub_20_channel_width !=
1762 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
1763 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1764 cds_cfg->sub_20_channel_width =
1765 WLAN_SUB_20_CH_WIDTH_NONE;
1766 } else {
1767 cds_cfg->sub_20_channel_width =
1768 hdd_ctx->config->enable_sub_20_channel_width;
1769 }
1770 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771
1772 /* first store the INI band capability */
1773 temp_band_cap = hdd_ctx->config->nBandCapability;
1774
1775 hdd_ctx->config->nBandCapability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301776 hdd_ctx->is_fils_roaming_supported =
1777 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001779 /*
1780 * now overwrite the target band capability with INI
1781 * setting if INI setting is a subset
1782 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001783
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001784 if ((hdd_ctx->config->nBandCapability == BAND_ALL) &&
1785 (temp_band_cap != BAND_ALL))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 hdd_ctx->config->nBandCapability = temp_band_cap;
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001787 else if ((hdd_ctx->config->nBandCapability != BAND_ALL) &&
1788 (temp_band_cap != BAND_ALL) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001789 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001790 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001791 }
1792
Amar Singhal58b45ef2017-08-01 13:43:54 -07001793 hdd_ctx->curr_band = hdd_ctx->config->nBandCapability;
1794
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301795 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 hdd_ctx->reg.reg_domain = cfg->reg_domain;
1797 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
1798 }
1799
1800 /* This can be extended to other configurations like ht, vht cap... */
1801
Anurag Chouhanc5548422016-02-24 18:33:27 +05301802 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001804 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001806 static struct qdf_mac_addr default_mac_addr = {
1807 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
1808 };
1809 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
1810 &default_mac_addr)) {
1811 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
1812 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
1813 MAC_ADDRESS_STR,
1814 MAC_ADDR_ARRAY(hdd_ctx->config->
1815 intfMacAddr[0].bytes));
1816 } else {
1817 hdd_err("Invalid MAC passed from target, using MAC from ini file "
1818 MAC_ADDRESS_STR,
1819 MAC_ADDR_ARRAY(hdd_ctx->config->
1820 intfMacAddr[0].bytes));
1821 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001822 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 }
1824
1825 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07001826 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827
1828 hdd_ctx->max_intf_count = cfg->max_intf_count;
1829
Jeff Johnsonc875e242016-09-23 18:12:34 -07001830 hdd_lpass_target_config(hdd_ctx, cfg);
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07001831 hdd_green_ap_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001832
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
1834 hdd_update_tgt_services(hdd_ctx, &cfg->services);
1835
1836 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
1837
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07001839 if (cfg->services.en_11ax) {
1840 hdd_info("11AX: 11ax is enabled - update HDD config");
1841 hdd_update_tgt_he_cap(hdd_ctx, cfg);
1842 }
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07001843
1844 hdd_update_vdev_nss(hdd_ctx);
1845
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301846 hdd_update_hw_dbs_capable(hdd_ctx);
1847
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08001848 hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
Krunal Sonie3531942016-04-12 17:43:53 -07001849 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001850 hdd_debug("fine_time_meas_cap: 0x%x",
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08001851 hdd_ctx->config->fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001852
Nitesh Shahe50711f2017-04-26 16:30:45 +05301853 antenna_mode = (hdd_ctx->config->enable2x2 == 0x01) ?
1854 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
1855 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001856 hdd_debug("Init current antenna mode: %d",
Archana Ramachandran393f3792015-11-13 17:13:21 -08001857 hdd_ctx->current_antenna_mode);
1858
Rajeev Kumardd3bc602016-08-16 14:21:05 -07001859 hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
1860 hdd_ctx->config->bpf_packet_filter_enable);
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05301861 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301862 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301863
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05301864 if ((hdd_ctx->config->txBFCsnValue >
1865 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
1866 !cfg->tx_bfee_8ss_enabled)
1867 hdd_ctx->config->txBFCsnValue =
1868 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF;
1869
1870 if (sme_cfg_set_int(hdd_ctx->hHal,
1871 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
1872 hdd_ctx->config->txBFCsnValue) == QDF_STATUS_E_FAILURE)
1873 hdd_err("fw update WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED to CFG fails");
1874
1875
1876 hdd_debug("Target BPF %d Host BPF %d 8ss fw support %d txBFCsnValue %d",
1877 cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable,
1878 cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301879
1880 /*
1881 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
1882 */
1883 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05301884
1885 hdd_ctx->fw_mem_dump_enabled = cfg->fw_mem_dump_enabled;
1886
Arun Khandavallid454d422016-08-17 12:47:05 +05301887 /*
1888 * If BPF is enabled, maxWowFilters set to WMA_STA_WOW_DEFAULT_PTRN_MAX
1889 * because we need atleast WMA_STA_WOW_DEFAULT_PTRN_MAX free slots to
1890 * configure the STA mode wow pattern.
1891 */
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301892 if (hdd_ctx->bpf_enabled)
Arun Khandavallid454d422016-08-17 12:47:05 +05301893 hdd_ctx->config->maxWoWFilters = WMA_STA_WOW_DEFAULT_PTRN_MAX;
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301894
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05301895 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
1896
Yue Macd359b72017-10-03 15:21:00 -07001897 /*
1898 * This needs to be done after HDD pdev is created and stored since
1899 * it will access the HDD pdev object lock.
1900 */
1901 hdd_runtime_suspend_context_init(hdd_ctx);
1902
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07001903 /* Configure NAN datapath features */
1904 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07001905 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08001906 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907}
1908
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001909bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910{
Jeff Johnson9d295242017-08-29 14:39:48 -07001911 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07001912 struct hdd_ap_ctx *ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001913
Arif Hussaincd151632017-02-11 16:57:19 -08001914 if (!hdd_ctx || hdd_ctx->config->disableDFSChSwitch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07001915 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussaincd151632017-02-11 16:57:19 -08001916 hdd_ctx, hdd_ctx->config->disableDFSChSwitch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301917 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08001918 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001919
Dustin Brown920397d2017-12-13 16:27:50 -08001920 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08001921 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
1922
1923 if ((QDF_SAP_MODE == adapter->device_mode ||
1924 QDF_P2P_GO_MODE == adapter->device_mode) &&
1925 (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07001926 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08001927 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
1928 true;
1929 hdd_info("tx blocked for session: %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07001930 adapter->session_id);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301931 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301933
1934 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001936
1937/**
1938 * hdd_is_valid_mac_address() - validate MAC address
1939 * @pMacAddr: Pointer to the input MAC address
1940 *
1941 * This function validates whether the given MAC address is valid or not
1942 * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
1943 * where X is the hexa decimal digit character and separated by ':'
1944 * This algorithm works even if MAC address is not separated by ':'
1945 *
1946 * This code checks given input string mac contains exactly 12 hexadecimal
1947 * digits and a separator colon : appears in the input string only after
1948 * an even number of hex digits.
1949 *
1950 * Return: 1 for valid and 0 for invalid
1951 */
1952bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
1953{
1954 int xdigit = 0;
1955 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001956
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001957 while (*pMacAddr) {
1958 if (isxdigit(*pMacAddr)) {
1959 xdigit++;
1960 } else if (':' == *pMacAddr) {
1961 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
1962 break;
1963
1964 ++separator;
1965 } else {
1966 /* Invalid MAC found */
1967 return 0;
1968 }
1969 ++pMacAddr;
1970 }
1971 return xdigit == 12 && (separator == 5 || separator == 0);
1972}
1973
1974/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05301975 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
1976 * @dev: Handle to struct net_device to be updated.
1977 *
1978 * Return: None
1979 */
1980static void hdd_mon_mode_ether_setup(struct net_device *dev)
1981{
1982 dev->header_ops = NULL;
1983 dev->type = ARPHRD_IEEE80211_RADIOTAP;
1984 dev->hard_header_len = ETH_HLEN;
1985 dev->mtu = ETH_DATA_LEN;
1986 dev->addr_len = ETH_ALEN;
1987 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
1988 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
1989 dev->priv_flags |= IFF_TX_SKB_SHARING;
1990
1991 memset(dev->broadcast, 0xFF, ETH_ALEN);
1992}
1993
1994/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07001995 * __hdd__mon_open() - HDD Open function
1996 * @dev: Pointer to net_device structure
1997 *
1998 * This is called in response to ifconfig up
1999 *
2000 * Return: 0 for success; non-zero for failure
2001 */
2002static int __hdd_mon_open(struct net_device *dev)
2003{
2004 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002005 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2006 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002007
2008 ENTER_DEV(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002009
2010 ret = wlan_hdd_validate_context(hdd_ctx);
2011 if (ret)
2012 return ret;
2013
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302014 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002015
2016 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
2017 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
2018 if (ret) {
2019 hdd_err("Failed to start WLAN modules return");
2020 return ret;
2021 }
2022 hdd_err("hdd_wlan_start_modules() successful !");
2023
2024 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2025 ret = hdd_start_adapter(adapter);
2026 if (ret) {
2027 hdd_err("Failed to start adapter :%d",
2028 adapter->device_mode);
2029 return ret;
2030 }
2031 hdd_err("hdd_start_adapters() successful !");
2032 }
2033 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2034 }
2035
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002036 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002037
2038 if (!ret)
2039 ret = hdd_enable_monitor_mode(dev);
2040
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002041 return ret;
2042}
2043
2044/**
2045 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2046 * @dev: Pointer to net_device structure
2047 *
2048 * This is called in response to ifconfig up
2049 *
2050 * Return: 0 for success; non-zero for failure
2051 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002052static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002053{
2054 int ret;
2055
2056 cds_ssr_protect(__func__);
2057 ret = __hdd_mon_open(dev);
2058 cds_ssr_unprotect(__func__);
2059
2060 return ret;
2061}
2062
2063/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302064 * hdd_start_adapter() - Wrapper function for device specific adapter
2065 * @adapter: pointer to HDD adapter
2066 *
2067 * This function is called to start the device specific adapter for
2068 * the mode passed in the adapter's device_mode.
2069 *
2070 * Return: 0 for success; non-zero for failure
2071 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002072int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302073{
2074
2075 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002076 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302077
2078 ENTER_DEV(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002079 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302080
2081 switch (device_mode) {
2082 case QDF_P2P_CLIENT_MODE:
2083 case QDF_P2P_DEVICE_MODE:
2084 case QDF_OCB_MODE:
2085 case QDF_STA_MODE:
2086 case QDF_MONITOR_MODE:
2087 ret = hdd_start_station_adapter(adapter);
2088 if (ret)
2089 goto err_start_adapter;
2090 break;
2091 case QDF_P2P_GO_MODE:
2092 case QDF_SAP_MODE:
2093 ret = hdd_start_ap_adapter(adapter);
2094 if (ret)
2095 goto err_start_adapter;
2096 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302097 case QDF_IBSS_MODE:
2098 /*
2099 * For IBSS interface is initialized as part of
2100 * hdd_init_station_mode()
2101 */
2102 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302103 case QDF_FTM_MODE:
2104 ret = hdd_start_ftm_adapter(adapter);
2105 if (ret)
2106 goto err_start_adapter;
Lin Bai1c678482017-12-18 18:29:11 +08002107 else
2108 goto ftm_complete;
Arun Khandavallifae92942016-08-01 13:31:08 +05302109 break;
2110 default:
2111 hdd_err("Invalid session type %d", device_mode);
2112 QDF_ASSERT(0);
2113 goto err_start_adapter;
2114 }
2115 if (hdd_set_fw_params(adapter))
2116 hdd_err("Failed to set the FW params for the adapter!");
2117
2118 /*
2119 * Action frame registered in one adapter which will
2120 * applicable to all interfaces
2121 */
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302122 ret = wlan_hdd_cfg80211_register_frames(adapter);
2123 if (ret < 0) {
2124 hdd_err("Failed to register frames - ret %d", ret);
2125 goto err_start_adapter;
2126 }
2127
Lin Bai1c678482017-12-18 18:29:11 +08002128ftm_complete:
Arun Khandavallifae92942016-08-01 13:31:08 +05302129 EXIT();
2130 return 0;
2131err_start_adapter:
2132 return -EINVAL;
2133}
2134
2135/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302136 * hdd_enable_power_management() - API to Enable Power Management
2137 *
2138 * API invokes Bus Interface Layer power management functionality
2139 *
2140 * Return: None
2141 */
2142static void hdd_enable_power_management(void)
2143{
2144 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2145
2146 if (!hif_ctx) {
2147 hdd_err("Bus Interface Context is Invalid");
2148 return;
2149 }
2150
2151 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2152}
2153
2154/**
2155 * hdd_disable_power_management() - API to disable Power Management
2156 *
2157 * API disable Bus Interface Layer Power management functionality
2158 *
2159 * Return: None
2160 */
2161static void hdd_disable_power_management(void)
2162{
2163 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2164
2165 if (!hif_ctx) {
2166 hdd_err("Bus Interface Context is Invalid");
2167 return;
2168 }
2169
2170 hif_disable_power_management(hif_ctx);
2171}
2172
2173/**
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302174 * hdd_update_hw_sw_info() - API to update the HW/SW information
2175 *
2176 * API to update the HW and SW information in the driver
2177 *
2178 * Return: None
2179 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002180static void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302181{
2182 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002183 size_t target_hw_name_len;
2184 const char *target_hw_name;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302185
2186 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2187 if (!hif_sc) {
2188 hdd_err("HIF context is NULL");
2189 return;
2190 }
2191
2192 /*
2193 * target hw version/revision would only be retrieved after firmware
2194 * download
2195 */
Dustin Brown6f17a022017-07-19 13:40:55 -07002196 hif_get_hw_info(hif_sc,
2197 &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302198 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002199 &target_hw_name);
2200
2201 if (hdd_ctx->target_hw_name)
2202 qdf_mem_free(hdd_ctx->target_hw_name);
2203
2204 target_hw_name_len = strlen(target_hw_name) + 1;
2205 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2206 if (hdd_ctx->target_hw_name)
2207 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2208 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302209
2210 /* Get the wlan hw/fw version */
2211 hdd_wlan_get_version(hdd_ctx, NULL, NULL);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302212}
2213
2214/**
gbian62edd7e2017-03-07 13:12:13 +08002215 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2216 * @hdd_ctx: Pointer to hdd context
2217 *
2218 * Return: none
2219 */
2220static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002221hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002222{
2223 uint8_t num_entries = 0;
2224 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
2225 uint8_t *tx_sched_wrr_ac;
2226 int i;
2227 cds_context_type *cds_ctx;
2228
2229 if (NULL == hdd_ctx)
2230 return;
2231
2232 if (NULL == hdd_ctx->config) {
2233 /* Do nothing if hdd_ctx is invalid */
2234 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2235 return;
2236 }
2237
2238 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2239
2240 if (!cds_ctx) {
2241 hdd_err("Invalid CDS Context");
2242 return;
2243 }
2244
2245 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
2246 switch (i) {
2247 case OL_TX_WMM_AC_BE:
2248 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_be;
2249 break;
2250 case OL_TX_WMM_AC_BK:
2251 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_bk;
2252 break;
2253 case OL_TX_WMM_AC_VI:
2254 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vi;
2255 break;
2256 case OL_TX_WMM_AC_VO:
2257 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vo;
2258 break;
2259 default:
2260 tx_sched_wrr_ac = NULL;
2261 break;
2262 }
2263
2264 hdd_string_to_u8_array(tx_sched_wrr_ac,
2265 tx_sched_wrr_param,
2266 &num_entries,
2267 sizeof(tx_sched_wrr_param));
2268
2269 if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
2270 cds_ctx->ac_specs[i].wrr_skip_weight =
2271 tx_sched_wrr_param[0];
2272 cds_ctx->ac_specs[i].credit_threshold =
2273 tx_sched_wrr_param[1];
2274 cds_ctx->ac_specs[i].send_limit =
2275 tx_sched_wrr_param[2];
2276 cds_ctx->ac_specs[i].credit_reserve =
2277 tx_sched_wrr_param[3];
2278 cds_ctx->ac_specs[i].discard_weight =
2279 tx_sched_wrr_param[4];
2280 }
2281
2282 num_entries = 0;
2283 }
2284}
2285
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002286#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002287static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2288 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2289{
Jeff Johnson9d295242017-08-29 14:39:48 -07002290 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002291 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002292
2293 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2294 if (!adapter) {
2295 hdd_err("Adapter is NULL");
2296 return PM_MAX_NUM_OF_MODE;
2297 }
2298
2299 return policy_mgr_convert_device_mode_to_qdf_type(
2300 adapter->device_mode);
2301}
2302
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002303static void hdd_register_policy_manager_callback(
2304 struct wlan_objmgr_psoc *psoc)
2305{
2306 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002307
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002308 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002309 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002310 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2311 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002312 hdd_cbacks.get_mode_for_non_connected_vdev =
2313 wlan_hdd_get_mode_for_non_connected_vdev;
2314
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002315 if (QDF_STATUS_SUCCESS !=
2316 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2317 hdd_err("HDD callback registration with policy manager failed");
2318 }
2319}
2320#else
2321static void hdd_register_policy_manager_callback(
2322 struct wlan_objmgr_psoc *psoc)
2323{
2324}
2325#endif
2326
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002327#ifdef WLAN_FEATURE_NAN_CONVERGENCE
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002328static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002329{
2330 struct nan_callbacks cb_obj = {0};
2331
2332 cb_obj.ndi_open = hdd_ndi_open;
2333 cb_obj.ndi_close = hdd_ndi_close;
2334 cb_obj.ndi_start = hdd_ndi_start;
2335 cb_obj.ndi_delete = hdd_ndi_delete;
2336 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2337 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2338
Naveen Rawat37f62c82017-03-26 22:24:43 -07002339 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2340 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002341 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002342
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002343 os_if_nan_register_hdd_callbacks(hdd_ctx->hdd_psoc, &cb_obj);
2344}
2345#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002346static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002347{
2348}
2349#endif
2350
Dustin Brown4c5b9902017-12-19 11:17:19 -08002351/**
2352 * hdd_check_for_leaks() - Perform runtime memory leak checks
2353 *
2354 * This API triggers runtime memory leak detection. This feature enforces the
2355 * policy that any memory allocated at runtime must also be released at runtime.
2356 *
2357 * Allocating memory at runtime and releasing it at unload is effectively a
2358 * memory leak for configurations which never unload (e.g. LONU, statically
2359 * compiled driver). Such memory leaks are NOT false positives, and must be
2360 * fixed.
2361 *
2362 * Return: None
2363 */
Dustin Brown4bc0a622017-12-06 15:56:50 -08002364static void hdd_check_for_leaks(void)
2365{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002366 /* DO NOT REMOVE these checks; for false positives, read above first */
2367
Dustin Brown677e0862017-10-10 16:30:09 -07002368 qdf_mc_timer_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002369}
2370
gbian62edd7e2017-03-07 13:12:13 +08002371/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302372 * hdd_wlan_start_modules() - Single driver state machine for starting modules
2373 * @hdd_ctx: HDD context
2374 * @adapter: HDD adapter
2375 * @reinit: flag to indicate from SSR or normal path
2376 *
2377 * This function maintains the driver state machine it will be invoked from
2378 * startup, reinit and change interface. Depending on the driver state shall
2379 * perform the opening of the modules.
2380 *
2381 * Return: 0 for success; non-zero for failure
2382 */
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002383int hdd_wlan_start_modules(struct hdd_context *hdd_ctx,
2384 struct hdd_adapter *adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05302385 bool reinit)
2386{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002387 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302388 qdf_device_t qdf_dev;
2389 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302390 bool unint = false;
2391 void *hif_ctx;
2392
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002393 hdd_debug("state:%d reinit:%d", hdd_ctx->driver_status, reinit);
Arun Khandavallifae92942016-08-01 13:31:08 +05302394
2395 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2396 if (!qdf_dev) {
2397 hdd_err("QDF Device Context is Invalid return");
2398 return -EINVAL;
2399 }
2400
Dustin Brown6f427922017-09-19 12:19:00 -07002401 hdd_set_idle_ps_config(hdd_ctx, false);
2402 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Arun Khandavallifae92942016-08-01 13:31:08 +05302403
Dustin Brown1fe30a82017-10-03 16:13:36 -07002404 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302405 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
2406 mutex_unlock(&hdd_ctx->iface_change_lock);
2407 hdd_info("Driver modules already Enabled");
2408 EXIT();
2409 return 0;
2410 }
2411
Dustin Brown1fe30a82017-10-03 16:13:36 -07002412 hdd_ctx->start_modules_in_progress = true;
2413
Arun Khandavallifae92942016-08-01 13:31:08 +05302414 switch (hdd_ctx->driver_status) {
2415 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002416 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302417 unint = true;
2418 /* Fall through dont add break here */
2419 case DRIVER_MODULES_CLOSED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002420 hdd_info("Wlan transitioning (CLOSED -> OPENED)");
2421
Dustin Brown4bc0a622017-12-06 15:56:50 -08002422 qdf_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
2423
Arun Khandavallifae92942016-08-01 13:31:08 +05302424 if (!reinit && !unint) {
2425 ret = pld_power_on(qdf_dev->dev);
2426 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002427 hdd_err("Failed to Powerup the device; errno: %d",
2428 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302429 goto release_lock;
2430 }
2431 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002432
2433 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2434 hdd_ctx->config->enable_fw_log);
2435
Arun Khandavallifae92942016-08-01 13:31:08 +05302436 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2437 qdf_dev->bus_type,
2438 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2439 HIF_ENABLE_TYPE_PROBE);
2440 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002441 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302442 goto power_down;
2443 }
2444
2445 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302446 if (!hif_ctx) {
2447 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002448 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302449 goto power_down;
2450 }
2451
Arun Khandavallifae92942016-08-01 13:31:08 +05302452 status = ol_cds_init(qdf_dev, hif_ctx);
2453 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002454 hdd_err("No Memory to Create BMI Context; status: %d",
2455 status);
2456 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302457 goto hif_close;
2458 }
2459
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002460 ret = hdd_update_config(hdd_ctx);
2461 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002462 hdd_err("Failed to update configuration; errno: %d",
2463 ret);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002464 goto cds_free;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002465 }
2466
gbian62edd7e2017-03-07 13:12:13 +08002467 hdd_update_cds_ac_specs_params(hdd_ctx);
2468
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302469 status = cds_open(hdd_ctx->hdd_psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002470 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002471 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002472 ret = qdf_status_to_os_return(status);
2473 goto deinit_config;
Arun Khandavallifae92942016-08-01 13:31:08 +05302474 }
2475
Mukul Sharma9d797a02017-01-05 20:26:03 +05302476 /* initalize components configurations after psoc open */
2477 ret = hdd_update_components_config(hdd_ctx);
2478 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002479 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302480 ret);
2481 goto close;
2482 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002483 status = cds_dp_open(hdd_ctx->hdd_psoc);
2484 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002485 hdd_err("Failed to Open cds post open; status: %d",
2486 status);
2487 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002488 goto close;
2489 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302490
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002491 /*
2492 * NAN compoenet requires certian operations like, open adapter,
2493 * close adapter, etc. to be initiated by HDD, for those
2494 * register HDD callbacks with UMAC's NAN componenet.
2495 */
2496 hdd_nan_register_callbacks(hdd_ctx);
2497
Arun Khandavallifae92942016-08-01 13:31:08 +05302498 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
2499
Jeff Johnson3a280122017-09-13 07:42:00 -07002500 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302501 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002502 hdd_err("Failed to pre-enable CDS; status: %d", status);
2503 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002504 goto cds_txrx_free;
Arun Khandavallifae92942016-08-01 13:31:08 +05302505 }
2506
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002507 hdd_register_policy_manager_callback(
2508 hdd_ctx->hdd_psoc);
2509
Amar Singhal0928b192017-12-01 10:50:54 -08002510 hdd_sysfs_create_version_interface(hdd_ctx->hdd_psoc);
2511
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302512 hdd_update_hw_sw_info(hdd_ctx);
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05302513 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002514 hdd_info("Wlan transitioned (now OPENED)");
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302515
Arun Khandavallifae92942016-08-01 13:31:08 +05302516 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2517 sme_register_ftm_msg_processor(hdd_ctx->hHal,
2518 hdd_ftm_mc_process_msg);
2519 break;
2520 }
2521 if (unint) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002522 hdd_debug("In phase-1 initialization don't enable modules");
Arun Khandavallifae92942016-08-01 13:31:08 +05302523 break;
2524 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302525
2526 if (reinit) {
Dustin Browndca39692017-11-09 15:30:25 -08002527 ret = hdd_ipa_uc_ssr_reinit(hdd_ctx);
2528 if (ret) {
2529 hdd_err("HDD IPA UC reinit failed; errno: %d",
2530 ret);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002531 goto post_disable;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08002532 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302533 }
2534
Arun Khandavallifae92942016-08-01 13:31:08 +05302535 /* Fall through dont add break here */
2536 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002537 hdd_info("Wlan transitioning (OPENED -> ENABLED)");
2538
Arun Khandavallifae92942016-08-01 13:31:08 +05302539 if (!adapter) {
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002540 hdd_alert("adapter is Null");
Dustin Browndca39692017-11-09 15:30:25 -08002541 ret = -EINVAL;
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002542 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302543 }
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302544 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2545 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002546 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302547 break;
2548 }
Dustin Browndca39692017-11-09 15:30:25 -08002549
2550 ret = hdd_configure_cds(hdd_ctx, adapter);
2551 if (ret) {
2552 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002553 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302554 }
Dustin Browndca39692017-11-09 15:30:25 -08002555
Komal Seelamf2136bb2016-09-28 18:30:44 +05302556 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08002557
Arun Khandavallifae92942016-08-01 13:31:08 +05302558 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002559 hdd_info("Wlan transitioned (now ENABLED)");
2560
Arun Khandavallifae92942016-08-01 13:31:08 +05302561 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08002562
Arun Khandavallifae92942016-08-01 13:31:08 +05302563 default:
2564 hdd_err("WLAN start invoked in wrong state! :%d\n",
2565 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08002566 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05302567 goto release_lock;
2568 }
Dustin Brown550f6d22017-12-14 15:44:01 -08002569
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302570 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302571 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown550f6d22017-12-14 15:44:01 -08002572
Arun Khandavallifae92942016-08-01 13:31:08 +05302573 EXIT();
Dustin Brown550f6d22017-12-14 15:44:01 -08002574
Arun Khandavallifae92942016-08-01 13:31:08 +05302575 return 0;
2576
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002577post_disable:
Rajeev Kumarbe021242017-02-16 16:12:23 -08002578 cds_post_disable();
Dustin Brownbd68fe12017-11-21 15:28:52 -08002579 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002580
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002581cds_txrx_free:
2582 cds_dp_close(hdd_ctx->hdd_psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08002583
Arun Khandavallifae92942016-08-01 13:31:08 +05302584close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002585 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08002586 hdd_info("Wlan transition aborted (now CLOSED)");
2587
Jeff Johnsone4b14592017-09-13 14:23:33 -07002588 cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05302589
Dustin Brown28b17892017-10-10 13:29:38 -07002590deinit_config:
2591 cds_deinit_ini_config();
2592
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002593cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05302594 ol_cds_free();
2595
2596hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07002597 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2598 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302599power_down:
2600 if (!reinit && !unint)
2601 pld_power_off(qdf_dev->dev);
2602release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302603 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302604 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002605
2606 /* many adapter resources are not freed by design in SSR case */
2607 if (!reinit)
2608 hdd_check_for_leaks();
2609 qdf_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
2610
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302611 EXIT();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002612
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002613 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05302614}
2615
Naveen Rawat910726a2017-03-06 11:42:51 -08002616#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002617static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002618{
2619 int ret = os_if_wifi_pos_register_nl();
2620
2621 if (ret)
2622 hdd_err("os_if_wifi_pos_register_nl failed");
2623
2624 return ret;
2625}
2626
2627static int hdd_deactivate_wifi_pos(void)
2628{
2629 int ret = os_if_wifi_pos_deregister_nl();
2630
2631 if (ret)
2632 hdd_err("os_if_wifi_pos_deregister_nl failed");
2633
2634 return ret;
2635}
2636
2637/**
2638 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
2639 * @hdd_ctx: hdd context
2640 *
2641 * Return: status of operation
2642 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002643static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002644{
2645 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
2646 struct hdd_config *cfg = hdd_ctx->config;
2647
2648 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
2649 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
2650 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
2651 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
2652 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
2653 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
2654 wifi_pos_set_dwell_time_min(psoc, cfg->nNeighborScanMinChanTime);
2655 wifi_pos_set_dwell_time_max(psoc, cfg->nNeighborScanMaxChanTime);
2656}
2657#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002658static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002659{
2660 return oem_activate_service(hdd_ctx);
2661}
2662
2663static int hdd_deactivate_wifi_pos(void)
2664{
2665 return 0;
2666}
2667
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002668static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08002669{
2670}
2671#endif
2672
Arun Khandavallifae92942016-08-01 13:31:08 +05302673/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674 * __hdd_open() - HDD Open function
2675 * @dev: Pointer to net_device structure
2676 *
2677 * This is called in response to ifconfig up
2678 *
2679 * Return: 0 for success; non-zero for failure
2680 */
2681static int __hdd_open(struct net_device *dev)
2682{
Jeff Johnson9d295242017-08-29 14:39:48 -07002683 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002684 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002685 int ret;
2686
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002687 ENTER_DEV(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302688 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002689 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05302691 /* Nothing to be done if device is unloading */
2692 if (cds_is_driver_unloading()) {
2693 hdd_err("Driver is unloading can not open the hdd");
2694 return -EBUSY;
2695 }
2696
Dustin Brown01847752017-10-25 13:56:27 -07002697 if (cds_is_driver_recovering()) {
2698 hdd_err("WLAN is currently recovering; Please try again.");
2699 return -EBUSY;
2700 }
2701
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302702 mutex_lock(&hdd_init_deinit_lock);
2703
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05302704 hdd_start_driver_ops_timer(eHDD_DRV_OP_IFF_UP);
2705
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302706 /*
2707 * This scenario can be hit in cases where in the wlan driver after
2708 * registering the netdevices and there is a failure in driver
2709 * initialization. So return error gracefully because the netdevices
2710 * will be de-registered as part of the load failure.
2711 */
2712
2713 if (!cds_is_driver_loaded()) {
2714 hdd_err("Failed to start the wlan driver!!");
2715 ret = -EIO;
2716 goto err_hdd_hdd_init_deinit_lock;
2717 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302718
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002719
Arun Khandavallifae92942016-08-01 13:31:08 +05302720 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
2721 if (ret) {
2722 hdd_err("Failed to start WLAN modules return");
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302723 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05302724 }
2725
2726
2727 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2728 ret = hdd_start_adapter(adapter);
2729 if (ret) {
2730 hdd_err("Failed to start adapter :%d",
2731 adapter->device_mode);
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302732 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05302733 }
2734 }
2735
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2737 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002738 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002739 /* Enable TX queues only when we are connected */
2740 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05302741 WLAN_START_ALL_NETIF_QUEUE,
2742 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 }
2744
Naveen Rawat286def52016-09-23 15:38:02 -07002745 /* Enable carrier and transmit queues for NDI */
2746 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002747 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07002748 wlan_hdd_netif_queue_control(adapter,
2749 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2750 WLAN_CONTROL_PATH);
2751 }
2752
Naveen Rawat910726a2017-03-06 11:42:51 -08002753 hdd_populate_wifi_pos_cfg(hdd_ctx);
2754
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302755err_hdd_hdd_init_deinit_lock:
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05302756 hdd_stop_driver_ops_timer();
Arunk Khandavalli16d84252017-06-21 15:26:29 +05302757 mutex_unlock(&hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758 return ret;
2759}
2760
Arun Khandavallifae92942016-08-01 13:31:08 +05302761
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762/**
2763 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
2764 * @dev: Pointer to net_device structure
2765 *
2766 * This is called in response to ifconfig up
2767 *
2768 * Return: 0 for success; non-zero for failure
2769 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002770static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771{
2772 int ret;
2773
2774 cds_ssr_protect(__func__);
2775 ret = __hdd_open(dev);
2776 cds_ssr_unprotect(__func__);
2777
2778 return ret;
2779}
2780
2781/**
2782 * __hdd_stop() - HDD stop function
2783 * @dev: Pointer to net_device structure
2784 *
2785 * This is called in response to ifconfig down
2786 *
2787 * Return: 0 for success; non-zero for failure
2788 */
2789static int __hdd_stop(struct net_device *dev)
2790{
Jeff Johnson9d295242017-08-29 14:39:48 -07002791 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002792 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002793 int ret;
2794
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002795 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002796
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302797 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002798 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799
2800 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302801 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002803
2804 /* Nothing to be done if the interface is not opened */
2805 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07002806 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 return -ENODEV;
2808 }
2809
2810 /* Make sure the interface is marked as closed */
2811 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05302812
2813 hdd_debug("Disabling Auto Power save timer");
2814 sme_ps_disable_auto_ps_timer(
2815 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07002816 adapter->session_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05302817
2818 /*
2819 * Disable TX on the interface, after this hard_start_xmit() will not
2820 * be called on that interface
2821 */
Kabilan Kannan8dac3502017-10-30 12:40:27 -07002822 hdd_notice("Disabling queues, adapter device mode: %s(%d)",
2823 hdd_device_mode_to_string(adapter->device_mode),
2824 adapter->device_mode);
2825
Himanshu Agarwal865201d2017-04-12 15:45:31 +05302826 wlan_hdd_netif_queue_control(adapter,
2827 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2828 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002829
2830 /*
Naveen Rawat286def52016-09-23 15:38:02 -07002831 * NAN data interface is different in some sense. The traffic on NDI is
2832 * bursty in nature and depends on the need to transfer. The service
2833 * layer may down the interface after the usage and up again when
2834 * required. In some sense, the NDI is expected to be available
2835 * (like SAP) iface until NDI delete request is issued by the service
2836 * layer. Skip BSS termination and adapter deletion for NAN Data
2837 * interface (NDI).
2838 */
2839 if (WLAN_HDD_IS_NDI(adapter))
2840 return 0;
2841
Tushnim Bhattacharyya86294892017-10-25 16:29:11 -07002842 policy_mgr_check_and_stop_opportunistic_timer(hdd_ctx->hdd_psoc);
2843
Naveen Rawat286def52016-09-23 15:38:02 -07002844 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845 * The interface is marked as down for outside world (aka kernel)
2846 * But the driver is pretty much alive inside. The driver needs to
2847 * tear down the existing connection on the netdev (session)
2848 * cleanup the data pipes and wait until the control plane is stabilized
2849 * for this interface. The call also needs to wait until the above
2850 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002851 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852 * That is intentional to be able to scan if it is a STA/P2P interface
2853 */
Arun Khandavallifae92942016-08-01 13:31:08 +05302854 hdd_stop_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855
2856 /* DeInit the adapter. This ensures datapath cleanup as well */
2857 hdd_deinit_adapter(hdd_ctx, adapter, true);
2858
Arun Khandavallifae92942016-08-01 13:31:08 +05302859
2860 /*
2861 * Find if any iface is up. If any iface is up then can't put device to
2862 * sleep/power save mode
2863 */
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05302864 if (hdd_check_for_opened_interfaces(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002865 hdd_debug("Closing all modules from the hdd_stop");
Dustin Brown6f427922017-09-19 12:19:00 -07002866 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
2867 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +05302868 hdd_prevent_suspend_timeout(
2869 hdd_ctx->config->iface_change_wait_time,
2870 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Arun Khandavallifae92942016-08-01 13:31:08 +05302871 }
2872
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002873 EXIT();
2874 return 0;
2875}
2876
2877/**
2878 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
2879 * @dev: pointer to net_device structure
2880 *
2881 * This is called in response to ifconfig down
2882 *
2883 * Return: 0 for success and error number for failure
2884 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002885static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886{
2887 int ret;
2888
2889 cds_ssr_protect(__func__);
2890 ret = __hdd_stop(dev);
2891 cds_ssr_unprotect(__func__);
2892
2893 return ret;
2894}
2895
2896/**
2897 * __hdd_uninit() - HDD uninit function
2898 * @dev: Pointer to net_device structure
2899 *
2900 * This is called during the netdev unregister to uninitialize all data
2901 * associated with the device
2902 *
2903 * Return: None
2904 */
2905static void __hdd_uninit(struct net_device *dev)
2906{
Jeff Johnson9d295242017-08-29 14:39:48 -07002907 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07002908 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002909
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002910 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911
2912 do {
2913 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002914 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002915 break;
2916 }
2917
Jeff Johnson399c6272017-08-30 10:51:00 -07002918 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2919 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002920 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002921 break;
2922 }
2923
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002924 if (dev != adapter->dev)
2925 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002926
Jeff Johnson399c6272017-08-30 10:51:00 -07002927 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002928
2929 /* after uninit our adapter structure will no longer be valid */
2930 adapter->dev = NULL;
2931 adapter->magic = 0;
2932 } while (0);
2933
2934 EXIT();
2935}
2936
2937/**
2938 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
2939 * @dev: pointer to net_device structure
2940 *
2941 * This is called during the netdev unregister to uninitialize all data
2942 * associated with the device
2943 *
2944 * Return: none
2945 */
2946static void hdd_uninit(struct net_device *dev)
2947{
2948 cds_ssr_protect(__func__);
2949 __hdd_uninit(dev);
2950 cds_ssr_unprotect(__func__);
2951}
2952
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08002953static int hdd_open_cesium_nl_sock(void)
2954{
2955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2956 struct netlink_kernel_cfg cfg = {
2957 .groups = WLAN_NLINK_MCAST_GRP_ID,
2958 .input = NULL
2959 };
2960#endif
2961 int ret = 0;
2962
2963#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2964 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2965#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
2966 THIS_MODULE,
2967#endif
2968 &cfg);
2969#else
2970 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2971 WLAN_NLINK_MCAST_GRP_ID,
2972 NULL, NULL, THIS_MODULE);
2973#endif
2974
2975 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07002976 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08002977 ret = -ECONNREFUSED;
2978 }
2979
2980 return ret;
2981}
2982
2983static void hdd_close_cesium_nl_sock(void)
2984{
2985 if (NULL != cesium_nl_srv_sock) {
2986 netlink_kernel_release(cesium_nl_srv_sock);
2987 cesium_nl_srv_sock = NULL;
2988 }
2989}
2990
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002991/**
2992 * __hdd_set_mac_address() - set the user specified mac address
2993 * @dev: Pointer to the net device.
2994 * @addr: Pointer to the sockaddr.
2995 *
2996 * This function sets the user specified mac address using
2997 * the command ifconfig wlanX hw ether <mac adress>.
2998 *
2999 * Return: 0 for success, non zero for failure
3000 */
3001static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3002{
Jeff Johnson9d295242017-08-29 14:39:48 -07003003 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003004 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003005 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303006 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003007 int ret;
3008
Jeff Johnson3c3994a2016-02-11 08:12:30 -08003009 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003010
3011 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3012 ret = wlan_hdd_validate_context(hdd_ctx);
3013 if (0 != ret)
3014 return ret;
3015
Jeff Johnson1e851a12017-10-28 14:36:12 -07003016 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003017 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3018
3019 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303020 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021}
3022
3023/**
3024 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
3025 * function from SSR
3026 * @dev: pointer to net_device structure
3027 * @addr: Pointer to the sockaddr
3028 *
3029 * This function sets the user specified mac address using
3030 * the command ifconfig wlanX hw ether <mac adress>.
3031 *
3032 * Return: 0 for success.
3033 */
3034static int hdd_set_mac_address(struct net_device *dev, void *addr)
3035{
3036 int ret;
3037
3038 cds_ssr_protect(__func__);
3039 ret = __hdd_set_mac_address(dev, addr);
3040 cds_ssr_unprotect(__func__);
3041
3042 return ret;
3043}
3044
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003045uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003046{
3047 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003048
Anurag Chouhan6d760662016-02-20 16:05:43 +05303049 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003050 if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
3051 break;
3052 }
3053
Anurag Chouhan6d760662016-02-20 16:05:43 +05303054 if (QDF_MAX_CONCURRENCY_PERSONA == i)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003055 return NULL;
3056
3057 hdd_ctx->config->intfAddrMask |= (1 << i);
3058 return &hdd_ctx->config->intfMacAddr[i].bytes[0];
3059}
3060
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003061void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3062 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063{
3064 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003065
Anurag Chouhan6d760662016-02-20 16:05:43 +05303066 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067 if (!memcmp(releaseAddr,
3068 &hdd_ctx->config->intfMacAddr[i].bytes[0],
3069 6)) {
3070 hdd_ctx->config->intfAddrMask &= ~(1 << i);
3071 break;
3072 }
3073 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003074}
3075
3076#ifdef WLAN_FEATURE_PACKET_FILTERING
3077/**
3078 * __hdd_set_multicast_list() - set the multicast address list
3079 * @dev: Pointer to the WLAN device.
3080 * @skb: Pointer to OS packet (sk_buff).
3081 *
3082 * This funciton sets the multicast address list.
3083 *
3084 * Return: None
3085 */
3086static void __hdd_set_multicast_list(struct net_device *dev)
3087{
Jeff Johnson9d295242017-08-29 14:39:48 -07003088 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 int i = 0, status;
3090 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003091 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303092 struct pmo_mc_addr_list_params *mc_list_request = NULL;
3093 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
3094 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095
Jeff Johnson3c3994a2016-02-11 08:12:30 -08003096 ENTER_DEV(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303097 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303098 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303099
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303101 if (0 != status)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303102 goto out;
3103
Dustin Brownc788acb2017-08-01 17:43:51 -07003104 status = hdd_validate_adapter(adapter);
3105 if (status)
3106 goto out;
3107
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303108 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3109 hdd_err("%s: Driver module is closed", __func__);
3110 return;
3111 }
3112
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303113 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
3114 if (!mc_list_request) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003115 hdd_err("Cannot allocate mc_list_request");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303116 goto out;
3117 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003118
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303119 /* Delete already configured multicast address list */
3120 if (adapter->mc_addr_list.mc_cnt > 0) {
3121 hdd_info("clear previously configured MC address list");
3122 hdd_disable_and_flush_mc_addr_list(adapter,
3123 pmo_mc_list_change_notify);
3124 }
3125
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003126 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003127 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303128 hdd_disable_and_flush_mc_addr_list(adapter,
3129 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130 } else {
3131 mc_count = netdev_mc_count(dev);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303132 if (mc_count > pmo_ucfg_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003133 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303134 pmo_ucfg_max_mc_addr_supported(psoc));
3135 hdd_disable_and_flush_mc_addr_list(adapter,
3136 pmo_mc_list_change_notify);
3137 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003139 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003140 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303141 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003142 if (i == mc_count)
3143 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303144 memset(&(mc_list_request->mc_addr[i].bytes),
3145 0, ETH_ALEN);
3146 memcpy(&(mc_list_request->mc_addr[i].bytes),
3147 ha->addr, ETH_ALEN);
3148 hdd_info("mlist[%d] = %pM", i,
3149 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003150 i++;
3151 }
3152 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303153
3154 mc_list_request->psoc = psoc;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003155 mc_list_request->vdev_id = adapter->session_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303156 mc_list_request->count = mc_count;
3157 status = hdd_cache_mc_addr_list(mc_list_request);
3158 if (status == 0) {
3159 hdd_enable_mc_addr_filtering(adapter,
3160 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003161 } else {
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303162 hdd_err("error while caching mc list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303164out:
3165 if (mc_list_request)
3166 qdf_mem_free(mc_list_request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303167 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003168}
3169
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303170
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003171/**
3172 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
3173 * @dev: pointer to net_device
3174 *
3175 * Return: none
3176 */
3177static void hdd_set_multicast_list(struct net_device *dev)
3178{
3179 cds_ssr_protect(__func__);
3180 __hdd_set_multicast_list(dev);
3181 cds_ssr_unprotect(__func__);
3182}
3183#endif
3184
3185/**
3186 * hdd_select_queue() - used by Linux OS to decide which queue to use first
3187 * @dev: Pointer to the WLAN device.
3188 * @skb: Pointer to OS packet (sk_buff).
3189 *
3190 * This function is registered with the Linux OS for network
3191 * core to decide which queue to use first.
3192 *
3193 * Return: ac, Queue Index/access category corresponding to UP in IP header
3194 */
3195static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
3196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
3197 , void *accel_priv
3198#endif
3199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3200 , select_queue_fallback_t fallback
3201#endif
3202)
3203{
3204 return hdd_wmm_select_queue(dev, skb);
3205}
3206
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003207static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003208 .ndo_open = hdd_open,
3209 .ndo_stop = hdd_stop,
3210 .ndo_uninit = hdd_uninit,
3211 .ndo_start_xmit = hdd_hard_start_xmit,
3212 .ndo_tx_timeout = hdd_tx_timeout,
3213 .ndo_get_stats = hdd_get_stats,
3214 .ndo_do_ioctl = hdd_ioctl,
3215 .ndo_set_mac_address = hdd_set_mac_address,
3216 .ndo_select_queue = hdd_select_queue,
3217#ifdef WLAN_FEATURE_PACKET_FILTERING
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003218 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219#endif
3220};
3221
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003222/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003223static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003224 .ndo_open = hdd_mon_open,
3225 .ndo_stop = hdd_stop,
3226 .ndo_get_stats = hdd_get_stats,
3227};
3228
3229/**
3230 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003231 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003232 * Return: None
3233 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003234void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003236 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
Jeff Johnson5505db82017-11-02 21:19:23 -07003237 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003238 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003239 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003240}
3241
3242/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003243 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3244 * @hdd_ctx: global hdd context
3245 * @macAddr: mac address to assign to the interface
3246 * @name: User-visible name of the interface
3247 *
3248 * hdd adapter pointer would point to the netdev->priv space, this function
3249 * would retrive the pointer, and setup the hdd adapter configuration.
3250 *
3251 * Return: the pointer to hdd adapter, otherwise NULL
3252 */
Jeff Johnson9d295242017-08-29 14:39:48 -07003253static struct hdd_adapter *hdd_alloc_station_adapter(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003254 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003255 unsigned char name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256 const char *name)
3257{
Jeff Johnson5505db82017-11-02 21:19:23 -07003258 struct net_device *dev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07003259 struct hdd_adapter *adapter = NULL;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003260 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303261 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262 /*
3263 * cfg80211 initialization and registration....
3264 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003265 dev = alloc_netdev_mq(sizeof(struct hdd_adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
3267 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003268#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003269 (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
3270 hdd_mon_mode_ether_setup : ether_setup),
3271 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272
Jeff Johnson5505db82017-11-02 21:19:23 -07003273 if (dev != NULL) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274
3275 /* Save the pointer to the net_device in the HDD adapter */
Jeff Johnson5505db82017-11-02 21:19:23 -07003276 adapter = (struct hdd_adapter *) netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277
Jeff Johnson9d295242017-08-29 14:39:48 -07003278 qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
Jeff Johnsonb9424862017-10-30 08:49:35 -07003279 sta_ctx = &adapter->session.station;
Hanumanth Reddy Pothula18553ae2017-04-28 15:03:10 +05303280 qdf_mem_set(sta_ctx->conn_info.staId,
3281 sizeof(sta_ctx->conn_info.staId),
3282 HDD_WLAN_INVALID_STA_ID);
Jeff Johnson5505db82017-11-02 21:19:23 -07003283 adapter->dev = dev;
Jeff Johnsondba0db62017-08-30 11:12:39 -07003284 adapter->hdd_ctx = hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003285 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003286 adapter->session_id = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003287
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303288 qdf_status = qdf_event_create(
3289 &adapter->qdf_session_open_event);
3290 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3291 hdd_err("Session open QDF event init failed!");
3292 free_netdev(adapter->dev);
3293 return NULL;
3294 }
3295
3296 qdf_status = qdf_event_create(
3297 &adapter->qdf_session_close_event);
3298 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3299 hdd_err("Session close QDF event init failed!");
3300 free_netdev(adapter->dev);
3301 return NULL;
3302 }
3303
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003304 init_completion(&adapter->disconnect_comp_var);
Abhishek Singh533c9da2017-05-04 10:23:34 +05303305 init_completion(&adapter->roaming_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003306 init_completion(&adapter->linkup_event_var);
3307 init_completion(&adapter->cancel_rem_on_chan_var);
3308 init_completion(&adapter->rem_on_chan_ready_event);
3309 init_completion(&adapter->sta_authorized_event);
3310 init_completion(&adapter->offchannel_tx_event);
3311 init_completion(&adapter->tx_action_cnf_event);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003312 init_completion(&adapter->ibss_peer_info_comp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313 init_completion(&adapter->change_country_code);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05303314 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003315
3316 adapter->offloads_configured = false;
Jeff Johnsonc72c5732017-10-28 12:49:37 -07003317 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003318 /* Init the net_device structure */
Jeff Johnson5505db82017-11-02 21:19:23 -07003319 strlcpy(dev->name, name, IFNAMSIZ);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003320
Jeff Johnson5505db82017-11-02 21:19:23 -07003321 qdf_mem_copy(dev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003322 sizeof(tSirMacAddr));
Jeff Johnson1e851a12017-10-28 14:36:12 -07003323 qdf_mem_copy(adapter->mac_addr.bytes, macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003324 sizeof(tSirMacAddr));
Jeff Johnson5505db82017-11-02 21:19:23 -07003325 dev->watchdog_timeo = HDD_TX_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003326
3327 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
Jeff Johnson5505db82017-11-02 21:19:23 -07003328 dev->features |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003329 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
Jeff Johnson5505db82017-11-02 21:19:23 -07003330 dev->features |= NETIF_F_RXCSUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003331
Jeff Johnson5505db82017-11-02 21:19:23 -07003332 hdd_set_tso_flags(hdd_ctx, dev);
Dhanashri Atre83d373d2015-07-28 16:45:59 -07003333
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003334 hdd_set_station_ops(adapter->dev);
3335
Jeff Johnson5505db82017-11-02 21:19:23 -07003336 hdd_dev_setup_destructor(dev);
3337 dev->ieee80211_ptr = &adapter->wdev;
3338 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003339 adapter->wdev.wiphy = hdd_ctx->wiphy;
Jeff Johnson5505db82017-11-02 21:19:23 -07003340 adapter->wdev.netdev = dev;
3341 /* set dev's parent to underlying device */
3342 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003343 hdd_wmm_init(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05303344 hdd_adapter_runtime_suspend_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003345 spin_lock_init(&adapter->pause_map_lock);
Nirav Shah617cff92016-04-25 10:24:24 +05303346 adapter->start_time = adapter->last_time = qdf_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003347 }
3348
3349 return adapter;
3350}
3351
Jeff Johnson9d295242017-08-29 14:39:48 -07003352static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003354 struct net_device *dev = adapter->dev;
3355 int ret;
3356
3357 ENTER();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003358
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003359 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003360 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3361
3362 ret = dev_alloc_name(dev, dev->name);
3363 if (ret < 0) {
3364 hdd_err(
3365 "unable to get dev name: %s, err = 0x%x",
3366 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303367 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 }
3369 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003370
3371 ret = register_netdevice(dev);
3372 if (ret) {
3373 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3374 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303375 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003376 }
3377 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003378 ret = register_netdev(dev);
3379 if (ret) {
3380 hdd_err("register_netdev(%s) failed, err = 0x%x",
3381 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303382 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003383 }
3384 }
3385 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3386
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003387 EXIT();
3388
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303389 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003390}
3391
Krunal Sonib51eec72017-11-20 21:53:01 -08003392QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003393{
Krunal Sonib51eec72017-11-20 21:53:01 -08003394 struct hdd_adapter *adapter;
3395 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396
Krunal Sonib51eec72017-11-20 21:53:01 -08003397 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3398 if (!hdd_ctx) {
3399 hdd_err("Invalid HDD_CTX");
3400 return QDF_STATUS_E_FAILURE;
3401 }
3402
3403 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
3404 if (NULL == adapter) {
3405 hdd_err("NULL adapter");
3406 return QDF_STATUS_E_INVAL;
3407 }
3408 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303409 qdf_event_set(&adapter->qdf_session_open_event);
Krunal Sonib51eec72017-11-20 21:53:01 -08003410 hdd_debug("session %d opened", adapter->session_id);
3411
3412 return QDF_STATUS_SUCCESS;
3413}
3414
3415QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
3416{
3417 struct hdd_adapter *adapter;
3418 struct hdd_context *hdd_ctx;
3419
3420 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3421 if (!hdd_ctx) {
3422 hdd_err("Invalid HDD_CTX");
3423 return QDF_STATUS_E_FAILURE;
3424 }
3425
3426 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003427 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003428 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303429 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003430 }
3431
3432 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003433 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303434 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003435 }
3436
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003437 /*
3438 * For NAN Data interface, the close session results in the final
3439 * indication to the userspace
3440 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003441 if (adapter->device_mode == QDF_NDI_MODE)
3442 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003443
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003444 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3445
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003446 /*
3447 * We can be blocked while waiting for scheduled work to be
3448 * flushed, and the adapter structure can potentially be freed, in
3449 * which case the magic will have been reset. So make sure the
3450 * magic is still good, and hence the adapter structure is still
3451 * valid, before signaling completion
3452 */
3453 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303454 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003455
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303456 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457}
3458
Jeff Johnson9d295242017-08-29 14:39:48 -07003459int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003460{
Dustin Brownd28772b2017-03-17 14:16:07 -07003461 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003462
Dustin Brownd28772b2017-03-17 14:16:07 -07003463 status = pmo_vdev_ready(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003464 if (QDF_IS_STATUS_ERROR(status))
3465 return qdf_status_to_os_return(status);
3466
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003467 status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003468 if (QDF_IS_STATUS_ERROR(status))
3469 return qdf_status_to_os_return(status);
3470
3471 if (wma_capability_enhanced_mcast_filter())
3472 status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev);
3473 else
3474 status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07003475
3476 return qdf_status_to_os_return(status);
3477}
3478
Jeff Johnson9d295242017-08-29 14:39:48 -07003479int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07003480{
3481 QDF_STATUS status;
3482 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003483 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003484 uint8_t vdev_id;
Dustin Brownd28772b2017-03-17 14:16:07 -07003485
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003486 vdev_id = adapter->session_id;
3487 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003488
3489 /* vdev created sanity check */
3490 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07003491 hdd_err("vdev for Id %d does not exist", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003492 return -EINVAL;
3493 }
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003494 status = ucfg_reg_11d_vdev_delete_update(adapter->hdd_vdev);
Yue Maf9782842017-05-08 12:49:49 -07003495 /*
3496 * In SSR case, there is no need to destroy vdev in firmware since
3497 * it has already asserted. vdev can be released directly.
3498 */
Krunal Sonib51eec72017-11-20 21:53:01 -08003499 if (cds_is_driver_recovering()) {
3500 hdd_debug("SSR: silently release the vdev for session-id: %d",
3501 adapter->session_id);
3502 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
Yue Maf9782842017-05-08 12:49:49 -07003503 goto release_vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08003504 }
Yue Maf9782842017-05-08 12:49:49 -07003505
Dustin Brownd28772b2017-03-17 14:16:07 -07003506 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303507 qdf_event_reset(&adapter->qdf_session_close_event);
Dustin Brownd28772b2017-03-17 14:16:07 -07003508 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08003509 status = sme_close_session(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003510 if (QDF_IS_STATUS_ERROR(status)) {
3511 hdd_err("failed to close sme session: %d", status);
3512 return qdf_status_to_os_return(status);
3513 }
3514
3515 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303516 status = qdf_wait_for_event_completion(
3517 &adapter->qdf_session_close_event,
3518 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3519 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003520 if (adapter->device_mode == QDF_NDI_MODE)
3521 hdd_ndp_session_end_handler(adapter);
3522 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303523 adapter->session_id = HDD_SESSION_ID_INVALID;
3524 if (QDF_STATUS_E_TIMEOUT != status) {
3525 hdd_err("timed out waiting for close sme session: %u", status);
3526 return -ETIMEDOUT;
3527 } else if (adapter->qdf_session_close_event.force_set) {
3528 hdd_err("Session close evt focefully set, SSR/PDR has occurred");
3529 return -EINVAL;
3530 } else {
3531 hdd_err("Failed to close sme session (%u)", status);
3532 return -EINVAL;
3533 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003534 }
Yue Maf9782842017-05-08 12:49:49 -07003535release_vdev:
Sandeep Puligillaef415362017-08-30 16:37:13 -07003536 /* do vdev logical destroy via objmgr */
3537 errno = hdd_objmgr_destroy_vdev(adapter);
3538 if (errno) {
3539 hdd_err("failed to destroy objmgr vdev: %d", errno);
3540 return errno;
3541 }
3542
Dustin Brown0d2eeae2017-03-24 15:21:32 -07003543 /* now that sme session is closed, allow physical vdev destroy */
3544 errno = hdd_objmgr_release_vdev(adapter);
3545 if (errno) {
3546 hdd_err("failed to release objmgr vdev: %d", errno);
3547 return errno;
3548 }
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08003549 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003550
3551 return 0;
3552}
3553
Krunal Sonib51eec72017-11-20 21:53:01 -08003554static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
3555 struct sme_session_params *session_param,
3556 csr_roam_completeCallback callback,
3557 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07003558{
Dustin Brownd28772b2017-03-17 14:16:07 -07003559 uint32_t type;
3560 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08003561 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07003562
3563 /* determine vdev (sub)type */
3564 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303565 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003566 hdd_err("failed to get vdev type: %d", status);
3567 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003568 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003569 session_param->sme_session_id = adapter->session_id;
3570 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
3571 session_param->type_of_persona = type;
3572 session_param->subtype_of_persona = sub_type;
3573 session_param->session_open_cb = hdd_sme_open_session_callback;
3574 session_param->session_close_cb = hdd_sme_close_session_callback;
3575 session_param->callback = callback;
3576 session_param->callback_ctx = callback_ctx;
3577
3578 return 0;
3579}
3580
3581int hdd_vdev_create(struct hdd_adapter *adapter,
3582 csr_roam_completeCallback callback, void *ctx)
3583{
3584 QDF_STATUS status;
3585 int errno;
3586 struct hdd_context *hdd_ctx;
3587 struct sme_session_params sme_session_params = {0};
Krunal Sonib51eec72017-11-20 21:53:01 -08003588
3589 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07003590
3591 /* do vdev create via objmgr */
3592 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown7d043f62017-03-27 12:07:36 -07003593 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07003594 if (errno) {
3595 hdd_err("failed to create objmgr vdev: %d", errno);
3596 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003597 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003598
3599 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303600 status = qdf_event_reset(&adapter->qdf_session_open_event);
3601 if (QDF_STATUS_SUCCESS != status) {
3602 hdd_err("failed to reinit session open event");
3603 return -EINVAL;
3604 }
Krunal Sonib51eec72017-11-20 21:53:01 -08003605 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
3606 callback, ctx);
3607 if (errno) {
3608 hdd_err("failed to populating SME params");
3609 goto objmgr_vdev_destroy_procedure;
3610 }
3611
3612 status = sme_open_session(hdd_ctx->hHal, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07003613 if (QDF_IS_STATUS_ERROR(status)) {
3614 hdd_err("failed to open sme session: %d", status);
3615 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07003616 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003617 }
3618
3619 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303620 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
3621 WLAN_WAIT_TIME_SESSIONOPENCLOSE);
3622 if (QDF_STATUS_SUCCESS != status) {
3623 if (adapter->qdf_session_open_event.force_set) {
3624 /*
3625 * SSR/PDR has caused shutdown, which has forcefully
3626 * set the event. Return without the closing session.
3627 */
3628 adapter->session_id = HDD_SESSION_ID_INVALID;
3629 hdd_err("Session open event forcefully set");
3630 return -EINVAL;
3631 } else {
3632 if (QDF_STATUS_E_TIMEOUT == status)
3633 hdd_err("Session failed to open within timeout period");
3634 else
3635 hdd_err("Failed to wait for session open event(status-%d)",
3636 status);
3637 errno = -ETIMEDOUT;
3638 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3639 goto hdd_vdev_destroy_procedure;
3640 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003641 }
3642
3643 /* firmware ready for component communication, raise vdev_ready event */
3644 errno = hdd_vdev_ready(adapter);
3645 if (errno) {
3646 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07003647 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07003648 }
3649
Jeff Johnson1b780e42017-10-31 14:11:45 -07003650 hdd_info("vdev %d created successfully", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003651
3652 return 0;
3653
3654 /*
3655 * Due to legacy constraints, we need to destroy in the same order as
3656 * create. So, split error handling into 2 cases to accommodate.
3657 */
3658
Krunal Soni4a020c72017-10-30 20:58:40 -07003659objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07003660 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07003661
3662 return errno;
3663
Krunal Soni4a020c72017-10-30 20:58:40 -07003664hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07003665 QDF_BUG(!hdd_vdev_destroy(adapter));
3666
3667 return errno;
3668}
3669
Jeff Johnson9d295242017-08-29 14:39:48 -07003670QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07003671{
Jeff Johnsonb9424862017-10-30 08:49:35 -07003672 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003673 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07003674 QDF_STATUS status;
3675 int ret_val;
3676
Dustin Brownd28772b2017-03-17 14:16:07 -07003677 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3678 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
3679 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Jeff Johnson1b780e42017-10-31 14:11:45 -07003680 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07003681
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003682 /* Register wireless extensions */
Dustin Brownd28772b2017-03-17 14:16:07 -07003683 status = hdd_register_wext(adapter->dev);
3684 if (QDF_IS_STATUS_ERROR(status)) {
3685 hdd_err("failed to register wireless extensions: %d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003686 goto error_register_wext;
3687 }
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07003688 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003689
Jeff Johnsond377dce2017-10-04 10:32:42 -07003690 qdf_mem_set(sta_ctx->conn_info.staId,
3691 sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05303692
Deepak Dhamdherea2785822016-11-17 01:17:45 -08003693 /* set fast roaming capability in sme session */
Jeff Johnson1b780e42017-10-31 14:11:45 -07003694 status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->session_id,
Deepak Dhamdherea2785822016-11-17 01:17:45 -08003695 adapter->fast_roaming_allowed);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003696 /* Set the default operation channel */
Jeff Johnsond377dce2017-10-04 10:32:42 -07003697 sta_ctx->conn_info.operationChannel =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003698 hdd_ctx->config->OperatingChannel;
3699
3700 /* Make the default Auth Type as OPEN */
Jeff Johnsond377dce2017-10-04 10:32:42 -07003701 sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003702
3703 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303704 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003705 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003706 status, status);
3707 goto error_init_txrx;
3708 }
3709
3710 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3711
3712 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303713 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003714 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003715 status, status);
3716 goto error_wmm_init;
3717 }
3718
3719 set_bit(WMM_INIT_DONE, &adapter->event_flags);
3720
Jeff Johnson1b780e42017-10-31 14:11:45 -07003721 ret_val = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003722 WMI_PDEV_PARAM_BURST_ENABLE,
3723 hdd_ctx->config->enableSifsBurst,
3724 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07003725 if (ret_val)
3726 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05303728 /*
3729 * In case of USB tethering, LRO is disabled. If SSR happened
3730 * during that time, then as part of SSR init, do not enable
3731 * the LRO again. Keep the LRO state same as before SSR.
3732 */
3733 if (!(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Dhanashri Atre1a6a4ce2017-05-03 19:40:33 -07003734 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05303735
3736 /* rcpi info initialization */
3737 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
3738
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303739 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003740
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741error_wmm_init:
3742 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3743 hdd_deinit_tx_rx(adapter);
3744error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07003745 hdd_unregister_wext(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003746error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07003747 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003748
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003749 return status;
3750}
3751
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303752/**
Krunal Soni4a020c72017-10-30 20:58:40 -07003753 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303754 * @hdd_ctx: global hdd context
3755 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07003756 * @rtnl_held: Used to indicate whether or not the caller is holding
3757 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303758 *
3759 * This function De-initializes the STA/P2P/OCB adapter.
3760 *
3761 * Return: None.
3762 */
Krunal Soni4a020c72017-10-30 20:58:40 -07003763static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07003764 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07003765 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303766{
3767 ENTER_DEV(adapter->dev);
3768
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05303769 if (adapter->dev) {
3770 if (rtnl_held)
3771 adapter->dev->wireless_handlers = NULL;
3772 else {
3773 rtnl_lock();
3774 adapter->dev->wireless_handlers = NULL;
3775 rtnl_unlock();
3776 }
3777 }
3778
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303779 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
3780 hdd_deinit_tx_rx(adapter);
3781 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3782 }
3783
3784 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
3785 hdd_wmm_adapter_close(adapter);
3786 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3787 }
3788
Krunal Sonib51eec72017-11-20 21:53:01 -08003789
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303790 EXIT();
3791}
3792
Krunal Sonib51eec72017-11-20 21:53:01 -08003793void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
3794 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795 bool rtnl_held)
3796{
3797 ENTER();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303798
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003799 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003800 case QDF_STA_MODE:
3801 case QDF_P2P_CLIENT_MODE:
3802 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08003803 case QDF_IBSS_MODE:
3804 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003805 {
Krunal Soni4a020c72017-10-30 20:58:40 -07003806 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003807 break;
3808 }
3809
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003810 case QDF_SAP_MODE:
3811 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003812 {
Krunal Soni4a020c72017-10-30 20:58:40 -07003813 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003814 break;
3815 }
3816
3817 default:
3818 break;
3819 }
3820
3821 EXIT();
3822}
3823
Jeff Johnson9d295242017-08-29 14:39:48 -07003824static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07003825 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003826{
Jeff Johnson5505db82017-11-02 21:19:23 -07003827 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003828
3829 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07003830 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003831 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07003832 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 return;
3834 }
3835
Rajeev Kumardca5f812016-02-04 17:28:06 -08003836 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05303837
Yue Ma9e89e832017-11-14 11:40:23 -08003838 hdd_adapter_runtime_suspend_deinit(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05303839
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003840 /*
3841 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
3842 * the driver is almost closed and cannot handle either control
3843 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003844 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
3845 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003846 * is not right. Setting this flag helps hdd_stop() to recognize that
3847 * the interface is closed and restricts any operations on that
3848 */
3849 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3850
3851 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003852 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07003853 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003854 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003855 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003856 /*
3857 * Note that the adapter is no longer valid at this point
3858 * since the memory has been reclaimed
3859 */
3860 }
3861}
3862
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003863static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07003864 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865{
Jeff Johnson9d295242017-08-29 14:39:48 -07003866 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003867
Dustin Brown920397d2017-12-13 16:27:50 -08003868 hdd_for_each_adapter(hdd_ctx, adapter) {
3869 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
3870 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303871 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003872 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 }
Dustin Brown920397d2017-12-13 16:27:50 -08003874
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303875 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876}
Ryan Hsu07495ea2016-01-21 15:25:39 -08003877
Arun Khandavalli2358d522016-05-16 18:05:37 +05303878#ifdef CONFIG_FW_LOGS_BASED_ON_INI
3879/**
3880 * hdd_set_fw_log_params() - Set log parameters to FW
3881 * @hdd_ctx: HDD Context
3882 * @adapter: HDD Adapter
3883 *
3884 * This function set the FW Debug log level based on the INI.
3885 *
3886 * Return: None
3887 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003888static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07003889 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05303890{
3891 uint8_t count = 0, numentries = 0,
3892 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
3893 uint32_t value = 0;
3894 int ret;
3895
Arun Khandavallifae92942016-08-01 13:31:08 +05303896 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
3897 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003898 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05303899 return;
3900 }
3901
Arun Khandavallifae92942016-08-01 13:31:08 +05303902 /* Enable FW logs based on INI configuration */
Arun Khandavalli2358d522016-05-16 18:05:37 +05303903 hdd_ctx->fw_log_settings.dl_type =
3904 hdd_ctx->config->enableFwLogType;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003905 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05303906 WMI_DBGLOG_TYPE,
3907 hdd_ctx->config->enableFwLogType,
3908 DBG_CMD);
3909 if (ret != 0)
3910 hdd_err("Failed to enable FW log type ret %d",
3911 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05303912
3913 hdd_ctx->fw_log_settings.dl_loglevel =
Arun Khandavallifae92942016-08-01 13:31:08 +05303914 hdd_ctx->config->enableFwLogLevel;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003915 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05303916 WMI_DBGLOG_LOG_LEVEL,
3917 hdd_ctx->config->enableFwLogLevel,
3918 DBG_CMD);
3919 if (ret != 0)
3920 hdd_err("Failed to enable FW log level ret %d",
3921 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05303922
3923 hdd_string_to_u8_array(
3924 hdd_ctx->config->enableFwModuleLogLevel,
3925 moduleloglevel,
3926 &numentries,
3927 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
3928
3929 while (count < numentries) {
3930 /*
3931 * FW module log level input string looks like
3932 * below:
3933 * gFwDebugModuleLoglevel=<FW Module ID>,
3934 * <Log Level>,...
3935 * For example:
3936 * gFwDebugModuleLoglevel=
3937 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
3938 * Above input string means :
3939 * For FW module ID 1 enable log level 0
3940 * For FW module ID 2 enable log level 1
3941 * For FW module ID 3 enable log level 2
3942 * For FW module ID 4 enable log level 3
3943 * For FW module ID 5 enable log level 4
3944 * For FW module ID 6 enable log level 5
3945 * For FW module ID 7 enable log level 6
3946 */
3947
Nishank Aggarwale239d962017-03-03 12:26:02 +05303948 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
3949 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
3950 hdd_err("Module id %d and dbglog level %d input length is more than max",
3951 moduleloglevel[count],
3952 moduleloglevel[count + 1]);
3953 return;
3954 }
3955
3956 value = moduleloglevel[count] << 16;
3957 value |= moduleloglevel[count + 1];
Jeff Johnson1b780e42017-10-31 14:11:45 -07003958 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05303959 WMI_DBGLOG_MOD_LOG_LEVEL,
3960 value, DBG_CMD);
3961 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05303962 hdd_err("Failed to enable FW module log level %d ret %d",
3963 value, ret);
3964
3965 count += 2;
3966 }
Arun Khandavallifae92942016-08-01 13:31:08 +05303967
Arun Khandavalli2358d522016-05-16 18:05:37 +05303968}
3969#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003970static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07003971 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05303972{
3973}
3974
3975#endif
3976
3977/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08003978 * hdd_configure_chain_mask() - programs chain mask to firmware
3979 * @adapter: HDD adapter
3980 *
3981 * Return: 0 on success or errno on failure
3982 */
3983static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
3984{
3985 int ret_val;
3986 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3987
3988 hdd_debug("enable2x2: %d, lte_coex: %d, ChainMask1x1: tx: %d rx: %d",
3989 hdd_ctx->config->enable2x2, hdd_ctx->lte_coex_ant_share,
3990 hdd_ctx->config->txchainmask1x1,
3991 hdd_ctx->config->rxchainmask1x1);
3992 hdd_debug("disable_DBS: %d, tx_chain_mask_2g: %d, rx_chain_mask_2g: %d",
3993 hdd_ctx->config->dual_mac_feature_disable,
3994 hdd_ctx->config->tx_chain_mask_2g,
3995 hdd_ctx->config->rx_chain_mask_2g);
3996 hdd_debug("tx_chain_mask_5g: %d, rx_chain_mask_5g: %d",
3997 hdd_ctx->config->tx_chain_mask_5g,
3998 hdd_ctx->config->rx_chain_mask_5g);
3999
4000 if (hdd_ctx->config->enable2x2) {
4001 hdd_info("2x2 enabled. skip chain mask programming");
4002 return 0;
4003 }
4004
4005 if (hdd_ctx->config->txchainmask1x1) {
4006 ret_val = sme_cli_set_command(adapter->session_id,
4007 WMI_PDEV_PARAM_TX_CHAIN_MASK,
4008 hdd_ctx->config->txchainmask1x1,
4009 PDEV_CMD);
4010 if (ret_val)
4011 goto error;
4012 }
4013
4014 if (hdd_ctx->config->rxchainmask1x1) {
4015 ret_val = sme_cli_set_command(adapter->session_id,
4016 WMI_PDEV_PARAM_RX_CHAIN_MASK,
4017 hdd_ctx->config->rxchainmask1x1,
4018 PDEV_CMD);
4019 if (ret_val)
4020 goto error;
4021 }
4022
4023 if (hdd_ctx->lte_coex_ant_share) {
4024 hdd_info("lte ant sharing enabled. skip per band chain mask");
4025 return 0;
4026 }
4027
4028 if (hdd_ctx->config->txchainmask1x1 ||
4029 hdd_ctx->config->rxchainmask1x1) {
4030 hdd_info("band agnostic tx/rx chain mask set. skip per band chain mask");
4031 return 0;
4032 }
4033
4034 if (!hdd_ctx->config->dual_mac_feature_disable) {
4035 hdd_info("DBS enabled. skip per band chain mask");
4036 return 0;
4037 }
4038
4039 if (hdd_ctx->config->tx_chain_mask_2g) {
4040 ret_val = sme_cli_set_command(adapter->session_id,
4041 WMI_PDEV_PARAM_TX_CHAIN_MASK_2G,
4042 hdd_ctx->config->tx_chain_mask_2g, PDEV_CMD);
4043 if (0 != ret_val)
4044 goto error;
4045 }
4046
4047 if (hdd_ctx->config->rx_chain_mask_2g) {
4048 ret_val = sme_cli_set_command(adapter->session_id,
4049 WMI_PDEV_PARAM_RX_CHAIN_MASK_2G,
4050 hdd_ctx->config->rx_chain_mask_2g, PDEV_CMD);
4051 if (0 != ret_val)
4052 goto error;
4053 }
4054
4055 if (hdd_ctx->config->tx_chain_mask_5g) {
4056 ret_val = sme_cli_set_command(adapter->session_id,
4057 WMI_PDEV_PARAM_TX_CHAIN_MASK_5G,
4058 hdd_ctx->config->tx_chain_mask_5g, PDEV_CMD);
4059 if (0 != ret_val)
4060 goto error;
4061 }
4062
4063 if (hdd_ctx->config->rx_chain_mask_5g) {
4064 ret_val = sme_cli_set_command(adapter->session_id,
4065 WMI_PDEV_PARAM_RX_CHAIN_MASK_5G,
4066 hdd_ctx->config->rx_chain_mask_5g, PDEV_CMD);
4067 if (0 != ret_val)
4068 goto error;
4069 }
4070
4071 return 0;
4072
4073error:
4074 hdd_err("WMI PDEV set param failed %d", ret_val);
4075 return -EINVAL;
4076}
4077
4078/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304079 * hdd_set_fw_params() - Set parameters to firmware
4080 * @adapter: HDD adapter
4081 *
4082 * This function Sets various parameters to fw once the
4083 * adapter is started.
4084 *
4085 * Return: 0 on success or errno on failure
4086 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004087int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304088{
4089 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004090 struct hdd_context *hdd_ctx;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304091
4092 ENTER_DEV(adapter->dev);
4093
4094 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4095 if (!hdd_ctx)
4096 return -EINVAL;
4097
Dustin Brown732ab9c2017-06-15 13:24:09 -07004098 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4099 hdd_debug("FTM Mode is active; nothing to do");
4100 return 0;
4101 }
4102
Jeff Johnson1b780e42017-10-31 14:11:45 -07004103 ret = sme_cli_set_command(adapter->session_id,
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304104 WMI_PDEV_PARAM_DTIM_SYNTH,
4105 hdd_ctx->config->enable_lprx, PDEV_CMD);
4106 if (ret) {
4107 hdd_err("Failed to set LPRx");
4108 goto error;
4109 }
4110
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304111 if (adapter->device_mode == QDF_STA_MODE) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07004112 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304113 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
4114 hdd_ctx->config->upper_brssi_thresh);
4115
Jeff Johnson1b780e42017-10-31 14:11:45 -07004116 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304117 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
4118 hdd_ctx->config->lower_brssi_thresh);
4119
Jeff Johnson1b780e42017-10-31 14:11:45 -07004120 sme_set_smps_cfg(adapter->session_id,
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304121 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
4122 hdd_ctx->config->enable_dtim_1chrx);
4123 }
4124
Dustin Brown732ab9c2017-06-15 13:24:09 -07004125 if (hdd_ctx->config->enable2x2) {
4126 hdd_debug("configuring 2x2 mode fw params");
4127
Jeff Johnson1b780e42017-10-31 14:11:45 -07004128 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004129 WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE,
4130 hdd_ctx->config->enable_cck_tx_fir_override,
4131 PDEV_CMD);
4132 if (ret) {
4133 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
4134 ret);
4135 goto error;
4136 }
4137 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304138#define HDD_DTIM_1CHAIN_RX_ID 0x5
4139#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004140 hdd_debug("configuring 1x1 mode fw params");
4141
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004142 /*
4143 * Disable DTIM 1 chain Rx when in 1x1,
4144 * we are passing two value
4145 * as param_id << 29 | param_value.
4146 * Below param_value = 0(disable)
4147 */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004148 ret = sme_cli_set_command(adapter->session_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004149 WMI_STA_SMPS_PARAM_CMDID,
4150 HDD_DTIM_1CHAIN_RX_ID <<
4151 HDD_SMPS_PARAM_VALUE_S,
4152 VDEV_CMD);
4153 if (ret) {
4154 hdd_err("DTIM 1 chain set failed %d", ret);
4155 goto error;
4156 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304157
Arun Khandavalli2358d522016-05-16 18:05:37 +05304158#undef HDD_DTIM_1CHAIN_RX_ID
4159#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004160
4161 if (hdd_configure_chain_mask(adapter))
4162 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004163 }
4164
Jeff Johnson1b780e42017-10-31 14:11:45 -07004165 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004166 WMI_PDEV_PARAM_HYST_EN,
4167 hdd_ctx->config->enableMemDeepSleep,
4168 PDEV_CMD);
4169 if (ret) {
4170 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4171 goto error;
4172 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304173
Jeff Johnson1b780e42017-10-31 14:11:45 -07004174 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004175 WMI_VDEV_PARAM_ENABLE_RTSCTS,
4176 hdd_ctx->config->rts_profile,
4177 VDEV_CMD);
4178 if (ret) {
4179 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4180 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304181 }
4182
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004183 hdd_debug("SET AMSDU num %d", hdd_ctx->config->max_amsdu_num);
4184
Jeff Johnson1b780e42017-10-31 14:11:45 -07004185 ret = wma_cli_set_command(adapter->session_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004186 GEN_VDEV_PARAM_AMSDU,
4187 hdd_ctx->config->max_amsdu_num,
4188 GEN_CMD);
4189 if (ret != 0) {
4190 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4191 goto error;
4192 }
4193
Arun Khandavalli2358d522016-05-16 18:05:37 +05304194 hdd_set_fw_log_params(hdd_ctx, adapter);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304195 EXIT();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004196
Arun Khandavalli2358d522016-05-16 18:05:37 +05304197 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304198
Arun Khandavalli2358d522016-05-16 18:05:37 +05304199error:
4200 return -EINVAL;
4201}
4202
Ryan Hsu07495ea2016-01-21 15:25:39 -08004203/**
4204 * hdd_open_adapter() - open and setup the hdd adatper
4205 * @hdd_ctx: global hdd context
4206 * @session_type: type of the interface to be created
4207 * @iface_name: User-visible name of the interface
4208 * @macAddr: MAC address to assign to the interface
4209 * @name_assign_type: the name of assign type of the netdev
4210 * @rtnl_held: the rtnl lock hold flag
4211 *
4212 * This function open and setup the hdd adpater according to the device
4213 * type request, assign the name, the mac address assigned, and then prepared
4214 * the hdd related parameters, queue, lock and ready to start.
4215 *
4216 * Return: the pointer of hdd adapter, otherwise NULL.
4217 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004218struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004219 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08004220 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004221 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222{
Jeff Johnson9d295242017-08-29 14:39:48 -07004223 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304224 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004225
4226 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
4227 /*
4228 * Max limit reached on the number of vdevs configured by the
4229 * host. Return error
4230 */
Arun Khandavallifae92942016-08-01 13:31:08 +05304231 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
4232 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004233 return NULL;
4234 }
4235
4236 if (macAddr == NULL) {
4237 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05304238 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004239 return NULL;
4240 }
4241 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304242 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304243 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
4244 " already exists",
4245 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004246 return NULL;
4247 }
4248
4249 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004250 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251 /* Reset locally administered bit if the device mode is STA */
4252 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
Arunk Khandavalli794fdfc2017-09-13 18:00:40 +05304253 hdd_info("locally administered bit reset in sta mode: "
4254 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004255 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004256 case QDF_P2P_CLIENT_MODE:
4257 case QDF_P2P_DEVICE_MODE:
4258 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07004259 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304260 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004261 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4262 name_assign_type,
4263 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004264
4265 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05304266 hdd_err("failed to allocate adapter for session %d",
4267 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004268 return NULL;
4269 }
4270
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004271 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004272 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004273 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004274 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304275 else if (QDF_MONITOR_MODE == session_type)
4276 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 else
4278 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4279
4280 adapter->device_mode = session_type;
4281
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004283 /*
4284 * Workqueue which gets scheduled in IPv4 notification
4285 * callback
4286 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004287 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004288 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004289
4290#ifdef WLAN_NS_OFFLOAD
4291 /*
4292 * Workqueue which gets scheduled in IPv6
4293 * notification callback.
4294 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004295 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004296 hdd_ipv6_notifier_work_queue);
4297#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004298 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004299 if (QDF_STATUS_SUCCESS != status)
Yue Ma9e89e832017-11-14 11:40:23 -08004300 goto err_deinit_adapter_runtime_pm;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004301
4302 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004303 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004304 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304305 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4306 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05304307
Ravi Joshi1a292562017-05-18 16:28:54 -07004308 /* Initialize NAN Data Interface */
4309 if (QDF_NDI_MODE == session_type) {
4310 status = hdd_init_nan_data_mode(adapter);
4311 if (QDF_STATUS_SUCCESS != status)
Yue Ma9e89e832017-11-14 11:40:23 -08004312 goto err_deinit_adapter_runtime_pm;
Ravi Joshi1a292562017-05-18 16:28:54 -07004313 }
4314
4315 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004316
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004317 case QDF_P2P_GO_MODE:
4318 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08004319 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
4320 name_assign_type,
4321 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004322 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004323 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05304324 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004325 return NULL;
4326 }
4327
4328 adapter->wdev.iftype =
4329 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004330 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004331 NL80211_IFTYPE_P2P_GO;
4332 adapter->device_mode = session_type;
4333
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004334 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004335 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004336 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004337
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004338 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004339 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304340 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4341 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304342
4343 /*
4344 * Workqueue which gets scheduled in IPv4 notification
4345 * callback
4346 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004347 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304348 hdd_ipv4_notifier_work_queue);
4349
4350#ifdef WLAN_NS_OFFLOAD
4351 /*
4352 * Workqueue which gets scheduled in IPv6
4353 * notification callback.
4354 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004355 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304356 hdd_ipv6_notifier_work_queue);
4357#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004358 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304359 case QDF_FTM_MODE:
4360 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
4361 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08004362 iface_name);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304363 if (NULL == adapter) {
4364 hdd_err("Failed to allocate adapter for FTM mode");
4365 return NULL;
4366 }
4367 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
4368 adapter->device_mode = session_type;
4369 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08004370 if (QDF_STATUS_SUCCESS != status)
Yue Ma9e89e832017-11-14 11:40:23 -08004371 goto err_deinit_adapter_runtime_pm;
Krunal Sonib51eec72017-11-20 21:53:01 -08004372
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304373 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004374 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304375 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304376 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4377 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304378 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004380 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304381 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004382 return NULL;
4383 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004384
hqueaa33ee2017-05-04 17:56:35 +08004385 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
4386
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304387 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004388 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08004389 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004390 }
4391
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304392 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004393 if (NULL != adapter) {
4394 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4395 adapter = NULL;
4396 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004397
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004398 return NULL;
4399 }
4400
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304401 if (QDF_STATUS_SUCCESS == status) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004402 policy_mgr_set_concurrency_mode(hdd_ctx->hdd_psoc,
4403 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004405 /* Adapter successfully added. Increment the vdev count */
4406 hdd_ctx->current_intf_count++;
4407
Jeff Johnson5880d792016-08-15 13:32:30 -07004408 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004409 hdd_ctx->current_intf_count);
4410
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004411 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004412 }
4413
Rajeev Kumardca5f812016-02-04 17:28:06 -08004414 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07004415 hdd_err("Interface %s wow debug_fs init failed",
4416 netdev_name(adapter->dev));
4417
4418 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
4419 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004420
4421 return adapter;
4422
Yue Ma9e89e832017-11-14 11:40:23 -08004423err_deinit_adapter_runtime_pm:
4424 /*
4425 * For certain error cases that hdd_alloc_station_adapter()
4426 * is used to allocate the adapter.
4427 */
4428 hdd_adapter_runtime_suspend_deinit(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07004430 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05304431 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004432
4433 return NULL;
4434}
4435
Jeff Johnson9d295242017-08-29 14:39:48 -07004436QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004437 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004438{
Dustin Brown920397d2017-12-13 16:27:50 -08004439 /*
4440 * Here we are stopping global bus_bw timer & work per adapter.
4441 *
4442 * The reason is to fix one race condition between
4443 * bus bandwidth work and cleaning up an adapter.
4444 * Under some conditions, it is possible for the bus bandwidth
4445 * work to access a particularly destroyed adapter, leading to
4446 * use-after-free.
4447 */
4448 hdd_debug("wait for bus bw work to flush");
4449 hdd_bus_bw_compute_timer_stop(hdd_ctx);
4450 hdd_bus_bw_cancel_work(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451
Dustin Brown920397d2017-12-13 16:27:50 -08004452 /* cleanup adapter */
4453 policy_mgr_clear_concurrency_mode(hdd_ctx->hdd_psoc,
4454 adapter->device_mode);
4455 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4456 hdd_remove_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004457
Dustin Brown920397d2017-12-13 16:27:50 -08004458 /* conditionally restart the bw timer */
4459 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004460
Dustin Brown920397d2017-12-13 16:27:50 -08004461 /* Adapter removed. Decrement vdev count */
4462 if (hdd_ctx->current_intf_count != 0)
4463 hdd_ctx->current_intf_count--;
Dustin Brown5ec6b552017-03-31 12:11:40 -07004464
Dustin Brown920397d2017-12-13 16:27:50 -08004465 /* Fw will take care incase of concurrency */
4466 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004467}
4468
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004469/**
4470 * hdd_close_all_adapters - Close all open adapters
4471 * @hdd_ctx: Hdd context
4472 * rtnl_held: True if RTNL lock held
4473 *
4474 * Close all open adapters.
4475 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304476 * Return: QDF status code
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004477 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004478QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004479{
Dustin Brown920397d2017-12-13 16:27:50 -08004480 struct hdd_adapter *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304481 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004482
4483 ENTER();
4484
4485 do {
Dustin Brown920397d2017-12-13 16:27:50 -08004486 status = hdd_remove_front_adapter(hdd_ctx, &adapter);
4487 if (QDF_IS_STATUS_SUCCESS(status)) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304488 wlan_hdd_release_intf_addr(hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08004489 adapter->mac_addr.bytes);
4490 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
4491
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304492 /* Adapter removed. Decrement vdev count */
4493 if (hdd_ctx->current_intf_count != 0)
4494 hdd_ctx->current_intf_count--;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004495 }
Dustin Brown920397d2017-12-13 16:27:50 -08004496 } while (QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004497
4498 EXIT();
4499
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304500 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004501}
4502
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004503void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504{
Anurag Chouhan6d760662016-02-20 16:05:43 +05304505 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004506 tSirUpdateIE updateIE;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004507
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004508 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004509 case QDF_STA_MODE:
4510 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004511 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07004512 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004513 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -07004514 bssid = &sta_ctx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004515 break;
4516 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004517 case QDF_SAP_MODE:
4518 case QDF_P2P_GO_MODE:
4519 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004520 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07004521 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004522 break;
4523 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004524 case QDF_FTM_MODE:
4525 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526 default:
4527 /*
4528 * wlan_hdd_reset_prob_rspies should not have been called
4529 * for these kind of devices
4530 */
Jeff Johnson5880d792016-08-15 13:32:30 -07004531 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004532 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004533 return;
4534 }
4535
Anurag Chouhanc5548422016-02-24 18:33:27 +05304536 qdf_copy_macaddr(&updateIE.bssid, bssid);
Jeff Johnson1b780e42017-10-31 14:11:45 -07004537 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004538 updateIE.ieBufferlength = 0;
4539 updateIE.pAdditionIEBuffer = NULL;
4540 updateIE.append = true;
4541 updateIE.notify = false;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004542 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004543 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304544 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004545 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004546 }
4547}
4548
Jeff Johnson9d295242017-08-29 14:39:48 -07004549QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004550 const bool bCloseSession)
4551{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304552 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Jeff Johnson2a722002017-09-30 20:02:35 -07004553 struct hdd_wext_state *pWextState =
4554 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004555 union iwreq_data wrqu;
4556 tSirUpdateIE updateIE;
4557 unsigned long rc;
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05304558 tsap_Config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004559
4560 ENTER();
4561
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004562 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304563 wlan_hdd_netif_queue_control(adapter,
4564 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4565 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004566 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004567 case QDF_STA_MODE:
4568 case QDF_P2P_CLIENT_MODE:
4569 case QDF_IBSS_MODE:
4570 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004571 case QDF_NDI_MODE:
4572 if ((QDF_NDI_MODE == adapter->device_mode) ||
4573 hdd_conn_is_connected(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004574 WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
4575 hdd_is_connecting(
4576 WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004577 INIT_COMPLETION(adapter->disconnect_comp_var);
4578 /*
4579 * For NDI do not use pWextState from sta_ctx, if needed
4580 * extract from ndi_ctx.
4581 */
4582 if (QDF_NDI_MODE == adapter->device_mode)
4583 qdf_ret_status = sme_roam_disconnect(
4584 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004585 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004586 eCSR_DISCONNECT_REASON_NDI_DELETE);
4587 else if (pWextState->roamProfile.BSSType ==
4588 eCSR_BSS_TYPE_START_IBSS)
4589 qdf_ret_status = sme_roam_disconnect(
4590 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004591 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004592 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004593 else if (QDF_STA_MODE == adapter->device_mode) {
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004594 qdf_ret_status =
4595 wlan_hdd_try_disconnect(adapter);
Jingxiang Gecc7e1f42017-11-14 16:21:27 +08004596 hdd_debug("Send disconnected event to userspace");
4597 wlan_hdd_cfg80211_indicate_disconnect(
4598 adapter->dev, true,
4599 WLAN_REASON_UNSPECIFIED);
4600 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004601 else
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004602 qdf_ret_status = sme_roam_disconnect(
4603 hdd_ctx->hHal,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004604 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004605 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004606 /* success implies disconnect command got
4607 * queued up successfully
4608 */
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004609 if (qdf_ret_status == QDF_STATUS_SUCCESS &&
4610 QDF_STA_MODE != adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004611 rc = wait_for_completion_timeout(
4612 &adapter->disconnect_comp_var,
4613 msecs_to_jiffies
4614 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004615 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004616 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004617 }
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004618 if (qdf_ret_status != QDF_STATUS_SUCCESS)
4619 hdd_warn("failed to post disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004620 memset(&wrqu, '\0', sizeof(wrqu));
4621 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4622 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
4623 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
4624 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05304625 }
Wu Gaoaceec6c2017-08-30 16:08:21 +08004626 wlan_hdd_scan_abort(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004627
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05304628 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05304629 hdd_clear_fils_connection_info(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004630
4631#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004632 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004633#endif
4634
4635 hdd_deregister_tx_flow_control(adapter);
4636
4637#ifdef WLAN_NS_OFFLOAD
4638#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004639 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004640#endif
4641#endif
4642
Hanumanth Reddy Pothula05860142017-07-26 18:45:27 +05304643 if (adapter->device_mode == QDF_STA_MODE)
4644 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
4645 adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004646 /*
4647 * It is possible that the caller of this function does not
4648 * wish to close the session
4649 */
Krunal Soni985b8132017-02-10 18:49:08 -08004650 if (true == bCloseSession) {
4651 if (0 != wlan_hdd_try_disconnect(adapter)) {
4652 hdd_err("Error: Can't disconnect adapter");
4653 return QDF_STATUS_E_FAILURE;
4654 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004655 hdd_debug("Destroying adapter: %d",
4656 adapter->session_id);
Dustin Brown0d2eeae2017-03-24 15:21:32 -07004657 hdd_vdev_destroy(adapter);
Krunal Soni985b8132017-02-10 18:49:08 -08004658 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004659 break;
4660
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004661 case QDF_SAP_MODE:
wadesongf9b15ed2017-12-14 14:12:32 +08004662 wlan_hdd_scan_abort(adapter);
Govind Singh1dab23b2017-08-12 13:31:00 +05304663 /* Flush IPA exception path packets */
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05304664 sap_config = &adapter->session.ap.sap_config;
4665 if (sap_config)
4666 wlansap_reset_sap_config_add_ie(sap_config,
4667 eUPDATE_IE_ALL);
Govind Singh1dab23b2017-08-12 13:31:00 +05304668 hdd_ipa_flush(hdd_ctx);
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004669 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Dustin Browna5cf8e02017-10-19 16:04:19 -07004670
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004671 case QDF_P2P_GO_MODE:
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07004672 if (QDF_SAP_MODE == adapter->device_mode) {
4673 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
4674 cds_flush_delayed_work(
4675 &adapter->acs_pending_work);
4676 clear_bit(ACS_PENDING, &adapter->event_flags);
4677 }
4678 }
Krunal Soni22208392017-09-29 18:10:34 -07004679 cds_flush_work(&adapter->sap_stop_bss_work);
Dustin Browna5cf8e02017-10-19 16:04:19 -07004680
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004681 /* Any softap specific cleanup here... */
Dustin Browna5cf8e02017-10-19 16:04:19 -07004682 wlan_hdd_undo_acs(adapter);
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004683 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004684 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
4685
4686 hdd_deregister_tx_flow_control(adapter);
4687
Kapil Guptac1224bf2017-06-22 21:22:40 +05304688 hdd_destroy_acs_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004689 mutex_lock(&hdd_ctx->sap_lock);
4690 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304691 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05304692 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004693
4694 /* Stop Bss. */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004695 status = wlansap_stop_bss(
4696 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004697
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304698 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07004699 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004700 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05304701 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304702 qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05304703 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +05304704 qdf_wait_for_event_completion(
4705 &hostapd_state->qdf_stop_bss_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -08004706 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004707
Anurag Chouhance0dc992016-02-16 18:18:03 +05304708 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004709 hdd_err("failure waiting for wlansap_stop_bss %d",
4710 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004711 }
4712 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004713 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004714 }
4715 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004716 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
4717 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004718 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004719
Anurag Chouhanc5548422016-02-24 18:33:27 +05304720 qdf_copy_macaddr(&updateIE.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07004721 &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07004722 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004723 updateIE.ieBufferlength = 0;
4724 updateIE.pAdditionIEBuffer = NULL;
4725 updateIE.append = false;
4726 updateIE.notify = false;
4727 /* Probe bcn reset */
4728 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
4729 &updateIE, eUPDATE_IE_PROBE_BCN)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304730 == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004731 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004732 }
4733 /* Assoc resp reset */
4734 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
4735 &updateIE,
4736 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304737 QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004738 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004739 }
4740 /* Reset WNI_CFG_PROBE_RSP Flags */
4741 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004742 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07004743 qdf_mem_free(adapter->session.ap.beacon);
4744 adapter->session.ap.beacon = NULL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05304745 /*
4746 * If Do_Not_Break_Stream was enabled clear avoid channel list.
4747 */
4748 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev))
4749 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
4750
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304751#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004752 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304753#endif
4754
4755#ifdef WLAN_NS_OFFLOAD
4756#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07004757 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05304758#endif
4759#endif
Krunal Sonib51eec72017-11-20 21:53:01 -08004760 if (true == bCloseSession) {
4761 hdd_debug("Destroying adapter: %d",
4762 adapter->session_id);
4763 hdd_vdev_destroy(adapter);
4764 }
4765 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004766 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004767 case QDF_OCB_MODE:
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08004768 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004769 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
Leo Changfdb45c32016-10-28 11:09:23 -07004770 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.staId[0]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004771 break;
4772 default:
4773 break;
4774 }
4775
Dustin Brown04348372017-12-14 16:13:39 -08004776 if (adapter->scan_info.default_scan_ies) {
4777 qdf_mem_free(adapter->scan_info.default_scan_ies);
4778 adapter->scan_info.default_scan_ies = NULL;
4779 }
4780
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004781 EXIT();
Dustin Brown04348372017-12-14 16:13:39 -08004782
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304783 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004784}
4785
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304786/**
4787 * hdd_deinit_all_adapters - deinit all adapters
4788 * @hdd_ctx: HDD context
4789 * @rtnl_held: True if RTNL lock held
4790 *
4791 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004792void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304793{
Jeff Johnson9d295242017-08-29 14:39:48 -07004794 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304795
4796 ENTER();
4797
Dustin Brown920397d2017-12-13 16:27:50 -08004798 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304799 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304800
4801 EXIT();
4802}
4803
Dustin Brown27cd9942017-09-27 16:11:44 -07004804QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx,
4805 bool close_session)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004806{
Jeff Johnson9d295242017-08-29 14:39:48 -07004807 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004808
4809 ENTER();
4810
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304811 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
4812
Dustin Brown920397d2017-12-13 16:27:50 -08004813 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Brown27cd9942017-09-27 16:11:44 -07004814 hdd_stop_adapter(hdd_ctx, adapter, close_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004815
4816 EXIT();
4817
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304818 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004819}
4820
Paul Zhang84fa9382017-11-10 21:18:21 +08004821static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
4822 struct hdd_adapter *adapter)
4823{
4824 switch (adapter->device_mode) {
4825 case QDF_STA_MODE:
4826 case QDF_P2P_CLIENT_MODE:
4827 case QDF_IBSS_MODE:
4828 case QDF_P2P_DEVICE_MODE:
4829 case QDF_NDI_MODE:
4830 wlan_hdd_scan_abort(adapter);
4831 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
4832 if (adapter->device_mode == QDF_STA_MODE)
4833 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
4834 adapter->dev);
4835 break;
4836 case QDF_P2P_GO_MODE:
4837 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
4838 break;
4839 case QDF_SAP_MODE:
4840 wlan_hdd_undo_acs(adapter);
4841 break;
4842 default:
4843 break;
4844 }
4845}
4846
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004847QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848{
Jeff Johnson9d295242017-08-29 14:39:48 -07004849 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07004850 struct hdd_station_ctx *sta_ctx;
Yue Mad5b4b9f2017-05-26 16:23:40 -07004851 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004852
4853 ENTER();
4854
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304855 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
4856
Dustin Brown920397d2017-12-13 16:27:50 -08004857 hdd_for_each_adapter(hdd_ctx, adapter) {
Yue Mad5b4b9f2017-05-26 16:23:40 -07004858 hdd_notice("Disabling queues for adapter type: %d",
4859 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304860
4861 if ((adapter->device_mode == QDF_STA_MODE) ||
Kabilan Kannan00d20412017-06-04 14:20:32 -07004862 (adapter->device_mode == QDF_P2P_CLIENT_MODE))
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304863 /* Stop tdls timers */
Kabilan Kannan00d20412017-06-04 14:20:32 -07004864 hdd_notify_tdls_reset_adapter(adapter->hdd_vdev);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304865
Arun Khandavallicc544b32017-01-30 19:52:16 +05304866 if (hdd_ctx->config->sap_internal_restart &&
4867 adapter->device_mode == QDF_SAP_MODE) {
4868 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304869 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05304870 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004871 if (test_bit(SOFTAP_BSS_STARTED,
Krunal Sonib51eec72017-11-20 21:53:01 -08004872 &adapter->event_flags))
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004873 hdd_sap_indicate_disconnect_for_sta(adapter);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004874 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
4875 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05304876 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304877 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004879 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004880
Paul Zhang84fa9382017-11-10 21:18:21 +08004881 hdd_reset_scan_operation(hdd_ctx, adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -07004882 adapter->session.station.hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883
4884 hdd_deinit_tx_rx(adapter);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004885 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004886 adapter->device_mode, adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4888 hdd_wmm_adapter_close(adapter);
4889 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4890 }
4891
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05304892 if (adapter->device_mode == QDF_STA_MODE)
4893 hdd_clear_fils_connection_info(adapter);
4894
Wu Gao3545e642017-07-14 19:24:41 +08004895 if (adapter->device_mode == QDF_SAP_MODE) {
4896 /*
4897 * If adapter is SAP, set session ID to invalid
4898 * since SAP session will be cleanup during SSR.
4899 */
Wu Gao36717432016-11-21 15:09:48 +08004900 wlansap_set_invalid_session(
4901 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
4902
Wu Gao3545e642017-07-14 19:24:41 +08004903 wlansap_cleanup_cac_timer(
4904 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
4905 }
4906
Yue Mad5b4b9f2017-05-26 16:23:40 -07004907 /* Delete peers if any for STA and P2P client modes */
4908 if (adapter->device_mode == QDF_STA_MODE ||
4909 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07004910 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Yue Mad5b4b9f2017-05-26 16:23:40 -07004911 qdf_copy_macaddr(&peerMacAddr,
Jeff Johnsond377dce2017-10-04 10:32:42 -07004912 &sta_ctx->conn_info.bssId);
Yue Mad5b4b9f2017-05-26 16:23:40 -07004913
4914 hdd_objmgr_remove_peer_object(adapter->hdd_vdev,
4915 peerMacAddr.bytes);
4916 }
4917
Yue Maf9782842017-05-08 12:49:49 -07004918 /* Destroy vdev which will be recreated during reinit. */
4919 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004920 }
4921
4922 EXIT();
4923
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304924 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004925}
4926
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004927bool hdd_check_for_opened_interfaces(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304928{
Dustin Brown920397d2017-12-13 16:27:50 -08004929 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304930 bool close_modules = true;
4931
Arun Khandavalliba479c42017-07-26 21:29:40 +05304932 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4933 hdd_info("FTM mode, don't close the module");
4934 return false;
4935 }
4936
Dustin Brown920397d2017-12-13 16:27:50 -08004937 hdd_for_each_adapter(hdd_ctx, adapter) {
4938 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
4939 test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004940 hdd_debug("Still other ifaces are up cannot close modules");
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304941 close_modules = false;
4942 break;
4943 }
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304944 }
4945
4946 return close_modules;
4947}
4948
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05304949bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05304950{
4951 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
4952 return true;
4953 else
4954 return false;
4955}
4956
Anurag Chouhanc4092922016-09-08 15:56:11 +05304957#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08004958 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05304959struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
4960 struct ieee80211_channel *channel,
4961 const u8 *bssid, const u8 *ssid,
4962 size_t ssid_len)
4963{
4964 return cfg80211_get_bss(wiphy, channel, bssid,
4965 ssid, ssid_len,
4966 WLAN_CAPABILITY_ESS,
4967 WLAN_CAPABILITY_ESS);
4968}
4969#else
4970struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
4971 struct ieee80211_channel *channel,
4972 const u8 *bssid, const u8 *ssid,
4973 size_t ssid_len)
4974{
4975 return cfg80211_get_bss(wiphy, channel, bssid,
4976 ssid, ssid_len,
4977 IEEE80211_BSS_TYPE_ESS,
4978 IEEE80211_PRIVACY_ANY);
4979}
4980#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05304981
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05304982#if defined CFG80211_CONNECT_BSS || \
4983 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304984#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05304985 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304986/**
4987 * hdd_convert_timeout_reason() - Convert to kernel specific enum
4988 * @timeout_reason: reason for connect timeout
4989 *
4990 * This function is used to convert host timeout
4991 * reason enum to kernel specific enum.
4992 *
4993 * Return: nl timeout enum
4994 */
4995static enum nl80211_timeout_reason hdd_convert_timeout_reason(
4996 tSirResultCodes timeout_reason)
4997{
4998 switch (timeout_reason) {
4999 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5000 return NL80211_TIMEOUT_SCAN;
5001 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5002 return NL80211_TIMEOUT_AUTH;
5003 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5004 return NL80211_TIMEOUT_ASSOC;
5005 default:
5006 return NL80211_TIMEOUT_UNSPECIFIED;
5007 }
5008}
5009
5010/**
5011 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5012 * @dev: network device
5013 * @bssid: bssid to which we want to associate
5014 * @timeout_reason: reason for connect timeout
5015 *
5016 * This API is used to send connection timeout reason to supplicant
5017 *
5018 * Return: void
5019 */
5020static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5021 const u8 *bssid,
5022 tSirResultCodes timeout_reason)
5023{
5024 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005025
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305026 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5027
5028 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
5029 nl_timeout_reason);
5030}
5031
5032/**
5033 * __hdd_connect_bss() - API to send connection status to supplicant
5034 * @dev: network device
5035 * @bssid: bssid to which we want to associate
5036 * @req_ie: Request Information Element
5037 * @req_ie_len: len of the req IE
5038 * @resp_ie: Response IE
5039 * @resp_ie_len: len of ht response IE
5040 * @status: status
5041 * @gfp: Kernel Flag
5042 * @timeout_reason: reason for connect timeout
5043 *
5044 * Return: void
5045 */
5046static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5047 struct cfg80211_bss *bss, const u8 *req_ie,
5048 size_t req_ie_len, const u8 *resp_ie,
5049 size_t resp_ie_len, int status, gfp_t gfp,
5050 tSirResultCodes timeout_reason)
5051{
5052 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005053
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305054 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5055
5056 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5057 resp_ie, resp_ie_len, status, gfp,
5058 nl_timeout_reason);
5059}
5060#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305061#if defined CFG80211_CONNECT_TIMEOUT || \
5062 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305063static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5064 const u8 *bssid,
5065 tSirResultCodes timeout_reason)
5066{
5067 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
5068}
5069#endif
5070
5071static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5072 struct cfg80211_bss *bss, const u8 *req_ie,
5073 size_t req_ie_len, const u8 *resp_ie,
5074 size_t resp_ie_len, int status, gfp_t gfp,
5075 tSirResultCodes timeout_reason)
5076{
5077 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5078 resp_ie, resp_ie_len, status, gfp);
5079}
5080#endif
5081
Abhishek Singha84d3952016-09-13 13:45:05 +05305082/**
5083 * hdd_connect_bss() - API to send connection status to supplicant
5084 * @dev: network device
5085 * @bssid: bssid to which we want to associate
5086 * @req_ie: Request Information Element
5087 * @req_ie_len: len of the req IE
5088 * @resp_ie: Response IE
5089 * @resp_ie_len: len of ht response IE
5090 * @status: status
5091 * @gfp: Kernel Flag
5092 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305093 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05305094 *
5095 * The API is a wrapper to send connection status to supplicant
5096 *
5097 * Return: Void
5098 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305099#if defined CFG80211_CONNECT_TIMEOUT || \
5100 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05305101static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5102 struct cfg80211_bss *bss, const u8 *req_ie,
5103 size_t req_ie_len, const u8 *resp_ie,
5104 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305105 bool connect_timeout,
5106 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305107{
5108 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305109 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305110 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305111 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5112 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305113}
5114#else
5115static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5116 struct cfg80211_bss *bss, const u8 *req_ie,
5117 size_t req_ie_len, const u8 *resp_ie,
5118 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305119 bool connect_timeout,
5120 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305121{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305122 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5123 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305124}
5125#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305126
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305127#if defined(WLAN_FEATURE_FILS_SK)
5128#if defined(CFG80211_CONNECT_DONE) || \
5129 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
5130#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
5131 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305132/**
5133 * hdd_populate_fils_params() - Populate FILS keys to connect response
5134 * @fils_params: connect response to supplicant
5135 * @fils_kek: FILS kek
5136 * @fils_kek_len: FILS kek length
5137 * @pmk: FILS PMK
5138 * @pmk_len: FILS PMK length
5139 * @pmkid: PMKID
5140 * @fils_seq_num: FILS Seq number
5141 *
5142 * Return: None
5143 */
5144static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5145 *fils_params, const uint8_t *fils_kek,
5146 size_t fils_kek_len, const uint8_t *pmk,
5147 size_t pmk_len, const uint8_t *pmkid,
5148 uint16_t fils_seq_num)
5149{
5150 /* Increament seq number to be used for next FILS */
5151 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
5152 fils_params->update_erp_next_seq_num = true;
5153 fils_params->fils_kek = fils_kek;
5154 fils_params->fils_kek_len = fils_kek_len;
5155 fils_params->pmk = pmk;
5156 fils_params->pmk_len = pmk_len;
5157 fils_params->pmkid = pmkid;
5158}
5159#else
5160static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
5161 *fils_params, const uint8_t
5162 *fils_kek, size_t fils_kek_len,
5163 const uint8_t *pmk, size_t pmk_len,
5164 const uint8_t *pmkid,
5165 uint16_t fils_seq_num)
5166{ }
5167#endif
5168
Jeff Johnson172237b2017-11-07 15:32:59 -08005169void hdd_update_hlp_info(struct net_device *dev,
5170 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305171{
5172 struct sk_buff *skb;
5173 uint16_t skb_len;
5174 struct llc_snap_hdr_t *llc_hdr;
5175 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305176 uint8_t *hlp_data;
5177 uint16_t hlp_data_len;
5178 struct fils_join_rsp_params *roam_fils_params
5179 = roam_info->fils_join_rsp;
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305180 struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
5181
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305182 if (!roam_fils_params) {
5183 hdd_err("FILS Roam Param NULL");
5184 return;
5185 }
5186
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08005187 if (!roam_fils_params->hlp_data_len) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305188 hdd_err("FILS HLP Data NULL, len %d",
5189 roam_fils_params->hlp_data_len);
5190 return;
5191 }
5192
5193 hlp_data = roam_fils_params->hlp_data;
5194 hlp_data_len = roam_fils_params->hlp_data_len;
5195
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305196 /* Calculate skb length */
5197 skb_len = (2 * ETH_ALEN) + hlp_data_len;
5198 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
5199 if (skb == NULL) {
5200 hdd_err("HLP packet nbuf alloc fails");
5201 return;
5202 }
5203
5204 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
5205 QDF_MAC_ADDR_SIZE);
5206 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
5207 QDF_MAC_ADDR_SIZE);
5208
5209 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
5210 if (IS_SNAP(llc_hdr)) {
5211 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5212 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
5213 }
5214
5215 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
5216
5217 /*
5218 * This HLP packet is formed from HLP info encapsulated
5219 * in assoc response frame which is AEAD encrypted.
5220 * Hence, this checksum validation can be set unnecessary.
5221 * i.e. network layer need not worry about checksum.
5222 */
5223 skb->ip_summed = CHECKSUM_UNNECESSARY;
5224
5225 status = hdd_rx_packet_cbk(padapter, skb);
5226 if (QDF_IS_STATUS_ERROR(status)) {
5227 hdd_err("Sending HLP packet fails");
5228 return;
5229 }
5230 hdd_debug("send HLP packet to netif successfully");
5231}
5232
5233/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305234 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
5235 * @dev: network device
5236 * @bssid: bssid to which we want to associate
5237 * @bss: cfg80211 bss info
5238 * @roam_info: information about connected bss
5239 * @req_ie: Request Information Element
5240 * @req_ie_len: len of the req IE
5241 * @resp_ie: Response IE
5242 * @resp_ie_len: len of ht response IE
5243 * @status: status
5244 * @gfp: allocation flags
5245 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5246 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305247 *
5248 * This API is used as wrapper to send FILS key/sequence number
5249 * params etc. to supplicant in case of FILS connection
5250 *
5251 * Return: None
5252 */
5253static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005254 struct cfg80211_bss *bss,
5255 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305256 const u8 *req_ie, size_t req_ie_len,
5257 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005258 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305259 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305260{
5261 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305262 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5263 struct fils_join_rsp_params *roam_fils_params =
5264 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005265
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305266 qdf_mem_zero(&fils_params, sizeof(fils_params));
5267
5268 if (!roam_fils_params) {
5269 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
5270 } else {
5271 fils_params.status = status;
5272 fils_params.bssid = bssid;
5273 fils_params.timeout_reason = timeout_reason;
5274 fils_params.req_ie = req_ie;
5275 fils_params.req_ie_len = req_ie_len;
5276 fils_params.resp_ie = resp_ie;
5277 fils_params.resp_ie_len = resp_ie_len;
5278 fils_params.bss = bss;
5279 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
5280 roam_fils_params->kek_len,
5281 roam_fils_params->fils_pmk,
5282 roam_fils_params->fils_pmk_len,
5283 roam_fils_params->fils_pmkid,
5284 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05305285 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305286 }
5287 hdd_debug("FILS indicate connect status %d seq no %d",
5288 fils_params.status,
5289 fils_params.fils_erp_next_seq_num);
5290
5291 cfg80211_connect_done(dev, &fils_params, gfp);
5292
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305293 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305294 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305295
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305296 /* Clear all the FILS key info */
5297 if (roam_fils_params && roam_fils_params->fils_pmk)
5298 qdf_mem_free(roam_fils_params->fils_pmk);
5299 if (roam_fils_params)
5300 qdf_mem_free(roam_fils_params);
5301 roam_info->fils_join_rsp = NULL;
5302}
5303#else
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005304static inline void
5305hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005306 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005307 const u8 *req_ie, size_t req_ie_len,
5308 const u8 *resp_ie, size_t resp_ie_len, u16 status,
5309 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305310 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05305311{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305312#endif
5313#endif
5314
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305315#if defined(WLAN_FEATURE_FILS_SK) && \
5316 (defined(CFG80211_CONNECT_DONE) || \
5317 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305318/**
5319 * hdd_fils_update_connect_results() - API to send fils connection status to
5320 * supplicant.
5321 * @dev: network device
5322 * @bssid: bssid to which we want to associate
5323 * @bss: cfg80211 bss info
5324 * @roam_info: information about connected bss
5325 * @req_ie: Request Information Element
5326 * @req_ie_len: len of the req IE
5327 * @resp_ie: Response IE
5328 * @resp_ie_len: len of ht response IE
5329 * @status: status
5330 * @gfp: allocation flags
5331 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
5332 * @timeout_reason: reason for connect timeout
5333 *
5334 * The API is a wrapper to send connection status to supplicant
5335 *
5336 * Return: 0 if success else failure
5337 */
5338static int hdd_fils_update_connect_results(struct net_device *dev,
5339 const u8 *bssid,
5340 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005341 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305342 size_t req_ie_len, const u8 *resp_ie,
5343 size_t resp_ie_len, u16 status, gfp_t gfp,
5344 bool connect_timeout,
5345 tSirResultCodes timeout_reason)
5346{
5347 ENTER();
5348 if (!roam_info || !roam_info->is_fils_connection)
5349 return -EINVAL;
5350
5351 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
5352 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305353 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305354 return 0;
5355}
5356#else
5357static inline int hdd_fils_update_connect_results(struct net_device *dev,
5358 const u8 *bssid,
5359 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08005360 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305361 size_t req_ie_len, const u8 *resp_ie,
5362 size_t resp_ie_len, u16 status, gfp_t gfp,
5363 bool connect_timeout,
5364 tSirResultCodes timeout_reason)
5365{
5366 return -EINVAL;
5367}
5368#endif
5369
Anurag Chouhanc4092922016-09-08 15:56:11 +05305370/**
5371 * hdd_connect_result() - API to send connection status to supplicant
5372 * @dev: network device
5373 * @bssid: bssid to which we want to associate
5374 * @roam_info: information about connected bss
5375 * @req_ie: Request Information Element
5376 * @req_ie_len: len of the req IE
5377 * @resp_ie: Response IE
5378 * @resp_ie_len: len of ht response IE
5379 * @status: status
5380 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05305381 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305382 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05305383 *
5384 * The API is a wrapper to send connection status to supplicant
5385 * and allow runtime suspend
5386 *
5387 * Return: Void
5388 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05305389void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005390 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305391 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305392 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305393 bool connect_timeout,
5394 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305395{
Jeff Johnson9d295242017-08-29 14:39:48 -07005396 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305397 struct cfg80211_bss *bss = NULL;
5398
5399 if (WLAN_STATUS_SUCCESS == status) {
5400 struct ieee80211_channel *chan;
5401 int freq;
5402 int chan_no = roam_info->pBssDesc->channelId;
5403
5404 if (chan_no <= 14)
5405 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005406 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305407 else
5408 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07005409 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305410
5411 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
5412 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
5413 roam_info->u.pConnectedProfile->SSID.ssId,
5414 roam_info->u.pConnectedProfile->SSID.length);
5415 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305416
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05305417 if (hdd_fils_update_connect_results(dev, bssid, bss,
5418 roam_info, req_ie, req_ie_len, resp_ie,
5419 resp_ie_len, status, gfp, connect_timeout,
5420 timeout_reason) != 0) {
5421 hdd_connect_bss(dev, bssid, bss, req_ie,
5422 req_ie_len, resp_ie, resp_ie_len,
5423 status, gfp, connect_timeout, timeout_reason);
5424 }
Komal Seelama89be8d2016-09-29 11:09:26 +05305425
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08005426 qdf_runtime_pm_allow_suspend(&padapter->connect_rpm_ctx.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005427 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305428}
5429#else
5430void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08005431 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05305432 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05305433 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305434 bool connect_timeout,
5435 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305436{
Jeff Johnson9d295242017-08-29 14:39:48 -07005437 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Komal Seelama89be8d2016-09-29 11:09:26 +05305438
Anurag Chouhanc4092922016-09-08 15:56:11 +05305439 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
5440 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08005441
5442 qdf_runtime_pm_allow_suspend(&padapter->connect_rpm_ctx.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07005443 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05305444}
5445#endif
5446
5447
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005448QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005449{
Jeff Johnson9d295242017-08-29 14:39:48 -07005450 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005451#ifndef MSM_PLATFORM
Anurag Chouhan6d760662016-02-20 16:05:43 +05305452 struct qdf_mac_addr bcastMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005453#endif
5454 eConnectionState connState;
5455
5456 ENTER();
5457
Dustin Brown920397d2017-12-13 16:27:50 -08005458 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305459 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08005460 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05305461
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005462 hdd_wmm_init(adapter);
5463
5464 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005465 case QDF_STA_MODE:
5466 case QDF_P2P_CLIENT_MODE:
5467 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005468
5469 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
5470 ->conn_info.connState;
5471
Krunal Sonib51eec72017-11-20 21:53:01 -08005472 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005473 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07005474 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005476 /* Indicate disconnect event to supplicant
5477 * if associated previously
5478 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005479 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07005480 eConnectionState_IbssConnected == connState ||
5481 eConnectionState_NotConnected == connState ||
5482 eConnectionState_IbssDisconnected == connState ||
5483 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005484 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005485
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005486 memset(&wrqu, '\0', sizeof(wrqu));
5487 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5488 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5489 wireless_send_event(adapter->dev, SIOCGIWAP,
5490 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005491 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07005492 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005493
5494 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05305495 wlan_hdd_cfg80211_indicate_disconnect(
5496 adapter->dev, false,
5497 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005498 } else if (eConnectionState_Connecting == connState) {
5499 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005500 * Indicate connect failure to supplicant if we
5501 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005502 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05305503 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305504 NULL, 0, NULL, 0,
5505 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005506 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005507 }
5508
5509 hdd_register_tx_flow_control(adapter,
5510 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08005511 hdd_tx_resume_cb,
5512 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005513
5514 break;
5515
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005516 case QDF_SAP_MODE:
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005517 if (hdd_ctx->config->sap_internal_restart)
Krunal Sonib51eec72017-11-20 21:53:01 -08005518 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05305519
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005520 break;
5521
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005522 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005523#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005524 hdd_debug("[SSR] send stop ap to supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005525 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
5526#else
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005527 hdd_debug("[SSR] send restart supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005528 /* event supplicant to restart */
5529 cfg80211_del_sta(adapter->dev,
5530 (const u8 *)&bcastMac.bytes[0],
5531 GFP_KERNEL);
5532#endif
5533 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05305534 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08005535 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05305536 hdd_set_mon_rx_cb(adapter->dev);
5537 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
5538 adapter->mon_bandwidth);
5539 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005540 default:
5541 break;
5542 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07005543 /*
5544 * Action frame registered in one adapter which will
5545 * applicable to all interfaces
5546 */
5547 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005548 }
5549
5550 EXIT();
5551
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305552 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005553}
5554
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005555QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005556 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005557{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305558 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08005559 qdf_list_node_t *node;
5560
5561 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005562
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005563 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005564 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005565 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005566
5567 if (QDF_IS_STATUS_ERROR(status))
5568 return status;
5569
5570 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
5571
5572 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005573}
5574
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005575QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005576 struct hdd_adapter *current_adapter,
5577 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005578{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305579 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08005580 qdf_list_node_t *node;
5581
5582 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005583
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005584 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07005585 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08005586 &current_adapter->node,
5587 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005588 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005589
5590 if (QDF_IS_STATUS_ERROR(status))
5591 return status;
5592
5593 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
5594
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005595 return status;
5596}
5597
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005598QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005599 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005600{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305601 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005602
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005603 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005604 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005605 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005607 return status;
5608}
5609
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005610QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005611 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005612{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305613 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08005614 qdf_list_node_t *node;
5615
5616 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005617
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005618 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005619 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005620 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005621
5622 if (QDF_IS_STATUS_ERROR(status))
5623 return status;
5624
5625 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
5626
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005627 return status;
5628}
5629
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005630QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005631 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005632{
Anurag Chouhanffb21542016-02-17 14:33:03 +05305633 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005634
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005635 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005636 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005637 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005638
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005639 return status;
5640}
5641
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005642QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08005643 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005644{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305645 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005646
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005647 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005648 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08005649 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08005650
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005651 return status;
5652}
5653
Jeff Johnson9d295242017-08-29 14:39:48 -07005654struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005655 tSirMacAddr macAddr)
5656{
Jeff Johnson9d295242017-08-29 14:39:48 -07005657 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005658
Dustin Brown920397d2017-12-13 16:27:50 -08005659 hdd_for_each_adapter(hdd_ctx, adapter) {
5660 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
5661 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005662 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005663 }
5664
5665 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005666}
5667
Jeff Johnson9d295242017-08-29 14:39:48 -07005668struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005669 uint32_t vdev_id)
5670{
Jeff Johnson9d295242017-08-29 14:39:48 -07005671 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005672
Dustin Brown920397d2017-12-13 16:27:50 -08005673 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07005674 if (adapter->session_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005675 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005676 }
5677
Jeff Johnson5880d792016-08-15 13:32:30 -07005678 hdd_err("vdev_id %d does not exist with host", vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005679
5680 return NULL;
5681}
5682
Abhishek Singh7996eb72015-12-30 17:24:02 +05305683/**
5684 * hdd_get_adapter_by_sme_session_id() - Return adapter with
5685 * the sessionid
5686 * @hdd_ctx: hdd context.
5687 * @sme_session_id: sme session is for the adapter to get.
5688 *
5689 * This function is used to get the adapter with provided session id
5690 *
5691 * Return: adapter pointer if found
5692 *
5693 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07005694struct hdd_adapter *
5695hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
5696 uint32_t sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05305697{
Jeff Johnson9d295242017-08-29 14:39:48 -07005698 struct hdd_adapter *adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05305699
Dustin Brown920397d2017-12-13 16:27:50 -08005700 hdd_for_each_adapter(hdd_ctx, adapter) {
5701 if (adapter->session_id == sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05305702 return adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05305703 }
Dustin Brown920397d2017-12-13 16:27:50 -08005704
Abhishek Singh7996eb72015-12-30 17:24:02 +05305705 return NULL;
5706}
5707
Jeff Johnson9d295242017-08-29 14:39:48 -07005708struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07005709 const char *iface_name)
5710{
Jeff Johnson9d295242017-08-29 14:39:48 -07005711 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07005712
Dustin Brown920397d2017-12-13 16:27:50 -08005713 hdd_for_each_adapter(hdd_ctx, adapter) {
5714 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07005715 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07005716 }
Dustin Brown920397d2017-12-13 16:27:50 -08005717
Naveen Rawat4edb6822017-04-12 10:09:17 -07005718 return NULL;
5719}
5720
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005721/**
5722 * hdd_get_adapter() - to get adapter matching the mode
5723 * @hdd_ctx: hdd context
5724 * @mode: adapter mode
5725 *
5726 * This routine will return the pointer to adapter matching
5727 * with the passed mode.
5728 *
5729 * Return: pointer to adapter or null
5730 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005731struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08005732 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005733{
Jeff Johnson9d295242017-08-29 14:39:48 -07005734 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005735
Dustin Brown920397d2017-12-13 16:27:50 -08005736 hdd_for_each_adapter(hdd_ctx, adapter) {
5737 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005738 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005739 }
5740
5741 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005742}
5743
5744/**
5745 * hdd_get_operating_channel() - return operating channel of the device mode
5746 * @hdd_ctx: Pointer to the HDD context.
5747 * @mode: Device mode for which operating channel is required.
5748 * Suported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005749 * QDF_STA_MODE,
5750 * QDF_P2P_CLIENT_MODE,
5751 * QDF_SAP_MODE,
5752 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005753 *
5754 * This API returns the operating channel of the requested device mode
5755 *
5756 * Return: channel number. "0" id the requested device is not found OR it is
5757 * not connected.
5758 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005759uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08005760 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005761{
Jeff Johnson9d295242017-08-29 14:39:48 -07005762 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005763 uint8_t operatingChannel = 0;
5764
Dustin Brown920397d2017-12-13 16:27:50 -08005765 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005766 if (mode == adapter->device_mode) {
5767 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005768 case QDF_STA_MODE:
5769 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005770 if (hdd_conn_is_connected
5771 (WLAN_HDD_GET_STATION_CTX_PTR
5772 (adapter))) {
5773 operatingChannel =
5774 (WLAN_HDD_GET_STATION_CTX_PTR
5775 (adapter))->conn_info.
5776 operationChannel;
5777 }
5778 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005779 case QDF_SAP_MODE:
5780 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005781 /* softap connection info */
5782 if (test_bit
5783 (SOFTAP_BSS_STARTED,
5784 &adapter->event_flags))
5785 operatingChannel =
5786 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07005787 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005788 break;
5789 default:
5790 break;
5791 }
5792
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005793 /* Found the device of interest. break the loop */
5794 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005795 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005796 }
Dustin Brown920397d2017-12-13 16:27:50 -08005797
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005798 return operatingChannel;
5799}
5800
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005801static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005802 hdd_ctx)
5803{
Jeff Johnson9d295242017-08-29 14:39:48 -07005804 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005805
5806 ENTER();
5807
Dustin Brown920397d2017-12-13 16:27:50 -08005808 hdd_for_each_adapter(hdd_ctx, adapter) {
5809 if (adapter->device_mode == QDF_STA_MODE ||
5810 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
5811 adapter->device_mode == QDF_IBSS_MODE ||
5812 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
5813 adapter->device_mode == QDF_SAP_MODE ||
5814 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005815 wlan_hdd_cfg80211_deregister_frames(adapter);
5816 hdd_unregister_wext(adapter->dev);
5817 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005818 }
5819
5820 EXIT();
5821
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305822 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005823}
5824
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005825QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005826{
Jeff Johnson9d295242017-08-29 14:39:48 -07005827 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005828
5829 ENTER();
5830
Dustin Brown920397d2017-12-13 16:27:50 -08005831 hdd_for_each_adapter(hdd_ctx, adapter) {
5832 if (adapter->device_mode == QDF_STA_MODE ||
5833 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
5834 adapter->device_mode == QDF_IBSS_MODE ||
5835 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
5836 adapter->device_mode == QDF_SAP_MODE ||
5837 adapter->device_mode == QDF_P2P_GO_MODE) {
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07005838 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005839 adapter->session_id, INVALID_SCAN_ID,
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07005840 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005841 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005842 }
5843
5844 EXIT();
5845
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305846 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005847}
5848
Dustin Brownf27bce82016-11-03 12:52:27 -07005849/**
5850 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
5851 * adapters
5852 * @hdd_ctx: The HDD context containing the adapters to operate on
5853 *
5854 * return: QDF_STATUS_SUCCESS
5855 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005856static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07005857{
Jeff Johnson9d295242017-08-29 14:39:48 -07005858 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07005859 int err;
5860
5861 ENTER();
5862
Dustin Brown920397d2017-12-13 16:27:50 -08005863 hdd_for_each_adapter(hdd_ctx, adapter) {
5864 if (adapter->device_mode == QDF_STA_MODE ||
5865 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
5866 adapter->device_mode == QDF_IBSS_MODE ||
5867 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
5868 adapter->device_mode == QDF_SAP_MODE ||
5869 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07005870 err = wlan_hdd_sched_scan_stop(adapter->dev);
5871 if (err)
5872 hdd_err("Unable to stop scheduled scan");
5873 }
Dustin Brownf27bce82016-11-03 12:52:27 -07005874 }
5875
5876 EXIT();
5877
5878 return QDF_STATUS_SUCCESS;
5879}
5880
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005881#ifdef WLAN_NS_OFFLOAD
5882/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005883 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005884 * @hdd_ctx: Pointer to hdd context
5885 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005886 * Unregister for IPv6 address change notifications.
5887 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005888 * Return: None
5889 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005890static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005891{
5892 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005893}
5894
5895/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005896 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005897 * @hdd_ctx: Pointer to hdd context
5898 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005899 * Register for IPv6 address change notifications.
5900 *
5901 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005902 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005903static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005904{
5905 int ret;
5906
5907 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
5908 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005909 if (ret) {
5910 hdd_err("Failed to register IPv6 notifier: %d", ret);
5911 goto out;
5912 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005913
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005914 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005915out:
5916 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005917}
5918#else
5919/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005920 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005921 * @hdd_ctx: Pointer to hdd context
5922 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005923 * Unregister for IPv6 address change notifications.
5924 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005925 * Return: None
5926 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005927static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005928{
5929}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005930
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005931/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005932 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005933 * @hdd_ctx: Pointer to hdd context
5934 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005935 * Register for IPv6 address change notifications.
5936 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005937 * Return: None
5938 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005939static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005940{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005941 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005942}
5943#endif
5944
5945/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005946 * hdd_register_notifiers - Register netdev notifiers.
5947 * @hdd_ctx: HDD context
5948 *
5949 * Register netdev notifiers like IPv4 and IPv6.
5950 *
5951 * Return: 0 on success and errno on failure
5952 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005953static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005954{
5955 int ret;
5956
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005957 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
5958 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05305959 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005960
5961 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
5962 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
5963 if (ret) {
5964 hdd_err("Failed to register IPv4 notifier: %d", ret);
5965 goto unregister_ip6_notifier;
5966 }
5967
5968 return 0;
5969
5970unregister_ip6_notifier:
5971 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005972out:
5973 return ret;
5974
5975}
5976
5977/**
5978 * hdd_unregister_notifiers - Unregister netdev notifiers.
5979 * @hdd_ctx: HDD context
5980 *
5981 * Unregister netdev notifiers like IPv4 and IPv6.
5982 *
5983 * Return: None.
5984 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005985void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005986{
5987 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
5988
5989 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005990}
5991
5992/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005993 * hdd_exit_netlink_services - Exit netlink services
5994 * @hdd_ctx: HDD context
5995 *
5996 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
5997 * nl service.
5998 *
5999 * Return: None.
6000 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006001static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006002{
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006003 hdd_close_cesium_nl_sock();
Naveen Rawat910726a2017-03-06 11:42:51 -08006004 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006005 ptt_sock_deactivate_svc();
6006
6007 nl_srv_exit();
6008}
6009
6010/**
6011 * hdd_init_netlink_services- Init netlink services
6012 * @hdd_ctx: HDD context
6013 *
6014 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
6015 * nl service.
6016 *
6017 * Return: 0 on success and errno on failure.
6018 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006019static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006020{
6021 int ret;
6022
Ryan Hsuceddceb2016-04-28 10:20:14 -07006023 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006024 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006025 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006026 goto out;
6027 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07006028 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006029
Naveen Rawat910726a2017-03-06 11:42:51 -08006030 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006031 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006032 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006033 goto err_nl_srv;
6034 }
6035
6036 ret = ptt_sock_activate_svc();
6037 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006038 hdd_err("ptt_sock_activate_svc failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006039 goto err_nl_srv;
6040 }
6041
6042 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07006043 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006044 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006045
6046 ret = cnss_diag_activate_service();
6047 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006048 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006049 goto err_close_cesium;
6050 }
6051
6052 return 0;
6053
6054err_close_cesium:
6055 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006056 ptt_sock_deactivate_svc();
6057err_nl_srv:
6058 nl_srv_exit();
6059out:
6060 return ret;
6061}
6062
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006063/**
6064 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
6065 * @hdd_ctx: HDD context.
6066 *
6067 * Destroy RX wakelock.
6068 *
6069 * Return: None.
6070 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006071static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006072{
6073 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
6074}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08006075
6076/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006077 * hdd_rx_wake_lock_create() - Create RX wakelock
6078 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006079 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006080 * Create RX wakelock.
6081 *
6082 * Return: None.
6083 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006084static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006085{
6086 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
6087}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006088
6089/**
Houston Hoffman160db392016-10-10 17:37:51 -07006090 * hdd_context_deinit() - Deinitialize HDD context
6091 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006092 *
Houston Hoffman160db392016-10-10 17:37:51 -07006093 * Deinitialize HDD context along with all the feature specific contexts but
6094 * do not free hdd context itself. Caller of this API is supposed to free
6095 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006096 *
Houston Hoffman160db392016-10-10 17:37:51 -07006097 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006098 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006099static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006100{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306101 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
6102
Houston Hoffman160db392016-10-10 17:37:51 -07006103 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006104
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006105 hdd_sap_context_destroy(hdd_ctx);
6106
6107 hdd_rx_wake_lock_destroy(hdd_ctx);
6108
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006109 hdd_scan_context_destroy(hdd_ctx);
6110
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006111 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006112
Houston Hoffman160db392016-10-10 17:37:51 -07006113 return 0;
6114}
6115
6116/**
6117 * hdd_context_destroy() - Destroy HDD context
6118 * @hdd_ctx: HDD context to be destroyed.
6119 *
6120 * Free config and HDD context as well as destroy all the resources.
6121 *
6122 * Return: None
6123 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006124static void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07006125{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07006126 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05306127
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05306128 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
6129
Houston Hoffman160db392016-10-10 17:37:51 -07006130 hdd_context_deinit(hdd_ctx);
6131
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306132 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08006133 hdd_ctx->config = NULL;
6134
6135 wiphy_free(hdd_ctx->wiphy);
6136}
6137
6138/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05306139 * wlan_destroy_bug_report_lock() - Destroy bug report lock
6140 *
6141 * This function is used to destroy bug report lock
6142 *
6143 * Return: None
6144 */
6145static void wlan_destroy_bug_report_lock(void)
6146{
6147 p_cds_contextType p_cds_context;
6148
6149 p_cds_context = cds_get_global_context();
6150 if (!p_cds_context) {
6151 hdd_err("cds context is NULL");
6152 return;
6153 }
6154
6155 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
6156}
6157
6158/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006159 * hdd_wlan_exit() - HDD WLAN exit function
6160 * @hdd_ctx: Pointer to the HDD Context
6161 *
6162 * This is the driver exit point (invoked during rmmod)
6163 *
6164 * Return: None
6165 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006166static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006167{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006168 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05306169 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006170
6171 ENTER();
6172
Dustin Brown6f427922017-09-19 12:19:00 -07006173 qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
Arun Khandavallifae92942016-08-01 13:31:08 +05306174
6175 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006176
Prashanth Bhattaab004382016-10-11 16:08:11 -07006177 hdd_bus_bandwidth_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006178
6179#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05306180 if (QDF_TIMER_STATE_RUNNING ==
6181 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
6182 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006183 }
6184
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306185 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05306186 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07006187 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006188 }
Liangwei Dongaef84342016-10-21 05:28:00 -04006189 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6190 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6191 hdd_ctx->last_acs_channel_list = NULL;
6192 hdd_ctx->num_of_channels = 0;
6193 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006194#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006195
Arun Khandavallifae92942016-08-01 13:31:08 +05306196 mutex_lock(&hdd_ctx->iface_change_lock);
6197 driver_status = hdd_ctx->driver_status;
6198 mutex_unlock(&hdd_ctx->iface_change_lock);
6199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006200 /*
6201 * Powersave Offload Case
6202 * Disable Idle Power Save Mode
6203 */
6204 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07006205 /* clear the scan queue in all the scenarios */
6206 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006207
Arun Khandavallifae92942016-08-01 13:31:08 +05306208 if (driver_status != DRIVER_MODULES_CLOSED) {
6209 hdd_unregister_wext_all_adapters(hdd_ctx);
6210 /*
6211 * Cancel any outstanding scan requests. We are about to close
6212 * all of our adapters, but an adapter structure is what SME
6213 * passes back to our callback function. Hence if there
6214 * are any outstanding scan requests then there is a
6215 * race condition between when the adapter is closed and
6216 * when the callback is invoked. We try to resolve that
6217 * race condition here by canceling any outstanding scans
6218 * before we close the adapters.
6219 * Note that the scans may be cancelled in an asynchronous
6220 * manner, so ideally there needs to be some kind of
6221 * synchronization. Rather than introduce a new
6222 * synchronization here, we will utilize the fact that we are
6223 * about to Request Full Power, and since that is synchronized,
6224 * the expectation is that by the time Request Full Power has
6225 * completed, all scans will be cancelled
6226 */
6227 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07006228 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Brown27cd9942017-09-27 16:11:44 -07006229 hdd_stop_all_adapters(hdd_ctx, true);
bings29c99862017-11-01 13:54:13 +08006230 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006231 }
6232
Arun Khandavalli08479ba2017-08-07 19:56:23 +05306233 unregister_netdevice_notifier(&hdd_netdev_notifier);
6234
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07006235 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05306236
Dustin Brown021cecd2017-12-11 13:56:43 -08006237 memdump_deinit();
6238 hdd_driver_memdump_deinit();
6239
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05306240 qdf_nbuf_deinit_replenish_timer();
6241
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05306242 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
6243 hdd_info("Release wakelock for monitor mode!");
6244 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
6245 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
6246 }
6247
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05306248 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
6249 qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
6250 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
6251
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006252 /*
6253 * Close CDS
6254 * This frees pMac(HAL) context. There should not be any call
6255 * that requires pMac access after this.
6256 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006257
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07006258 hdd_green_ap_deinit(hdd_ctx);
Jeff Johnsonce0032c2017-01-20 07:18:27 -08006259 hdd_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006260
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08006261 hdd_close_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006262
6263 hdd_ipa_cleanup(hdd_ctx);
6264
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05306265 wlansap_global_deinit();
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05306266 wlan_hdd_deinit_chan_info(hdd_ctx);
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306267 /*
6268 * If there is re_init failure wiphy would have already de-registered
6269 * check the wiphy status before un-registering again
6270 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05306271 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306272 wiphy_unregister(wiphy);
6273 wlan_hdd_cfg80211_deinit(wiphy);
6274 hdd_lpass_notify_stop(hdd_ctx);
6275 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07006276
Arun Khandavallifae92942016-08-01 13:31:08 +05306277 hdd_exit_netlink_services(hdd_ctx);
6278 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05306279#ifdef FEATURE_WLAN_CH_AVOID
6280 mutex_destroy(&hdd_ctx->avoid_freq_lock);
6281#endif
Abhishek Singhe9068f12017-03-31 14:14:52 +05306282
Abhishek Singhe9068f12017-03-31 14:14:52 +05306283 driver_status = hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
6284 if (driver_status)
6285 hdd_err("Psoc delete failed");
Dustin Brown6f17a022017-07-19 13:40:55 -07006286
Prashanth Bhatta527fd752016-04-28 12:35:23 -07006287 hdd_context_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006288}
6289
6290void __hdd_wlan_exit(void)
6291{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006292 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293
6294 ENTER();
6295
Anurag Chouhan6d760662016-02-20 16:05:43 +05306296 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006297 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006298 hdd_err("Invalid HDD Context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006299 EXIT();
6300 return;
6301 }
6302
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006303 /* Do all the cleanup before deregistering the driver */
6304 hdd_wlan_exit(hdd_ctx);
Mohit Khannaebf8a862016-04-28 17:53:59 -07006305
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006306 EXIT();
6307}
6308
6309#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04006310/**
6311 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006312 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04006313 *
6314 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
6315 * Then new ACS request will do a fresh scan without reusing the cached
6316 * scan information.
6317 *
6318 * Return: void
6319 */
Tang Yingying523322d2017-01-17 23:28:43 +08006320static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006321{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006322 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006323
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006324 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006325 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04006326 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
6327 qdf_mem_free(hdd_ctx->last_acs_channel_list);
6328 hdd_ctx->last_acs_channel_list = NULL;
6329 hdd_ctx->num_of_channels = 0;
6330 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006331
6332 if (!hdd_ctx->hHal)
6333 return;
6334 sme_scan_flush_result(hdd_ctx->hHal);
6335}
6336#endif
6337
6338#ifdef QCA_HT_2040_COEX
Jeff Johnsone7672e72017-10-21 15:10:04 -07006339int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
6340 struct qdf_mac_addr sta_mac, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006341{
6342 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306343 QDF_STATUS qdf_status;
Jeff Johnsone7672e72017-10-21 15:10:04 -07006344 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006345
6346 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6347
6348 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306349 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006350 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306351
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006352 if (!hdd_ctx->hHal)
6353 return -EINVAL;
6354
Jeff Johnsone7672e72017-10-21 15:10:04 -07006355 qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, sta_id, sta_mac,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006356 adapter->session_id, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306357 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006358 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006359 return -EINVAL;
6360 }
6361
6362 return 0;
6363}
6364#endif
6365
6366/**
6367 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
6368 * @state: state
6369 *
6370 * This function notifies FW with modem power status
6371 *
6372 * Return: 0 if successful, error number otherwise
6373 */
6374int hdd_wlan_notify_modem_power_state(int state)
6375{
6376 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306377 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006378 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006379
Anurag Chouhan6d760662016-02-20 16:05:43 +05306380 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006381 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306382 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006383 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306384
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006385 if (!hdd_ctx->hHal)
6386 return -EINVAL;
6387
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306388 qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
6389 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006390 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006391 state);
6392 return -EINVAL;
6393 }
6394 return 0;
6395}
6396
6397/**
6398 *
6399 * hdd_post_cds_enable_config() - HDD post cds start config helper
6400 * @adapter - Pointer to the HDD
6401 *
6402 * Return: None
6403 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006404QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006405{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306406 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006407
6408 /*
6409 * Send ready indication to the HDD. This will kick off the MAC
6410 * into a 'running' state and should kick off an initial scan.
6411 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306412 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
6413 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006414 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
6415 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306416 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006417 }
6418
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306419 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006420}
6421
6422/* wake lock APIs for HDD */
6423void hdd_prevent_suspend(uint32_t reason)
6424{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05306425 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006426}
6427
6428void hdd_allow_suspend(uint32_t reason)
6429{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05306430 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006431}
6432
6433void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
6434{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05306435 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
6436 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006437}
6438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006439/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006440QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006441{
Amar Singhal5cccafe2017-02-15 12:42:58 -08006442
Amar Singhal6f8592b2017-04-26 14:31:58 -07006443 return sme_init_chan_list(hdd_ctx->hHal,
6444 hdd_ctx->reg.alpha2,
6445 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006446}
6447
6448/**
6449 * hdd_is_5g_supported() - check if hardware supports 5GHz
6450 * @hdd_ctx: Pointer to the hdd context
6451 *
6452 * HDD function to know if hardware supports 5GHz
6453 *
6454 * Return: true if hardware supports 5GHz
6455 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006456bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006457{
Amar Singhal58b45ef2017-08-01 13:43:54 -07006458 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08006459 return true;
6460
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08006461 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08006462 return true;
6463 else
6464 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006465}
6466
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006467static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006468{
6469 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07006470 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006471
6472 wiphy = hdd_ctx->wiphy;
6473
6474 /*
6475 * The channel information in
6476 * wiphy needs to be initialized before wiphy registration
6477 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006478 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
6479 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006480 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07006481 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006482 }
6483
6484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
6485 wiphy->wowlan = &wowlan_support_reg_init;
6486#else
6487 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
6488 WIPHY_WOWLAN_MAGIC_PKT |
6489 WIPHY_WOWLAN_DISCONNECT |
6490 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
6491 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
6492 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
6493 WIPHY_WOWLAN_4WAY_HANDSHAKE |
6494 WIPHY_WOWLAN_RFKILL_RELEASE;
6495
6496 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
6497 WOW_MAX_FILTERS_PER_LIST);
6498 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
6499 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
6500#endif
6501
6502 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006503 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306504 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07006505 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306506 return ret_val;
6507 }
6508
Amar Singhal5cccafe2017-02-15 12:42:58 -08006509 if (!hdd_ctx->reg_offload)
6510 hdd_program_country_code(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006511
Amar Singhale4f28ee2015-10-21 14:36:56 -07006512 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006513}
6514
Mohit Khannaca4173b2017-09-12 21:52:19 -07006515#ifdef MSM_PLATFORM
6516/**
6517 * hdd_display_periodic_stats() - Function to display periodic stats
6518 * @hdd_ctx - handle to hdd context
6519 * @bool data_in_interval - true, if data detected in bw time interval
6520 *
6521 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
6522 * Stats show up in wlan driver logs.
6523 *
6524 * Returns: None
6525 */
6526static inline
6527void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
6528 bool data_in_interval)
6529{
6530 static u32 counter;
6531 static bool data_in_time_period;
6532 ol_txrx_pdev_handle pdev;
6533
6534 if (hdd_ctx->config->periodic_stats_disp_time == 0)
6535 return;
6536
6537 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
6538 if (!pdev) {
6539 hdd_err("pdev is NULL");
6540 return;
6541 }
6542
6543 counter++;
6544 if (data_in_interval)
6545 data_in_time_period = data_in_interval;
6546
6547 if (counter * hdd_ctx->config->busBandwidthComputeInterval >=
6548 hdd_ctx->config->periodic_stats_disp_time * 1000) {
6549 if (data_in_time_period) {
6550 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
6551 CDP_TXRX_PATH_STATS,
6552 QDF_STATS_VERBOSITY_LEVEL_LOW);
6553 wlan_hdd_display_netif_queue_history
6554 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
6555 qdf_dp_trace_dump_stats();
6556 }
6557 counter = 0;
6558 data_in_time_period = false;
6559 }
6560}
6561
Ravi Joshie2331e82015-07-01 18:18:54 -07006562/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07006563 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07006564 * @hdd_ctx - handle to hdd context
6565 * @tx_packets - transmit packet count
6566 * @rx_packets - receive packet count
6567 *
6568 * The function controls the bus bandwidth and dynamic control of
6569 * tcp delayed ack configuration
6570 *
6571 * Returns: None
6572 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07006573
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006574static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07006575 const uint64_t tx_packets,
6576 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006577{
Mohit Khannaca4173b2017-09-12 21:52:19 -07006578 u64 total_pkts = tx_packets + rx_packets;
Mohit Khannae71e2262015-11-10 09:37:24 -08006579 uint64_t temp_rx = 0;
6580 uint64_t temp_tx = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07006581 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08006582 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08006583 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07006584 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006585 uint16_t index = 0;
6586 bool vote_level_change = false;
6587 bool rx_level_change = false;
6588 bool tx_level_change = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006589
Mohit Khannaca4173b2017-09-12 21:52:19 -07006590 if (total_pkts > hdd_ctx->config->busBandwidthHighThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006591 next_vote_level = PLD_BUS_WIDTH_HIGH;
Mohit Khannaca4173b2017-09-12 21:52:19 -07006592 else if (total_pkts > hdd_ctx->config->busBandwidthMediumThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006593 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
Mohit Khannaca4173b2017-09-12 21:52:19 -07006594 else if (total_pkts > hdd_ctx->config->busBandwidthLowThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006595 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07006596 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07006597 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006598
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006599 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07006600 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
6601 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006602 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006603 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07006604 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Nirav Shah3bbfa512016-05-12 16:43:49 +05306605 if (next_vote_level == PLD_BUS_WIDTH_LOW) {
Nirav Shahffc6a092016-06-09 16:09:08 +05306606 if (hdd_ctx->hbw_requested) {
6607 pld_remove_pm_qos(hdd_ctx->parent_dev);
6608 hdd_ctx->hbw_requested = false;
6609 }
Nirav Shah3bbfa512016-05-12 16:43:49 +05306610 if (cds_sched_handle_throughput_req(false))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006611 hdd_warn("low bandwidth set rx affinity fail");
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07006612 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05306613 if (!hdd_ctx->hbw_requested) {
6614 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
6615 hdd_ctx->hbw_requested = true;
6616 }
6617
Nirav Shah3bbfa512016-05-12 16:43:49 +05306618 if (cds_sched_handle_throughput_req(true))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006619 hdd_warn("high bandwidth set rx affinity fail");
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07006620 }
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -07006621 hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006622 }
Mohit Khannae71e2262015-11-10 09:37:24 -08006623
Mohit Khannaf8f96822017-05-17 17:11:59 -07006624 qdf_dp_trace_throttle_live_mode(
6625 (next_vote_level > PLD_BUS_WIDTH_NONE) ? true : false);
6626
Mohit Khannae71e2262015-11-10 09:37:24 -08006627 /* fine-tuning parameters for RX Flows */
6628 temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
6629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006630 hdd_ctx->prev_rx = rx_packets;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08006631
Poddar, Siddarth47c23402017-10-25 12:17:39 +05306632 if (temp_rx < hdd_ctx->config->busBandwidthLowThreshold)
6633 hdd_disable_lro_for_low_tput(hdd_ctx, true);
6634 else
6635 hdd_disable_lro_for_low_tput(hdd_ctx, false);
6636
Ravi Joshifed83572016-10-07 16:20:37 -07006637 if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) {
6638 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
6639 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
6640 next_rx_level = WLAN_SVC_TP_HIGH;
6641 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07006642 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07006643 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08006644 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07006645 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006646
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006647 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07006648 struct wlan_rx_tp_data rx_tp_data = {0};
6649
Ravi Joshie2331e82015-07-01 18:18:54 -07006650 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006651 next_rx_level, temp_rx);
6652 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006653 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07006654 /* Send throughput indication only if it is enabled.
6655 * Disabling tcp_del_ack will revert the tcp stack behavior
6656 * to default delayed ack. Note that this will disable the
6657 * dynamic delayed ack mechanism across the system
6658 */
6659 if (hdd_ctx->config->enable_tcp_delack)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07006660 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
6661
Mohit Khanna6272fb682017-04-13 09:34:36 -07006662 if (hdd_ctx->config->enable_tcp_adv_win_scale)
6663 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
6664
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07006665 rx_tp_data.level = next_rx_level;
6666 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
6667 WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
6668 sizeof(rx_tp_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006669 }
6670
Mohit Khannae71e2262015-11-10 09:37:24 -08006671 /* fine-tuning parameters for TX Flows */
6672 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
6673 hdd_ctx->prev_tx = tx_packets;
6674 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
6675 next_tx_level = WLAN_SVC_TP_HIGH;
6676 else
6677 next_tx_level = WLAN_SVC_TP_LOW;
6678
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006679 if (hdd_ctx->cur_tx_level != next_tx_level) {
Mohit Khannae71e2262015-11-10 09:37:24 -08006680 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
6681 next_tx_level, temp_tx);
6682 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006683 tx_level_change = true;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05306684 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
6685 WLAN_SVC_WLAN_TP_TX_IND,
Mohit Khannae71e2262015-11-10 09:37:24 -08006686 &next_tx_level,
6687 sizeof(next_tx_level));
6688 }
6689
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006690 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006691 if (vote_level_change || tx_level_change || rx_level_change) {
6692 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
6693 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
6694 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
6695 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
6696 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
6697 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
6698 hdd_ctx->hdd_txrx_hist_idx++;
6699 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
6700 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07006701
6702 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006703}
6704
6705#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306706static void hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006707{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006708 struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306709 bus_bw_work);
Jeff Johnson9d295242017-08-29 14:39:48 -07006710 struct hdd_adapter *adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306711 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05306712 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
6713 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006714 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306715 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006716 bool connected = false;
6717 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
6718
Prashanth Bhattaab004382016-10-11 16:08:11 -07006719 if (wlan_hdd_validate_context(hdd_ctx))
6720 return;
6721
Jeff Johnson214671b2017-10-30 19:45:23 -07006722 if (hdd_ctx->is_wiphy_suspended)
Jingxiang Gec64e1932017-08-22 14:38:59 +08006723 goto restart_timer;
6724
Dustin Brown920397d2017-12-13 16:27:50 -08006725 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05306726 /*
6727 * Validate magic so we don't end up accessing
6728 * an invalid adapter.
6729 */
6730 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
6731 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006732
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006733 if ((adapter->device_mode == QDF_STA_MODE ||
6734 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006735 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
6736 != eConnectionState_Associated) {
6737
6738 continue;
6739 }
6740
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006741 if ((adapter->device_mode == QDF_SAP_MODE ||
6742 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07006743 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006744
6745 continue;
6746 }
6747
6748 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
6749 adapter->prev_tx_packets);
6750 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
6751 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306752
6753 if (adapter->device_mode == QDF_SAP_MODE ||
6754 adapter->device_mode == QDF_P2P_GO_MODE ||
6755 adapter->device_mode == QDF_IBSS_MODE) {
6756
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08006757 ret = cdp_get_intra_bss_fwd_pkts_count(
6758 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07006759 adapter->session_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306760 &fwd_tx_packets, &fwd_rx_packets);
6761 if (ret == A_OK) {
6762 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
6763 fwd_tx_packets,
6764 adapter->prev_fwd_tx_packets);
6765 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
6766 fwd_tx_packets,
6767 adapter->prev_fwd_rx_packets);
6768 }
6769 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006770
6771 total_rx += adapter->stats.rx_packets;
6772 total_tx += adapter->stats.tx_packets;
6773
6774 spin_lock_bh(&hdd_ctx->bus_bw_lock);
6775 adapter->prev_tx_packets = adapter->stats.tx_packets;
6776 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306777 adapter->prev_fwd_tx_packets = fwd_tx_packets;
6778 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006779 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
6780 connected = true;
6781 }
6782
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306783 /* add intra bss forwarded tx and rx packets */
6784 tx_packets += fwd_tx_packets_diff;
6785 rx_packets += fwd_rx_packets_diff;
6786
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006787 hdd_ipa_uc_stat_query(hdd_ctx, &ipa_tx_packets, &ipa_rx_packets);
6788 tx_packets += (uint64_t)ipa_tx_packets;
6789 rx_packets += (uint64_t)ipa_rx_packets;
6790
Yun Park2aa880c2017-08-22 10:58:10 -07006791 if (adapter) {
6792 adapter->stats.tx_packets += ipa_tx_packets;
6793 adapter->stats.rx_packets += ipa_rx_packets;
6794 }
6795
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006796 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006797 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006798 return;
6799 }
6800
Yuanyuan Liu13738502016-04-06 17:41:37 -07006801 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006802
6803 hdd_ipa_set_perf_level(hdd_ctx, tx_packets, rx_packets);
6804 hdd_ipa_uc_stat_request(adapter, 2);
6805
Jingxiang Gec64e1932017-08-22 14:38:59 +08006806restart_timer:
Dustin Brown2ed60362017-01-18 12:25:50 -08006807 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08006808 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08006809 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05306810 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
Dustin Brownfce08d12017-01-17 16:29:38 -08006811 hdd_ctx->config->busBandwidthComputeInterval);
Dustin Brownfce08d12017-01-17 16:29:38 -08006812 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006813}
Prashanth Bhattaab004382016-10-11 16:08:11 -07006814
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306815/**
6816 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
6817 * @arg: Argument of timer function
6818 *
6819 * Schedule a workqueue in this function where all the processing is done.
6820 *
6821 * Return: None.
6822 */
6823static void __hdd_bus_bw_cbk(void *arg)
6824{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006825 struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306826
6827 if (wlan_hdd_validate_context(hdd_ctx))
6828 return;
6829
6830 schedule_work(&hdd_ctx->bus_bw_work);
6831}
6832
6833/**
6834 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
6835 * @arg: Argument of timer function
6836 *
6837 * Return: None.
6838 */
6839static void hdd_bus_bw_cbk(void *arg)
6840{
6841 cds_ssr_protect(__func__);
6842 __hdd_bus_bw_cbk(arg);
6843 cds_ssr_unprotect(__func__);
6844}
6845
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006846int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07006847{
6848 spin_lock_init(&hdd_ctx->bus_bw_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306849 INIT_WORK(&hdd_ctx->bus_bw_work,
6850 hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08006851 hdd_ctx->bus_bw_timer_running = false;
6852 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306853 qdf_timer_init(NULL,
6854 &hdd_ctx->bus_bw_timer,
6855 hdd_bus_bw_cbk, (void *)hdd_ctx,
6856 QDF_TIMER_TYPE_SW);
Prashanth Bhattaab004382016-10-11 16:08:11 -07006857
6858 return 0;
6859}
6860
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006861void hdd_bus_bandwidth_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07006862{
Dustin Brownfce08d12017-01-17 16:29:38 -08006863 if (hdd_ctx->bus_bw_timer_running)
Prashanth Bhattaab004382016-10-11 16:08:11 -07006864 hdd_reset_tcp_delack(hdd_ctx);
6865
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006866 hdd_debug("wait for bus bw work to flush");
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306867 cancel_work_sync(&hdd_ctx->bus_bw_work);
6868 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08006869 hdd_ctx->bus_bw_timer_running = false;
6870 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Prashanth Bhattaab004382016-10-11 16:08:11 -07006871}
Lin Baic5c06882017-09-21 13:58:43 +08006872
6873void hdd_bus_bw_cancel_work(struct hdd_context *hdd_ctx)
6874{
6875 if (hdd_ctx)
6876 cancel_work_sync(&hdd_ctx->bus_bw_work);
6877}
jiadcdaf9bd2017-10-26 12:20:21 +08006878
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006879#endif
6880
6881/**
Nirav Shahed34b212016-04-25 10:59:16 +05306882 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
6883 * @hdd_ctx: hdd context
6884 *
6885 * Return: 0 for success or error code
6886 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006887static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05306888{
6889 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
6890 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
6891 if (hdd_ctx->hdd_txrx_hist == NULL) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006892 hdd_err("Failed malloc for hdd_txrx_hist");
Nirav Shahed34b212016-04-25 10:59:16 +05306893 return -ENOMEM;
6894 }
6895 return 0;
6896}
6897
6898/**
6899 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
6900 * @hdd_ctx: hdd context
6901 *
6902 * Return: none
6903 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006904void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05306905{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306906 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
6907 return;
6908
6909 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
6910 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05306911}
6912
Nirav Shahda008342016-05-17 18:50:40 +05306913static uint8_t *convert_level_to_string(uint32_t level)
6914{
6915 switch (level) {
6916 /* initialize the wlan sub system */
6917 case WLAN_SVC_TP_NONE:
6918 return "NONE";
6919 case WLAN_SVC_TP_LOW:
6920 return "LOW";
6921 case WLAN_SVC_TP_MEDIUM:
6922 return "MED";
6923 case WLAN_SVC_TP_HIGH:
6924 return "HIGH";
6925 default:
6926 return "INVAL";
6927 }
6928}
6929
Nirav Shahed34b212016-04-25 10:59:16 +05306930
6931/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006932 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
6933 * @hdd_ctx: hdd context
6934 *
6935 * Return: none
6936 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006937void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006938{
6939 int i;
6940
6941#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006942 hdd_debug("BW compute Interval: %dms",
Nirav Shahda008342016-05-17 18:50:40 +05306943 hdd_ctx->config->busBandwidthComputeInterval);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006944 hdd_debug("BW High TH: %d BW Med TH: %d BW Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006945 hdd_ctx->config->busBandwidthHighThreshold,
6946 hdd_ctx->config->busBandwidthMediumThreshold,
6947 hdd_ctx->config->busBandwidthLowThreshold);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006948 hdd_debug("Enable TCP DEL ACK: %d",
Nirav Shahda008342016-05-17 18:50:40 +05306949 hdd_ctx->config->enable_tcp_delack);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006950 hdd_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006951 hdd_ctx->config->tcpDelackThresholdHigh,
6952 hdd_ctx->config->tcpDelackThresholdLow);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006953 hdd_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
Nirav Shahda008342016-05-17 18:50:40 +05306954 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006955#endif
6956
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006957 hdd_debug("Total entries: %d Current index: %d",
Nirav Shahda008342016-05-17 18:50:40 +05306958 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
6959
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006960 hdd_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006961
6962 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006963 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006964 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Houston Hoffman00227112017-08-14 23:58:18 -07006965 hdd_log(QDF_TRACE_LEVEL_DEBUG,
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006966 "[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
6967 i, hdd_ctx->hdd_txrx_hist[i].qtime,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006968 hdd_ctx->hdd_txrx_hist[i].interval_rx,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006969 hdd_ctx->hdd_txrx_hist[i].interval_tx,
6970 convert_level_to_string(
6971 hdd_ctx->hdd_txrx_hist[i].
6972 next_vote_level),
6973 convert_level_to_string(
6974 hdd_ctx->hdd_txrx_hist[i].
6975 next_rx_level),
6976 convert_level_to_string(
6977 hdd_ctx->hdd_txrx_hist[i].
6978 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006979 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006980}
6981
6982/**
6983 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
6984 * @hdd_ctx: hdd context
6985 *
6986 * Return: none
6987 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006988void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006989{
6990 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05306991 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
6992 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006993}
6994
Mohit Khannaca4173b2017-09-12 21:52:19 -07006995/* length of the netif queue log needed per adapter */
6996#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
6997
6998/**
6999 *
7000 * hdd_display_netif_queue_history_compact() - display compact netifq history
7001 * @hdd_ctx: hdd context
7002 *
7003 * Return: none
7004 */
7005static void
7006hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
7007{
7008 int adapter_num = 0;
7009 int i;
7010 int bytes_written;
7011 u32 tbytes;
7012 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007013 char temp_str[20 * WLAN_REASON_TYPE_MAX];
7014 char comb_log_str[(ADAP_NETIFQ_LOG_LEN * MAX_NUMBER_OF_ADAPTERS) + 1];
7015 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007016
7017 bytes_written = 0;
7018 qdf_mem_set(comb_log_str, 0, sizeof(comb_log_str));
Mohit Khannaca4173b2017-09-12 21:52:19 -07007019
Dustin Brown920397d2017-12-13 16:27:50 -08007020 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07007021 curr_time = qdf_system_ticks();
7022 total = curr_time - adapter->start_time;
7023 delta = curr_time - adapter->last_time;
7024
7025 if (adapter->pause_map) {
7026 pause = adapter->total_pause_time + delta;
7027 unpause = adapter->total_unpause_time;
7028 } else {
7029 unpause = adapter->total_unpause_time + delta;
7030 pause = adapter->total_pause_time;
7031 }
7032
7033 tbytes = 0;
7034 qdf_mem_set(temp_str, 0, sizeof(temp_str));
7035 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7036 if (adapter->queue_oper_stats[i].pause_count == 0)
7037 continue;
7038 tbytes +=
7039 snprintf(
7040 &temp_str[tbytes],
7041 (tbytes >= sizeof(temp_str) ?
7042 0 : sizeof(temp_str) - tbytes),
7043 "%d(%d,%d) ",
7044 i,
7045 adapter->queue_oper_stats[i].
7046 pause_count,
7047 adapter->queue_oper_stats[i].
7048 unpause_count);
7049 }
7050 if (tbytes >= sizeof(temp_str))
7051 hdd_warn("log truncated");
7052
7053 bytes_written += snprintf(&comb_log_str[bytes_written],
7054 bytes_written >= sizeof(comb_log_str) ? 0 :
7055 sizeof(comb_log_str) - bytes_written,
7056 "[%d %d] (%d) %u/%ums %s|",
7057 adapter->session_id, adapter->device_mode,
7058 adapter->pause_map,
7059 qdf_system_ticks_to_msecs(pause),
7060 qdf_system_ticks_to_msecs(total),
7061 temp_str);
7062
Mohit Khannaca4173b2017-09-12 21:52:19 -07007063 adapter_num++;
7064 }
7065
7066 /* using QDF_TRACE to avoid printing function name */
7067 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
7068 "STATS |%s", comb_log_str);
7069
7070 if (bytes_written >= sizeof(comb_log_str))
7071 hdd_warn("log string truncated");
7072}
7073
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007074/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007075 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07007076 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007077 *
7078 * Return: none
7079 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007080void
7081wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
7082 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007083{
7084
Jeff Johnson9d295242017-08-29 14:39:48 -07007085 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007086 int i;
Nirav Shahda008342016-05-17 18:50:40 +05307087 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007088
Mohit Khannaca4173b2017-09-12 21:52:19 -07007089 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
7090 hdd_display_netif_queue_history_compact(hdd_ctx);
7091 return;
7092 }
7093
Dustin Brown920397d2017-12-13 16:27:50 -08007094 hdd_for_each_adapter(hdd_ctx, adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007095 hdd_debug("Netif queue operation statistics:");
7096 hdd_debug("Session_id %d device mode %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07007097 adapter->session_id, adapter->device_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007098 hdd_debug("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05307099 curr_time = qdf_system_ticks();
7100 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05307101 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05307102 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05307103 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307104 unpause = adapter->total_unpause_time;
7105 } else {
Nirav Shahda008342016-05-17 18:50:40 +05307106 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05307107 pause = adapter->total_pause_time;
7108 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007109 hdd_debug("Total: %ums Pause: %ums Unpause: %ums",
Nirav Shah617cff92016-04-25 10:24:24 +05307110 qdf_system_ticks_to_msecs(total),
7111 qdf_system_ticks_to_msecs(pause),
7112 qdf_system_ticks_to_msecs(unpause));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007113 hdd_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007114
Nirav Shahda008342016-05-17 18:50:40 +05307115 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
7116 qdf_time_t pause_delta = 0;
7117
7118 if (adapter->pause_map & (1 << i))
7119 pause_delta = delta;
7120
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007121 /* using hdd_log to avoid printing function name */
Houston Hoffman00227112017-08-14 23:58:18 -07007122 hdd_log(QDF_TRACE_LEVEL_DEBUG,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007123 "%s: %d: %d: %ums",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007124 hdd_reason_type_to_string(i),
7125 adapter->queue_oper_stats[i].pause_count,
Nirav Shahda008342016-05-17 18:50:40 +05307126 adapter->queue_oper_stats[i].unpause_count,
7127 qdf_system_ticks_to_msecs(
7128 adapter->queue_oper_stats[i].total_pause_time +
7129 pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007130 }
7131
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007132 hdd_debug("Netif queue operation history:");
7133 hdd_debug("Total entries: %d current index %d",
Nirav Shahda008342016-05-17 18:50:40 +05307134 WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index);
7135
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007136 hdd_debug("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007137
7138 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007139 /* using hdd_log to avoid printing function name */
7140 if (adapter->queue_oper_history[i].time == 0)
7141 continue;
Houston Hoffman00227112017-08-14 23:58:18 -07007142 hdd_log(QDF_TRACE_LEVEL_DEBUG,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07007143 "%d: %u: %s: %s: %x",
Anurag Chouhan50220ce2016-02-18 20:11:33 +05307144 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007145 adapter->queue_oper_history[i].time),
7146 hdd_action_type_to_string(
7147 adapter->queue_oper_history[i].netif_action),
7148 hdd_reason_type_to_string(
7149 adapter->queue_oper_history[i].netif_reason),
7150 adapter->queue_oper_history[i].pause_map);
7151 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007152 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007153}
7154
7155/**
7156 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
7157 * @hdd_ctx: hdd context
7158 *
7159 * Return: none
7160 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007161void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007162{
Jeff Johnson9d295242017-08-29 14:39:48 -07007163 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007164
Dustin Brown920397d2017-12-13 16:27:50 -08007165 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307166 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007167 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307168 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007169 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05307170 adapter->history_index = 0;
7171 adapter->start_time = adapter->last_time = qdf_system_ticks();
7172 adapter->total_pause_time = 0;
7173 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007174 }
7175}
7176
7177/**
7178 * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
7179 * @halHandle: Hal handle
7180 * @pContext: Pointer to the context
7181 * @sessionId: Session ID
7182 * @scanId: Scan ID
7183 * @status: Status
7184 *
7185 * This is the callback to be executed when 11d scan is completed to flush out
7186 * the scan results
7187 *
7188 * 11d scan is done during driver load and is a passive scan on all
7189 * channels supported by the device, 11d scans may find some APs on
7190 * frequencies which are forbidden to be used in the regulatory domain
7191 * the device is operating in. If these APs are notified to the supplicant
7192 * it may try to connect to these APs, thus flush out all the scan results
7193 * which are present in SME after 11d scan is done.
7194 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307195 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007196 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307197static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007198 uint8_t sessionId, uint32_t scanId,
7199 eCsrScanStatus status)
7200{
7201 ENTER();
7202
7203 sme_scan_flush_result(halHandle);
7204
7205 EXIT();
7206
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307207 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007208}
7209
7210#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7211/**
7212 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
7213 * @hdd_ctx: hdd global context
7214 *
7215 * Return: none
7216 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007217static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007218{
7219 uint8_t i;
7220
7221 mutex_init(&hdd_ctx->op_ctx.op_lock);
7222 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
7223 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
7224 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
7225 }
7226}
7227#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007228static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007229{
7230}
7231#endif
7232
Yingying Tang95409972016-10-20 15:16:15 +08007233#ifdef WLAN_FEATURE_WOW_PULSE
7234/**
7235 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007236 * @phddctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08007237 * @enable: enable or disable this behaviour
7238 *
7239 * Return: int
7240 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007241static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007242{
7243 struct hdd_config *pcfg_ini = phddctx->config;
7244 struct wow_pulse_mode wow_pulse_set_info;
7245 QDF_STATUS status;
7246
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007247 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08007248
7249 if (false == phddctx->config->wow_pulse_support)
7250 return 0;
7251
7252 /* prepare the request to send to SME */
7253 if (enable == true) {
7254 wow_pulse_set_info.wow_pulse_enable = true;
7255 wow_pulse_set_info.wow_pulse_pin =
7256 pcfg_ini->wow_pulse_pin;
7257 wow_pulse_set_info.wow_pulse_interval_low =
7258 pcfg_ini->wow_pulse_interval_low;
7259 wow_pulse_set_info.wow_pulse_interval_high =
7260 pcfg_ini->wow_pulse_interval_high;
7261 } else {
7262 wow_pulse_set_info.wow_pulse_enable = false;
7263 wow_pulse_set_info.wow_pulse_pin = 0;
7264 wow_pulse_set_info.wow_pulse_interval_low = 0;
7265 wow_pulse_set_info.wow_pulse_interval_high = 0;
7266 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007267 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08007268 wow_pulse_set_info.wow_pulse_enable,
7269 wow_pulse_set_info.wow_pulse_pin,
7270 wow_pulse_set_info.wow_pulse_interval_low,
7271 wow_pulse_set_info.wow_pulse_interval_high);
7272
7273 status = sme_set_wow_pulse(&wow_pulse_set_info);
7274 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007275 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08007276 return -EIO;
7277 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007278 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08007279 return 0;
7280}
7281#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007282static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08007283{
7284 return 0;
7285}
7286#endif
7287
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007288#ifdef WLAN_FEATURE_FASTPATH
7289/**
7290 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
7291 * @hdd_cfg: hdd config
7292 * @context: lower layer context
7293 *
7294 * Return: none
7295 */
Arun Khandavallifae92942016-08-01 13:31:08 +05307296void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007297 void *context)
7298{
7299 if (hdd_cfg->fastpath_enable)
7300 hif_enable_fastpath(context);
7301}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007302#endif
7303
Yuanyuan Liu13738502016-04-06 17:41:37 -07007304#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007305/**
7306 * hdd_set_thermal_level_cb() - set thermal level callback function
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007307 * @context: hdd context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007308 * @level: thermal level
7309 *
7310 * Change IPA data path to SW path when the thermal throttle level greater
7311 * than 0, and restore the original data path when throttle level is 0
7312 *
7313 * Return: none
7314 */
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007315static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007316{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007317 struct hdd_context *hdd_ctx = context;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007318
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007319 /* Change IPA to SW path when throttle level greater than 0 */
7320 if (level > THROTTLE_LEVEL_0)
7321 hdd_ipa_send_mcc_scc_msg(hdd_ctx, true);
7322 else
7323 /* restore original concurrency mode */
7324 hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode);
7325}
7326
7327/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307328 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
7329 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05307330 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007331 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307332 * Get a safe channel to restart SAP. PCL already takes into account the
7333 * unsafe channels. So, the PCL is validated with the ACS range to provide
7334 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007335 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307336 * Return: Channel number to restart SAP in case of success. In case of any
7337 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007338 */
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307339static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range(
Jeff Johnson9d295242017-08-29 14:39:48 -07007340 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007341{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307342 struct sir_pcl_list pcl;
7343 QDF_STATUS status;
7344 uint32_t i, j;
7345 tHalHandle *hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007346 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307347 bool found = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007348
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307349 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7350 if (!hdd_ctx) {
7351 hdd_err("invalid HDD context");
7352 return INVALID_CHANNEL_ID;
7353 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007354
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05307355 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
7356 if (!hal_handle) {
7357 hdd_err("invalid HAL handle");
7358 return INVALID_CHANNEL_ID;
7359 }
7360
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007361 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->hdd_psoc,
7362 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08007363 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
7364 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307365 if (QDF_IS_STATUS_ERROR(status)) {
7366 hdd_err("Get PCL failed");
7367 return INVALID_CHANNEL_ID;
7368 }
7369
Frank Liudc2cefb2017-06-21 15:38:18 +08007370 /*
7371 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
7372 * channel is unsafe channel, the pcl may be empty, instead of return,
7373 * try to choose a safe channel from acs range.
7374 */
7375 if (!pcl.pcl_len)
7376 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307377
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007378 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07007379 adapter->session.ap.sap_config.acs_cfg.start_ch,
7380 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307381
7382 /* PCL already takes unsafe channel into account */
7383 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007384 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307385 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007386 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307387 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007388 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007389 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307390 return pcl.pcl_list[i];
7391 }
7392 }
7393
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007394 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307395
7396 /* Try for safe channel from all valid channel */
7397 pcl.pcl_len = MAX_NUM_CHAN;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007398 status = sme_get_cfg_valid_channels(pcl.pcl_list,
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307399 &pcl.pcl_len);
7400 if (QDF_IS_STATUS_ERROR(status)) {
7401 hdd_err("error in getting valid channel list");
7402 return INVALID_CHANNEL_ID;
7403 }
7404
7405 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007406 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307407 found = false;
7408 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
Krunal Soni15f0db12016-10-11 18:53:37 -07007409 if (pcl.pcl_list[i] ==
7410 hdd_ctx->unsafe_channel_list[j]) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007411 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307412 found = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007413 break;
7414 }
7415 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307416
7417 if (found)
7418 continue;
7419
7420 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007421 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307422 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07007423 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007424 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307425 return pcl.pcl_list[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007426 }
7427 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307428
7429 return INVALID_CHANNEL_ID;
7430}
7431
7432/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007433 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307434 * @adapter: AP adapter
7435 * @channel: Channel
7436 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007437 * Moves the SAP interface by invoking the function which
7438 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307439 *
7440 * Return: None
7441 */
Jeff Johnson9d295242017-08-29 14:39:48 -07007442void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307443{
Jeff Johnson87251032017-08-29 13:31:11 -07007444 struct hdd_ap_ctx *hdd_ap_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307445 tHalHandle *hal_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007446 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307447
7448 if (!adapter) {
7449 hdd_err("invalid adapter");
7450 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007451 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307452
7453 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
7454
7455 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
7456 if (!hal_handle) {
7457 hdd_err("invalid HAL handle");
7458 return;
7459 }
7460
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007461 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7462
Jeff Johnson91df29d2017-10-27 19:29:50 -07007463 hdd_ap_ctx->sap_config.channel = channel;
7464 hdd_ap_ctx->sap_config.ch_params.ch_width =
7465 hdd_ap_ctx->sap_config.ch_width_orig;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307466
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007467 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07007468 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307469
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07007470 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
Jeff Johnson91df29d2017-10-27 19:29:50 -07007471 hdd_ap_ctx->sap_config.channel,
7472 hdd_ap_ctx->sap_config.sec_ch,
7473 &hdd_ap_ctx->sap_config.ch_params);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05307474
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007475 policy_mgr_change_sap_channel_with_csa(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07007476 adapter->session_id, channel,
Jeff Johnson91df29d2017-10-27 19:29:50 -07007477 hdd_ap_ctx->sap_config.ch_width_orig);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007478}
Kapil Gupta8878ad92017-02-13 11:56:04 +05307479
Jeff Johnson9d295242017-08-29 14:39:48 -07007480int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05307481{
7482 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307483 int status;
7484 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307485
7486 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
7487
7488 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07007489 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05307490 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07007491 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307492 }
7493 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07007494 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307495 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307496 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07007497 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307498 WLAN_VENDOR_ACS_WAIT_TIME);
7499 if (qdf_status != QDF_STATUS_SUCCESS) {
7500 hdd_err("failed to start external acs timer");
7501 return -ENOSPC;
7502 }
7503 /* Update config to application */
7504 status = hdd_cfg80211_update_acs_config(adapter, reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307505 hdd_notice("Updated ACS config to nl with reason %d", reason);
7506
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05307507 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307508}
7509
Agrawal Ashish467dde42016-09-08 18:44:22 +05307510/**
7511 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
7512 * @hdd_ctx: hdd context pointer
7513 *
7514 * hdd_unsafe_channel_restart_sap check all unsafe channel list
7515 * and if ACS is enabled, driver will ask userspace to restart the
7516 * sap. User space on LTE coex indication restart driver.
7517 *
7518 * Return - none
7519 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007520void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05307521{
Dustin Brown920397d2017-12-13 16:27:50 -08007522 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307523 uint32_t i;
7524 bool found = false;
7525 uint8_t restart_chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007526
Dustin Brown920397d2017-12-13 16:27:50 -08007527 hdd_for_each_adapter(hdd_ctxt, adapter) {
7528 if (!(adapter->device_mode == QDF_SAP_MODE &&
7529 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007530 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08007531 adapter->device_mode,
7532 adapter->session.ap.sap_config.
7533 acs_cfg.acs_mode);
7534 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307535 }
7536
7537 found = false;
7538 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
Dustin Brown920397d2017-12-13 16:27:50 -08007539 if (adapter->session.ap.operating_channel ==
Agrawal Ashish467dde42016-09-08 18:44:22 +05307540 hdd_ctxt->unsafe_channel_list[i]) {
7541 found = true;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007542 hdd_debug("operating ch:%d is unsafe",
Dustin Brown920397d2017-12-13 16:27:50 -08007543 adapter->session.ap.operating_channel);
Agrawal Ashish467dde42016-09-08 18:44:22 +05307544 break;
7545 }
7546 }
7547
7548 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007549 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08007550 adapter->session.ap.operating_channel);
7551 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307552 }
7553
Kapil Gupta8878ad92017-02-13 11:56:04 +05307554 if (hdd_ctxt->config->vendor_acs_support &&
7555 hdd_ctxt->config->acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08007556 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05307557 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08007558 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307559 } else
7560 restart_chan =
7561 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08007562 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05307563 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007564 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05307565 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08007566 /*
7567 * SAP restart due to unsafe channel. While
7568 * restarting the SAP, make sure to clear
7569 * acs_channel, channel to reset to
7570 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05307571 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08007572 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05307573 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown920397d2017-12-13 16:27:50 -08007574 adapter->session.ap.sap_config.channel =
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05307575 AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007576 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05307577 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
7578 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Liangwei Dong6663d162017-07-10 03:29:36 -04007579 hdd_debug("driver to start sap: %d",
7580 hdd_ctxt->config->sap_internal_restart);
7581 if (hdd_ctxt->config->sap_internal_restart)
Dustin Brown920397d2017-12-13 16:27:50 -08007582 hdd_switch_sap_channel(adapter, restart_chan);
Liangwei Dong6663d162017-07-10 03:29:36 -04007583 else
7584 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05307585 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05307586 }
7587}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307588
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007589/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007590 * hdd_init_channel_avoidance() - Initialize channel avoidance
7591 * @hdd_ctx: HDD global context
7592 *
7593 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07007594 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007595 * down to the lower layers. Then subscribe to subsequent channel
7596 * avoidance events.
7597 *
7598 * Return: None
7599 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007600static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007601{
7602 uint16_t unsafe_channel_count;
7603 int index;
7604
Yuanyuan Liu13738502016-04-06 17:41:37 -07007605 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
7606 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007607 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08007608 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007609
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007610 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007611 hdd_ctx->unsafe_channel_count);
7612
Anurag Chouhan6d760662016-02-20 16:05:43 +05307613 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08007614 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007615
7616 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007617 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007618 hdd_ctx->unsafe_channel_list[index]);
7619
7620 }
7621
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007622}
Dustin Brown676a2322017-08-15 13:16:13 -07007623
Jeff Johnson9d295242017-08-29 14:39:48 -07007624static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007625 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07007626{
7627 uint8_t restart_chan;
7628
7629 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
7630 if (!restart_chan) {
7631 hdd_alert("fail to restart SAP");
7632 return;
7633 }
7634
7635 /* SAP restart due to unsafe channel. While restarting
7636 * the SAP, make sure to clear acs_channel, channel to
7637 * reset to 0. Otherwise these settings will override
7638 * the ACS while restart.
7639 */
7640 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -07007641 adapter->session.ap.sap_config.channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07007642
7643 hdd_debug("sending coex indication");
7644
7645 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7646 WLAN_SVC_LTE_COEX_IND, NULL, 0);
7647 hdd_switch_sap_channel(adapter, restart_chan);
7648}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08007649
7650int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
7651 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
7652{
7653 uint32_t size;
7654 uint16_t *unsafe_list;
7655 uint16_t chan_count;
7656
7657 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
7658 return -EINVAL;
7659
7660 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
7661 NUM_CHANNELS);
7662 if (chan_count) {
7663 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
7664 unsafe_list = qdf_mem_malloc(size);
7665 if (!unsafe_list) {
7666 hdd_err("No memory for unsafe chan list size%d",
7667 size);
7668 return -ENOMEM;
7669 }
7670 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
7671 } else {
7672 unsafe_list = NULL;
7673 }
7674
7675 *local_unsafe_list = unsafe_list;
7676 *local_unsafe_list_count = chan_count;
7677
7678 return 0;
7679}
7680
7681bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
7682 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
7683{
7684 int i, j;
7685
7686 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
7687 return true;
7688 if (local_unsafe_list_count == 0)
7689 return false;
7690 for (i = 0; i < local_unsafe_list_count; i++) {
7691 for (j = 0; j < local_unsafe_list_count; j++)
7692 if (local_unsafe_list[i] ==
7693 hdd_ctx->unsafe_channel_list[j])
7694 break;
7695 if (j >= local_unsafe_list_count)
7696 break;
7697 }
7698 if (i >= local_unsafe_list_count) {
7699 hdd_info("unsafe chan list same");
7700 return false;
7701 }
7702
7703 return true;
7704}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007705#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007706static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007707{
7708}
Dustin Brown676a2322017-08-15 13:16:13 -07007709
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007710static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007711{
7712}
Dustin Brown676a2322017-08-15 13:16:13 -07007713
Jeff Johnson9d295242017-08-29 14:39:48 -07007714static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007715 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07007716{
7717 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
7718}
Yuanyuan Liu13738502016-04-06 17:41:37 -07007719#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007720
7721/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08007722 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
7723 * user space
7724 * @frame_ind: Management frame data to be informed.
7725 *
7726 * This function is used to indicate management frame to
7727 * user space
7728 *
7729 * Return: None
7730 *
7731 */
7732void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
7733{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007734 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07007735 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08007736 int i;
7737
Rajeev Kumard004abc2016-02-17 12:09:56 -08007738 /* Get the HDD context.*/
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007739 hdd_ctx = (struct hdd_context *)cds_get_context(QDF_MODULE_ID_HDD);
Rajeev Kumard004abc2016-02-17 12:09:56 -08007740
7741 if (0 != wlan_hdd_validate_context(hdd_ctx))
7742 return;
7743
7744 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
7745 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
7746 adapter =
7747 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
7748 if (adapter)
7749 break;
7750 }
7751 } else {
7752 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
7753 frame_ind->sessionId);
7754 }
7755
7756 if ((NULL != adapter) &&
7757 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
7758 __hdd_indicate_mgmt_frame(adapter,
7759 frame_ind->frame_len,
7760 frame_ind->frameBuf,
7761 frame_ind->frameType,
7762 frame_ind->rxChan,
7763 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08007764}
7765
Kapil Gupta8878ad92017-02-13 11:56:04 +05307766void hdd_acs_response_timeout_handler(void *context)
7767{
7768 struct hdd_external_acs_timer_context *timer_context =
7769 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07007770 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007771 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05307772 uint8_t reason;
7773
7774 ENTER();
7775 if (!timer_context) {
7776 hdd_err("invlaid timer context");
7777 return;
7778 }
7779 adapter = timer_context->adapter;
7780 reason = timer_context->reason;
7781
7782
7783 if ((!adapter) ||
7784 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
7785 hdd_err("invalid adapter or adapter has invalid magic");
7786 return;
7787 }
7788 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7789 if (wlan_hdd_validate_context(hdd_ctx))
7790 return;
7791
7792 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
7793 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
7794 else
7795 return;
7796
7797 hdd_err("ACS timeout happened for %s reason %d",
7798 adapter->dev->name, reason);
7799 switch (reason) {
7800 /* SAP init case */
7801 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
7802 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
7803 false);
7804 wlan_hdd_cfg80211_start_acs(adapter);
7805 break;
7806 /* DFS detected on current channel */
7807 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
7808 wlan_sap_update_next_channel(
7809 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
7810 sme_update_new_channel_event(WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -07007811 adapter->session_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307812 break;
7813 /* LTE coex event on current channel */
7814 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
7815 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
7816 break;
7817 default:
7818 hdd_info("invalid reason for timer invoke");
7819
7820 }
7821}
7822
Rajeev Kumard004abc2016-02-17 12:09:56 -08007823/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007824 * wlan_hdd_disable_all_dual_mac_features() - Disable dual mac features
7825 * @hdd_ctx: HDD context
7826 *
7827 * Disables all the dual mac features like DBS, Agile DFS etc.
7828 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307829 * Return: QDF_STATUS_SUCCESS on success
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007830 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007831static QDF_STATUS wlan_hdd_disable_all_dual_mac_features(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007832{
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007833 struct policy_mgr_dual_mac_config cfg = {0};
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307834 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007835
7836 if (!hdd_ctx) {
7837 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307838 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007839 }
7840
7841 cfg.scan_config = 0;
7842 cfg.fw_mode_config = 0;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007843 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007844
7845 hdd_debug("Disabling all dual mac features...");
7846
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007847 status = sme_soc_set_dual_mac_config(cfg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307848 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007849 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
7850 return status;
7851 }
7852
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307853 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007854}
7855
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07007856static QDF_STATUS
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007857wlan_hdd_update_dbs_scan_and_fw_mode_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07007858{
7859 struct policy_mgr_dual_mac_config cfg = {0};
7860 QDF_STATUS status;
7861
7862 if (!hdd_ctx) {
7863 hdd_err("HDD context is NULL");
7864 return QDF_STATUS_E_FAILURE;
7865 }
7866
7867 cfg.scan_config = 0;
7868 cfg.fw_mode_config = 0;
7869 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
7870 status = policy_mgr_get_updated_scan_and_fw_mode_config(
7871 hdd_ctx->hdd_psoc, &cfg.scan_config,
7872 &cfg.fw_mode_config,
7873 hdd_ctx->config->dual_mac_feature_disable);
7874
7875 if (status != QDF_STATUS_SUCCESS) {
7876 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
7877 status);
7878 return status;
7879 }
7880
7881 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
7882 cfg.scan_config, cfg.fw_mode_config);
7883
7884 status = sme_soc_set_dual_mac_config(cfg);
7885 if (status != QDF_STATUS_SUCCESS) {
7886 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
7887 return status;
7888 }
7889
7890 return QDF_STATUS_SUCCESS;
7891}
7892
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007893/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007894 * hdd_override_ini_config - Override INI config
7895 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007896 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007897 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007898 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007899 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007901static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007902{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007903
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007904 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
7905 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007906 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007907 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007908 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007909 if (0 == enable_11d || 1 == enable_11d) {
7910 hdd_ctx->config->Is11dSupportEnabled = enable_11d;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007911 hdd_debug("Module enable_11d set to %d", enable_11d);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007912 }
Leo Chang11545d62016-10-17 14:53:50 -07007913
7914 if (!hdd_ipa_is_present(hdd_ctx))
7915 hdd_ctx->config->IpaConfig = 0;
Yeshwanth Sriram Guntuka2ba6fe92017-10-04 14:40:45 +05307916
7917 if (!hdd_ctx->config->rssi_assoc_reject_enabled ||
7918 !hdd_ctx->config->enable_bcast_probe_rsp) {
7919 hdd_debug("OCE disabled, rssi_assoc_reject_enabled: %d enable_bcast_probe_rsp: %d",
7920 hdd_ctx->config->rssi_assoc_reject_enabled,
7921 hdd_ctx->config->enable_bcast_probe_rsp);
7922 hdd_ctx->config->oce_sta_enabled = 0;
7923 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007924}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007925
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007926/**
7927 * hdd_set_trace_level_for_each - Set trace level for each INI config
7928 * @hdd_ctx - HDD context
7929 *
7930 * Set trace level for each module based on INI config.
7931 *
7932 * Return: None
7933 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007934static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007935{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307936 hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
7937 hdd_ctx->config->qdf_trace_enable_wdi);
7938 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
7939 hdd_ctx->config->qdf_trace_enable_hdd);
7940 hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
7941 hdd_ctx->config->qdf_trace_enable_sme);
7942 hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
7943 hdd_ctx->config->qdf_trace_enable_pe);
7944 hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
7945 hdd_ctx->config->qdf_trace_enable_wma);
7946 hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
7947 hdd_ctx->config->qdf_trace_enable_sys);
7948 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
7949 hdd_ctx->config->qdf_trace_enable_qdf);
7950 hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
7951 hdd_ctx->config->qdf_trace_enable_sap);
7952 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
7953 hdd_ctx->config->qdf_trace_enable_hdd_sap);
7954 hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
7955 hdd_ctx->config->qdf_trace_enable_bmi);
7956 hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
7957 hdd_ctx->config->qdf_trace_enable_cfg);
7958 hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
7959 hdd_ctx->config->qdf_trace_enable_epping);
7960 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
7961 hdd_ctx->config->qdf_trace_enable_qdf_devices);
7962 hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
Houston Hoffmanfbf05102017-08-28 11:37:01 -07007963 hdd_ctx->config->qdf_trace_enable_txrx);
7964 hdd_qdf_trace_enable(QDF_MODULE_ID_DP,
7965 hdd_ctx->config->qdf_trace_enable_dp);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307966 hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
7967 hdd_ctx->config->qdf_trace_enable_htc);
7968 hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
7969 hdd_ctx->config->qdf_trace_enable_hif);
7970 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
7971 hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
7972 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
7973 hdd_ctx->config->qdf_trace_enable_hdd_data);
Naveen Rawat7df31862017-03-01 17:09:30 -08007974 hdd_qdf_trace_enable(QDF_MODULE_ID_WIFIPOS,
7975 hdd_ctx->config->qdf_trace_enable_wifi_pos);
Naveen Rawatf2b0dbd2017-03-27 10:00:15 -07007976 hdd_qdf_trace_enable(QDF_MODULE_ID_NAN,
7977 hdd_ctx->config->qdf_trace_enable_nan);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07007978 hdd_qdf_trace_enable(QDF_MODULE_ID_REGULATORY,
7979 hdd_ctx->config->qdf_trace_enable_regulatory);
7980
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007981 hdd_cfg_print(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007982}
7983
7984/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007985 * hdd_context_init() - Initialize HDD context
7986 * @hdd_ctx: HDD context.
7987 *
7988 * Initialize HDD context along with all the feature specific contexts.
7989 *
7990 * return: 0 on success and errno on failure.
7991 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007992static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007993{
7994 int ret;
7995
7996 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
7997 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
7998
7999 hdd_init_ll_stats_ctx();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +05308000 hdd_init_nud_stats_ctx(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008001
8002 init_completion(&hdd_ctx->mc_sus_event_var);
8003 init_completion(&hdd_ctx->ready_to_suspend);
8004
8005 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308006 qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008007 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05308008
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008009 qdf_list_create(&hdd_ctx->hdd_adapters, MAX_NUMBER_OF_ADAPTERS);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008010
8011 init_completion(&hdd_ctx->set_antenna_mode_cmpl);
8012
8013 ret = hdd_scan_context_init(hdd_ctx);
8014 if (ret)
8015 goto list_destroy;
8016
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008017 hdd_rx_wake_lock_create(hdd_ctx);
8018
8019 ret = hdd_sap_context_init(hdd_ctx);
8020 if (ret)
8021 goto scan_destroy;
8022
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008023 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
8024
8025 hdd_init_offloaded_packets_ctx(hdd_ctx);
8026
8027 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
8028 hdd_ctx->config);
8029 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08008030 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008031
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05308032 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
8033 "monitor_mode_wakelock");
8034
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008035 return 0;
8036
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008037sap_destroy:
8038 hdd_sap_context_destroy(hdd_ctx);
8039
8040scan_destroy:
8041 hdd_scan_context_destroy(hdd_ctx);
8042 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008043list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07008044 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08008045
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008046 return ret;
8047}
8048
8049/**
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308050 * ie_whitelist_attrs_init() - initialize ie whitelisting attributes
8051 * @hdd_ctx: pointer to hdd context
8052 *
8053 * Return: status of initialization
8054 * 0 - success
8055 * negative value - failure
8056 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008057static int ie_whitelist_attrs_init(struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308058{
8059 int ret;
8060
8061 if (!hdd_ctx->config->probe_req_ie_whitelist)
8062 return 0;
8063
8064 if (!hdd_validate_prb_req_ie_bitmap(hdd_ctx)) {
8065 hdd_err("invalid ie bitmap and ouis: disable ie whitelisting");
8066 hdd_ctx->config->probe_req_ie_whitelist = false;
8067 return -EINVAL;
8068 }
8069
8070 /* parse ini string probe req oui */
8071 ret = hdd_parse_probe_req_ouis(hdd_ctx);
8072 if (ret) {
8073 hdd_err("parsing error: disable ie whitelisting");
8074 hdd_ctx->config->probe_req_ie_whitelist = false;
8075 }
8076
8077 return ret;
8078}
8079
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308080
8081/**
8082 * hdd_iface_change_callback() - Function invoked when stop modules expires
8083 * @priv: pointer to hdd context
8084 *
8085 * This function is invoked when the timer waiting for the interface change
8086 * expires, it shall cut-down the power to wlan and stop all the modules.
8087 *
8088 * Return: void
8089 */
8090static void hdd_iface_change_callback(void *priv)
8091{
8092 struct hdd_context *hdd_ctx = (struct hdd_context *) priv;
8093 int ret;
8094 int status = wlan_hdd_validate_context(hdd_ctx);
8095
8096 if (status)
8097 return;
8098
8099 ENTER();
8100 hdd_debug("Interface change timer expired close the modules!");
8101 ret = hdd_wlan_stop_modules(hdd_ctx, false);
8102 if (ret)
8103 hdd_err("Failed to stop modules");
8104 EXIT();
8105}
8106
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308107/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008108 * hdd_context_create() - Allocate and inialize HDD context.
Arun Khandavallifae92942016-08-01 13:31:08 +05308109 * @dev: Device Pointer to the underlying device
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008110 *
8111 * Allocate and initialize HDD context. HDD context is allocated as part of
8112 * wiphy allocation and then context is initialized.
8113 *
8114 * Return: HDD context on success and ERR_PTR on failure
8115 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008116static struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008117{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308118 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008119 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008120 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008121
8122 ENTER();
8123
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008124 hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(struct hdd_context));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008125 if (hdd_ctx == NULL) {
8126 ret = -ENOMEM;
8127 goto err_out;
8128 }
8129
Dustin Brown6f427922017-09-19 12:19:00 -07008130 qdf_create_delayed_work(&hdd_ctx->iface_idle_work,
8131 hdd_iface_change_callback,
8132 (void *)hdd_ctx);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308133
8134 mutex_init(&hdd_ctx->iface_change_lock);
8135
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008136 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05308137 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008138
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308139 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008140 if (hdd_ctx->config == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008141 hdd_err("Failed to alloc memory for HDD config!");
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008142 ret = -ENOMEM;
8143 goto err_free_hdd_context;
8144 }
8145
8146 /* Read and parse the qcom_cfg.ini file */
8147 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308148 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05308149 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008150 WLAN_INI_FILE);
8151 ret = -EINVAL;
8152 goto err_free_config;
8153 }
8154
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05308155 ie_whitelist_attrs_init(hdd_ctx);
8156
Dustin Brown7f939932017-05-18 15:02:17 -07008157 hdd_debug("setting timer multiplier: %u",
8158 hdd_ctx->config->timer_multiplier);
8159 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
8160
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008161
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308162 if (hdd_ctx->config->fhostNSOffload)
8163 hdd_ctx->ns_offload_enable = true;
8164
Abhishek Singh5ea86532016-04-27 14:10:53 +05308165 cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
8166
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008167 hdd_override_ini_config(hdd_ctx);
8168
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008169 ret = hdd_context_init(hdd_ctx);
8170
8171 if (ret)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008172 goto err_free_config;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07008173
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008174 /* Uses to enabled logging after SSR */
Komal Seelamc11bb222016-01-27 18:57:10 +05308175 hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008176
Anurag Chouhan6d760662016-02-20 16:05:43 +05308177 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008178 goto skip_multicast_logging;
8179
8180 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
8181
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008182 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
8183 if (ret)
8184 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05308185
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008186 ret = hdd_init_netlink_services(hdd_ctx);
8187 if (ret)
8188 goto err_deinit_txrx_histogram;
8189
Dustin Brown7b3dea22017-07-10 13:02:47 -07008190 wlan_logging_set_log_to_console(hdd_ctx->config->wlanLoggingToConsole);
8191 wlan_logging_set_active(hdd_ctx->config->wlanLoggingEnable);
Nirav Shahed34b212016-04-25 10:59:16 +05308192
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008193skip_multicast_logging:
8194 hdd_set_trace_level_for_each(hdd_ctx);
8195
Rajeev Kumar493a31b2017-09-29 14:01:24 -07008196 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
8197
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07008198 EXIT();
8199
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008200 return hdd_ctx;
8201
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07008202err_deinit_txrx_histogram:
8203 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
8204
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07008205err_deinit_hdd_context:
8206 hdd_context_deinit(hdd_ctx);
8207
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008208err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308209 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008210
8211err_free_hdd_context:
8212 wiphy_free(hdd_ctx->wiphy);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05308213 mutex_destroy(&hdd_ctx->iface_change_lock);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08008214
8215err_out:
8216 return ERR_PTR(ret);
8217}
8218
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008219#ifdef WLAN_OPEN_P2P_INTERFACE
8220/**
8221 * hdd_open_p2p_interface - Open P2P interface
8222 * @hdd_ctx: HDD context
8223 * @rtnl_held: True if RTNL lock held
8224 *
8225 * Open P2P interface during probe. This function called to open the P2P
8226 * interface at probe along with STA interface.
8227 *
8228 * Return: 0 on success and errno on failure
8229 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008230static int hdd_open_p2p_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008231{
Jeff Johnson9d295242017-08-29 14:39:48 -07008232 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008233 uint8_t *p2p_dev_addr;
8234
8235 if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
8236 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008237 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008238 hdd_ctx->config->intfMacAddr[0].bytes,
8239 sizeof(tSirMacAddr));
8240
8241 /*
8242 * Generate the P2P Device Address. This consists of
8243 * the device's primary MAC address with the locally
8244 * administered bit set.
8245 */
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008246 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008247 } else {
8248 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
8249 if (p2p_dev_addr == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008250 hdd_err("Failed to allocate mac_address for p2p_device");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008251 return -ENOSPC;
8252 }
8253
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008254 qdf_mem_copy(&hdd_ctx->p2p_device_address.bytes[0],
8255 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008256 }
8257
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008258 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07008259 &hdd_ctx->p2p_device_address.bytes[0],
Ryan Hsu07495ea2016-01-21 15:25:39 -08008260 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008261
8262 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008263 hdd_err("Failed to do hdd_open_adapter for P2P Device Interface");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008264 return -ENOSPC;
8265 }
8266
8267 return 0;
8268}
8269#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008270static inline int hdd_open_p2p_interface(struct hdd_context *hdd_ctx,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008271 bool rtnl_held)
8272{
8273 return 0;
8274}
8275#endif
8276
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008277static int hdd_open_ocb_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
Jeff Johnson957bc272017-02-02 08:54:48 -08008278{
Jeff Johnson9d295242017-08-29 14:39:48 -07008279 struct hdd_adapter *adapter;
Jeff Johnson957bc272017-02-02 08:54:48 -08008280 int ret = 0;
8281
8282 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
8283 wlan_hdd_get_intf_addr(hdd_ctx),
8284 NET_NAME_UNKNOWN, rtnl_held);
8285 if (adapter == NULL) {
8286 hdd_err("Failed to open 802.11p interface");
8287 ret = -ENOSPC;
8288 }
8289
8290 return ret;
8291}
8292
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008293/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308294 * hdd_start_station_adapter()- Start the Station Adapter
8295 * @adapter: HDD adapter
8296 *
8297 * This function initializes the adapter for the station mode.
8298 *
8299 * Return: 0 on success or errno on failure.
8300 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008301int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308302{
8303 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08008304 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308305
8306 ENTER_DEV(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08008307 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8308 hdd_err("session is already opened, %d",
8309 adapter->session_id);
8310 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8311 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308312
Krunal Sonib51eec72017-11-20 21:53:01 -08008313 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
8314 if (ret) {
8315 hdd_err("failed to create vdev: %d", ret);
8316 return ret;
8317 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308318 status = hdd_init_station_mode(adapter);
8319
8320 if (QDF_STATUS_SUCCESS != status) {
8321 hdd_err("Error Initializing station mode: %d", status);
8322 return qdf_status_to_os_return(status);
8323 }
8324
Arun Khandavallifae92942016-08-01 13:31:08 +05308325 hdd_register_tx_flow_control(adapter,
8326 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008327 hdd_tx_resume_cb,
8328 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308329
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308330 EXIT();
8331 return 0;
8332}
8333
8334/**
8335 * hdd_start_ap_adapter()- Start AP Adapter
8336 * @adapter: HDD adapter
8337 *
8338 * This function initializes the adapter for the AP mode.
8339 *
8340 * Return: 0 on success errno on failure.
8341 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008342int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308343{
8344 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008345 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08008346 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308347
8348 ENTER();
8349
Krunal Sonib51eec72017-11-20 21:53:01 -08008350 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
8351 hdd_err("session is already opened, %d",
8352 adapter->session_id);
8353 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
8354 }
8355 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008356 * In SSR case no need to create new sap context.
8357 * Otherwise create sap context first and then create
8358 * vdev as while creating the vdev, driver needs to
8359 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08008360 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008361 if (adapter->session.ap.sap_context) {
8362 is_ssr = true;
8363 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08008364 hdd_err("sap creation failed");
8365 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
8366 }
8367
8368 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
8369 adapter->session.ap.sap_context);
8370 if (ret) {
8371 hdd_err("failed to create vdev, status:%d", ret);
8372 hdd_sap_destroy_ctx(adapter);
8373 return ret;
8374 }
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08008375 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308376
8377 if (QDF_STATUS_SUCCESS != status) {
8378 hdd_err("Error Initializing the AP mode: %d", status);
8379 return qdf_status_to_os_return(status);
8380 }
8381
Arun Khandavallifae92942016-08-01 13:31:08 +05308382 hdd_register_tx_flow_control(adapter,
8383 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08008384 hdd_softap_tx_resume_cb,
8385 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05308386
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308387 EXIT();
8388 return 0;
8389}
8390
8391/**
8392 * hdd_start_ftm_adapter()- Start FTM adapter
8393 * @adapter: HDD adapter
8394 *
8395 * This function initializes the adapter for the FTM mode.
8396 *
8397 * Return: 0 on success or errno on failure.
8398 */
Jeff Johnson9d295242017-08-29 14:39:48 -07008399int hdd_start_ftm_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308400{
8401 QDF_STATUS qdf_status;
8402
8403 ENTER_DEV(adapter->dev);
8404
8405 qdf_status = hdd_init_tx_rx(adapter);
8406
8407 if (QDF_STATUS_SUCCESS != qdf_status) {
8408 hdd_err("Failed to start FTM adapter: %d", qdf_status);
8409 return qdf_status_to_os_return(qdf_status);
8410 }
8411
8412 return 0;
8413 EXIT();
8414}
8415
Sourav Mohapatra57006c72017-11-19 16:15:55 +05308416static int hdd_open_concurrent_interface(struct hdd_context *hdd_ctx,
8417 bool rtnl_held)
8418{
8419 struct hdd_adapter *adapter;
8420
8421 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
8422 hdd_ctx->config->enableConcurrentSTA,
8423 wlan_hdd_get_intf_addr(hdd_ctx),
8424 NET_NAME_UNKNOWN, rtnl_held);
8425
8426 if (!adapter)
8427 return -ENOSPC;
8428
8429 return 0;
8430}
8431
Arun Khandavalli7e857c32016-06-26 12:07:16 +05308432/**
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008433 * hdd_open_interfaces - Open all required interfaces
8434 * hdd_ctx: HDD context
8435 * rtnl_held: True if RTNL lock is held
8436 *
8437 * Open all the interfaces like STA, P2P and OCB based on the configuration.
8438 *
Jeff Johnson957bc272017-02-02 08:54:48 -08008439 * Return: 0 if all interfaces were created, otherwise negative errno
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008440 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008441static int hdd_open_interfaces(struct hdd_context *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008442{
Jeff Johnson9d295242017-08-29 14:39:48 -07008443 struct hdd_adapter *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008444 int ret;
8445
Ravi Joshia307f632017-07-17 23:41:41 -07008446 /* open monitor mode adapter if con_mode is monitor mode */
Lin Bai1c678482017-12-18 18:29:11 +08008447 if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
8448 con_mode == QDF_GLOBAL_FTM_MODE) {
8449 uint8_t session_type = (con_mode == QDF_GLOBAL_MONITOR_MODE) ?
8450 QDF_MONITOR_MODE : QDF_FTM_MODE;
8451
8452 adapter = hdd_open_adapter(hdd_ctx, session_type, "wlan%d",
8453 wlan_hdd_get_intf_addr(hdd_ctx),
8454 NET_NAME_UNKNOWN, rtnl_held);
Ravi Joshia307f632017-07-17 23:41:41 -07008455 if (!adapter) {
8456 hdd_err("open adapter failed");
8457 return -ENOSPC;
8458 }
Lin Bai1c678482017-12-18 18:29:11 +08008459
Ravi Joshia307f632017-07-17 23:41:41 -07008460 return 0;
8461 }
8462
Jeff Johnson957bc272017-02-02 08:54:48 -08008463 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE)
Arun Khandavallifae92942016-08-01 13:31:08 +05308464 /* Create only 802.11p interface */
Jeff Johnson957bc272017-02-02 08:54:48 -08008465 return hdd_open_ocb_interface(hdd_ctx, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008466
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008467 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008468 wlan_hdd_get_intf_addr(hdd_ctx),
Ryan Hsu07495ea2016-01-21 15:25:39 -08008469 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008470
8471 if (adapter == NULL)
Jeff Johnson957bc272017-02-02 08:54:48 -08008472 return -ENOSPC;
8473
Deepak Dhamdherea2785822016-11-17 01:17:45 -08008474 /* fast roaming is allowed only on first STA, i.e. wlan adapter */
8475 adapter->fast_roaming_allowed = true;
8476
Sourav Mohapatra57006c72017-11-19 16:15:55 +05308477 if (strlen(hdd_ctx->config->enableConcurrentSTA) != 0) {
8478 ret = hdd_open_concurrent_interface(hdd_ctx, rtnl_held);
8479 if (ret)
8480 hdd_err("Cannot create concurrent STA interface");
8481 }
8482
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008483 ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
8484 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -08008485 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008486
8487 /* Open 802.11p Interface */
8488 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
Jeff Johnson957bc272017-02-02 08:54:48 -08008489 ret = hdd_open_ocb_interface(hdd_ctx, rtnl_held);
8490 if (ret)
8491 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008492 }
8493
Jeff Johnson957bc272017-02-02 08:54:48 -08008494 return 0;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008495
Jeff Johnson957bc272017-02-02 08:54:48 -08008496err_close_adapters:
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008497 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Jeff Johnson957bc272017-02-02 08:54:48 -08008498 return ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008499}
8500
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008501/**
8502 * hdd_update_country_code - Update country code
8503 * @hdd_ctx: HDD context
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008504 *
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07008505 * Update country code based on module parameter country_code
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008506 *
8507 * Return: 0 on success and errno on failure
8508 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008509static int hdd_update_country_code(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008510{
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07008511 if (!country_code)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008512 return 0;
8513
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07008514 return hdd_reg_set_country(hdd_ctx, country_code);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008515}
8516
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308517#ifdef QCA_LL_TX_FLOW_CONTROL_V2
8518/**
8519 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
8520 * @cds_cfg: CDS Configuration
8521 * @hdd_ctx: Pointer to hdd context
8522 *
8523 * Return: none
8524 */
8525static inline void hdd_txrx_populate_cds_config(struct cds_config_info
8526 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008527 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308528{
8529 cds_cfg->tx_flow_stop_queue_th =
8530 hdd_ctx->config->TxFlowStopQueueThreshold;
8531 cds_cfg->tx_flow_start_queue_offset =
8532 hdd_ctx->config->TxFlowStartQueueOffset;
8533}
8534#else
8535static inline void hdd_txrx_populate_cds_config(struct cds_config_info
8536 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008537 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308538{
8539}
8540#endif
8541
8542#ifdef FEATURE_WLAN_RA_FILTERING
8543/**
8544 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
8545 * @cds_cfg: CDS Configuration
8546 * @hdd_ctx: Pointer to hdd context
8547 *
8548 * Return: none
8549 */
Anand Kumar3b92a912016-12-05 12:01:26 +05308550static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008551 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308552{
8553 cds_cfg->ra_ratelimit_interval =
8554 hdd_ctx->config->RArateLimitInterval;
8555 cds_cfg->is_ra_ratelimit_enabled =
8556 hdd_ctx->config->IsRArateLimitEnabled;
8557}
8558#else
Anand Kumar3b92a912016-12-05 12:01:26 +05308559static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008560 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308561{
8562}
8563#endif
8564
8565/**
8566 * hdd_update_cds_config() - API to update cds configuration parameters
8567 * @hdd_ctx: HDD Context
8568 *
8569 * Return: 0 for Success, errno on failure
8570 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008571static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308572{
8573 struct cds_config_info *cds_cfg;
8574
8575 cds_cfg = (struct cds_config_info *)qdf_mem_malloc(sizeof(*cds_cfg));
8576 if (!cds_cfg) {
8577 hdd_err("failed to allocate cds config");
8578 return -ENOMEM;
8579 }
8580
Srinivas Girigowda35b00312017-06-27 21:52:03 -07008581 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -08008582 if (!hdd_ctx->config->nMaxPsPoll ||
8583 !hdd_ctx->config->enablePowersaveOffload) {
8584 cds_cfg->powersave_offload_enabled =
8585 hdd_ctx->config->enablePowersaveOffload;
8586 } else {
8587 if ((hdd_ctx->config->enablePowersaveOffload ==
8588 PS_QPOWER_NODEEPSLEEP) ||
8589 (hdd_ctx->config->enablePowersaveOffload ==
8590 PS_LEGACY_NODEEPSLEEP))
8591 cds_cfg->powersave_offload_enabled =
8592 PS_LEGACY_NODEEPSLEEP;
8593 else
8594 cds_cfg->powersave_offload_enabled =
8595 PS_LEGACY_DEEPSLEEP;
8596 hdd_info("Qpower disabled in cds config, %d",
8597 cds_cfg->powersave_offload_enabled);
8598 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308599 cds_cfg->sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
8600 cds_cfg->sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
8601 cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
8602 cds_cfg->wow_enable = hdd_ctx->config->wowEnable;
8603 cds_cfg->max_wow_filters = hdd_ctx->config->maxWoWFilters;
8604
8605 /* Here ol_ini_info is used to store ini status of arp offload
8606 * ns offload and others. Currently 1st bit is used for arp
8607 * off load and 2nd bit for ns offload currently, rest bits are unused
8608 */
8609 if (hdd_ctx->config->fhostArpOffload)
8610 cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x1;
8611 if (hdd_ctx->config->fhostNSOffload)
8612 cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x2;
8613
8614 /*
8615 * Copy the DFS Phyerr Filtering Offload status.
8616 * This parameter reflects the value of the
8617 * dfs_phyerr_filter_offload flag as set in the ini.
8618 */
8619 cds_cfg->dfs_phyerr_filter_offload =
8620 hdd_ctx->config->fDfsPhyerrFilterOffload;
8621 if (hdd_ctx->config->ssdp)
8622 cds_cfg->ssdp = hdd_ctx->config->ssdp;
8623
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05308624 cds_cfg->force_target_assert_enabled =
8625 hdd_ctx->config->crash_inject_enabled;
8626
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308627 cds_cfg->enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
8628 cds_cfg->ap_maxoffload_peers = hdd_ctx->config->apMaxOffloadPeers;
8629
8630 cds_cfg->ap_maxoffload_reorderbuffs =
8631 hdd_ctx->config->apMaxOffloadReorderBuffs;
8632
8633 cds_cfg->ap_disable_intrabss_fwd =
8634 hdd_ctx->config->apDisableIntraBssFwd;
8635
8636 cds_cfg->dfs_pri_multiplier =
8637 hdd_ctx->config->dfsRadarPriMultiplier;
8638 cds_cfg->reorder_offload =
8639 hdd_ctx->config->reorderOffloadSupport;
8640
8641 /* IPA micro controller data path offload resource config item */
8642 cds_cfg->uc_offload_enabled = hdd_ipa_uc_is_enabled(hdd_ctx);
Yun Parkde380782016-08-17 16:26:54 -07008643 if (!is_power_of_2(hdd_ctx->config->IpaUcTxBufCount)) {
8644 /* IpaUcTxBufCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008645 hdd_debug("Round down IpaUcTxBufCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07008646 hdd_ctx->config->IpaUcTxBufCount);
8647 hdd_ctx->config->IpaUcTxBufCount =
8648 rounddown_pow_of_two(
8649 hdd_ctx->config->IpaUcTxBufCount);
8650 if (!hdd_ctx->config->IpaUcTxBufCount) {
8651 hdd_err("Failed to round down IpaUcTxBufCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05308652 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07008653 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008654 hdd_debug("IpaUcTxBufCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07008655 hdd_ctx->config->IpaUcTxBufCount);
8656 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308657 cds_cfg->uc_txbuf_count = hdd_ctx->config->IpaUcTxBufCount;
8658 cds_cfg->uc_txbuf_size = hdd_ctx->config->IpaUcTxBufSize;
Yun Parkde380782016-08-17 16:26:54 -07008659 if (!is_power_of_2(hdd_ctx->config->IpaUcRxIndRingCount)) {
8660 /* IpaUcRxIndRingCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008661 hdd_debug("Round down IpaUcRxIndRingCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07008662 hdd_ctx->config->IpaUcRxIndRingCount);
8663 hdd_ctx->config->IpaUcRxIndRingCount =
8664 rounddown_pow_of_two(
8665 hdd_ctx->config->IpaUcRxIndRingCount);
8666 if (!hdd_ctx->config->IpaUcRxIndRingCount) {
8667 hdd_err("Failed to round down IpaUcRxIndRingCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05308668 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07008669 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008670 hdd_debug("IpaUcRxIndRingCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07008671 hdd_ctx->config->IpaUcRxIndRingCount);
8672 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308673 cds_cfg->uc_rxind_ringcount =
Yun Parkde380782016-08-17 16:26:54 -07008674 hdd_ctx->config->IpaUcRxIndRingCount;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308675 cds_cfg->uc_tx_partition_base =
8676 hdd_ctx->config->IpaUcTxPartitionBase;
8677 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
8678
8679 cds_cfg->ip_tcp_udp_checksum_offload =
8680 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07008681 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308682 cds_cfg->ce_classify_enabled =
8683 hdd_ctx->config->ce_classify_enabled;
Dustin Brownd3fc9ee2016-09-14 13:57:27 -07008684 cds_cfg->bpf_packet_filter_enable =
8685 hdd_ctx->config->bpf_packet_filter_enable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308686 cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
8687 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
8688 cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
Naveen Rawat64e477e2016-05-20 10:34:56 -07008689 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Manjunathappa Prakashfff753c2016-09-01 19:34:56 -07008690 cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07008691 cds_cfg->max_msdus_per_rxinorderind =
8692 hdd_ctx->config->max_msdus_per_rxinorderind;
Naveen Rawat91df30a2016-10-12 21:26:18 -07008693 cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
Sandeep Puligillaafa52892016-10-26 19:03:16 -07008694 cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05308695 cds_cfg->active_uc_bpf_mode = hdd_ctx->config->active_uc_bpf_mode;
8696 cds_cfg->active_mc_bc_bpf_mode = hdd_ctx->config->active_mc_bc_bpf_mode;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05308697 cds_cfg->auto_power_save_fail_mode =
8698 hdd_ctx->config->auto_pwr_save_fail_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308699
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05308700 cds_cfg->ito_repeat_count = hdd_ctx->config->ito_repeat_count;
Sandeep Puligilla819d94f2017-10-10 18:33:56 -07008701 cds_cfg->bandcapability = hdd_ctx->config->nBandCapability;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05308702
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308703 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
8704 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
8705 hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07008706 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308707 cds_init_ini_config(cds_cfg);
8708 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05308709
8710exit:
8711 qdf_mem_free(cds_cfg);
8712 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308713}
8714
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008715/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08008716 * hdd_update_user_config() - API to update user configuration
8717 * parameters to obj mgr which are used by multiple components
8718 * @hdd_ctx: HDD Context
8719 *
8720 * Return: 0 for Success, errno on failure
8721 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008722static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08008723{
8724 struct wlan_objmgr_psoc_user_config *user_config;
8725
8726 user_config = qdf_mem_malloc(sizeof(*user_config));
8727 if (user_config == NULL) {
8728 hdd_alert("Failed to alloc memory for user_config!");
8729 return -ENOMEM;
8730 }
8731
8732 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
8733 user_config->dual_mac_feature_disable =
8734 hdd_ctx->config->dual_mac_feature_disable;
8735 user_config->indoor_channel_support =
8736 hdd_ctx->config->indoor_channel_support;
8737 user_config->is_11d_support_enabled =
8738 hdd_ctx->config->Is11dSupportEnabled;
8739 user_config->is_11h_support_enabled =
8740 hdd_ctx->config->Is11hSupportEnabled;
8741 user_config->optimize_chan_avoid_event =
8742 hdd_ctx->config->goptimize_chan_avoid_event;
8743 user_config->skip_dfs_chnl_in_p2p_search =
8744 hdd_ctx->config->skipDfsChnlInP2pSearch;
Naveen Rawat222b2e92017-03-16 09:52:21 -07008745 user_config->band_capability = hdd_ctx->config->nBandCapability;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08008746 wlan_objmgr_psoc_set_user_config(hdd_ctx->hdd_psoc, user_config);
8747
8748 qdf_mem_free(user_config);
8749 return 0;
8750}
8751
8752/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008753 * hdd_init_thermal_info - Initialize thermal level
8754 * @hdd_ctx: HDD context
8755 *
8756 * Initialize thermal level at SME layer and set the thermal level callback
8757 * which would be called when a configured thermal threshold is hit.
8758 *
8759 * Return: 0 on success and errno on failure
8760 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008761static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008762{
8763 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308764 QDF_STATUS status;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008765
8766 thermal_param.smeThermalMgmtEnabled =
8767 hdd_ctx->config->thermalMitigationEnable;
8768 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
8769
Poddar, Siddarth83905022016-04-16 17:56:08 -07008770 thermal_param.sme_throttle_duty_cycle_tbl[0] =
8771 hdd_ctx->config->throttle_dutycycle_level0;
8772 thermal_param.sme_throttle_duty_cycle_tbl[1] =
8773 hdd_ctx->config->throttle_dutycycle_level1;
8774 thermal_param.sme_throttle_duty_cycle_tbl[2] =
8775 hdd_ctx->config->throttle_dutycycle_level2;
8776 thermal_param.sme_throttle_duty_cycle_tbl[3] =
8777 hdd_ctx->config->throttle_dutycycle_level3;
8778
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008779 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
8780 hdd_ctx->config->thermalTempMinLevel0;
8781 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
8782 hdd_ctx->config->thermalTempMaxLevel0;
8783 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
8784 hdd_ctx->config->thermalTempMinLevel1;
8785 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
8786 hdd_ctx->config->thermalTempMaxLevel1;
8787 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
8788 hdd_ctx->config->thermalTempMinLevel2;
8789 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
8790 hdd_ctx->config->thermalTempMaxLevel2;
8791 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
8792 hdd_ctx->config->thermalTempMinLevel3;
8793 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
8794 hdd_ctx->config->thermalTempMaxLevel3;
8795
8796 status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);
8797
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308798 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05308799 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008800
8801 sme_add_set_thermal_level_callback(hdd_ctx->hHal,
8802 hdd_set_thermal_level_cb);
8803
8804 return 0;
8805
8806}
8807
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008808#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
8809/**
8810 * hdd_hold_rtnl_lock - Hold RTNL lock
8811 *
8812 * Hold RTNL lock
8813 *
8814 * Return: True if held and false otherwise
8815 */
8816static inline bool hdd_hold_rtnl_lock(void)
8817{
8818 rtnl_lock();
8819 return true;
8820}
8821
8822/**
8823 * hdd_release_rtnl_lock - Release RTNL lock
8824 *
8825 * Release RTNL lock
8826 *
8827 * Return: None
8828 */
8829static inline void hdd_release_rtnl_lock(void)
8830{
8831 rtnl_unlock();
8832}
8833#else
8834static inline bool hdd_hold_rtnl_lock(void) { return false; }
8835static inline void hdd_release_rtnl_lock(void) { }
8836#endif
8837
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008838#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008839
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308840/* MAX iwpriv command support */
8841#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308842#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308843#define MAX_PKTLOG_SIZE 16
8844
8845/**
8846 * hdd_pktlog_set_buff_size() - set pktlog buffer size
8847 * @hdd_ctx: hdd context
8848 * @set_value2: pktlog buffer size value
8849 *
8850 *
8851 * Return: 0 for success or error.
8852 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008853static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308854{
8855 struct sir_wifi_start_log start_log = { 0 };
8856 QDF_STATUS status;
8857
8858 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8859 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
8860 start_log.ini_triggered = cds_is_packet_log_enabled();
8861 start_log.user_triggered = 1;
8862 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308863 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308864
8865 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8866 if (!QDF_IS_STATUS_SUCCESS(status)) {
8867 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8868 EXIT();
8869 return -EINVAL;
8870 }
8871
8872 return 0;
8873}
8874
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008875/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308876 * hdd_pktlog_clear_buff() - clear pktlog buffer
8877 * @hdd_ctx: hdd context
8878 *
8879 * Return: 0 for success or error.
8880 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008881static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308882{
8883 struct sir_wifi_start_log start_log;
8884 QDF_STATUS status;
8885
8886 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8887 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
8888 start_log.ini_triggered = cds_is_packet_log_enabled();
8889 start_log.user_triggered = 1;
8890 start_log.size = 0;
8891 start_log.is_pktlog_buff_clear = true;
8892
8893 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8894 if (!QDF_IS_STATUS_SUCCESS(status)) {
8895 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8896 EXIT();
8897 return -EINVAL;
8898 }
8899
8900 return 0;
8901}
8902
8903
8904/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008905 * hdd_process_pktlog_command() - process pktlog command
8906 * @hdd_ctx: hdd context
8907 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308908 * @set_value2: pktlog buffer size value
8909 *
8910 * This function process pktlog command.
8911 * set_value2 only matters when set_value is 3 (set buff size)
8912 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008913 *
8914 * Return: 0 for success or error.
8915 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008916int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308917 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008918{
8919 int ret;
8920 bool enable;
8921 uint8_t user_triggered = 0;
8922
8923 ret = wlan_hdd_validate_context(hdd_ctx);
8924 if (0 != ret)
8925 return ret;
8926
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008927 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008928
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308929 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008930 hdd_err("invalid pktlog value %d", set_value);
8931 return -EINVAL;
8932 }
8933
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308934 if (set_value == PKTLOG_SET_BUFF_SIZE) {
8935 if (set_value2 <= 0) {
8936 hdd_err("invalid pktlog size %d", set_value2);
8937 return -EINVAL;
8938 } else if (set_value2 > MAX_PKTLOG_SIZE) {
8939 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
8940 return -EINVAL;
8941 }
8942 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308943 } else if (set_value == PKTLOG_CLEAR_BUFF) {
8944 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308945 }
8946
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008947 /*
8948 * set_value = 0 then disable packetlog
8949 * set_value = 1 enable packetlog forcefully
8950 * set_vlaue = 2 then disable packetlog if disabled through ini or
8951 * enable packetlog with AUTO type.
8952 */
8953 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
8954 true : false;
8955
8956 if (1 == set_value) {
8957 enable = true;
8958 user_triggered = 1;
8959 }
8960
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308961 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008962}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07008963
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008964/**
8965 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
8966 * @hdd_ctx: HDD context
8967 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308968 * @user_triggered: triggered through iwpriv
8969 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008970 *
8971 * Return: 0 on success; error number otherwise
8972 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008973int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308974 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008975{
8976 struct sir_wifi_start_log start_log;
8977 QDF_STATUS status;
8978
8979 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8980 start_log.verbose_level =
8981 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008982 start_log.ini_triggered = cds_is_packet_log_enabled();
8983 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308984 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308985 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +05308986 /*
8987 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
8988 * commands. Host uses this flag to decide whether to send pktlog
8989 * disable command to fw without sending pktlog enable command
8990 * previously. For eg, If vendor sends pktlog disable command without
8991 * sending pktlog enable command, then host discards the packet
8992 * but for iwpriv command, host will send it to fw.
8993 */
8994 start_log.is_iwpriv_command = 1;
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008995 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8996 if (!QDF_IS_STATUS_SUCCESS(status)) {
8997 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8998 EXIT();
8999 return -EINVAL;
9000 }
9001
Poddar, Siddarth61fbc932017-12-19 14:27:55 +05309002 if (enable == true)
9003 hdd_ctx->is_pktlog_enabled = 1;
9004 else
9005 hdd_ctx->is_pktlog_enabled = 0;
9006
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009007 return 0;
9008}
9009#endif /* REMOVE_PKT_LOG */
9010
Komal Seelam92fff912016-03-24 11:51:41 +05309011/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009012 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
9013 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +05309014 * @dev: Device Pointer
9015 * @num: Number of Valid Mac address
9016 *
9017 * Return: Pointer to MAC address buffer
9018 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009019static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
9020 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +05309021{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009022 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +05309023}
Komal Seelam92fff912016-03-24 11:51:41 +05309024
9025/**
9026 * hdd_populate_random_mac_addr() - API to populate random mac addresses
9027 * @hdd_ctx: HDD Context
9028 * @num: Number of random mac addresses needed
9029 *
9030 * Generate random addresses using bit manipulation on the base mac address
9031 *
9032 * Return: None
9033 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009034void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +05309035{
9036 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
9037 uint32_t iter;
9038 struct hdd_config *ini = hdd_ctx->config;
9039 uint8_t *buf = NULL;
9040 uint8_t macaddr_b3, tmp_br3;
9041 uint8_t *src = ini->intfMacAddr[0].bytes;
9042
9043 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
9044 buf = ini->intfMacAddr[iter].bytes;
9045 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
9046 macaddr_b3 = buf[3];
9047 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
9048 INTF_MACADDR_MASK;
9049 macaddr_b3 += tmp_br3;
9050 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
9051 buf[0] |= 0x02;
9052 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009053 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309054 }
9055}
9056
9057/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009058 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +05309059 * @hdd_ctx: HDD Context
9060 *
9061 * API to get mac addresses from platform driver and update the driver
9062 * structures and configure FW with the base mac address.
9063 * Return: int
9064 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009065static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309066{
9067 uint32_t no_of_mac_addr, iter;
9068 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
9069 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
9070 uint8_t *addr, *buf;
9071 struct device *dev = hdd_ctx->parent_dev;
9072 struct hdd_config *ini = hdd_ctx->config;
9073 tSirMacAddr mac_addr;
9074 QDF_STATUS status;
9075
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009076 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +05309077
9078 if (no_of_mac_addr == 0 || !addr) {
9079 hdd_warn("Platform Driver Doesn't have wlan mac addresses");
9080 return -EINVAL;
9081 }
9082
9083 if (no_of_mac_addr > max_mac_addr)
9084 no_of_mac_addr = max_mac_addr;
9085
9086 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
9087
9088 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
9089 buf = ini->intfMacAddr[iter].bytes;
9090 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009091 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05309092 }
9093
9094 status = sme_set_custom_mac_addr(mac_addr);
9095
9096 if (!QDF_IS_STATUS_SUCCESS(status))
9097 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009098
Komal Seelam92fff912016-03-24 11:51:41 +05309099 if (no_of_mac_addr < max_mac_addr)
9100 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
9101 no_of_mac_addr);
9102 return 0;
9103}
9104
9105/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009106 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
9107 * @hdd_ctx: HDD Context
9108 *
9109 * Update MAC address to FW. If MAC address passed by FW is invalid, host
9110 * will generate its own MAC and update it to FW.
9111 *
9112 * Return: 0 for success
9113 * Non-zero error code for failure
9114 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009115static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009116{
9117 tSirMacAddr customMacAddr;
9118 QDF_STATUS status;
9119
9120 qdf_mem_copy(&customMacAddr,
9121 &hdd_ctx->config->intfMacAddr[0].bytes[0],
9122 sizeof(tSirMacAddr));
9123 status = sme_set_custom_mac_addr(customMacAddr);
9124 if (!QDF_IS_STATUS_SUCCESS(status))
9125 return -EAGAIN;
9126 return 0;
9127}
9128
9129/**
Komal Seelam92fff912016-03-24 11:51:41 +05309130 * hdd_initialize_mac_address() - API to get wlan mac addresses
9131 * @hdd_ctx: HDD Context
9132 *
9133 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
9134 * is provisioned with mac addresses, driver uses it, else it will use
9135 * wlan_mac.bin to update HW MAC addresses.
9136 *
9137 * Return: None
9138 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009139static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05309140{
9141 QDF_STATUS status;
9142 int ret;
9143
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08009144 ret = hdd_platform_wlan_mac(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +05309145 if (ret == 0)
9146 return;
9147
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009148 hdd_info("MAC is not programmed in platform driver ret: %d, use wlan_mac.bin",
9149 ret);
Komal Seelam92fff912016-03-24 11:51:41 +05309150
9151 status = hdd_update_mac_config(hdd_ctx);
9152
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009153 if (QDF_IS_STATUS_SUCCESS(status))
9154 return;
9155
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07009156 hdd_info("MAC is not programmed in wlan_mac.bin ret %d, use default MAC",
9157 status);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009158
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009159 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009160 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08009161 if (ret != 0) {
9162 hdd_err("MAC address out-of-sync, ret:%d", ret);
9163 QDF_ASSERT(ret);
9164 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07009165 }
Komal Seelam92fff912016-03-24 11:51:41 +05309166}
9167
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009168static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009169{
9170 int vdev_id = 0;
9171 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
9172 int value = hdd_ctx->config->smart_chainmask_enabled;
9173 int vpdev = PDEV_CMD;
9174 int ret;
9175
Naveen Rawat247a8682017-06-05 15:00:31 -07009176 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009177 if (ret)
9178 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
9179
9180 return ret;
9181}
9182
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009183static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009184{
9185 int vdev_id = 0;
9186 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
9187 int value = hdd_ctx->config->alternative_chainmask_enabled;
9188 int vpdev = PDEV_CMD;
9189 int ret;
9190
Naveen Rawat247a8682017-06-05 15:00:31 -07009191 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009192 if (ret)
9193 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
9194 ret);
9195
9196 return ret;
9197}
9198
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009199static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -07009200{
9201 int vdev_id = 0;
9202 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
9203 int value = hdd_ctx->config->ani_enabled;
9204 int vpdev = PDEV_CMD;
9205 int ret;
9206
Naveen Rawat247a8682017-06-05 15:00:31 -07009207 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -07009208 if (ret)
9209 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
9210
9211 return ret;
9212}
9213
Jeff Johnson89c66ff2016-04-22 15:21:37 -07009214/**
Prashanth Bhatta07998752016-04-28 12:35:33 -07009215 * hdd_pre_enable_configure() - Configurations prior to cds_enable
9216 * @hdd_ctx: HDD context
9217 *
9218 * Pre configurations to be done at lower layer before calling cds enable.
9219 *
9220 * Return: 0 on success and errno on failure.
9221 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009222static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -07009223{
9224 int ret;
9225 QDF_STATUS status;
9226 tSirRetStatus hal_status;
Leo Changfdb45c32016-10-28 11:09:23 -07009227 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009228
Leo Changfdb45c32016-10-28 11:09:23 -07009229 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009230 /*
9231 * Set 802.11p config
9232 * TODO-OCB: This has been temporarily added here to ensure this
9233 * parameter is set in CSR when we init the channel list. This should
9234 * be removed once the 5.9 GHz channels are added to the regulatory
9235 * domain.
9236 */
9237 hdd_set_dot11p_config(hdd_ctx);
9238
9239 /*
9240 * Note that the cds_pre_enable() sequence triggers the cfg download.
9241 * The cfg download must occur before we update the SME config
9242 * since the SME config operation must access the cfg database
9243 */
9244 status = hdd_set_sme_config(hdd_ctx);
9245
9246 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009247 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009248 ret = qdf_status_to_os_return(status);
9249 goto out;
9250 }
9251
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -07009252 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
9253 if (QDF_STATUS_SUCCESS != status) {
9254 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
9255 ret = qdf_status_to_os_return(status);
9256 goto out;
9257 }
9258
Naveen Rawat247a8682017-06-05 15:00:31 -07009259 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
Prashanth Bhatta07998752016-04-28 12:35:33 -07009260 hdd_ctx->config->tx_chain_mask_1ss,
9261 PDEV_CMD);
9262 if (0 != ret) {
9263 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
9264 goto out;
9265 }
9266
Jeff Johnsona89e25d2017-02-24 12:25:07 -08009267 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
9268 if (ret)
9269 goto out;
9270
9271 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
9272 if (ret)
9273 goto out;
9274
Jeff Johnson12a744b2017-04-04 08:19:37 -07009275 ret = hdd_set_ani_enabled(hdd_ctx);
9276 if (ret)
9277 goto out;
9278
Naveen Rawat247a8682017-06-05 15:00:31 -07009279 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -08009280 hdd_ctx->config->arp_ac_category,
9281 PDEV_CMD);
9282 if (0 != ret) {
9283 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
9284 hdd_ctx->config->arp_ac_category, ret);
9285 goto out;
9286 }
9287
Prashanth Bhatta07998752016-04-28 12:35:33 -07009288 status = hdd_set_sme_chan_list(hdd_ctx);
9289 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009290 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009291 ret = qdf_status_to_os_return(status);
9292 goto out;
9293 }
9294
9295 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -07009296 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009297 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -07009298 ret = -EINVAL;
9299 goto out;
9300 }
9301
Prashanth Bhatta07998752016-04-28 12:35:33 -07009302 /*
9303 * Set the MAC Address Currently this is used by HAL to add self sta.
9304 * Remove this once self sta is added as part of session open.
9305 */
9306 hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
9307 hdd_ctx->config->intfMacAddr[0].bytes,
9308 sizeof(hdd_ctx->config->intfMacAddr[0]));
9309
9310 if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
9311 hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
9312 hal_status, hal_status);
9313 ret = -EINVAL;
9314 goto out;
9315 }
9316
9317 hdd_init_channel_avoidance(hdd_ctx);
9318
Ganesh Kondabattini408fb8d2017-08-08 22:00:20 +05309319 /* update enable sap mandatory chan list */
9320 policy_mgr_enable_disable_sap_mandatory_chan_list(hdd_ctx->hdd_psoc,
9321 hdd_ctx->config->enable_sap_mandatory_chan_list);
Prashanth Bhatta07998752016-04-28 12:35:33 -07009322out:
9323 return ret;
9324}
9325
9326/**
Peng Xu8fdaa492016-06-22 10:20:47 -07009327 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
9328 * @context_ptr - hdd context pointer
9329 * @event_ptr - event structure pointer
9330 *
9331 * This is the p2p listen offload stop event handler, it sends vendor
9332 * event back to supplicant to notify the stop reason.
9333 *
9334 * Return: None
9335 */
9336static void wlan_hdd_p2p_lo_event_callback(void *context_ptr,
9337 void *event_ptr)
9338{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009339 struct hdd_context *hdd_ctx = (struct hdd_context *)context_ptr;
Peng Xu8fdaa492016-06-22 10:20:47 -07009340 struct sir_p2p_lo_event *evt = event_ptr;
9341 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -07009342 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -07009343
9344 ENTER();
9345
9346 if (hdd_ctx == NULL) {
9347 hdd_err("Invalid HDD context pointer");
9348 return;
9349 }
9350
Peng Xu5c682812017-08-06 07:39:13 -07009351 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
9352 if (!adapter) {
9353 hdd_err("Cannot find adapter by vdev_id = %d",
9354 evt->vdev_id);
9355 return;
9356 }
9357
Peng Xu8fdaa492016-06-22 10:20:47 -07009358 vendor_event =
9359 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -07009360 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -07009361 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
9362 GFP_KERNEL);
9363
9364 if (!vendor_event) {
9365 hdd_err("cfg80211_vendor_event_alloc failed");
9366 return;
9367 }
9368
9369 if (nla_put_u32(vendor_event,
9370 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
9371 evt->reason_code)) {
9372 hdd_err("nla put failed");
9373 kfree_skb(vendor_event);
9374 return;
9375 }
9376
9377 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -07009378 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
9379 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -07009380}
9381
9382/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309383 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
9384 * @hdd_ctx: HDD context
9385 *
9386 * This function sends the adaptive dwell time config configuration to the
9387 * firmware via WMA
9388 *
9389 * Return: 0 - success, < 0 - failure
9390 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009391static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309392{
9393 QDF_STATUS status;
9394 struct adaptive_dwelltime_params dwelltime_params;
9395
9396 dwelltime_params.is_enabled =
9397 hdd_ctx->config->adaptive_dwell_mode_enabled;
9398 dwelltime_params.dwelltime_mode =
9399 hdd_ctx->config->global_adapt_dwelltime_mode;
9400 dwelltime_params.lpf_weight =
9401 hdd_ctx->config->adapt_dwell_lpf_weight;
9402 dwelltime_params.passive_mon_intval =
9403 hdd_ctx->config->adapt_dwell_passive_mon_intval;
9404 dwelltime_params.wifi_act_threshold =
9405 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
9406
9407 status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
9408 &dwelltime_params);
9409
9410 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
9411 if (!QDF_IS_STATUS_SUCCESS(status)) {
9412 hdd_err("Failed to send Adaptive Dwelltime configuration!");
9413 return -EAGAIN;
9414 }
9415 return 0;
9416}
9417
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009418int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309419{
9420 QDF_STATUS status;
9421 struct wmi_dbs_scan_sel_params dbs_scan_params;
9422 uint32_t i = 0;
9423 uint8_t count = 0, numentries = 0;
9424 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
9425 * CDS_DBS_SCAN_CLIENTS_MAX];
9426
9427 /* check if DBS is enabled or supported */
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07009428 if (hdd_ctx->config->dual_mac_feature_disable ==
9429 DISABLE_DBS_CXN_AND_SCAN)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309430 return -EINVAL;
9431
9432 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
9433 dbs_scan_config, &numentries,
9434 (CDS_DBS_SCAN_PARAM_PER_CLIENT
9435 * CDS_DBS_SCAN_CLIENTS_MAX));
9436
9437 hdd_info("numentries %hu", numentries);
9438 if (!numentries) {
9439 hdd_info("Donot send scan_selection_config");
9440 return 0;
9441 }
9442
9443 /* hdd_set_fw_log_params */
9444 dbs_scan_params.num_clients = 0;
9445 while (count < (numentries - 2)) {
9446 dbs_scan_params.module_id[i] = dbs_scan_config[count];
9447 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
9448 dbs_scan_params.num_non_dbs_scans[i] =
9449 dbs_scan_config[count + 2];
9450 dbs_scan_params.num_clients++;
9451 hdd_debug("module:%d NDS:%d NNDS:%d",
9452 dbs_scan_params.module_id[i],
9453 dbs_scan_params.num_dbs_scans[i],
9454 dbs_scan_params.num_non_dbs_scans[i]);
9455 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
9456 i++;
9457 }
9458
9459 dbs_scan_params.pdev_id = 0;
9460
9461 hdd_debug("clients:%d pdev:%d",
9462 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
9463
9464 status = sme_set_dbs_scan_selection_config(hdd_ctx->hHal,
9465 &dbs_scan_params);
9466 hdd_debug("Sending DBS Scan Selection Configuration to fw");
9467 if (!QDF_IS_STATUS_SUCCESS(status)) {
9468 hdd_err("Failed to send DBS Scan selection configuration!");
9469 return -EAGAIN;
9470 }
9471 return 0;
9472}
9473
Arun Khandavallid4349a92016-07-25 11:10:43 +05309474#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9475/**
9476 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
9477 * @hdd_ctx: HDD context
9478 *
9479 * Set auto shutdown callback to get indications from firmware to indicate
9480 * userspace to shutdown WLAN after a configured amount of inactivity.
9481 *
9482 * Return: 0 on success and errno on failure.
9483 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009484static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309485{
9486 QDF_STATUS status;
9487
9488 if (!hdd_ctx->config->WlanAutoShutdown)
9489 return 0;
9490
9491 status = sme_set_auto_shutdown_cb(hdd_ctx->hHal,
9492 wlan_hdd_auto_shutdown_cb);
9493 if (status != QDF_STATUS_SUCCESS)
9494 hdd_err("Auto shutdown feature could not be enabled: %d",
9495 status);
9496
9497 return qdf_status_to_os_return(status);
9498}
9499#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009500static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309501{
9502 return 0;
9503}
9504#endif
9505
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009506static QDF_STATUS hdd_set_dbs_scan_and_fw_mode_cfg(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07009507{
9508 QDF_STATUS status = QDF_STATUS_SUCCESS;
9509
9510 switch (hdd_ctx->config->dual_mac_feature_disable) {
9511 case DISABLE_DBS_CXN_AND_SCAN:
9512 status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx);
9513 if (status != QDF_STATUS_SUCCESS)
9514 hdd_err("Failed to disable dual mac features");
9515 break;
9516 case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN:
9517 case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF:
9518 case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF:
9519 status = wlan_hdd_update_dbs_scan_and_fw_mode_config(hdd_ctx);
9520 if (status != QDF_STATUS_SUCCESS)
9521 hdd_err("Failed to set dbs scan and fw mode config");
9522 break;
9523 default:
9524 break;
9525 }
9526
9527 return status;
9528}
9529
Arun Khandavallid4349a92016-07-25 11:10:43 +05309530/**
9531 * hdd_features_init() - Init features
9532 * @hdd_ctx: HDD context
9533 * @adapter: Primary adapter context
9534 *
9535 * Initialize features and their feature context after WLAN firmware is up.
9536 *
9537 * Return: 0 on success and errno on failure.
9538 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009539static int hdd_features_init(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
Arun Khandavallid4349a92016-07-25 11:10:43 +05309540{
9541 tSirTxPowerLimit hddtxlimit;
9542 QDF_STATUS status;
Manjeet Singha9cae432017-02-28 11:58:22 +05309543 struct sme_5g_band_pref_params band_pref_params;
Arun Khandavallid4349a92016-07-25 11:10:43 +05309544 int ret;
9545
9546 ENTER();
9547
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07009548 ret = hdd_update_country_code(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309549 if (ret) {
9550 hdd_err("Failed to update country code: %d", ret);
9551 goto out;
9552 }
9553
9554 /* FW capabilities received, Set the Dot11 mode */
9555 sme_setdef_dot11mode(hdd_ctx->hHal);
Kiran Kumar Lokere1aa9c9a2016-10-05 18:50:59 -07009556 sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal,
9557 hdd_ctx->config->sta_prefer_80MHz_over_160MHz);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309558
Arun Khandavallid4349a92016-07-25 11:10:43 +05309559
9560 if (hdd_ctx->config->fIsImpsEnabled)
9561 hdd_set_idle_ps_config(hdd_ctx, true);
9562 else
9563 hdd_set_idle_ps_config(hdd_ctx, false);
9564
Poddar, Siddarth37033032017-10-11 15:47:40 +05309565 /* Send Enable/Disable data stall detection cmd to FW */
9566 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
9567 hdd_ctx->config->enable_data_stall_det, PDEV_CMD);
9568
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05309569 if (hdd_ctx->config->enable_go_cts2self_for_sta)
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009570 sme_set_cts2self_for_p2p_go(hdd_ctx->hHal);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05309571
Nachiket Kukade8983cf62017-10-12 18:14:48 +05309572 if (sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap))
9573 hdd_warn("Error in setting Voltage Corner mode config to FW");
9574
Arun Khandavallid4349a92016-07-25 11:10:43 +05309575 if (hdd_lro_init(hdd_ctx))
9576 hdd_err("Unable to initialize LRO in fw");
9577
9578 if (hdd_adaptive_dwelltime_init(hdd_ctx))
9579 hdd_err("Unable to send adaptive dwelltime setting to FW");
9580
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05309581 if (hdd_dbs_scan_selection_init(hdd_ctx))
9582 hdd_err("Unable to send DBS scan selection setting to FW");
9583
Arun Khandavallid4349a92016-07-25 11:10:43 +05309584 ret = hdd_init_thermal_info(hdd_ctx);
9585 if (ret) {
9586 hdd_err("Error while initializing thermal information");
9587 goto deregister_frames;
9588 }
9589
Poddar, Siddarth61fbc932017-12-19 14:27:55 +05309590 /**
9591 * In case of SSR/PDR, if pktlog was enabled manually before
9592 * SSR/PDR, Then enabled it again automatically after Wlan
9593 * device up.
9594 */
9595 if (cds_is_driver_recovering()) {
9596 if (hdd_ctx->is_pktlog_enabled)
9597 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
9598 } else if (cds_is_packet_log_enabled())
Poddar, Siddarth66a46592017-02-22 11:44:44 +05309599 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
9600
Arun Khandavallid4349a92016-07-25 11:10:43 +05309601 hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
9602 hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
9603 status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
9604 if (!QDF_IS_STATUS_SUCCESS(status))
9605 hdd_err("Error setting txlimit in sme: %d", status);
9606
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009607 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +05309608
Arun Khandavallid4349a92016-07-25 11:10:43 +05309609 ret = hdd_register_cb(hdd_ctx);
9610 if (ret) {
9611 hdd_err("Failed to register HDD callbacks!");
9612 goto deregister_frames;
9613 }
9614
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07009615 status = hdd_set_dbs_scan_and_fw_mode_cfg(hdd_ctx);
9616 if (!QDF_IS_STATUS_SUCCESS(status)) {
9617 hdd_err("Failed to set dbs scan and fw mode cfg");
9618 goto deregister_cb;
Arun Khandavallid4349a92016-07-25 11:10:43 +05309619 }
Tushnim Bhattacharyya49ed8ab2017-05-26 18:20:10 -07009620
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +05309621 if (hdd_ctx->config->goptimize_chan_avoid_event) {
9622 status = sme_enable_disable_chanavoidind_event(
9623 hdd_ctx->hHal, 0);
9624 if (!QDF_IS_STATUS_SUCCESS(status)) {
9625 hdd_err("Failed to disable Chan Avoidance Indication");
9626 goto deregister_cb;
9627 }
9628 }
Arun Khandavallid4349a92016-07-25 11:10:43 +05309629
Manjeet Singha9cae432017-02-28 11:58:22 +05309630 if (hdd_ctx->config->enable_5g_band_pref) {
9631 band_pref_params.rssi_boost_threshold_5g =
9632 hdd_ctx->config->rssi_boost_threshold_5g;
9633 band_pref_params.rssi_boost_factor_5g =
9634 hdd_ctx->config->rssi_boost_factor_5g;
9635 band_pref_params.max_rssi_boost_5g =
9636 hdd_ctx->config->max_rssi_boost_5g;
9637 band_pref_params.rssi_penalize_threshold_5g =
9638 hdd_ctx->config->rssi_penalize_threshold_5g;
9639 band_pref_params.rssi_penalize_factor_5g =
9640 hdd_ctx->config->rssi_penalize_factor_5g;
9641 band_pref_params.max_rssi_penalize_5g =
9642 hdd_ctx->config->max_rssi_penalize_5g;
9643 sme_set_5g_band_pref(hdd_ctx->hHal, &band_pref_params);
9644 }
9645
Arun Khandavallid4349a92016-07-25 11:10:43 +05309646 /* register P2P Listen Offload event callback */
9647 if (wma_is_p2p_lo_capable())
9648 sme_register_p2p_lo_event(hdd_ctx->hHal, hdd_ctx,
9649 wlan_hdd_p2p_lo_event_callback);
9650
9651 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
9652
9653 if (ret)
9654 goto deregister_cb;
9655
9656 EXIT();
9657 return 0;
9658
9659deregister_cb:
9660 hdd_deregister_cb(hdd_ctx);
9661deregister_frames:
9662 wlan_hdd_cfg80211_deregister_frames(adapter);
9663out:
9664 return -EINVAL;
9665
9666}
9667
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009668/**
9669 * hdd_features_deinit() - Deinit features
9670 * @hdd_ctx: HDD context
9671 *
9672 * De-Initialize features and their feature context.
9673 *
9674 * Return: none.
9675 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009676static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009677{
9678 wlan_hdd_tsf_deinit(hdd_ctx);
9679}
9680
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309681/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -07009682 * hdd_register_bcn_cb() - register scan beacon callback
9683 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309684 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -07009685 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309686 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009687static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309688{
9689 QDF_STATUS status;
9690
9691 status = ucfg_scan_register_bcn_cb(hdd_ctx->hdd_psoc,
9692 wlan_cfg80211_inform_bss_frame,
9693 SCAN_CB_TYPE_INFORM_BCN);
9694 if (!QDF_IS_STATUS_SUCCESS(status)) {
9695 hdd_err("failed with status code %08d [x%08x]",
9696 status, status);
9697 return status;
9698 }
9699
9700 return QDF_STATUS_SUCCESS;
9701}
Arun Khandavallid4349a92016-07-25 11:10:43 +05309702
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05309703/**
Arun Khandavallifae92942016-08-01 13:31:08 +05309704 * hdd_configure_cds() - Configure cds modules
9705 * @hdd_ctx: HDD context
9706 * @adapter: Primary adapter context
9707 *
9708 * Enable Cds modules after WLAN firmware is up.
9709 *
9710 * Return: 0 on success and errno on failure.
9711 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009712int hdd_configure_cds(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05309713{
9714 int ret;
9715 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +05309716 int set_value;
9717 uint32_t num_abg_tx_chains = 0;
9718 uint32_t num_11b_tx_chains = 0;
9719 uint32_t num_11ag_tx_chains = 0;
Yun Parkff6a16a2017-09-26 16:38:18 -07009720 struct policy_mgr_dp_cbacks dp_cbs;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +05309721
9722 if (hdd_ctx->config->sifs_burst_duration) {
9723 set_value = (SIFS_BURST_DUR_MULTIPLIER) *
9724 hdd_ctx->config->sifs_burst_duration;
9725
9726 if ((set_value > 0) && (set_value <= SIFS_BURST_DUR_MAX))
9727 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_BURST_DUR,
9728 set_value, PDEV_CMD);
9729 }
9730
9731 if (hdd_ctx->config->is_force_1x1)
9732 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
9733 1, PDEV_CMD);
9734 /* set chip power save failure detected callback */
9735 sme_set_chip_pwr_save_fail_cb(hdd_ctx->hHal,
9736 hdd_chip_pwr_save_fail_detected_cb);
9737
9738 if (hdd_ctx->config->max_mpdus_inampdu) {
9739 set_value = hdd_ctx->config->max_mpdus_inampdu;
9740 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
9741 set_value, PDEV_CMD);
9742 }
9743
9744 if (hdd_ctx->config->enable_rts_sifsbursting) {
9745 set_value = hdd_ctx->config->enable_rts_sifsbursting;
9746 sme_cli_set_command(0,
9747 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
9748 set_value, PDEV_CMD);
9749 }
9750
9751 if (hdd_ctx->config->sap_get_peer_info) {
9752 set_value = hdd_ctx->config->sap_get_peer_info;
9753 sme_cli_set_command(0,
9754 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
9755 set_value, PDEV_CMD);
9756 }
9757
9758 num_11b_tx_chains = hdd_ctx->config->num_11b_tx_chains;
9759 num_11ag_tx_chains = hdd_ctx->config->num_11ag_tx_chains;
9760 if (!hdd_ctx->config->enable2x2) {
9761 if (num_11b_tx_chains > 1)
9762 num_11b_tx_chains = 1;
9763 if (num_11ag_tx_chains > 1)
9764 num_11ag_tx_chains = 1;
9765 }
9766 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
9767 num_11b_tx_chains);
9768 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
9769 num_11ag_tx_chains);
9770 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
9771 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +05309772
9773 ret = hdd_pre_enable_configure(hdd_ctx);
9774 if (ret) {
9775 hdd_err("Failed to pre-configure cds");
9776 goto out;
9777 }
9778
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08009779 /* Always get latest IPA resources allocated from cds_open and configure
9780 * IPA module before configuring them to FW. Sequence required as crash
9781 * observed otherwise.
9782 */
Manikandan Mohan2e803a02017-02-14 14:57:53 -08009783 if (hdd_ipa_uc_ol_init(hdd_ctx)) {
9784 hdd_err("Failed to setup pipes");
9785 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08009786 }
9787
Arun Khandavallifae92942016-08-01 13:31:08 +05309788 /*
9789 * Start CDS which starts up the SME/MAC/HAL modules and everything
9790 * else
9791 */
Jeff Johnson8f9dd5f2017-09-13 14:16:08 -07009792 status = cds_enable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05309793
9794 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009795 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +05309796 goto out;
9797 }
9798
9799 status = hdd_post_cds_enable_config(hdd_ctx);
9800 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009801 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009802 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05309803 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309804 status = hdd_register_bcn_cb(hdd_ctx);
9805 if (!QDF_IS_STATUS_SUCCESS(status)) {
9806 hdd_alert("hdd_post_cds_enable_config failed");
9807 goto cds_disable;
9808 }
Arun Khandavallifae92942016-08-01 13:31:08 +05309809
9810 ret = hdd_features_init(hdd_ctx, adapter);
9811 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009812 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05309813
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -07009814 dp_cbs.hdd_disable_lro_in_concurrency = hdd_disable_lro_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -07009815 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -07009816 status = policy_mgr_register_dp_cb(hdd_ctx->hdd_psoc, &dp_cbs);
9817 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -07009818 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -07009819 goto cds_disable;
9820 }
9821
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +05309822 if (hdd_enable_egap(hdd_ctx))
9823 hdd_debug("enhance green ap is not enabled");
9824
Nachiket Kukadedd302662017-07-13 17:31:44 +05309825 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
9826 hdd_debug("Failed to set wow pulse");
9827
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +05309828 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
9829 hdd_ctx->config->auto_pwr_save_fail_mode, PDEV_CMD);
9830
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +05309831
9832 if (hdd_ctx->config->enable_phy_reg_retention)
9833 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
9834 hdd_ctx->config->enable_phy_reg_retention, PDEV_CMD);
9835
Arun Khandavallifae92942016-08-01 13:31:08 +05309836 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009837
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009838cds_disable:
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -07009839 cds_disable(hdd_ctx->hdd_psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009840
Arun Khandavallifae92942016-08-01 13:31:08 +05309841out:
9842 return -EINVAL;
9843}
9844
9845/**
9846 * hdd_deconfigure_cds() -De-Configure cds
9847 * @hdd_ctx: HDD context
9848 *
9849 * Deconfigure Cds modules before WLAN firmware is down.
9850 *
9851 * Return: 0 on success and errno on failure.
9852 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009853static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +05309854{
9855 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -07009856 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05309857
9858 ENTER();
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009859
9860 /* De-init features */
9861 hdd_features_deinit(hdd_ctx);
9862
Arun Khandavallifae92942016-08-01 13:31:08 +05309863 /* De-register the SME callbacks */
9864 hdd_deregister_cb(hdd_ctx);
9865
Jeff Johnsonea5c2aa12017-09-13 14:18:59 -07009866 qdf_status = cds_disable(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05309867 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
9868 hdd_err("Failed to Disable the CDS Modules! :%d",
9869 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -07009870 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309871 }
9872
Sravan Kumar Kairam71121712017-04-15 00:34:42 +05309873 if (hdd_ipa_uc_ol_deinit(hdd_ctx)) {
9874 hdd_err("Failed to disconnect pipes");
9875 ret = -EINVAL;
9876 }
9877
Arun Khandavallifae92942016-08-01 13:31:08 +05309878 EXIT();
Houston Hoffman6640cf32016-10-10 16:44:29 -07009879 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05309880}
9881
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07009882#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
9883static void hdd_deregister_policy_manager_callback(
9884 struct wlan_objmgr_psoc *psoc)
9885{
9886 if (QDF_STATUS_SUCCESS !=
9887 policy_mgr_deregister_hdd_cb(psoc)) {
9888 hdd_err("HDD callback deregister with policy manager failed");
9889 }
9890}
9891#else
9892static void hdd_deregister_policy_manager_callback(
9893 struct wlan_objmgr_psoc *psoc)
9894{
9895}
9896#endif
Arun Khandavallifae92942016-08-01 13:31:08 +05309897
9898/**
9899 * hdd_wlan_stop_modules - Single driver state machine for stoping modules
9900 * @hdd_ctx: HDD context
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009901 * @ftm_mode: ftm mode
Arun Khandavallifae92942016-08-01 13:31:08 +05309902 *
9903 * This function maintains the driver state machine it will be invoked from
9904 * exit, shutdown and con_mode change handler. Depending on the driver state
9905 * shall perform the stopping/closing of the modules.
9906 *
9907 * Return: 0 for success; non-zero for failure
9908 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009909int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +05309910{
9911 void *hif_ctx;
9912 qdf_device_t qdf_ctx;
9913 QDF_STATUS qdf_status;
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309914 int ret = 0;
Dustin Brown4bc0a622017-12-06 15:56:50 -08009915 bool is_recovery_stop = cds_is_driver_recovering();
9916 bool is_idle_stop = !cds_is_driver_unloading() && !is_recovery_stop;
Dustin Brown70111822017-03-30 15:31:40 -07009917 int active_threads;
Arun Khandavallifae92942016-08-01 13:31:08 +05309918
9919 ENTER();
Yun Parkfec73dc2017-09-06 10:40:07 -07009920 hdd_alert("stop WLAN module: entering driver status=%d",
9921 hdd_ctx->driver_status);
Arun Khandavallifae92942016-08-01 13:31:08 +05309922
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07009923 hdd_deregister_policy_manager_callback(hdd_ctx->hdd_psoc);
9924
Arun Khandavallifae92942016-08-01 13:31:08 +05309925 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
9926 if (!qdf_ctx) {
9927 hdd_err("QDF device context NULL");
9928 return -EINVAL;
9929 }
9930
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309931 mutex_lock(&hdd_ctx->iface_change_lock);
9932 hdd_ctx->stop_modules_in_progress = true;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -07009933 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +05309934
Dustin Brown70111822017-03-30 15:31:40 -07009935 active_threads = cds_return_external_threads_count();
Jeff Johnson214671b2017-10-30 19:45:23 -07009936 if (active_threads > 0 || hdd_ctx->is_wiphy_suspended) {
Rajeev Kumar86177c22017-03-16 19:44:39 -07009937 hdd_warn("External threads %d wiphy suspend %d",
Jeff Johnson214671b2017-10-30 19:45:23 -07009938 active_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -07009939
9940 cds_print_external_threads();
9941
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009942 if (is_idle_stop && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -07009943 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown6f427922017-09-19 12:19:00 -07009944 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
9945 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +05309946 hdd_prevent_suspend_timeout(
9947 hdd_ctx->config->iface_change_wait_time,
9948 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009949 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -07009950 cds_set_module_stop_in_progress(false);
Dustin Brown70111822017-03-30 15:31:40 -07009951 return 0;
9952 }
Rajeev Kumar86177c22017-03-16 19:44:39 -07009953 }
9954
Arun Khandavallifae92942016-08-01 13:31:08 +05309955 hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
9956
Kabilan Kannan6edafeb2017-11-16 16:34:34 -08009957 /* free user wowl patterns */
9958 hdd_free_user_wowl_ptrns();
9959
Arun Khandavallifae92942016-08-01 13:31:08 +05309960 switch (hdd_ctx->driver_status) {
9961 case DRIVER_MODULES_UNINITIALIZED:
9962 hdd_info("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309963 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309964 case DRIVER_MODULES_CLOSED:
9965 hdd_info("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309966 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309967 case DRIVER_MODULES_ENABLED:
Dustin Brown550f6d22017-12-14 15:44:01 -08009968 hdd_info("Wlan transitioning (OPENED <- ENABLED)");
9969
Komal Seelamf2136bb2016-09-28 18:30:44 +05309970 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +05309971 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009972 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +05309973 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309974 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309975 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009976 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -08009977
Arun Khandavallifae92942016-08-01 13:31:08 +05309978 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Dustin Brown550f6d22017-12-14 15:44:01 -08009979 hdd_info("Wlan transitioned (now OPENED)");
9980
9981 /* fall through */
Arun Khandavallifae92942016-08-01 13:31:08 +05309982 case DRIVER_MODULES_OPENED:
Dustin Brown550f6d22017-12-14 15:44:01 -08009983 hdd_info("Wlan transitioning (CLOSED <- OPENED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05309984 break;
9985 default:
9986 hdd_err("Trying to stop wlan in a wrong state: %d",
9987 hdd_ctx->driver_status);
9988 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309989 ret = -EINVAL;
9990 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309991 }
9992
Dustin Brown550f6d22017-12-14 15:44:01 -08009993 hdd_debug("Closing CDS modules!");
Rajeev Kumarbe021242017-02-16 16:12:23 -08009994 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +05309995 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
9996 hdd_err("Failed to process post CDS disable Modules! :%d",
9997 qdf_status);
9998 ret = -EINVAL;
9999 QDF_ASSERT(0);
10000 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010001
psimhadeea0a12017-12-18 14:50:02 -080010002 hdd_runtime_suspend_context_deinit(hdd_ctx);
10003
Dustin Brownbd68fe12017-11-21 15:28:52 -080010004 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
10005 if (ret) {
10006 hdd_err("Failed to destroy pdev; errno:%d", ret);
10007 QDF_ASSERT(0);
10008 }
10009
10010 /*
10011 * Reset total mac phy during module stop such that during
10012 * next module start same psoc is used to populate new service
10013 * ready data
10014 */
10015 hdd_ctx->hdd_psoc->total_mac_phy = 0;
10016
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070010017 qdf_status = cds_dp_close(hdd_ctx->hdd_psoc);
10018 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10019 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
10020 ret = -EINVAL;
10021 QDF_ASSERT(0);
10022 }
10023
Jeff Johnsone4b14592017-09-13 14:23:33 -070010024 qdf_status = cds_close(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053010025 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010026 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +053010027 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010028 QDF_ASSERT(0);
10029 }
Krunal Sonid32c6bc2016-10-18 18:00:21 -070010030
Arun Khandavallifae92942016-08-01 13:31:08 +053010031 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
10032 if (!hif_ctx) {
10033 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010034 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010035 }
10036
Arunk Khandavalli4b404332017-09-26 12:46:00 +053010037 if (hdd_ctx->target_hw_name) {
10038 qdf_mem_free(hdd_ctx->target_hw_name);
10039 hdd_ctx->target_hw_name = NULL;
10040 }
10041
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053010042 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053010043
10044 ol_cds_free();
10045
Dustin Brown70111822017-03-30 15:31:40 -070010046 if (is_idle_stop) {
Arun Khandavallifae92942016-08-01 13:31:08 +053010047 ret = pld_power_off(qdf_ctx->dev);
10048 if (ret)
10049 hdd_err("CNSS power down failed put device into Low power mode:%d",
10050 ret);
10051 }
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010052
Dustin Brown4bc0a622017-12-06 15:56:50 -080010053 /* many adapter resources are not freed by design in SSR case */
10054 if (!is_recovery_stop)
10055 hdd_check_for_leaks();
10056 qdf_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
10057
Arunk Khandavalli847969d2017-09-25 15:15:36 +053010058 /* Once the firmware sequence is completed reset this flag */
10059 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053010060 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080010061 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053010062
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010063done:
10064 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070010065 cds_set_module_stop_in_progress(false);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010066 mutex_unlock(&hdd_ctx->iface_change_lock);
Yun Parkfec73dc2017-09-06 10:40:07 -070010067 hdd_alert("stop WLAN module: exit driver status=%d",
10068 hdd_ctx->driver_status);
Dustin Brown4bc0a622017-12-06 15:56:50 -080010069
Arun Khandavallifae92942016-08-01 13:31:08 +053010070 EXIT();
10071
Arun Khandavallia172c3e2016-08-26 17:33:13 +053010072 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053010073}
10074
Arun Khandavallifae92942016-08-01 13:31:08 +053010075
10076/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010077 * hdd_state_info_dump() - prints state information of hdd layer
10078 * @buf: buffer pointer
10079 * @size: size of buffer to be filled
10080 *
10081 * This function is used to dump state information of hdd layer
10082 *
10083 * Return: None
10084 */
10085static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
10086{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010087 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070010088 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070010089 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010090 uint16_t len = 0;
10091 char *buf = *buf_ptr;
10092
10093 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10094 if (!hdd_ctx) {
10095 hdd_err("Failed to get hdd context ");
10096 return;
10097 }
10098
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010099 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010100
10101 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070010102 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010103 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080010104 "\n is_scheduler_suspended %d",
10105 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010106
Dustin Brown920397d2017-12-13 16:27:50 -080010107 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010108 if (adapter->dev)
10109 len += scnprintf(buf + len, *size - len,
10110 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080010111 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010112 "\n device_mode: %d", adapter->device_mode);
10113 switch (adapter->device_mode) {
10114 case QDF_STA_MODE:
10115 case QDF_P2P_CLIENT_MODE:
10116 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
10117 len += scnprintf(buf + len, *size - len,
10118 "\n connState: %d",
10119 hdd_sta_ctx->conn_info.connState);
10120 break;
10121
10122 default:
10123 break;
10124 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010125 }
10126
10127 *size -= len;
10128 *buf_ptr += len;
10129}
10130
10131/**
10132 * hdd_register_debug_callback() - registration function for hdd layer
10133 * to print hdd state information
10134 *
10135 * Return: None
10136 */
10137static void hdd_register_debug_callback(void)
10138{
10139 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
10140}
10141
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053010142/*
10143 * wlan_init_bug_report_lock() - Initialize bug report lock
10144 *
10145 * This function is used to create bug report lock
10146 *
10147 * Return: None
10148 */
10149static void wlan_init_bug_report_lock(void)
10150{
10151 p_cds_contextType p_cds_context;
10152
10153 p_cds_context = cds_get_global_context();
10154 if (!p_cds_context) {
10155 hdd_err("cds context is NULL");
10156 return;
10157 }
10158
10159 qdf_spinlock_create(&p_cds_context->bug_report_lock);
10160}
10161
Mohit Khannaf8f96822017-05-17 17:11:59 -070010162void hdd_dp_trace_init(struct hdd_config *config)
10163{
10164
10165 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
10166 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
10167 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
10168 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
10169 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
10170 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
10171 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080010172 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070010173
10174 hdd_string_to_u8_array(config->dp_trace_config, config_params,
10175 &num_entries, sizeof(config_params));
10176
10177 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080010178 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010179 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080010180 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080010181 else if (bw_compute_interval > 1000) {
10182 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
10183 thresh_time_limit = 1;
10184 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070010185 hdd_err("busBandwidthComputeInterval is 0, using defaults");
10186
10187 switch (num_entries) {
10188 case 4:
10189 proto_bitmap = config_params[3];
10190 case 3:
10191 verbosity = config_params[2];
10192 case 2:
10193 thresh = config_params[1];
10194 case 1:
10195 live_mode = config_params[0];
10196 default:
10197 hdd_info("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
10198 live_mode, thresh, thresh_time_limit,
10199 verbosity, proto_bitmap);
10200 };
10201
10202 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
10203 verbosity, proto_bitmap);
10204
10205}
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010206/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010207 * hdd_wlan_startup() - HDD init function
10208 * @dev: Pointer to the underlying device
10209 *
10210 * This is the driver startup code executed once a WLAN device has been detected
10211 *
10212 * Return: 0 for success, < 0 for failure
10213 */
Arun Khandavallifae92942016-08-01 13:31:08 +053010214int hdd_wlan_startup(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010215{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010216 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010217 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010218 int ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010219 bool rtnl_held;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010220
10221 ENTER();
10222
Arun Khandavallifae92942016-08-01 13:31:08 +053010223 hdd_ctx = hdd_context_create(dev);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010224
10225 if (IS_ERR(hdd_ctx))
10226 return PTR_ERR(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010227
Abhishek Singhe9068f12017-03-31 14:14:52 +053010228 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx,
10229 DEFAULT_PSOC_ID);
10230 if (ret) {
10231 hdd_err("Psoc creation fails!");
10232 QDF_BUG(0);
10233 goto err_hdd_free_context;
10234 }
10235
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010236 qdf_nbuf_init_replenish_timer();
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053010237#ifdef FEATURE_WLAN_CH_AVOID
10238 mutex_init(&hdd_ctx->avoid_freq_lock);
10239#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053010240
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010241 hdd_request_manager_init();
Jeff Johnsona7e5eed2016-09-28 15:19:13 -070010242 hdd_green_ap_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053010243
Dustin Brown021cecd2017-12-11 13:56:43 -080010244 memdump_init();
10245 hdd_driver_memdump_init();
10246
Jeff Johnson957bc272017-02-02 08:54:48 -080010247 ret = hdd_wlan_start_modules(hdd_ctx, NULL, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010248 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010249 hdd_err("Failed to start modules: %d", ret);
Dustin Brown021cecd2017-12-11 13:56:43 -080010250 goto err_memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010251 }
10252
Yingying Tang80e15f32016-09-27 18:23:01 +080010253 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010254
Anurag Chouhan6d760662016-02-20 16:05:43 +053010255 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010256
10257 if (NULL == hdd_ctx->hHal) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010258 hdd_err("HAL context is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053010259 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010260 }
10261
Prashanth Bhatta07998752016-04-28 12:35:33 -070010262 ret = hdd_wiphy_init(hdd_ctx);
10263 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010264 hdd_err("Failed to initialize wiphy: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053010265 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010266 }
10267
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053010268 if (hdd_ctx->config->enable_dp_trace)
Mohit Khannaf8f96822017-05-17 17:11:59 -070010269 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053010270
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010271 if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010272 goto err_wiphy_unregister;
10273
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053010274 wlan_hdd_init_chan_info(hdd_ctx);
10275
Yuanyuan Liuc98370e2016-10-13 11:22:13 -070010276 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080010277
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010278 ret = hdd_register_notifiers(hdd_ctx);
10279 if (ret)
10280 goto err_ipa_cleanup;
10281
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010282 rtnl_held = hdd_hold_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010283
Jeff Johnson957bc272017-02-02 08:54:48 -080010284 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
10285 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010286 hdd_err("Failed to open interfaces: %d", ret);
Jeff Johnson46bde382017-02-01 15:31:16 -080010287 goto err_release_rtnl_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010288 }
10289
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010290 hdd_release_rtnl_lock();
10291 rtnl_held = false;
10292
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080010293 wlan_hdd_update_11n_mode(hdd_ctx->config);
10294
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010295#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +053010296 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +053010297 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010298 hdd_skip_acs_scan_timer_handler,
10299 (void *)hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010300 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -070010301 hdd_err("Failed to init ACS Skip timer");
Liangwei Dongaef84342016-10-21 05:28:00 -040010302 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010303#endif
10304
Prashanth Bhattaab004382016-10-11 16:08:11 -070010305 hdd_bus_bandwidth_init(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010306
Jeff Johnson9afc5012016-09-23 13:56:27 -070010307 hdd_lpass_notify_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010308
Nirav Shahbd36b062016-07-18 11:12:59 +053010309 if (hdd_ctx->rps)
10310 hdd_set_rps_cpu_mask(hdd_ctx);
Peng Xu8fdaa492016-06-22 10:20:47 -070010311
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +053010312 status = wlansap_global_init();
10313 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson957bc272017-02-02 08:54:48 -080010314 goto err_close_adapters;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070010315
Arun Khandavallifae92942016-08-01 13:31:08 +053010316 if (hdd_ctx->config->fIsImpsEnabled)
10317 hdd_set_idle_ps_config(hdd_ctx, true);
Kiran Kumar Lokereb0f19c32017-10-13 12:23:26 -070010318 else
10319 hdd_set_idle_ps_config(hdd_ctx, false);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010320
Mukul Sharma07bd8752017-10-10 16:58:14 +053010321 if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
Dustin Brown6f427922017-09-19 12:19:00 -070010322 qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
10323 hdd_ctx->config->iface_change_wait_time);
Mukul Sharma07bd8752017-10-10 16:58:14 +053010324 hdd_prevent_suspend_timeout(
10325 hdd_ctx->config->iface_change_wait_time,
10326 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
10327 }
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053010328
Sachin Ahujadddd2632017-03-07 19:07:24 +053010329 hdd_start_complete(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010330 goto success;
10331
Jeff Johnson957bc272017-02-02 08:54:48 -080010332err_close_adapters:
Jeff Johnson46bde382017-02-01 15:31:16 -080010333 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010334
Jeff Johnson46bde382017-02-01 15:31:16 -080010335err_release_rtnl_lock:
Arun Khandavallid4349a92016-07-25 11:10:43 +053010336 if (rtnl_held)
10337 hdd_release_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010338
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053010339 unregister_netdevice_notifier(&hdd_netdev_notifier);
10340
Arun Khandavalli08479ba2017-08-07 19:56:23 +053010341err_ipa_cleanup:
Anurag Chouhance6a4052016-09-14 18:20:42 +053010342 hdd_ipa_cleanup(hdd_ctx);
Yun Park6a46ad82016-01-04 16:48:19 -080010343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010344err_wiphy_unregister:
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010345 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010346
Arun Khandavallifae92942016-08-01 13:31:08 +053010347err_stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070010348 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053010349
Dustin Brown021cecd2017-12-11 13:56:43 -080010350err_memdump_deinit:
10351 hdd_driver_memdump_deinit();
10352 memdump_deinit();
10353
Houston Hoffman47a4a052016-11-14 23:22:44 -080010354 hdd_green_ap_deinit(hdd_ctx);
Jeff Johnsonce0032c2017-01-20 07:18:27 -080010355 hdd_request_manager_deinit();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070010356 hdd_exit_netlink_services(hdd_ctx);
10357
Dustin Brown20912462017-06-07 13:48:25 -070010358 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10359
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010360err_hdd_free_context:
Nachiket Kukade8003d252017-03-30 15:55:58 +053010361 if (cds_is_fw_down())
10362 hdd_err("Not setting the complete event as fw is down");
10363 else
10364 hdd_start_complete(ret);
10365
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053010366 qdf_nbuf_deinit_replenish_timer();
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010367 hdd_context_destroy(hdd_ctx);
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -070010368 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010369
10370success:
10371 EXIT();
10372 return 0;
10373}
10374
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010375/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010376 * hdd_wlan_update_target_info() - update target type info
10377 * @hdd_ctx: HDD context
10378 * @context: hif context
10379 *
10380 * Update target info received from firmware in hdd context
10381 * Return:None
10382 */
10383
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010384void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053010385{
10386 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
10387
10388 if (!tgt_info) {
10389 hdd_err("Target info is Null");
10390 return;
10391 }
10392
10393 hdd_ctx->target_type = tgt_info->target_type;
10394}
10395
10396/**
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010397 * hdd_get_nud_stats_cb() - callback api to update the stats
10398 * received from the firmware
10399 * @data: pointer to adapter.
10400 * @rsp: pointer to data received from FW.
10401 *
10402 * This is called when wlan driver received response event for
10403 * get arp stats to firmware.
10404 *
10405 * Return: None
10406 */
10407static void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp)
10408{
10409 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
10410 struct hdd_nud_stats_context *context;
10411 int status;
10412 struct hdd_adapter *adapter = NULL;
10413
10414 ENTER();
10415
10416 if (!rsp) {
10417 hdd_err("data is null");
10418 return;
10419 }
10420
10421 status = wlan_hdd_validate_context(hdd_ctx);
10422 if (0 != status)
10423 return;
10424
10425 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
10426 if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
10427 hdd_err("Invalid adapter or adapter has invalid magic");
10428 return;
10429 }
10430
10431 hdd_notice("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
10432 hdd_notice("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
10433 hdd_notice("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
10434 hdd_notice("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
10435 hdd_notice("rsp->out_of_order_arp_rsp_drop_cnt :%x",
10436 rsp->out_of_order_arp_rsp_drop_cnt);
10437 hdd_notice("rsp->dad_detected :%x", rsp->dad_detected);
10438 hdd_notice("rsp->connect_status :%x", rsp->connect_status);
10439 hdd_notice("rsp->ba_session_establishment_status :%x",
10440 rsp->ba_session_establishment_status);
10441
10442 adapter->hdd_stats.hdd_arp_stats.tx_fw_cnt = rsp->arp_req_enqueue;
10443 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
10444 adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt = rsp->arp_req_tx_success;
10445 adapter->dad |= rsp->dad_detected;
10446 adapter->con_status = rsp->connect_status;
10447
10448 spin_lock(&hdd_context_lock);
10449 context = &hdd_ctx->nud_stats_context;
10450 complete(&context->response_event);
10451 spin_unlock(&hdd_context_lock);
10452
10453 EXIT();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010454}
10455
10456/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010457 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010458 * @hdd_ctx: HDD context
10459 *
10460 * Register the HDD callbacks to CDS/SME.
10461 *
10462 * Return: 0 for success or Error code for failure
10463 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010464int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010465{
10466 QDF_STATUS status;
10467 int ret = 0;
10468
10469 ENTER();
10470
10471 sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);
10472
10473 sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
10474 hdd_send_oem_data_rsp_msg);
10475
10476 status = sme_fw_mem_dump_register_cb(hdd_ctx->hHal,
10477 wlan_hdd_cfg80211_fw_mem_dump_cb);
10478 if (!QDF_IS_STATUS_SUCCESS(status)) {
10479 hdd_err("Failed to register memdump callback");
10480 ret = -EINVAL;
10481 return ret;
10482 }
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053010483 sme_register_mgmt_frame_ind_callback(hdd_ctx->hHal,
10484 hdd_indicate_mgmt_frame);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010485 sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
10486 sme_nan_register_callback(hdd_ctx->hHal,
10487 wlan_hdd_cfg80211_nan_callback);
10488 sme_stats_ext_register_callback(hdd_ctx->hHal,
10489 wlan_hdd_cfg80211_stats_ext_callback);
10490
10491 sme_ext_scan_register_callback(hdd_ctx->hHal,
10492 wlan_hdd_cfg80211_extscan_callback);
lifeng66831662017-05-19 16:01:35 +080010493 sme_stats_ext2_register_callback(hdd_ctx->hHal,
10494 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010495
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010496 sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
10497 hdd_rssi_threshold_breached);
10498
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053010499 sme_set_nud_debug_stats_cb(hdd_ctx->hHal, hdd_get_nud_stats_cb);
10500
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010501 sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
10502 wlan_hdd_cfg80211_link_layer_stats_callback);
10503
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010504 sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb);
10505
Zhang Qianca38fb12016-12-23 11:10:48 +080010506 sme_set_link_layer_ext_cb(hdd_ctx->hHal,
10507 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
10508
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053010509 status = sme_set_lost_link_info_cb(hdd_ctx->hHal,
10510 hdd_lost_link_info_cb);
10511 /* print error and not block the startup process */
10512 if (!QDF_IS_STATUS_SUCCESS(status))
10513 hdd_err("set lost link info callback failed");
10514
Poddar, Siddarth34872782017-08-10 14:08:51 +053010515 ret = hdd_register_data_stall_detect_cb();
10516 if (ret) {
10517 hdd_err("Register data stall detect detect callback failed.");
10518 return ret;
10519 }
10520
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010521 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
10522
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080010523 sme_register_set_connection_info_cb(hdd_ctx->hHal,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010524 hdd_set_connection_in_progress,
10525 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053010526
10527 status = sme_congestion_register_callback(hdd_ctx->hHal,
10528 hdd_update_cca_info_cb);
10529 if (!QDF_IS_STATUS_SUCCESS(status))
10530 hdd_err("set congestion callback failed");
10531
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053010532 status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
10533 hdd_bt_activity_cb);
10534 if (!QDF_IS_STATUS_SUCCESS(status))
10535 hdd_err("set bt activity info callback failed");
10536
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010537 EXIT();
10538
10539 return ret;
10540}
10541
10542/**
10543 * hdd_deregister_cb() - De-Register HDD callbacks.
10544 * @hdd_ctx: HDD context
10545 *
10546 * De-Register the HDD callbacks to CDS/SME.
10547 *
10548 * Return: void
10549 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010550void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010551{
10552 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053010553 int ret;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010554
10555 ENTER();
10556
10557 status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
10558 if (!QDF_IS_STATUS_SUCCESS(status))
10559 hdd_err("De-register of dcc stats callback failed: %d",
10560 status);
10561
10562 sme_reset_link_layer_stats_ind_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010563 sme_reset_rssi_threshold_breached_cb(hdd_ctx->hHal);
10564
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010565 sme_stats_ext_register_callback(hdd_ctx->hHal,
10566 wlan_hdd_cfg80211_stats_ext_callback);
10567
10568 sme_nan_deregister_callback(hdd_ctx->hHal);
10569 status = sme_reset_tsfcb(hdd_ctx->hHal);
10570 if (!QDF_IS_STATUS_SUCCESS(status))
10571 hdd_err("Failed to de-register tsfcb the callback:%d",
10572 status);
10573 status = sme_fw_mem_dump_unregister_cb(hdd_ctx->hHal);
10574 if (!QDF_IS_STATUS_SUCCESS(status))
10575 hdd_err("Failed to de-register the fw mem dump callback: %d",
10576 status);
10577
Poddar, Siddarth34872782017-08-10 14:08:51 +053010578 ret = hdd_deregister_data_stall_detect_cb();
10579 if (ret)
10580 hdd_err("Failed to de-register data stall detect event callback");
10581
Arun Khandavalli4b55da72016-07-19 19:55:01 +053010582 sme_deregister_oem_data_rsp_callback(hdd_ctx->hHal);
10583 sme_deregister11d_scan_done_callback(hdd_ctx->hHal);
10584
10585 EXIT();
10586}
10587
10588/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010589 * hdd_softap_sta_deauth() - handle deauth req from HDD
10590 * @adapter: Pointer to the HDD
10591 * @enable: bool value
10592 *
10593 * This to take counter measure to handle deauth req from HDD
10594 *
10595 * Return: None
10596 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010597QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080010598 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010599{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010600 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010601
10602 ENTER();
10603
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010604 /* Ignore request to deauth bcmc station */
10605 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010606 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010607
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010608 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010609 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
10610 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010611
10612 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010613 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010614}
10615
10616/**
10617 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
10618 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053010619 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010620 *
10621 * This to take counter measure to handle deauth req from HDD
10622 *
10623 * Return: None
10624 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010625void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080010626 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010627{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010628 ENTER();
10629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010630 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053010631 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010632 return;
10633
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010634 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053010635 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010636}
10637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010638/**
10639 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
10640 * @hdd_ctx: HDD Context
10641 *
10642 * API to find if there is any STA or P2P-Client is connected
10643 *
10644 * Return: true if connected; false otherwise
10645 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010646QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010647{
10648 return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
10649}
10650
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010651/**
10652 * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
10653 * @adapter: HDD adapter pointer
10654 *
10655 * This function loop through each adapter and disable roaming on each STA
10656 * device mode except the input adapter.
10657 *
10658 * Note: On the input adapter roaming is not enabled yet hence no need to
10659 * disable.
10660 *
10661 * Return: None
10662 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010663void wlan_hdd_disable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010664{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010665 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070010666 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010667
10668 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010669 hdd_ctx->config->isRoamOffloadScanEnabled &&
10670 QDF_STA_MODE == adapter->device_mode &&
10671 policy_mgr_is_sta_active_connection_exists(
10672 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070010673 hdd_debug("Connect received on STA session Id(%d)",
10674 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010675 /*
10676 * Loop through adapter and disable roaming for each STA device
10677 * mode except the input adapter.
10678 */
Dustin Brown920397d2017-12-13 16:27:50 -080010679 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070010680 if (QDF_STA_MODE == adapterIdx->device_mode &&
10681 adapter->session_id != adapterIdx->session_id) {
10682 hdd_debug("Disable Roaming on session Id(%d)",
10683 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010684 sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
10685 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070010686 adapterIdx->session_id, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010687 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010688 }
10689 }
10690}
10691
10692/**
10693 * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
10694 * @adapter: HDD adapter pointer
10695 *
10696 * This function loop through each adapter and enable roaming on each STA
10697 * device mode except the input adapter.
10698 * Note: On the input adapter no need to enable roaming because link got
10699 * disconnected on this.
10700 *
10701 * Return: None
10702 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010703void wlan_hdd_enable_roaming(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010704{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010705 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070010706 struct hdd_adapter *adapterIdx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010707
10708 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010709 hdd_ctx->config->isRoamOffloadScanEnabled &&
10710 QDF_STA_MODE == adapter->device_mode &&
10711 policy_mgr_is_sta_active_connection_exists(
10712 hdd_ctx->hdd_psoc)) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070010713 hdd_debug("Disconnect received on STA session Id(%d)",
10714 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010715 /*
10716 * Loop through adapter and enable roaming for each STA device
10717 * mode except the input adapter.
10718 */
Dustin Brown920397d2017-12-13 16:27:50 -080010719 hdd_for_each_adapter(hdd_ctx, adapterIdx) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070010720 if (QDF_STA_MODE == adapterIdx->device_mode &&
10721 adapter->session_id != adapterIdx->session_id) {
10722 hdd_debug("Enabling Roaming on session Id(%d)",
10723 adapterIdx->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010724 sme_start_roaming(WLAN_HDD_GET_HAL_CTX
10725 (adapterIdx),
Jeff Johnson1b780e42017-10-31 14:11:45 -070010726 adapterIdx->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010727 REASON_CONNECT);
10728 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010729 }
10730 }
10731}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010732
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053010733/**
10734 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
10735 * @skb: sk buffer pointer
10736 *
10737 * Sends the bcast message to SVC multicast group with generic nl socket
10738 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
10739 *
10740 * Return: None
10741 */
10742static void nl_srv_bcast_svc(struct sk_buff *skb)
10743{
10744#ifdef CNSS_GENL
10745 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
10746#else
10747 nl_srv_bcast(skb);
10748#endif
10749}
10750
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010751void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010752{
10753 struct sk_buff *skb;
10754 struct nlmsghdr *nlh;
10755 tAniMsgHdr *ani_hdr;
10756 void *nl_data = NULL;
10757 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010758 struct radio_index_tlv *radio_info;
10759 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010760
10761 if (in_interrupt() || irqs_disabled() || in_atomic())
10762 flags = GFP_ATOMIC;
10763
10764 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
10765
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010766 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010767 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010768
10769 nlh = (struct nlmsghdr *)skb->data;
10770 nlh->nlmsg_pid = 0; /* from kernel */
10771 nlh->nlmsg_flags = 0;
10772 nlh->nlmsg_seq = 0;
10773 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10774
10775 ani_hdr = NLMSG_DATA(nlh);
10776 ani_hdr->type = type;
10777
10778 switch (type) {
10779 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053010780 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010781 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010782 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070010783 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010784 ani_hdr->length = 0;
10785 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010786 break;
10787 case WLAN_SVC_WLAN_STATUS_IND:
10788 case WLAN_SVC_WLAN_VERSION_IND:
10789 case WLAN_SVC_DFS_CAC_START_IND:
10790 case WLAN_SVC_DFS_CAC_END_IND:
10791 case WLAN_SVC_DFS_RADAR_DETECT_IND:
10792 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
10793 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080010794 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053010795 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080010796 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010797 ani_hdr->length = len;
10798 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10799 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10800 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010801 break;
10802
10803 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070010804 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010805 type);
10806 kfree_skb(skb);
10807 return;
10808 }
10809
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010810 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080010811 * Add radio index at the end of the svc event in TLV format
10812 * to maintain the backward compatibility with userspace
10813 * applications.
10814 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010815
10816 tlv_len = 0;
10817
10818 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
10819 < WLAN_NL_MAX_PAYLOAD) {
10820 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
10821 sizeof(*ani_hdr) + len);
10822 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
10823 radio_info->length = (unsigned short) sizeof(radio_info->radio);
10824 radio_info->radio = radio;
10825 tlv_len = sizeof(*radio_info);
Srinivas Girigowdac06543c2017-03-09 15:10:03 -080010826 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010827 "Added radio index tlv - radio index %d",
10828 radio_info->radio);
10829 }
10830
10831 nlh->nlmsg_len += tlv_len;
10832 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
10833
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053010834 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010835}
10836
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010837#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10838void wlan_hdd_auto_shutdown_cb(void)
10839{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010840 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010841
10842 if (!hdd_ctx)
10843 return;
10844
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010845 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010846 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
10847 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010848}
10849
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010850void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010851{
Jeff Johnson9d295242017-08-29 14:39:48 -070010852 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010853 bool ap_connected = false, sta_connected = false;
10854 tHalHandle hal_handle;
10855
10856 hal_handle = hdd_ctx->hHal;
10857 if (hal_handle == NULL)
10858 return;
10859
10860 if (hdd_ctx->config->WlanAutoShutdown == 0)
10861 return;
10862
10863 if (enable == false) {
10864 if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010865 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010866 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010867 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010868 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070010869 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010870 return;
10871 }
10872
10873 /* To enable shutdown timer check conncurrency */
Dustin Brown920397d2017-12-13 16:27:50 -080010874 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->hdd_psoc)) {
10875 hdd_for_each_adapter(hdd_ctx, adapter) {
10876 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010877 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
10878 conn_info.connState ==
10879 eConnectionState_Associated) {
10880 sta_connected = true;
10881 break;
10882 }
10883 }
Dustin Brown920397d2017-12-13 16:27:50 -080010884
10885 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010886 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070010887 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010888 ap_connected = true;
10889 break;
10890 }
10891 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010892 }
10893 }
10894
10895 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010896 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010897 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010898 }
Jeff Johnson68755312017-02-10 11:46:55 -080010899
10900 if (sme_set_auto_shutdown_timer(hal_handle,
10901 hdd_ctx->config->WlanAutoShutdown)
10902 != QDF_STATUS_SUCCESS)
10903 hdd_err("Failed to start wlan auto shutdown timer");
10904 else
10905 hdd_notice("Auto Shutdown timer for %d seconds enabled",
10906 hdd_ctx->config->WlanAutoShutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010907}
10908#endif
10909
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010910struct hdd_adapter *
10911hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
10912 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010913{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010914 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070010915 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010916
10917 con_sap_adapter = NULL;
10918
Dustin Brown920397d2017-12-13 16:27:50 -080010919 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010920 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
10921 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010922 adapter != this_sap_adapter) {
10923 if (check_start_bss) {
10924 if (test_bit(SOFTAP_BSS_STARTED,
10925 &adapter->event_flags)) {
10926 con_sap_adapter = adapter;
10927 break;
10928 }
10929 } else {
10930 con_sap_adapter = adapter;
10931 break;
10932 }
10933 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010934 }
10935
10936 return con_sap_adapter;
10937}
10938
10939#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070010940static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010941{
Dustin Brown5ec6b552017-03-31 12:11:40 -070010942 return adapter->device_mode == QDF_STA_MODE ||
10943 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010944}
10945
Jeff Johnson9d295242017-08-29 14:39:48 -070010946static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010947{
Dustin Brown5ec6b552017-03-31 12:11:40 -070010948 return adapter->device_mode == QDF_SAP_MODE ||
10949 adapter->device_mode == QDF_P2P_GO_MODE;
10950}
10951
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010952static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070010953{
Dustin Brown920397d2017-12-13 16:27:50 -080010954 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070010955
Dustin Brown920397d2017-12-13 16:27:50 -080010956 hdd_for_each_adapter(hdd_ctx, adapter) {
10957 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070010958 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
10959 conn_info.connState == eConnectionState_Associated) {
10960 return true;
10961 }
10962
Dustin Brown920397d2017-12-13 16:27:50 -080010963 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070010964 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070010965 return true;
10966 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070010967 }
10968
10969 return false;
10970}
10971
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010972static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070010973{
10974 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010975
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053010976 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070010977 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053010978 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010979
Dustin Brown5ec6b552017-03-31 12:11:40 -070010980 return is_running;
10981}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010982
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010983static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070010984{
10985 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
10986 hdd_ctx->bus_bw_timer_running = true;
10987 qdf_timer_start(&hdd_ctx->bus_bw_timer,
10988 hdd_ctx->config->busBandwidthComputeInterval);
10989 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
10990}
10991
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010992void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070010993{
10994 ENTER();
10995
10996 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
10997 hdd_debug("Bandwidth compute timer already started");
10998 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010999 }
11000
Dustin Brown5ec6b552017-03-31 12:11:40 -070011001 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11002
11003 EXIT();
11004}
11005
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011006void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011007{
11008 ENTER();
11009
11010 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11011 hdd_debug("Bandwidth compute timer already started");
11012 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070011013 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070011014
11015 if (hdd_any_adapter_is_assoc(hdd_ctx))
11016 __hdd_bus_bw_compute_timer_start(hdd_ctx);
11017
11018 EXIT();
11019}
11020
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011021static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011022{
11023 hdd_ipa_set_perf_level(hdd_ctx, 0, 0);
11024
11025 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
11026 qdf_timer_stop(&hdd_ctx->bus_bw_timer);
11027 hdd_ctx->bus_bw_timer_running = false;
11028 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
11029
11030 hdd_reset_tcp_delack(hdd_ctx);
11031}
11032
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011033void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011034{
11035 ENTER();
11036
11037 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11038 hdd_debug("Bandwidth compute timer already stopped");
11039 return;
11040 }
11041
11042 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11043
11044 EXIT();
11045}
11046
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011047void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070011048{
11049 ENTER();
11050
11051 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
11052 hdd_debug("Bandwidth compute timer already stopped");
11053 return;
11054 }
11055
11056 if (!hdd_any_adapter_is_assoc(hdd_ctx))
11057 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
11058
11059 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011060}
11061#endif
11062
11063/**
11064 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
11065 * and sta's operating channel.
11066 * @sta_adapter: Describe the first argument to foobar.
11067 * @ap_adapter: Describe the second argument to foobar.
11068 * @roam_profile: Roam profile of AP to which STA wants to connect.
11069 * @concurrent_chnl_same: If both SAP and STA channels are same then
11070 * set this flag to true else false.
11071 *
11072 * This function checks the sap's operating channel and sta's operating channel.
11073 * if both are same then it will return false else it will restart the sap in
11074 * sta's channel and return true.
11075 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011076 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011077 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070011078QDF_STATUS
11079wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
11080 struct hdd_adapter *ap_adapter,
11081 tCsrRoamProfile *roam_profile,
11082 tScanResultHandle *scan_cache,
11083 bool *concurrent_chnl_same)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011084{
Jeff Johnson87251032017-08-29 13:31:11 -070011085 struct hdd_ap_ctx *hdd_ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011086 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011087 QDF_STATUS status;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080011088 enum QDF_OPMODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011089 *concurrent_chnl_same = true;
11090
11091 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11092 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070011093 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011094 scan_cache,
11095 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011096 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011097 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011098 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011099 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011100 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011101 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011102 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011103 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011104 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070011105 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011106 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011107 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011108 }
11109 }
11110 } else {
11111 /*
11112 * Lets handle worst case scenario here, Scan cache lookup is
11113 * failed so we have to stop the SAP to avoid any channel
11114 * discrepancy between SAP's channel and STA's channel.
11115 * Return the status as failure so caller function could know
11116 * that scan look up is failed.
11117 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070011118 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011119 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011120 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011121 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011122}
11123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011124/**
11125 * wlan_hdd_stop_sap() - This function stops bss of SAP.
11126 * @ap_adapter: SAP adapter
11127 *
11128 * This function will process the stopping of sap adapter.
11129 *
11130 * Return: None
11131 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011132void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011133{
Jeff Johnson87251032017-08-29 13:31:11 -070011134 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011135 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011136 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011137 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011138
11139 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011140 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011141 return;
11142 }
11143
11144 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11145 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011146 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011147 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053011148
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011149 mutex_lock(&hdd_ctx->sap_lock);
11150 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080011151 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011152 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011153 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011154 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011155 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011156 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053011157 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080011158 qdf_stop_bss_event,
11159 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011160 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011161 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070011162 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011163 return;
11164 }
11165 }
11166 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011167 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
11168 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011169 ap_adapter->session_id);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011170 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011171 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011172 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011173 }
11174 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011175}
11176
11177/**
11178 * wlan_hdd_start_sap() - this function starts bss of SAP.
11179 * @ap_adapter: SAP adapter
11180 *
11181 * This function will process the starting of sap adapter.
11182 *
11183 * Return: None
11184 */
Jeff Johnson9d295242017-08-29 14:39:48 -070011185void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011186{
Jeff Johnson87251032017-08-29 13:31:11 -070011187 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070011188 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053011189 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011190 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011191 tsap_Config_t *sap_config;
11192
11193 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011194 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011195 return;
11196 }
11197
Krunal Soni9b04c9b2016-03-10 13:08:05 -080011198 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070011199 hdd_err("SoftAp role has not been enabled");
11200 return;
11201 }
11202
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011203 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
11204 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11205 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070011206 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011207
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011208 mutex_lock(&hdd_ctx->sap_lock);
11209 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
11210 goto end;
11211
11212 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011213 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011214 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
11215 goto end;
11216 }
11217
Wei Song2f76f642016-11-18 16:32:53 +080011218 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070011219 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070011220 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011221 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011222 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011223 goto end;
11224
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011225 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053011226 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -080011227 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011228 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070011229 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011230 goto end;
11231 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070011232 hdd_info("SAP Start Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011233 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Jeff Johnson0f9f87b2017-10-28 09:21:06 -070011234 if (hostapd_state->bss_state == BSS_START)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011235 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
11236 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070011237 ap_adapter->session_id);
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053011238 mutex_unlock(&hdd_ctx->sap_lock);
11239
11240 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011241end:
11242 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070011243 /* SAP context and beacon cleanup will happen during driver unload
11244 * in hdd_stop_adapter
11245 */
11246 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
11247
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011248}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011249
11250/**
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011251 * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual
11252 * mac scan config
11253 * @status: Status of set antenna mode
11254 *
11255 * Callback on setting the dual mac configuration
11256 *
11257 * Return: None
11258 */
11259void wlan_hdd_soc_set_antenna_mode_cb(
11260 enum set_antenna_mode_status status)
11261{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011262 struct hdd_context *hdd_ctx;
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011263
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011264 hdd_debug("Status: %d", status);
Archana Ramachandrana20ef812015-11-13 16:12:13 -080011265
11266 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11267 if (0 != wlan_hdd_validate_context(hdd_ctx))
11268 return;
11269
11270 /* Signal the completion of set dual mac config */
11271 complete(&hdd_ctx->set_antenna_mode_cmpl);
11272}
11273
11274/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011275 * hdd_get_fw_version() - Get FW version
11276 * @hdd_ctx: pointer to HDD context.
11277 * @major_spid: FW version - major spid.
11278 * @minor_spid: FW version - minor spid
11279 * @ssid: FW version - ssid
11280 * @crmid: FW version - crmid
11281 *
11282 * This function is called to get the firmware build version stored
11283 * as part of the HDD context
11284 *
11285 * Return: None
11286 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011287void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011288 uint32_t *major_spid, uint32_t *minor_spid,
11289 uint32_t *siid, uint32_t *crmid)
11290{
11291 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
11292 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
11293 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
11294 *crmid = hdd_ctx->target_fw_version & 0x7fff;
11295}
11296
11297#ifdef QCA_CONFIG_SMP
11298/**
11299 * wlan_hdd_get_cpu() - get cpu_index
11300 *
11301 * Return: cpu_index
11302 */
11303int wlan_hdd_get_cpu(void)
11304{
11305 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011307 put_cpu();
11308 return cpu_index;
11309}
11310#endif
11311
11312/**
11313 * hdd_get_fwpath() - get framework path
11314 *
11315 * This function is used to get the string written by
11316 * userspace to start the wlan driver
11317 *
11318 * Return: string
11319 */
11320const char *hdd_get_fwpath(void)
11321{
11322 return fwpath.string;
11323}
11324
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011325static int hdd_qdf_print_init(void)
11326{
11327 int qdf_print_idx;
11328 QDF_STATUS status;
11329
11330 status = qdf_print_setup();
11331 if (status != QDF_STATUS_SUCCESS) {
11332 pr_err("qdf_print_setup failed\n");
11333 return -EINVAL;
11334 }
11335
11336 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
11337
11338 if (qdf_print_idx < 0) {
11339 pr_err("qdf_print_ctrl_register failed, ret = %d\n",
11340 qdf_print_idx);
11341 return -EINVAL;
11342 }
11343
11344 qdf_set_pidx(qdf_print_idx);
11345
11346 return 0;
11347}
11348
11349static void hdd_qdf_print_deinit(void)
11350{
11351 int qdf_print_idx;
11352
11353 qdf_print_idx = qdf_get_pidx();
11354 qdf_print_ctrl_cleanup(qdf_print_idx);
11355}
11356
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011357/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011358 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011359 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011360 * This function initilizes CDS global context with the help of cds_init. This
11361 * has to be the first function called after probe to get a valid global
11362 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011363 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011364 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011365 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011366int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011367{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011368 QDF_STATUS status;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011369 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011370
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070011371 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080011372 if (QDF_IS_STATUS_ERROR(status)) {
11373 hdd_err("Failed to allocate CDS context");
11374 ret = -ENOMEM;
11375 goto err_out;
11376 }
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053011377
11378 wlan_init_bug_report_lock();
11379
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011380#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11381 wlan_logging_sock_init_svc();
11382#endif
11383
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011384 qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
11385 (void *)hdd_drv_ops_inactivity_handler, NULL,
11386 QDF_TIMER_TYPE_SW);
11387
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011388 hdd_trace_init();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011389 hdd_qdf_print_init();
11390
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011391 hdd_register_debug_callback();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011392
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011393err_out:
11394 return ret;
11395}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011396
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011397/**
11398 * hdd_deinit() - Deinitialize Driver
11399 *
11400 * This function frees CDS global context with the help of cds_deinit. This
11401 * has to be the last function call in remove callback to free the global
11402 * context.
11403 */
11404void hdd_deinit(void)
11405{
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053011406 qdf_timer_free(&hdd_drv_ops_inactivity_timer);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011407
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070011408 wlan_destroy_bug_report_lock();
11409 cds_deinit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070011410
Rajeev Kumar2d0f2192017-10-18 19:48:21 -070011411 hdd_qdf_print_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011412#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11413 wlan_logging_sock_deinit_svc();
11414#endif
11415}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011416
Yue Ma6e7b1a02017-04-03 14:17:46 -070011417#ifdef QCA_WIFI_NAPIER_EMULATION
11418#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
11419#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011420#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070011421#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011422
Sachin Ahujadddd2632017-03-07 19:07:24 +053011423static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
11424 struct file *file)
11425{
11426 return 0;
11427}
11428
11429static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
11430 const char __user *user_buf,
11431 size_t count,
11432 loff_t *f_pos)
11433{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011434 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053011435 static const char wlan_off_str[] = "OFF";
11436 static const char wlan_on_str[] = "ON";
11437 int ret;
11438 unsigned long rc;
11439
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011440 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011441 pr_err("Failed to read buffer\n");
11442 return -EINVAL;
11443 }
11444
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011445 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011446 pr_debug("Wifi turning off from UI\n");
11447 goto exit;
11448 }
11449
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053011450 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053011451 pr_err("Invalid value received from framework");
11452 goto exit;
11453 }
11454
11455 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053011456 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053011457 rc = wait_for_completion_timeout(&wlan_start_comp,
11458 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
11459 if (!rc) {
11460 hdd_alert("Timed-out waiting in wlan_hdd_state_ctrl_param_write");
11461 ret = -EINVAL;
11462 hdd_start_complete(ret);
11463 return ret;
11464 }
11465
11466 hdd_start_complete(0);
11467 }
11468
11469exit:
11470 return count;
11471}
11472
11473
11474const struct file_operations wlan_hdd_state_fops = {
11475 .owner = THIS_MODULE,
11476 .open = wlan_hdd_state_ctrl_param_open,
11477 .write = wlan_hdd_state_ctrl_param_write,
11478};
11479
11480static int wlan_hdd_state_ctrl_param_create(void)
11481{
11482 unsigned int wlan_hdd_state_major = 0;
11483 int ret;
11484 struct device *dev;
11485
11486 device = MKDEV(wlan_hdd_state_major, 0);
11487
11488 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
11489 if (ret) {
11490 pr_err("Failed to register qcwlanstate");
11491 goto dev_alloc_err;
11492 }
11493 wlan_hdd_state_major = MAJOR(device);
11494
11495 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
11496 if (IS_ERR(class)) {
11497 pr_err("wlan_hdd_state class_create error");
11498 goto class_err;
11499 }
11500
11501 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
11502 if (IS_ERR(dev)) {
11503 pr_err("wlan_hdd_statedevice_create error");
11504 goto err_class_destroy;
11505 }
11506
11507 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
11508 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
11509 if (ret) {
11510 pr_err("Failed to add cdev error");
11511 goto cdev_add_err;
11512 }
11513
11514 pr_info("wlan_hdd_state %s major(%d) initialized",
11515 WLAN_MODULE_NAME, wlan_hdd_state_major);
11516
11517 return 0;
11518
11519cdev_add_err:
11520 device_destroy(class, device);
11521err_class_destroy:
11522 class_destroy(class);
11523class_err:
11524 unregister_chrdev_region(device, dev_num);
11525dev_alloc_err:
11526 return -ENODEV;
11527}
11528
11529static void wlan_hdd_state_ctrl_param_destroy(void)
11530{
11531 cdev_del(&wlan_hdd_state_cdev);
11532 device_destroy(class, device);
11533 class_destroy(class);
11534 unregister_chrdev_region(device, dev_num);
11535
11536 pr_info("Device node unregistered");
11537}
11538
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011539/**
Mukul Sharmad75a6672017-06-22 15:40:53 +053011540 * component_init - API to init cld component's
11541 *
11542 * Return: None
11543 */
11544static void component_init(void)
11545{
11546 pmo_init();
11547}
11548
11549/**
11550 * component_deinit - API to deinit cld component's
11551 *
11552 * Return: None
11553 */
11554static void component_deinit(void)
11555{
11556 pmo_deinit();
11557}
11558
11559/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011560 * __hdd_module_init - Module init helper
11561 *
11562 * Module init helper function used by both module and static driver.
11563 *
11564 * Return: 0 for success, errno on failure
11565 */
11566static int __hdd_module_init(void)
11567{
11568 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011569
Dustin Brown96cd9632017-11-13 12:45:04 -080011570 pr_err("%s: Loading driver v%s (%s)\n",
Dustin Brownab482ac2017-06-09 17:00:44 -070011571 WLAN_MODULE_NAME,
Dustin Brown96cd9632017-11-13 12:45:04 -080011572 g_wlan_driver_version,
Dustin Brownab482ac2017-06-09 17:00:44 -070011573 TIMER_MANAGER_STR MEMORY_DEBUG_STR);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011574
Sachin Ahujadddd2632017-03-07 19:07:24 +053011575 ret = wlan_hdd_state_ctrl_param_create();
11576 if (ret) {
11577 pr_err("wlan_hdd_state_create:%x\n", ret);
11578 goto err_dev_state;
11579 }
11580
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070011581 pld_init();
11582
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011583 ret = hdd_init();
11584 if (ret) {
11585 pr_err("hdd_init failed %x\n", ret);
11586 goto err_hdd_init;
11587 }
11588
Rajeev Kumar97767a02016-11-30 11:20:40 -080011589 dispatcher_init();
11590
Mukul Sharmad75a6672017-06-22 15:40:53 +053011591 /* Ensure to call post objmgr init */
11592 component_init();
11593
Anurag Chouhana37b5b72016-02-21 14:53:42 +053011594 qdf_wake_lock_create(&wlan_wake_lock, "wlan");
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011595
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011596 hdd_set_conparam((uint32_t) con_mode);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011597
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011598 ret = wlan_hdd_register_driver();
11599 if (ret) {
Mohit Khannafa99aea2016-05-12 21:43:13 -070011600 pr_err("%s: driver load failure, err %d\n", WLAN_MODULE_NAME,
11601 ret);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011602 goto out;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011603 }
11604
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011605 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011606
11607 return 0;
11608out:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053011609 qdf_wake_lock_destroy(&wlan_wake_lock);
Liangwei Dong9fcc7212017-10-24 13:43:52 +080011610 component_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080011611 dispatcher_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011612 hdd_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080011613
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011614err_hdd_init:
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070011615 pld_deinit();
Sachin Ahujadddd2632017-03-07 19:07:24 +053011616 wlan_hdd_state_ctrl_param_destroy();
11617err_dev_state:
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011618 return ret;
11619}
11620
11621/**
11622 * __hdd_module_exit - Module exit helper
11623 *
11624 * Module exit helper function used by both module and static driver.
11625 */
11626static void __hdd_module_exit(void)
11627{
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053011628
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011629 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
11630 QWLAN_VERSIONSTR);
11631
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053011632 hdd_wait_for_recovery_completion();
11633
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011634 wlan_hdd_unregister_driver();
11635
Anurag Chouhana37b5b72016-02-21 14:53:42 +053011636 qdf_wake_lock_destroy(&wlan_wake_lock);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011637
Mukul Sharmad75a6672017-06-22 15:40:53 +053011638 /* Ensure to call prior to objmgr deinit */
11639 component_deinit();
11640
Rajeev Kumar97767a02016-11-30 11:20:40 -080011641 dispatcher_deinit();
Amar Singhal0928b192017-12-01 10:50:54 -080011642
11643 hdd_sysfs_destroy_version_interface();
11644
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011645 hdd_deinit();
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070011646 pld_deinit();
11647
Sachin Ahujadddd2632017-03-07 19:07:24 +053011648 wlan_hdd_state_ctrl_param_destroy();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011649}
11650
Arun Khandavallifae92942016-08-01 13:31:08 +053011651#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011652/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011653 * wlan_boot_cb() - Wlan boot callback
11654 * @kobj: object whose directory we're creating the link in.
11655 * @attr: attribute the user is interacting with
11656 * @buff: the buffer containing the user data
11657 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011658 *
Arun Khandavallifae92942016-08-01 13:31:08 +053011659 * This callback is invoked when the fs is ready to start the
11660 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011661 *
Arun Khandavallifae92942016-08-01 13:31:08 +053011662 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011663 */
Arun Khandavallifae92942016-08-01 13:31:08 +053011664static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011665 struct kobj_attribute *attr,
11666 const char *buf,
11667 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011668{
Arun Khandavallifae92942016-08-01 13:31:08 +053011669
Arun Khandavallifae92942016-08-01 13:31:08 +053011670 if (wlan_loader->loaded_state) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011671 pr_err("%s: wlan driver already initialized\n", __func__);
11672 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053011673 }
11674
Arun Khandavallifae92942016-08-01 13:31:08 +053011675 if (__hdd_module_init()) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011676 pr_err("%s: wlan driver initialization failed\n", __func__);
11677 return -EIO;
11678 }
11679
11680 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053011681
11682 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011683}
Arun Khandavallifae92942016-08-01 13:31:08 +053011684
11685/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011686 * hdd_sysfs_cleanup() - cleanup sysfs
11687 *
11688 * Return: None
11689 *
11690 */
11691static void hdd_sysfs_cleanup(void)
11692{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011693 /* remove from group */
11694 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
11695 sysfs_remove_group(wlan_loader->boot_wlan_obj,
11696 wlan_loader->attr_group);
11697
11698 /* unlink the object from parent */
11699 kobject_del(wlan_loader->boot_wlan_obj);
11700
11701 /* free the object */
11702 kobject_put(wlan_loader->boot_wlan_obj);
11703
11704 kfree(wlan_loader->attr_group);
11705 kfree(wlan_loader);
11706
11707 wlan_loader = NULL;
11708}
11709
11710/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011711 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
11712 * ready
11713 *
11714 * This is creates the syfs entry boot_wlan. Which shall be invoked
11715 * when the filesystem is ready.
11716 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011717 * QDF API cannot be used here since this function is called even before
11718 * initializing WLAN driver.
11719 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070011720 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053011721 */
11722static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011723{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011724 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053011725
11726 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011727 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011728 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053011729
11730 wlan_loader->boot_wlan_obj = NULL;
11731 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
11732 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011733 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053011734 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053011735
11736 wlan_loader->loaded_state = 0;
11737 wlan_loader->attr_group->attrs = attrs;
11738
11739 wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
11740 kernel_kobj);
11741 if (!wlan_loader->boot_wlan_obj) {
11742 pr_err("%s: sysfs create and add failed\n", __func__);
Arun Khandavallifae92942016-08-01 13:31:08 +053011743 goto error_return;
11744 }
11745
11746 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
11747 wlan_loader->attr_group);
11748 if (ret) {
11749 pr_err("%s: sysfs create group failed %d\n", __func__, ret);
11750 goto error_return;
11751 }
11752
11753 return 0;
11754
11755error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011756 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053011757
11758 return ret;
11759}
11760
11761/**
11762 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
11763 *
11764 * Return: 0 on success or errno on failure
11765 */
11766static int wlan_deinit_sysfs(void)
11767{
Arun Khandavallifae92942016-08-01 13:31:08 +053011768 if (!wlan_loader) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011769 hdd_err("wlan loader context is Null!");
Arun Khandavallifae92942016-08-01 13:31:08 +053011770 return -EINVAL;
11771 }
11772
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011773 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011774 return 0;
11775}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011776
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070011777#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053011778
11779#ifdef MODULE
11780/**
11781 * __hdd_module_init - Module init helper
11782 *
11783 * Module init helper function used by both module and static driver.
11784 *
11785 * Return: 0 for success, errno on failure
11786 */
11787static int hdd_module_init(void)
11788{
Arun Khandavallifae92942016-08-01 13:31:08 +053011789 if (__hdd_module_init()) {
11790 pr_err("%s: Failed to register handler\n", __func__);
Dustin Brownab482ac2017-06-09 17:00:44 -070011791 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011792 }
11793
Dustin Brownab482ac2017-06-09 17:00:44 -070011794 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053011795}
11796#else
11797static int __init hdd_module_init(void)
11798{
11799 int ret = -EINVAL;
11800
11801 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070011802 if (ret)
Arun Khandavallifae92942016-08-01 13:31:08 +053011803 pr_err("Failed to create sysfs entry for loading wlan");
11804
11805 return ret;
11806}
11807#endif
11808
11809
11810#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011811/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011812 * hdd_module_exit() - Exit function
11813 *
11814 * This is the driver exit point (invoked when module is unloaded using rmmod)
11815 *
11816 * Return: None
11817 */
11818static void __exit hdd_module_exit(void)
11819{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011820 __hdd_module_exit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011821}
Arun Khandavallifae92942016-08-01 13:31:08 +053011822#else
11823static void __exit hdd_module_exit(void)
11824{
11825 __hdd_module_exit();
11826 wlan_deinit_sysfs();
11827}
11828#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011829
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011830static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
11831{
11832 return param_set_copystring(kmessage, kp);
11833}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011834
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011835/**
11836 * is_con_mode_valid() check con mode is valid or not
11837 * @mode: global con mode
11838 *
11839 * Return: TRUE on success FALSE on failure
11840 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080011841static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011842{
11843 switch (mode) {
11844 case QDF_GLOBAL_MONITOR_MODE:
11845 case QDF_GLOBAL_FTM_MODE:
11846 case QDF_GLOBAL_EPPING_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011847 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011848 return true;
11849 default:
11850 return false;
11851 }
11852}
11853
11854/**
11855 * hdd_get_adpter_mode() - returns adapter mode based on global con mode
11856 * @mode: global con mode
11857 *
11858 * Return: adapter mode
11859 */
Jeff Johnsonc1e62782017-11-09 09:50:17 -080011860static enum QDF_OPMODE hdd_get_adpter_mode(
Jeff Johnson876c1a62017-12-12 10:43:07 -080011861 enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011862{
11863
11864 switch (mode) {
11865 case QDF_GLOBAL_MISSION_MODE:
11866 return QDF_STA_MODE;
11867 case QDF_GLOBAL_MONITOR_MODE:
11868 return QDF_MONITOR_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011869 case QDF_GLOBAL_EPPING_MODE:
11870 return QDF_EPPING_MODE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011871 case QDF_GLOBAL_FTM_MODE:
11872 return QDF_FTM_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011873 case QDF_GLOBAL_QVIT_MODE:
11874 return QDF_QVIT_MODE;
11875 default:
11876 return QDF_MAX_NO_OF_MODE;
11877 }
11878}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011879
Dustin Brown27cd9942017-09-27 16:11:44 -070011880static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080011881 enum QDF_GLOBAL_MODE curr_mode)
Dustin Brown27cd9942017-09-27 16:11:44 -070011882{
11883 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
11884 return;
11885
11886 switch (curr_mode) {
Dustin Brown27cd9942017-09-27 16:11:44 -070011887 case QDF_GLOBAL_MONITOR_MODE:
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053011888 hdd_info("Release wakelock for monitor mode!");
11889 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
11890 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
11891 case QDF_GLOBAL_MISSION_MODE:
Dustin Brown27cd9942017-09-27 16:11:44 -070011892 case QDF_GLOBAL_FTM_MODE:
11893 hdd_abort_mac_scan_all_adapters(hdd_ctx);
11894 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
11895
11896 /* re-use the existing session */
11897 hdd_stop_all_adapters(hdd_ctx, false);
11898 break;
11899 default:
11900 break;
11901 }
11902}
11903
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011904static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080011905 enum QDF_GLOBAL_MODE curr_mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011906{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053011907 int driver_status;
11908
11909 driver_status = hdd_ctx->driver_status;
11910
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011911 switch (curr_mode) {
11912 case QDF_GLOBAL_MISSION_MODE:
11913 case QDF_GLOBAL_MONITOR_MODE:
11914 case QDF_GLOBAL_FTM_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011915 hdd_deinit_all_adapters(hdd_ctx, false);
11916 hdd_close_all_adapters(hdd_ctx, false);
11917 break;
11918 case QDF_GLOBAL_EPPING_MODE:
11919 epping_disable();
11920 epping_close();
11921 break;
11922 default:
11923 return;
11924 }
11925}
11926
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011927static int hdd_register_req_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080011928 enum QDF_GLOBAL_MODE mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011929{
Jeff Johnson9d295242017-08-29 14:39:48 -070011930 struct hdd_adapter *adapter;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011931 int ret = 0;
11932 bool rtnl_held;
11933 qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11934 QDF_STATUS status;
11935
11936 if (!qdf_dev) {
11937 hdd_err("qdf device context is Null return!");
11938 return -EINVAL;
11939 }
11940
11941 rtnl_held = hdd_hold_rtnl_lock();
11942 switch (mode) {
11943 case QDF_GLOBAL_MISSION_MODE:
Jeff Johnson957bc272017-02-02 08:54:48 -080011944 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
11945 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011946 hdd_err("Failed to open interfaces: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011947 break;
11948 case QDF_GLOBAL_FTM_MODE:
11949 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
11950 wlan_hdd_get_intf_addr(hdd_ctx),
11951 NET_NAME_UNKNOWN, rtnl_held);
11952 if (adapter == NULL)
11953 ret = -EINVAL;
11954 break;
11955 case QDF_GLOBAL_MONITOR_MODE:
11956 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
11957 wlan_hdd_get_intf_addr(hdd_ctx),
11958 NET_NAME_UNKNOWN, rtnl_held);
11959 if (adapter == NULL)
11960 ret = -EINVAL;
11961 break;
11962 case QDF_GLOBAL_EPPING_MODE:
11963 status = epping_open();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011964 if (status != QDF_STATUS_SUCCESS) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011965 hdd_err("Failed to open in eeping mode: %d", status);
11966 ret = -EINVAL;
11967 break;
11968 }
11969 ret = epping_enable(qdf_dev->dev);
11970 if (ret) {
11971 hdd_err("Failed to enable in epping mode : %d", ret);
11972 epping_close();
11973 }
11974 break;
11975 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011976 hdd_err("Mode not supported");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011977 ret = -ENOTSUPP;
11978 break;
11979 }
11980 hdd_release_rtnl_lock();
11981 rtnl_held = false;
11982 return ret;
11983}
11984
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011985/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011986 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011987 * @kmessage: con mode name on which driver to be bring up
11988 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011989 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011990 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011991 * This function is invoked when user updates con mode using sys entry,
11992 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011993 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011994 * Return - 0 on success and failure code on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011995 */
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011996static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011997 struct hdd_context *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011998{
11999 int ret;
Jeff Johnson9d295242017-08-29 14:39:48 -070012000 struct hdd_adapter *adapter;
Jeff Johnson876c1a62017-12-12 10:43:07 -080012001 enum QDF_GLOBAL_MODE curr_mode;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012002 enum QDF_OPMODE adapter_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012003
Dustin Brownab6029b2017-05-24 13:04:19 -070012004 hdd_info("con_mode handler: %s", kmessage);
12005
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053012006 ret = wlan_hdd_validate_context(hdd_ctx);
12007 if (ret)
12008 return ret;
12009
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012010 cds_set_load_in_progress(true);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012011
12012 ret = param_set_int(kmessage, kp);
Arun Khandavallifae92942016-08-01 13:31:08 +053012013
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012014 if (!(is_con_mode_valid(con_mode))) {
12015 hdd_err("invlaid con_mode %d", con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012016 ret = -EINVAL;
12017 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012018 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012019
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012020 curr_mode = hdd_get_conparam();
12021 if (curr_mode == con_mode) {
12022 hdd_err("curr mode: %d is same as user triggered mode %d",
12023 curr_mode, con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012024 ret = 0;
12025 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012026 }
12027
Sourav Mohapatra3bc5e982017-11-24 15:53:49 +053012028 if (!cds_wait_for_external_threads_completion(__func__))
12029 hdd_warn("Waiting for monitor mode: External threads are active");
12030
Dustin Brown27cd9942017-09-27 16:11:44 -070012031 /* ensure adapters are stopped */
12032 hdd_stop_present_mode(hdd_ctx, curr_mode);
12033
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012034 ret = hdd_wlan_stop_modules(hdd_ctx, true);
Arun Khandavallifae92942016-08-01 13:31:08 +053012035 if (ret) {
12036 hdd_err("Stop wlan modules failed");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012037 goto reset_flags;
12038 }
12039
Ashish Kumar Dhanotiyacda57662017-08-14 14:45:25 +053012040 /* Cleanup present mode before switching to new mode */
12041 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
12042
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012043 hdd_set_conparam(con_mode);
12044
12045 /* Register for new con_mode & then kick_start modules again */
12046 ret = hdd_register_req_mode(hdd_ctx, con_mode);
12047 if (ret) {
12048 hdd_err("Failed to register for new mode");
12049 goto reset_flags;
12050 }
12051
12052 adapter_mode = hdd_get_adpter_mode(con_mode);
12053 if (adapter_mode == QDF_MAX_NO_OF_MODE) {
12054 hdd_err("invalid adapter");
12055 ret = -EINVAL;
12056 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012057 }
12058
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053012059 adapter = hdd_get_adapter(hdd_ctx, adapter_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +053012060 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012061 hdd_err("Failed to get adapter:%d", adapter_mode);
12062 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012063 }
12064
12065 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
12066 if (ret) {
12067 hdd_err("Start wlan modules failed: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012068 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053012069 }
12070
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012071 if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
Dustin Brown27cd9942017-09-27 16:11:44 -070012072 con_mode == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012073 if (hdd_start_adapter(adapter)) {
12074 hdd_err("Failed to start %s adapter", kmessage);
12075 ret = -EINVAL;
12076 goto reset_flags;
12077 }
Arun Khandavallifae92942016-08-01 13:31:08 +053012078 }
12079
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053012080 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
12081 hdd_info("Acquire wakelock for monitor mode!");
12082 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
12083 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
12084 }
12085
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012086 hdd_info("Mode successfully changed to %s", kmessage);
12087 ret = 0;
12088
12089reset_flags:
12090 cds_set_load_in_progress(false);
12091 return ret;
12092}
12093
12094
12095static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
12096{
12097 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012098 struct hdd_context *hdd_ctx;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053012099
12100 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12101 ret = wlan_hdd_validate_context(hdd_ctx);
12102 if (ret)
12103 return ret;
12104
12105 cds_ssr_protect(__func__);
12106 ret = __con_mode_handler(kmessage, kp, hdd_ctx);
12107 cds_ssr_unprotect(__func__);
12108
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012109 return ret;
12110}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012111
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053012112static int con_mode_handler_ftm(const char *kmessage,
12113 struct kernel_param *kp)
12114{
12115 int ret;
12116
12117 ret = param_set_int(kmessage, kp);
12118
12119 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
12120 pr_err("Only FTM mode supported!");
12121 return -ENOTSUPP;
12122 }
12123
12124 hdd_set_conparam(con_mode_ftm);
12125 con_mode = con_mode_ftm;
12126
12127 return ret;
12128}
12129
Ravi Joshia307f632017-07-17 23:41:41 -070012130static int con_mode_handler_monitor(const char *kmessage,
12131 struct kernel_param *kp)
12132{
12133 int ret;
12134
12135 ret = param_set_int(kmessage, kp);
12136
12137 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
12138 pr_err("Only Monitor mode supported!");
12139 return -ENOTSUPP;
12140 }
12141
12142 hdd_set_conparam(con_mode_monitor);
12143 con_mode = con_mode_monitor;
12144
12145 return ret;
12146}
12147
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012148/**
12149 * hdd_get_conparam() - driver exit point
12150 *
12151 * This is the driver exit point (invoked when module is unloaded using rmmod)
12152 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080012153 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012154 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080012155enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012156{
Jeff Johnson876c1a62017-12-12 10:43:07 -080012157 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012158}
12159
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012160void hdd_set_conparam(uint32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012161{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080012162 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012163}
12164
Komal Seelamc11bb222016-01-27 18:57:10 +053012165/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012166 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
12167 * @hdd_ctx: HDD context
12168 *
12169 * Cleans up the pre cac interface, if it exists
12170 *
12171 * Return: None
12172 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012173void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012174{
12175 uint8_t session_id;
12176 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070012177 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053012178
12179 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->hHal, &session_id);
12180 if (QDF_IS_STATUS_ERROR(status)) {
12181 hdd_err("failed to get pre cac vdev id");
12182 return;
12183 }
12184
12185 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
12186 if (!precac_adapter) {
12187 hdd_err("invalid pre cac adapater");
12188 return;
12189 }
12190
12191 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
12192 wlan_hdd_sap_pre_cac_failure,
12193 (void *)precac_adapter);
12194 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
12195
12196}
12197
12198/**
Komal Seelamec702b02016-02-24 18:42:16 +053012199 * hdd_update_ol_config - API to update ol configuration parameters
12200 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053012201 *
Komal Seelamc11bb222016-01-27 18:57:10 +053012202 * Return: void
12203 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012204static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053012205{
Komal Seelamec702b02016-02-24 18:42:16 +053012206 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012207 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Komal Seelamc11bb222016-01-27 18:57:10 +053012208
Komal Seelamec702b02016-02-24 18:42:16 +053012209 if (!ol_ctx)
12210 return;
12211
12212 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
12213 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
12214 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
12215 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070012216 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053012217
12218 ol_init_ini_config(ol_ctx, &cfg);
12219}
12220
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012221#ifdef FEATURE_RUNTIME_PM
12222/**
12223 * hdd_populate_runtime_cfg() - populate runtime configuration
12224 * @hdd_ctx: hdd context
12225 * @cfg: pointer to the configuration memory being populated
12226 *
12227 * Return: void
12228 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012229static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012230 struct hif_config_info *cfg)
12231{
12232 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
12233 cfg->runtime_pm_delay = hdd_ctx->config->runtime_pm_delay;
12234}
12235#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012236static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012237 struct hif_config_info *cfg)
12238{
12239}
12240#endif
12241
Komal Seelamec702b02016-02-24 18:42:16 +053012242/**
12243 * hdd_update_hif_config - API to update HIF configuration parameters
12244 * @hdd_ctx: HDD Context
12245 *
12246 * Return: void
12247 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012248static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012249{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053012250 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053012251 struct hif_config_info cfg;
12252
12253 if (!scn)
12254 return;
12255
12256 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070012257 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053012258 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070012259
12260 if (hdd_ctx->config->prevent_link_down)
12261 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053012262}
12263
12264/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012265 * hdd_update_dp_config() - Propagate config parameters to Lithium
12266 * datapath
12267 * @hdd_ctx: HDD Context
12268 *
12269 * Return: 0 for success/errno for failure
12270 */
12271static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
12272{
12273 struct cdp_config_params params;
12274 QDF_STATUS status;
12275
12276 params.tso_enable = hdd_ctx->config->tso_enable;
12277 params.lro_enable = hdd_ctx->config->lro_enable;
12278#ifdef QCA_LL_TX_FLOW_CONTROL_V2
12279 params.tx_flow_stop_queue_threshold =
12280 hdd_ctx->config->TxFlowStopQueueThreshold;
12281 params.tx_flow_start_queue_offset =
12282 hdd_ctx->config->TxFlowStartQueueOffset;
12283#endif
12284 params.flow_steering_enable = hdd_ctx->config->flow_steering_enable;
12285 params.napi_enable = hdd_ctx->napi_enable;
12286 params.tcp_udp_checksumoffload =
12287 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
12288
12289 status = cdp_update_config_parameters(
12290 cds_get_context(QDF_MODULE_ID_SOC),
12291 &params);
12292 if (status) {
12293 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
12294 "%s: Failed to attach config parameters", __func__);
12295 return status;
12296 }
12297
12298 return 0;
12299}
12300
12301/**
Komal Seelamec702b02016-02-24 18:42:16 +053012302 * hdd_update_config() - Initialize driver per module ini parameters
12303 * @hdd_ctx: HDD Context
12304 *
12305 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012306 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053012307 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012308int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053012309{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012310 int ret;
12311
Komal Seelamec702b02016-02-24 18:42:16 +053012312 hdd_update_ol_config(hdd_ctx);
12313 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012314 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
12315 ret = hdd_update_cds_config_ftm(hdd_ctx);
12316 else
12317 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080012318 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053012319
12320 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053012321}
12322
Mukul Sharma9d797a02017-01-05 20:26:03 +053012323#ifdef FEATURE_WLAN_RA_FILTERING
12324/**
12325 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
12326 * @psoc_cfg: pmo psoc Configuration
12327 * @hdd_ctx: Pointer to hdd context
12328 *
12329 * Return: none
12330 */
12331static inline void hdd_ra_populate_pmo_config(
12332 struct pmo_psoc_cfg *psoc_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012333 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012334{
12335 psoc_cfg->ra_ratelimit_interval =
12336 hdd_ctx->config->RArateLimitInterval;
12337 psoc_cfg->ra_ratelimit_enable =
12338 hdd_ctx->config->IsRArateLimitEnabled;
12339}
12340#else
12341static inline void hdd_ra_populate_pmo_config(
12342 struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012343 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012344{
12345}
12346#endif
Will Huang3cd2b7c2017-11-17 13:16:56 +080012347
Mukul Sharma9d797a02017-01-05 20:26:03 +053012348/**
12349 * hdd_update_pmo_config - API to update pmo configuration parameters
12350 * @hdd_ctx: HDD context
12351 *
12352 * Return: void
12353 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012354static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012355{
12356 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
12357 struct pmo_psoc_cfg psoc_cfg;
12358 QDF_STATUS status;
12359
12360 /*
12361 * Value of hdd_ctx->wowEnable can be,
12362 * 0 - Disable both magic pattern match and pattern byte match.
12363 * 1 - Enable magic pattern match on all interfaces.
12364 * 2 - Enable pattern byte match on all interfaces.
12365 * 3 - Enable both magic patter and pattern byte match on
12366 * all interfaces.
12367 */
12368 psoc_cfg.magic_ptrn_enable =
12369 (hdd_ctx->config->wowEnable & 0x01) ? true : false;
12370 psoc_cfg.ptrn_match_enable_all_vdev =
12371 (hdd_ctx->config->wowEnable & 0x02) ? true : false;
Will Huangfe649172017-09-06 16:52:18 +080012372 psoc_cfg.ptrn_id_per_vdev = wma_is_service_enabled(
12373 WMI_SERVICE_UNIFIED_WOW_CAPABILITY);
Mukul Sharma9d797a02017-01-05 20:26:03 +053012374 psoc_cfg.bpf_enable =
12375 hdd_ctx->config->bpf_packet_filter_enable;
12376 psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
Dustin Brown1224e212017-05-12 14:02:12 -070012377 psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012378 psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
12379 if (hdd_ctx->config->fhostNSOffload)
12380 psoc_cfg.ns_offload_enable_dynamic = true;
12381 psoc_cfg.ssdp = hdd_ctx->config->ssdp;
12382 psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
12383 psoc_cfg.active_mode_offload =
12384 hdd_ctx->config->active_mode_offload;
12385 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080012386 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Mukul Sharma9d797a02017-01-05 20:26:03 +053012387 psoc_cfg.max_wow_filters = hdd_ctx->config->maxWoWFilters;
Mukul Sharma9223f232017-03-08 18:42:27 +053012388 psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
12389 psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
12390 psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
12391 psoc_cfg.power_save_mode =
12392 hdd_ctx->config->enablePowersaveOffload;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +053012393 psoc_cfg.auto_power_save_fail_mode =
12394 hdd_ctx->config->auto_pwr_save_fail_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053012395
12396 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053012397 hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx);
12398 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Rajeev Kumard1a7ac42017-11-08 14:54:22 -080012399 status = ucfg_pmo_update_psoc_config(psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053012400 if (status != QDF_STATUS_SUCCESS) {
12401 hdd_err("failed pmo psoc configuration");
12402 return -EINVAL;
12403 }
12404
12405 return 0;
12406}
12407
Abhishek Singhb20db962017-03-03 21:28:46 +053012408#ifdef FEATURE_WLAN_SCAN_PNO
12409static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
12410 struct hdd_config *cfg)
12411{
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070012412 struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
12413
Abhishek Singhb20db962017-03-03 21:28:46 +053012414 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
12415 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
12416 pno_cfg->stationary_thresh = cfg->stationary_thresh;
12417 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
12418 pno_cfg->channel_prediction_full_scan =
12419 cfg->channel_prediction_full_scan;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070012420 mawc_cfg->enable = cfg->MAWCEnabled && cfg->mawc_nlo_enabled;
12421 mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
12422 mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
12423 mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
Abhishek Singhb20db962017-03-03 21:28:46 +053012424}
12425#else
12426static inline void
12427hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Jeff Johnson33a07922017-10-05 09:08:46 -070012428 struct hdd_config *cfg)
Abhishek Singhb20db962017-03-03 21:28:46 +053012429{
Abhishek Singhb20db962017-03-03 21:28:46 +053012430}
12431#endif
12432
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053012433void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
12434 struct hdd_config *cfg)
12435{
12436 uint8_t i = 0;
12437
12438 ie_whitelist->white_list = cfg->probe_req_ie_whitelist;
12439 if (!ie_whitelist->white_list)
12440 return;
12441
12442 ie_whitelist->ie_bitmap[0] = cfg->probe_req_ie_bitmap_0;
12443 ie_whitelist->ie_bitmap[1] = cfg->probe_req_ie_bitmap_1;
12444 ie_whitelist->ie_bitmap[2] = cfg->probe_req_ie_bitmap_2;
12445 ie_whitelist->ie_bitmap[3] = cfg->probe_req_ie_bitmap_3;
12446 ie_whitelist->ie_bitmap[4] = cfg->probe_req_ie_bitmap_4;
12447 ie_whitelist->ie_bitmap[5] = cfg->probe_req_ie_bitmap_5;
12448 ie_whitelist->ie_bitmap[6] = cfg->probe_req_ie_bitmap_6;
12449 ie_whitelist->ie_bitmap[7] = cfg->probe_req_ie_bitmap_7;
12450
12451 ie_whitelist->num_vendor_oui = cfg->no_of_probe_req_ouis;
12452 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
12453 ie_whitelist->voui[i] = cfg->probe_req_voui[i];
12454}
12455
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053012456uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
12457{
12458 uint8_t i, score;
12459
12460 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
12461 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
12462 if (score > MAX_INDEX_SCORE)
12463 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
12464 MAX_INDEX_SCORE, i);
12465 }
12466
12467 return per_index_score;
12468}
12469
12470/**
12471 * hdd_update_score_config - API to update candidate scoring related params
12472 * configuration parameters
12473 * @score_config: score config to update
12474 * @cfg: config params
12475 *
12476 * Return: 0 if success else err
12477 */
12478static void hdd_update_score_config(
12479 struct scoring_config *score_config, struct hdd_config *cfg)
12480{
12481 int total_weight;
12482
12483 score_config->weight_cfg.rssi_weightage = cfg->rssi_weightage;
12484 score_config->weight_cfg.ht_caps_weightage = cfg->ht_caps_weightage;
12485 score_config->weight_cfg.vht_caps_weightage =
12486 cfg->vht_caps_weightage;
12487 score_config->weight_cfg.he_caps_weightage =
12488 cfg->he_caps_weightage;
12489 score_config->weight_cfg.chan_width_weightage =
12490 cfg->chan_width_weightage;
12491 score_config->weight_cfg.chan_band_weightage =
12492 cfg->chan_band_weightage;
12493 score_config->weight_cfg.nss_weightage = cfg->nss_weightage;
12494 score_config->weight_cfg.beamforming_cap_weightage =
12495 cfg->beamforming_cap_weightage;
12496 score_config->weight_cfg.pcl_weightage = cfg->pcl_weightage;
12497 score_config->weight_cfg.channel_congestion_weightage =
12498 cfg->channel_congestion_weightage;
12499 score_config->weight_cfg.oce_wan_weightage = cfg->oce_wan_weightage;
12500
12501 total_weight = score_config->weight_cfg.rssi_weightage +
12502 score_config->weight_cfg.ht_caps_weightage +
12503 score_config->weight_cfg.vht_caps_weightage +
12504 score_config->weight_cfg.he_caps_weightage +
12505 score_config->weight_cfg.chan_width_weightage +
12506 score_config->weight_cfg.chan_band_weightage +
12507 score_config->weight_cfg.nss_weightage +
12508 score_config->weight_cfg.beamforming_cap_weightage +
12509 score_config->weight_cfg.pcl_weightage +
12510 score_config->weight_cfg.channel_congestion_weightage +
12511 score_config->weight_cfg.oce_wan_weightage;
12512
12513 if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) {
12514 hdd_err("total weight is greater than %d fallback to default values",
12515 BEST_CANDIDATE_MAX_WEIGHT);
12516
12517 score_config->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE;
12518 score_config->weight_cfg.ht_caps_weightage =
12519 HT_CAPABILITY_WEIGHTAGE;
12520 score_config->weight_cfg.vht_caps_weightage = VHT_CAP_WEIGHTAGE;
12521 score_config->weight_cfg.he_caps_weightage = HE_CAP_WEIGHTAGE;
12522 score_config->weight_cfg.chan_width_weightage =
12523 CHAN_WIDTH_WEIGHTAGE;
12524 score_config->weight_cfg.chan_band_weightage =
12525 CHAN_BAND_WEIGHTAGE;
12526 score_config->weight_cfg.nss_weightage = NSS_WEIGHTAGE;
12527 score_config->weight_cfg.beamforming_cap_weightage =
12528 BEAMFORMING_CAP_WEIGHTAGE;
12529 score_config->weight_cfg.pcl_weightage = PCL_WEIGHT;
12530 score_config->weight_cfg.channel_congestion_weightage =
12531 CHANNEL_CONGESTION_WEIGHTAGE;
12532 score_config->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE;
12533 }
12534
12535 score_config->bandwidth_weight_per_index =
12536 hdd_limit_max_per_index_score(
12537 cfg->bandwidth_weight_per_index);
12538 score_config->nss_weight_per_index =
12539 hdd_limit_max_per_index_score(cfg->nss_weight_per_index);
12540 score_config->band_weight_per_index =
12541 hdd_limit_max_per_index_score(cfg->band_weight_per_index);
12542
12543 score_config->rssi_score.best_rssi_threshold =
12544 cfg->best_rssi_threshold;
12545 score_config->rssi_score.good_rssi_threshold =
12546 cfg->good_rssi_threshold;
12547 score_config->rssi_score.bad_rssi_threshold =
12548 cfg->bad_rssi_threshold;
12549 score_config->rssi_score.good_rssi_pcnt = cfg->good_rssi_pcnt;
12550 score_config->rssi_score.bad_rssi_pcnt = cfg->bad_rssi_pcnt;
12551 score_config->rssi_score.good_rssi_bucket_size =
12552 cfg->good_rssi_bucket_size;
12553 score_config->rssi_score.bad_rssi_bucket_size =
12554 cfg->bad_rssi_bucket_size;
12555 score_config->rssi_score.rssi_pref_5g_rssi_thresh =
12556 cfg->rssi_pref_5g_rssi_thresh;
12557
12558 score_config->esp_qbss_scoring.num_slot = cfg->num_esp_qbss_slots;
12559 score_config->esp_qbss_scoring.score_pcnt3_to_0 =
12560 hdd_limit_max_per_index_score(
12561 cfg->esp_qbss_score_slots3_to_0);
12562 score_config->esp_qbss_scoring.score_pcnt7_to_4 =
12563 hdd_limit_max_per_index_score(
12564 cfg->esp_qbss_score_slots7_to_4);
12565 score_config->esp_qbss_scoring.score_pcnt11_to_8 =
12566 hdd_limit_max_per_index_score(
12567 cfg->esp_qbss_score_slots11_to_8);
12568 score_config->esp_qbss_scoring.score_pcnt15_to_12 =
12569 hdd_limit_max_per_index_score(
12570 cfg->esp_qbss_score_slots15_to_12);
12571
12572 score_config->oce_wan_scoring.num_slot = cfg->num_oce_wan_slots;
12573 score_config->oce_wan_scoring.score_pcnt3_to_0 =
12574 hdd_limit_max_per_index_score(
12575 cfg->oce_wan_score_slots3_to_0);
12576 score_config->oce_wan_scoring.score_pcnt7_to_4 =
12577 hdd_limit_max_per_index_score(
12578 cfg->oce_wan_score_slots7_to_4);
12579 score_config->oce_wan_scoring.score_pcnt11_to_8 =
12580 hdd_limit_max_per_index_score(
12581 cfg->oce_wan_score_slots11_to_8);
12582 score_config->oce_wan_scoring.score_pcnt15_to_12 =
12583 hdd_limit_max_per_index_score(
12584 cfg->oce_wan_score_slots15_to_12);
12585
12586
12587 score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
12588 score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
12589 score_config->nss = cfg->enable2x2 ? 2 : 1;
12590
12591 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
12592 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
12593 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
12594 score_config->he_cap = 1;
12595
12596 if (score_config->he_cap ||
12597 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
12598 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
12599 score_config->vht_cap = 1;
12600
12601 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
12602 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
12603 score_config->ht_cap = 1;
12604
12605 if (score_config->vht_cap && cfg->enableVhtFor24GHzBand)
12606 score_config->vht_24G_cap = 1;
12607
12608 if (cfg->enableTxBF)
12609 score_config->beamformee_cap = 1;
12610
12611}
12612
Abhishek Singh257a9482017-03-06 16:52:39 +053012613/**
12614 * hdd_update_scan_config - API to update scan configuration parameters
12615 * @hdd_ctx: HDD context
12616 *
12617 * Return: 0 if success else err
12618 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012619static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053012620{
12621 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
12622 struct scan_user_cfg scan_cfg;
12623 struct hdd_config *cfg = hdd_ctx->config;
12624 QDF_STATUS status;
12625
12626 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
12627 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
12628 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
12629 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
12630 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
12631 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
12632 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053012633 /* convert to ms */
12634 scan_cfg.scan_cache_aging_time =
12635 cfg->scanAgingTimeout * 1000;
12636 scan_cfg.prefer_5ghz = cfg->nRoamPrefer5GHz;
12637 scan_cfg.select_5ghz_margin = cfg->nSelect5GHzMargin;
12638 scan_cfg.scan_bucket_threshold = cfg->first_scan_bucket_threshold;
12639 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053012640 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053012641 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Jeff Johnson81c00d02017-11-07 12:34:36 -080012642 scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
12643 scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
Abhishek Singhb58164a2017-07-19 18:47:23 +053012644 scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
Kiran Kumar Lokered547fdd2017-09-13 17:20:55 -070012645 scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
Abhishek Singh257a9482017-03-06 16:52:39 +053012646
Abhishek Singhb20db962017-03-03 21:28:46 +053012647 hdd_update_pno_config(&scan_cfg.pno_cfg, cfg);
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053012648 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, cfg);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053012649 hdd_update_score_config(&scan_cfg.score_config, cfg);
Abhishek Singhb20db962017-03-03 21:28:46 +053012650
Abhishek Singh257a9482017-03-06 16:52:39 +053012651 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
12652 if (status != QDF_STATUS_SUCCESS) {
12653 hdd_err("failed pmo psoc configuration");
12654 return -EINVAL;
12655 }
12656
12657 return 0;
12658}
Abhishek Singh257a9482017-03-06 16:52:39 +053012659
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012660int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053012661{
12662 int ret;
12663
12664 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053012665 if (ret)
12666 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012667
Abhishek Singh257a9482017-03-06 16:52:39 +053012668 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080012669 if (ret)
12670 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012671
Frank Liud4b2fa02017-03-29 11:46:48 +080012672 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012673 if (ret)
12674 return ret;
12675
12676 ret = hdd_update_dp_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053012677
12678 return ret;
12679}
12680
Agrawal Ashish65634612016-08-18 13:24:32 +053012681/**
12682 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
12683 * @mode : cfg80211 DFS mode
12684 *
12685 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
12686 */
12687enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
12688{
12689 switch (mode) {
12690 case DFS_MODE_ENABLE:
12691 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053012692 case DFS_MODE_DISABLE:
12693 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053012694 case DFS_MODE_DEPRIORITIZE:
12695 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053012696 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012697 hdd_debug("ACS dfs mode is NONE");
12698 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053012699 }
12700}
12701
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053012702/**
12703 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
12704 * @hddctx: pointer to hdd context
12705 * @set_value: enable/disable
12706 *
12707 * When Host sends vendor command enable, FW will send *ONE* CA ind to
12708 * Host(even though it is duplicate). When Host send vendor command
12709 * disable,FW doesn't perform any action. Whenever any change in
12710 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
12711 *
12712 * return - 0 on success, appropriate error values on failure.
12713 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012714int hdd_enable_disable_ca_event(struct hdd_context *hddctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053012715{
12716 QDF_STATUS status;
12717
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012718 if (0 != wlan_hdd_validate_context(hddctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053012719 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053012720
12721 if (!hddctx->config->goptimize_chan_avoid_event) {
12722 hdd_warn("goptimize_chan_avoid_event ini param disabled");
12723 return -EINVAL;
12724 }
12725
12726 status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
12727 if (!QDF_IS_STATUS_SUCCESS(status)) {
12728 hdd_err("Failed to send chan avoid command to SME");
12729 return -EINVAL;
12730 }
12731 return 0;
12732}
Agrawal Ashish65634612016-08-18 13:24:32 +053012733
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012734/**
12735 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
12736 * @value: value to set
12737 *
12738 * This function will set the passed value to roaming in progress flag.
12739 *
12740 * Return: None
12741 */
12742void hdd_set_roaming_in_progress(bool value)
12743{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012744 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012745
12746 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12747 if (!hdd_ctx) {
12748 hdd_err("HDD context is NULL");
12749 return;
12750 }
12751
12752 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012753 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012754}
12755
12756/**
12757 * hdd_is_roaming_in_progress() - check if roaming is in progress
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080012758 * @adapter - HDD adapter
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012759 *
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080012760 * Return: true if roaming is in progress for STA type, else false
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012761 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012762bool hdd_is_roaming_in_progress(struct hdd_adapter *adapter)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012763{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012764 struct hdd_context *hdd_ctx;
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080012765 bool ret_status = false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012766
12767 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12768 if (!hdd_ctx) {
12769 hdd_err("HDD context is NULL");
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080012770 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012771 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012772 hdd_debug("dev mode = %d, roaming_in_progress = %d",
12773 adapter->device_mode, hdd_ctx->roaming_in_progress);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080012774 ret_status = ((adapter->device_mode == QDF_STA_MODE) &&
12775 hdd_ctx->roaming_in_progress);
12776
12777 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080012778}
12779
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012780/**
12781 * hdd_is_connection_in_progress() - check if connection is in
12782 * progress
12783 * @session_id: session id
12784 * @reason: scan reject reason
12785 *
12786 * Go through each adapter and check if Connection is in progress
12787 *
12788 * Return: true if connection is in progress else false
12789 */
12790bool hdd_is_connection_in_progress(uint8_t *session_id,
12791 enum scan_reject_states *reason)
12792{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070012793 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070012794 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012795 uint8_t sta_id = 0;
12796 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012797 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012798
12799 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12800 if (!hdd_ctx) {
12801 hdd_err("HDD context is NULL");
12802 return false;
12803 }
12804
Dustin Brown920397d2017-12-13 16:27:50 -080012805 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012806 hdd_info("Adapter with device mode %s(%d) exists",
12807 hdd_device_mode_to_string(adapter->device_mode),
12808 adapter->device_mode);
12809 if (((QDF_STA_MODE == adapter->device_mode)
12810 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
12811 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
12812 && (eConnectionState_Connecting ==
12813 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
12814 conn_info.connState)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053012815 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012816 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070012817 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012818 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070012819 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012820 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012821 }
12822 return true;
12823 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070012824 /*
12825 * sme_neighbor_middle_of_roaming is for LFR2
12826 * hdd_is_roaming_in_progress is for LFR3
12827 */
12828 if (((QDF_STA_MODE == adapter->device_mode) &&
12829 sme_neighbor_middle_of_roaming(
12830 WLAN_HDD_GET_HAL_CTX(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070012831 adapter->session_id)) ||
Archana Ramachandran62886ce2017-03-24 14:46:32 -070012832 hdd_is_roaming_in_progress(adapter)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053012833 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012834 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070012835 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012836 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070012837 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012838 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012839 }
12840 return true;
12841 }
12842 if ((QDF_STA_MODE == adapter->device_mode) ||
12843 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
12844 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
12845 hdd_sta_ctx =
12846 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12847 if ((eConnectionState_Associated ==
12848 hdd_sta_ctx->conn_info.connState)
12849 && (false ==
12850 hdd_sta_ctx->conn_info.uIsAuthenticated)) {
12851 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070012852 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053012853 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012854 " is in middle of WPS/EAPOL exchange.",
12855 MAC_ADDR_ARRAY(sta_mac));
12856 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070012857 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012858 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012859 }
12860 return true;
12861 }
12862 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
12863 (QDF_P2P_GO_MODE == adapter->device_mode)) {
12864 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
12865 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070012866 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012867 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070012868 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012869 continue;
12870
12871 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070012872 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070012873 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053012874 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012875 " of SAP/GO is in middle of WPS/EAPOL exchange",
12876 MAC_ADDR_ARRAY(sta_mac));
12877 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070012878 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012879 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012880 }
12881 return true;
12882 }
12883 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053012884 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012885 return true;
12886 }
12887 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012888 }
Dustin Brown920397d2017-12-13 16:27:50 -080012889
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012890 return false;
12891}
12892
12893/**
12894 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070012895 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012896 *
12897 * Return: None
12898 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012899void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012900{
Jeff Johnson87251032017-08-29 13:31:11 -070012901 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012902 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012903 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012904 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012905 tsap_Config_t *sap_config;
12906 void *sap_ctx;
12907
12908 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070012909 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012910 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012911
12912 mutex_lock(&hdd_ctx->sap_lock);
12913 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
12914 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012915 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
12916 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
12917 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
12918 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053012919 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012920 qdf_stop_bss_event,
12921 SME_CMD_TIMEOUT_VALUE);
12922
12923 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012924 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012925 goto end;
12926 }
12927 }
12928 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012929 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012930 ap_adapter->device_mode, ap_adapter->session_id);
Jeff Johnson6867ec32017-09-29 20:30:20 -070012931 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012932
12933 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012934 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012935 wlansap_reset_sap_config_add_ie(sap_config,
12936 eUPDATE_IE_ALL);
12937 goto end;
12938 }
12939
12940 qdf_event_reset(&hostapd_state->qdf_event);
12941 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
12942 sap_config,
12943 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012944 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012945 wlansap_reset_sap_config_add_ie(sap_config,
12946 eUPDATE_IE_ALL);
12947 goto end;
12948 }
12949
Jeff Johnson6867ec32017-09-29 20:30:20 -070012950 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012951 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053012952 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012953 SME_CMD_TIMEOUT_VALUE);
12954 wlansap_reset_sap_config_add_ie(sap_config,
12955 eUPDATE_IE_ALL);
12956 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012957 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012958 goto end;
12959 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070012960 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012961 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Jeff Johnson0f9f87b2017-10-28 09:21:06 -070012962 if (hostapd_state->bss_state == BSS_START)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012963 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
12964 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012965 ap_adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012966 }
12967end:
12968 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012969}
12970
12971/**
12972 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
12973 * with non dfs acs
12974 *
12975 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
12976 *
12977 * Return: None
12978 */
12979void hdd_check_and_restart_sap_with_non_dfs_acs(void)
12980{
Jeff Johnson9d295242017-08-29 14:39:48 -070012981 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012982 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012983 cds_context_type *cds_ctx;
12984
12985 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12986 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012987 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012988 return;
12989 }
12990
12991 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
12992 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012993 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012994 return;
12995 }
12996
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012997 if (policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc)
12998 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070012999 hdd_info("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013000 return;
13001 }
13002
13003 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070013004 if (ap_adapter != NULL && test_bit(SOFTAP_BSS_STARTED,
13005 &ap_adapter->event_flags) &&
13006 wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Jeff Johnsonb9424862017-10-30 08:49:35 -070013007 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013008
Jeff Johnson6867ec32017-09-29 20:30:20 -070013009 hdd_warn("STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS");
Jeff Johnsonb9424862017-10-30 08:49:35 -070013010 ap_adapter->session.ap.sap_config.channel =
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013011 AUTO_CHANNEL_SELECT;
Jeff Johnsonb9424862017-10-30 08:49:35 -070013012 ap_adapter->session.ap.sap_config.
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013013 acs_cfg.acs_mode = true;
13014
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013015 hdd_restart_sap(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013016 }
13017}
13018
13019/**
13020 * hdd_set_connection_in_progress() - to set the connection in
13021 * progress flag
13022 * @value: value to set
13023 *
13024 * This function will set the passed value to connection in progress flag.
13025 * If value is previously being set to true then no need to set it again.
13026 *
13027 * Return: true if value is being set correctly and false otherwise.
13028 */
13029bool hdd_set_connection_in_progress(bool value)
13030{
13031 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013032 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013033
13034 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13035 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070013036 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080013037 return false;
13038 }
13039
13040 qdf_spin_lock(&hdd_ctx->connection_status_lock);
13041 /*
13042 * if the value is set to true previously and if someone is
13043 * trying to make it true again then it could be some race
13044 * condition being triggered. Avoid this situation by returning
13045 * false
13046 */
13047 if (hdd_ctx->connection_in_progress && value)
13048 status = false;
13049 else
13050 hdd_ctx->connection_in_progress = value;
13051 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
13052 return status;
13053}
13054
Jeff Johnson9d295242017-08-29 14:39:48 -070013055int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013056{
13057 if (!adapter) {
13058 hdd_err("Invalid adapter");
13059 return -EINVAL;
13060 }
13061 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013062 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013063 WMA_VDEV_MCC_SET_TIME_QUOTA,
13064 set_value, VDEV_CMD);
13065 return 0;
13066
13067}
13068
Jeff Johnson9d295242017-08-29 14:39:48 -070013069int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013070{
13071 if (!adapter) {
13072 hdd_err("Invalid adapter");
13073 return -EINVAL;
13074 }
13075
13076 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070013077 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070013078 WMA_VDEV_MCC_SET_TIME_LATENCY,
13079 set_value, VDEV_CMD);
13080 return 0;
13081}
13082
Jeff Johnson9d295242017-08-29 14:39:48 -070013083struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013084 *psoc, uint8_t vdev_id)
13085{
Jeff Johnson9d295242017-08-29 14:39:48 -070013086 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013087 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070013088
13089 /*
13090 * Currently PSOC is not being used. But this logic will
13091 * change once we have the converged implementation of
13092 * HDD context per PSOC in place. This would break if
13093 * multiple vdev objects reuse the vdev id.
13094 */
13095 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
13096 if (!adapter)
13097 hdd_err("Get adapter by vdev id failed");
13098
13099 return adapter;
13100}
13101
Jeff Johnson9d295242017-08-29 14:39:48 -070013102int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013103 int8_t *rssi, int8_t *snr)
13104{
13105 QDF_STATUS status;
Jeff Johnson2a722002017-09-30 20:02:35 -070013106 struct hdd_wext_state *wext_state =
13107 WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053013108 tCsrRoamProfile *profile = &wext_state->roamProfile;
13109
13110 status = sme_get_rssi_snr_by_bssid(WLAN_HDD_GET_HAL_CTX(adapter),
13111 profile, bssid, rssi, snr);
13112 if (QDF_STATUS_SUCCESS != status) {
13113 hdd_warn("sme_get_rssi_snr_by_bssid failed");
13114 return -EINVAL;
13115 }
13116
13117 return 0;
13118}
13119
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013120/**
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013121 * hdd_set_limit_off_chan_for_tos() - set limit off-channel command parameters
13122 * @adapter - HDD adapter
13123 * @tos - type of service
13124 * @status - status of the traffic
13125 *
13126 * Return: 0 on success and non zero value on failure
13127 */
13128
13129int hdd_set_limit_off_chan_for_tos(struct hdd_adapter *adapter, enum tos tos,
13130 bool is_tos_active)
13131{
13132 int ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013133 struct hdd_context *hdd_ctx;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013134 uint32_t max_off_chan_time = 0;
13135 QDF_STATUS status;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013136 int ret;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013137 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013138
13139 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13140 ret = wlan_hdd_validate_context(hdd_ctx);
13141
13142 if (ret < 0) {
13143 hdd_err("failed to set limit off chan params");
13144 return ret;
13145 }
13146
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013147 ac_bit = limit_off_chan_tbl[tos][HDD_AC_BIT_INDX];
13148
13149 if (is_tos_active)
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013150 adapter->active_ac |= ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013151 else
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013152 adapter->active_ac &= ~ac_bit;
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013153
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013154 if (adapter->active_ac) {
13155 if (adapter->active_ac & HDD_AC_VO_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013156 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013157 limit_off_chan_tbl[TOS_VO][HDD_DWELL_TIME_INDX];
13158 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13159 PM_LATENCY);
Ganesh Kondabattini1a2aed82017-09-28 12:21:58 +053013160 } else if (adapter->active_ac & HDD_AC_VI_BIT) {
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013161 max_off_chan_time =
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013162 limit_off_chan_tbl[TOS_VI][HDD_DWELL_TIME_INDX];
13163 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13164 PM_LATENCY);
13165 } else {
13166 /*ignore this command if only BE/BK is active */
13167 is_tos_active = false;
13168 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13169 hdd_ctx->config->conc_system_pref);
13170 }
13171 } else {
13172 /* No active tos */
13173 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13174 hdd_ctx->config->conc_system_pref);
13175 }
13176
Jeff Johnson1b780e42017-10-31 14:11:45 -070013177 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013178 is_tos_active, max_off_chan_time,
13179 hdd_ctx->config->nRestTimeConc, true);
13180 if (!QDF_IS_STATUS_SUCCESS(status)) {
13181 hdd_err("failed to set limit off chan params");
13182 ret = -EINVAL;
13183 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013184
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013185 return ret;
13186}
13187
13188/**
13189 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
13190 * @adapter - HDD adapter
13191 *
13192 * Return: 0 on success and non zero value on failure
13193 */
13194int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
13195{
13196 struct hdd_context *hdd_ctx;
13197 int ret;
13198 QDF_STATUS status;
13199 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
13200
13201 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13202 ret = wlan_hdd_validate_context(hdd_ctx);
13203 if (ret < 0)
13204 return ret;
13205
13206 /* set the system preferece to default */
13207 policy_mgr_set_cur_conc_system_pref(hdd_ctx->hdd_psoc,
13208 hdd_ctx->config->conc_system_pref);
13209
13210 /* clear the bitmap */
13211 adapter->active_ac = 0;
13212
13213 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson1b780e42017-10-31 14:11:45 -070013214 adapter->session_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013215
Jeff Johnson1b780e42017-10-31 14:11:45 -070013216 status = sme_send_limit_off_channel_params(hal, adapter->session_id,
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053013217 false, 0, 0, false);
13218 if (!QDF_IS_STATUS_SUCCESS(status)) {
13219 hdd_err("failed to reset limit off chan params");
13220 ret = -EINVAL;
13221 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053013222
13223 return ret;
13224}
13225
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013226/**
13227 * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
13228 * @drv_op: Enum indicating driver op
13229 *
13230 * Return: none
13231 */
13232void hdd_start_driver_ops_timer(int drv_op)
13233{
13234 memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
13235 switch (drv_op) {
13236 case eHDD_DRV_OP_PROBE:
13237 memcpy(drv_ops_string, "probe", sizeof("probe"));
13238 break;
13239 case eHDD_DRV_OP_REMOVE:
13240 memcpy(drv_ops_string, "remove", sizeof("remove"));
13241 break;
13242 case eHDD_DRV_OP_SHUTDOWN:
13243 memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
13244 break;
13245 case eHDD_DRV_OP_REINIT:
13246 memcpy(drv_ops_string, "reinit", sizeof("reinit"));
13247 break;
Arunk Khandavallie9ef42a2017-10-04 14:49:51 +053013248 case eHDD_DRV_OP_IFF_UP:
13249 memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
13250 break;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013251 }
13252
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013253 hdd_drv_ops_task = current;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013254 qdf_timer_start(&hdd_drv_ops_inactivity_timer,
13255 HDD_OPS_INACTIVITY_TIMEOUT);
13256}
13257
13258/**
13259 * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
13260 *
13261 * Return: none
13262 */
13263void hdd_stop_driver_ops_timer(void)
13264{
13265 qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
13266}
13267
13268/**
13269 * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
13270 * inactivity timer
13271 *
13272 * Return: None
13273 */
13274void hdd_drv_ops_inactivity_handler(void)
13275{
13276 hdd_err("%s: %d Sec timer expired while in .%s",
13277 __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
13278
Dustin Brown45ed4bb2017-12-18 12:00:13 -080013279 if (hdd_drv_ops_task) {
13280 printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
13281 qdf_print_thread_trace(hdd_drv_ops_task);
13282 } else {
13283 hdd_err("hdd_drv_ops_task is null");
13284 }
13285
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013286 /* Driver shutdown is stuck, no recovery possible at this point */
13287 if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
13288 sizeof("shutdown")))
13289 QDF_BUG(0);
13290
13291 if (cds_is_self_recovery_enabled())
Anurag Chouhan4085ff72017-10-05 18:09:56 +053013292 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053013293 else
13294 QDF_BUG(0);
13295}
13296
Sravan Kumar Kairamd80c7662017-10-03 16:11:05 +053013297void hdd_pld_ipa_uc_shutdown_pipes(void)
13298{
13299 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13300
13301 if (!hdd_ctx)
13302 return;
13303
13304 hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
13305}
13306
Yun Parkff6a16a2017-09-26 16:38:18 -070013307/**
13308 * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
13309 * @struct hdd_context *hdd_ctx
13310 * @struct hdd_adapter *padapter
13311 * @bool enble
13312 *
13313 * Return: none
13314 */
13315void hdd_set_rx_mode_rps(bool enable)
13316{
13317 struct cds_config_info *cds_cfg = cds_get_ini_config();
13318 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13319 struct hdd_adapter *adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
13320
13321 if (adapter && hdd_ctx &&
13322 !hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
13323 if (enable && !cds_cfg->rps_enabled)
13324 hdd_send_rps_ind(adapter);
13325 else if (!enable && cds_cfg->rps_enabled)
13326 hdd_send_rps_disable_ind(adapter);
13327 }
13328}
13329
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013330/* Register the module init/exit functions */
13331module_init(hdd_module_init);
13332module_exit(hdd_module_exit);
13333
13334MODULE_LICENSE("Dual BSD/GPL");
13335MODULE_AUTHOR("Qualcomm Atheros, Inc.");
13336MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
13337
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013338module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
13339 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013340
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013341module_param_call(con_mode_ftm, con_mode_handler_ftm, param_get_int,
13342 &con_mode_ftm, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13343
Ravi Joshia307f632017-07-17 23:41:41 -070013344module_param_call(con_mode_monitor, con_mode_handler_monitor, param_get_int,
13345 &con_mode_monitor, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13346
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013347module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
13348 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
13349
13350module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
13351
13352module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
13353
13354module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);