blob: 14f97ed29facff71b31c5d00e0d55a463b78e16f [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"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070060#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080061#include <cdp_txrx_misc.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63#include <net/addrconf.h>
64#include <linux/wireless.h>
65#include <net/cfg80211.h>
66#include <linux/inetdevice.h>
67#include <net/addrconf.h>
68#include "wlan_hdd_cfg80211.h"
69#include "wlan_hdd_ext_scan.h"
70#include "wlan_hdd_p2p.h"
71#include <linux/rtnetlink.h>
72#include "sap_api.h"
73#include <linux/semaphore.h>
74#include <linux/ctype.h>
75#include <linux/compat.h>
76#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#include <soc/qcom/subsystem_restart.h>
78#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079#include <wlan_hdd_hostapd.h>
80#include <wlan_hdd_softap_tx_rx.h>
81#include "cfg_api.h"
82#include "qwlan_version.h"
83#include "wma_types.h"
84#include "wlan_hdd_tdls.h"
85#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053086#include "cds_regdomain.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080087#include "cdp_txrx_flow_ctrl_v2.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088#endif /* FEATURE_WLAN_CH_AVOID */
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070089#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080090#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091#include "wlan_hdd_nan.h"
92#include "wlan_hdd_debugfs.h"
93#include "wlan_hdd_driver_ops.h"
94#include "epping_main.h"
95#include "wlan_hdd_memdump.h"
96
97#include <wlan_hdd_ipa.h>
98#include "hif.h"
99#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800100#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700101#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102#include "wlan_hdd_green_ap.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530103#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700104#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700105#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530106#include "nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700107#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530108#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800109#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800110#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530111#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800112#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800113#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530114#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530115#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800116#include "os_if_wifi_pos.h"
117#include "wifi_pos_api.h"
118#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800119#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700120#include "os_if_nan.h"
121#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700122#include "wlan_reg_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700123#include "wlan_hdd_rx_monitor.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530125#ifdef CNSS_GENL
126#include <net/cnss_nl.h>
127#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800128#include "wlan_reg_ucfg_api.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800130#ifdef MODULE
131#define WLAN_MODULE_NAME module_name(THIS_MODULE)
132#else
133#define WLAN_MODULE_NAME "wlan"
134#endif
135
136#ifdef TIMER_MANAGER
137#define TIMER_MANAGER_STR " +TIMER_MANAGER"
138#else
139#define TIMER_MANAGER_STR ""
140#endif
141
142#ifdef MEMORY_DEBUG
143#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
144#else
145#define MEMORY_DEBUG_STR ""
146#endif
147
Sachin Ahujadddd2632017-03-07 19:07:24 +0530148int wlan_start_ret_val;
149static DECLARE_COMPLETION(wlan_start_comp);
150static unsigned int dev_num = 1;
151static struct cdev wlan_hdd_state_cdev;
152static struct class *class;
153static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530154#ifndef MODULE
155static struct gwlan_loader *wlan_loader;
156static ssize_t wlan_boot_cb(struct kobject *kobj,
157 struct kobj_attribute *attr,
158 const char *buf, size_t count);
159struct gwlan_loader {
160 bool loaded_state;
161 struct kobject *boot_wlan_obj;
162 struct attribute_group *attr_group;
163};
164
165static struct kobj_attribute wlan_boot_attribute =
166 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
167
168static struct attribute *attrs[] = {
169 &wlan_boot_attribute.attr,
170 NULL,
171};
172
173#define MODULE_INITIALIZED 1
174#endif
175
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800176/* the Android framework expects this param even though we don't use it */
177#define BUF_LEN 20
178static char fwpath_buffer[BUF_LEN];
179static struct kparam_string fwpath = {
180 .string = fwpath_buffer,
181 .maxlen = BUF_LEN,
182};
183
184static char *country_code;
185static int enable_11d = -1;
186static int enable_dfs_chan_scan = -1;
187
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188/*
189 * spinlock for synchronizing asynchronous request/response
190 * (full description of use in wlan_hdd_main.h)
191 */
192DEFINE_SPINLOCK(hdd_context_lock);
193
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800194#define WLAN_NLINK_CESIUM 30
195
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530196static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197
198#define WOW_MAX_FILTER_LISTS 1
199#define WOW_MAX_FILTERS_PER_LIST 4
200#define WOW_MIN_PATTERN_SIZE 6
201#define WOW_MAX_PATTERN_SIZE 64
202
203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
204static const struct wiphy_wowlan_support wowlan_support_reg_init = {
205 .flags = WIPHY_WOWLAN_ANY |
206 WIPHY_WOWLAN_MAGIC_PKT |
207 WIPHY_WOWLAN_DISCONNECT |
208 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
209 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
210 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
211 WIPHY_WOWLAN_4WAY_HANDSHAKE |
212 WIPHY_WOWLAN_RFKILL_RELEASE,
213 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
214 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
215 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
216};
217#endif
218
219/* internal function declaration */
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530220struct notifier_block hdd_netdev_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800221
222struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700224static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225#endif
226
Sachin Ahujadddd2632017-03-07 19:07:24 +0530227void hdd_start_complete(int ret)
228{
229 wlan_start_ret_val = ret;
230
231 complete(&wlan_start_comp);
232}
233
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800234/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530235 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
236 * @hdd_ctx: pointer to hdd_context_t
237 *
238 * Return: none
239 */
Jeff Johnson590e2012016-10-05 16:16:24 -0700240static void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530241{
242 hdd_adapter_t *adapter;
243 hdd_adapter_list_node_t *adapter_node, *next;
244 QDF_STATUS status = QDF_STATUS_SUCCESS;
245
246 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
247 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
248 adapter = adapter_node->pAdapter;
249 if (NULL != adapter)
250 hdd_send_rps_ind(adapter);
251 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
252 adapter_node = next;
253 }
254}
255
256/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
258 * @vdev_id: vdev_id
259 * @action: action type
260 * @reason: reason type
261 *
262 * Return: none
263 */
264void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
265 enum netif_action_type action, enum netif_reason_type reason)
266{
Anurag Chouhan6d760662016-02-20 16:05:43 +0530267 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268 hdd_adapter_t *adapter;
269
270 if (!hdd_ctx) {
271 hdd_err("hdd ctx is NULL");
272 return;
273 }
274 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
275
276 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277}
278
279/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700280 * Store WLAN driver version and timestamp info in global variables such that
281 * crash debugger can extract them from driver debug symbol and crashdump for
282 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283 */
284uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;
Naveen Rawat93836252017-06-20 16:30:59 -0700285
286#ifndef BUILD_TIMESTAMP
287#define BUILD_TIMESTAMP ""
288#endif
Dustin Brownab482ac2017-06-09 17:00:44 -0700289uint8_t g_wlan_driver_timestamp[] = BUILD_TIMESTAMP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290
291/**
292 * hdd_device_mode_to_string() - return string conversion of device mode
293 * @device_mode: device mode
294 *
295 * This utility function helps log string conversion of device mode.
296 *
297 * Return: string conversion of device mode, if match found;
298 * "Unknown" otherwise.
299 */
300const char *hdd_device_mode_to_string(uint8_t device_mode)
301{
302 switch (device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -0800303 CASE_RETURN_STRING(QDF_STA_MODE);
304 CASE_RETURN_STRING(QDF_SAP_MODE);
305 CASE_RETURN_STRING(QDF_P2P_CLIENT_MODE);
306 CASE_RETURN_STRING(QDF_P2P_GO_MODE);
307 CASE_RETURN_STRING(QDF_FTM_MODE);
308 CASE_RETURN_STRING(QDF_IBSS_MODE);
309 CASE_RETURN_STRING(QDF_P2P_DEVICE_MODE);
310 CASE_RETURN_STRING(QDF_OCB_MODE);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -0700311 CASE_RETURN_STRING(QDF_NDI_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800312 default:
313 return "Unknown";
314 }
315}
316
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530317/**
318 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
319 * @adapter: HDD adapter
320 * @chan_number: Channel number
321 * @chan_bw: Bandwidth
322 *
323 * Checks if the given bandwidth is valid for the given channel number.
324 *
325 * Return: 0 for success, non-zero for failure
326 */
327int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
328 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800329 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530330{
331 uint8_t chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
332 uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN, i;
333 bool found = false;
334 tHalHandle hal;
335
336 hal = WLAN_HDD_GET_HAL_CTX(adapter);
337 if (!hal) {
338 hdd_err("Invalid HAL context");
339 return -EINVAL;
340 }
341
342 if (0 != sme_cfg_get_str(hal, WNI_CFG_VALID_CHANNEL_LIST, chan, &len)) {
343 hdd_err("No valid channel list");
344 return -EOPNOTSUPP;
345 }
346
347 for (i = 0; i < len; i++) {
348 if (chan[i] == chan_number) {
349 found = true;
350 break;
351 }
352 }
353
354 if (found == false) {
355 hdd_err("Channel not in driver's valid channel list");
356 return -EOPNOTSUPP;
357 }
358
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700359 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
360 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530361 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
362 return -EINVAL;
363 }
364
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700365 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530366 if (chan_bw == CH_WIDTH_80MHZ) {
367 hdd_err("BW80 not possible in 2.4GHz band");
368 return -EINVAL;
369 }
370 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
371 (chan_bw != CH_WIDTH_MAX)) {
372 hdd_err("Only BW20 possible on channel 14");
373 return -EINVAL;
374 }
375 }
376
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700377 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530378 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
379 (chan_bw != CH_WIDTH_MAX)) {
380 hdd_err("Only BW20 possible on channel 165");
381 return -EINVAL;
382 }
383 }
384
385 return 0;
386}
387
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388static int __hdd_netdev_notifier_call(struct notifier_block *nb,
389 unsigned long state, void *data)
390{
391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
392 struct netdev_notifier_info *dev_notif_info = data;
393 struct net_device *dev = dev_notif_info->dev;
394#else
395 struct net_device *dev = data;
396#endif
397 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
398 hdd_context_t *hdd_ctx;
399
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800400 ENTER_DEV(dev);
401
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 /* Make sure that this callback corresponds to our device. */
403 if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
404 return NOTIFY_DONE;
405
Samuel Ahnc9c48ca2016-09-19 15:46:36 +0530406 if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 (adapter->dev != dev)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700408 hdd_err("device adapter is not matching!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 return NOTIFY_DONE;
410 }
411
412 if (!dev->ieee80211_ptr) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700413 hdd_err("ieee80211_ptr is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 return NOTIFY_DONE;
415 }
416
417 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
418 if (NULL == hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800419 hdd_err("HDD Context Null Pointer");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530420 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 return NOTIFY_DONE;
422 }
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530423 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state())
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 return NOTIFY_DONE;
425
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800426 hdd_debug("%s New Net Device State = %lu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 dev->name, state);
428
429 switch (state) {
430 case NETDEV_REGISTER:
431 break;
432
433 case NETDEV_UNREGISTER:
434 break;
435
436 case NETDEV_UP:
437 sme_ch_avoid_update_req(hdd_ctx->hHal);
438 break;
439
440 case NETDEV_DOWN:
441 break;
442
443 case NETDEV_CHANGE:
444 if (true == adapter->isLinkUpSvcNeeded)
445 complete(&adapter->linkup_event_var);
446 break;
447
448 case NETDEV_GOING_DOWN:
449 if (adapter->scan_info.mScanPending != false) {
Abhishek Singh69ccb512017-04-25 11:58:16 +0530450 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
451 adapter->sessionId, INVALID_SCAN_ID, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 } else {
hqueaa33ee2017-05-04 17:56:35 +0800453 cds_flush_work(&adapter->scan_block_work);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800454 hdd_debug("Scan is not Pending from user");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 }
456 break;
457
458 default:
459 break;
460 }
461
462 return NOTIFY_DONE;
463}
464
465/**
466 * hdd_netdev_notifier_call() - netdev notifier callback function
467 * @nb: pointer to notifier block
468 * @state: state
469 * @ndev: ndev pointer
470 *
471 * Return: 0 on success, error number otherwise.
472 */
473static int hdd_netdev_notifier_call(struct notifier_block *nb,
474 unsigned long state,
475 void *ndev)
476{
477 int ret;
478
479 cds_ssr_protect(__func__);
480 ret = __hdd_netdev_notifier_call(nb, state, ndev);
481 cds_ssr_unprotect(__func__);
482
483 return ret;
484}
485
486struct notifier_block hdd_netdev_notifier = {
487 .notifier_call = hdd_netdev_notifier_call,
488};
489
490/* variable to hold the insmod parameters */
491static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800492
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530493static int con_mode_ftm;
494
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800495/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530498/**
499 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
500 * @ch_width: NL channel width
501 *
502 * Converts the NL channel width to the driver's internal representation
503 *
504 * Return: Converted channel width. In case of non matching NL channel width,
505 * CH_WIDTH_MAX will be returned.
506 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800507enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530508{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800509 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700510
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800511 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530512 switch (ch_width) {
513 case NL80211_CHAN_WIDTH_20_NOHT:
514 case NL80211_CHAN_WIDTH_20:
515 return CH_WIDTH_20MHZ;
516 case NL80211_CHAN_WIDTH_40:
517 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530518 case NL80211_CHAN_WIDTH_80:
519 return CH_WIDTH_80MHZ;
520 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800521 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
522 return CH_WIDTH_80P80MHZ;
523 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
524 return CH_WIDTH_160MHZ;
525 else
526 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530527 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800528 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
529 return CH_WIDTH_160MHZ;
530 else
531 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530532 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800533 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530534 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800535 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530536 default:
537 hdd_err("Invalid channel width %d, setting to default",
538 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800539 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530540 }
541}
542
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530543/* wlan_hdd_find_opclass() - Find operating class for a channel
544 * @hal: handler to HAL
545 * @channel: channel id
546 * @bw_offset: bandwidth offset
547 *
548 * Function invokes sme api to find the operating class
549 *
550 * Return: operating class
551 */
552uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
553 uint8_t bw_offset)
554{
555 uint8_t opclass = 0;
556
557 sme_get_opclass(hal, channel, bw_offset, &opclass);
558 return opclass;
559}
560
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800561/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530562 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530563 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 * @bitmask: Bitmask of log levels to be enabled
565 *
566 * Called immediately after the cfg.ini is read in order to configure
567 * the desired trace levels.
568 *
569 * Return: None
570 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530571int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530573 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530574 int qdf_print_idx = -1;
575 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 /*
577 * if the bitmask is the default value, then a bitmask was not
578 * specified in cfg.ini, so leave the logging level alone (it
579 * will remain at the "compiled in" default value)
580 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700581 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530582 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530584 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530586 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530587 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530588 QDF_TRACE_LEVEL_NONE, 0);
589
590 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530591 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 /* now cycle through the bitmask until all "set" bits are serviced */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530593 level = QDF_TRACE_LEVEL_FATAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 while (0 != bitmask) {
595 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530596 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530597 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530598 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530599 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700601
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 level++;
603 bitmask >>= 1;
604 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530605 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606}
607
608/**
Chris Guo1751acf2017-07-03 14:09:01 +0800609 * wlan_hdd_validate_context_in_loading() - check the HDD context in loading
610 * @hdd_ctx: HDD context pointer
611 *
612 * Return: 0 if the context is valid. Error code otherwise
613 */
614int wlan_hdd_validate_context_in_loading(hdd_context_t *hdd_ctx)
615{
616 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
617 hdd_info("%pS HDD context is Null", (void *)_RET_IP_);
618 return -ENODEV;
619 }
620
621 if (cds_is_driver_recovering()) {
622 hdd_info("%pS Recovery in Progress. State: 0x%x Ignore!!!",
623 (void *)_RET_IP_, cds_get_driver_state());
624 return -EAGAIN;
625 }
626
627 if (hdd_ctx->start_modules_in_progress ||
628 hdd_ctx->stop_modules_in_progress) {
629 hdd_info("%pS Start/Stop Modules in progress. Ignore!!!",
630 (void *)_RET_IP_);
631 return -EAGAIN;
632 }
633
634 return 0;
635}
636
637
638/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 * wlan_hdd_validate_context() - check the HDD context
640 * @hdd_ctx: HDD context pointer
641 *
642 * Return: 0 if the context is valid. Error code otherwise
643 */
644int wlan_hdd_validate_context(hdd_context_t *hdd_ctx)
645{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530647 hdd_err("%pS HDD context is Null", (void *)_RET_IP_);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648 return -ENODEV;
649 }
650
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800651 if (cds_is_driver_recovering()) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800652 hdd_debug("%pS Recovery in Progress. State: 0x%x Ignore!!!",
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530653 (void *)_RET_IP_, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 return -EAGAIN;
655 }
656
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800657 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800658 return -EAGAIN;
659 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530660
661 if (hdd_ctx->start_modules_in_progress ||
662 hdd_ctx->stop_modules_in_progress) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800663 hdd_debug("%pS Start/Stop Modules in progress. Ignore!!!",
Arun Khandavallia172c3e2016-08-26 17:33:13 +0530664 (void *)_RET_IP_);
665 return -EAGAIN;
666 }
667
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530668 if (cds_is_driver_in_bad_state()) {
669 hdd_debug("%pS driver in bad State: 0x%x Ignore!!!",
670 (void *)_RET_IP_, cds_get_driver_state());
671 return -ENODEV;
672 }
673
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 return 0;
675}
676
Dustin Brownf13b8c32017-05-19 17:23:08 -0700677int hdd_validate_adapter(hdd_adapter_t *adapter)
678{
679 if (!adapter) {
680 hdd_err("adapter is null");
681 return -EINVAL;
682 }
683
684 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
685 hdd_err("bad adapter magic: 0x%x (should be 0x%x)",
686 adapter->magic, WLAN_HDD_ADAPTER_MAGIC);
687 return -EINVAL;
688 }
689
690 if (!adapter->dev) {
691 hdd_err("adapter net_device is null");
692 return -EINVAL;
693 }
694
695 if (!(adapter->dev->flags & IFF_UP)) {
696 hdd_info("adapter net_device is not up");
697 return -EAGAIN;
698 }
699
700 if (adapter->sessionId == HDD_SESSION_ID_INVALID) {
701 hdd_info("adapter session is not open");
702 return -EAGAIN;
703 }
704
705 if (adapter->sessionId >= MAX_NUMBER_OF_ADAPTERS) {
706 hdd_err("bad adapter session Id: %u", adapter->sessionId);
707 return -EINVAL;
708 }
709
710 return 0;
711}
712
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800713/**
Arun Khandavallica892f62017-05-26 14:25:50 +0530714 * wlan_hdd_validate_modules_state() - Check modules status
715 * @hdd_ctx: HDD context pointer
716 *
717 * Check's the driver module's state and returns true if the
718 * modules are enabled returns false if modules are closed.
719 *
720 * Return: True if modules are enabled or false.
721 */
722bool wlan_hdd_validate_modules_state(hdd_context_t *hdd_ctx)
723{
724 mutex_lock(&hdd_ctx->iface_change_lock);
725 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
726 mutex_unlock(&hdd_ctx->iface_change_lock);
727 hdd_notice("Modules not enabled, Present status: %d",
728 hdd_ctx->driver_status);
729 return false;
730 }
731 mutex_unlock(&hdd_ctx->iface_change_lock);
732 return true;
733}
734
735/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
737 * @hdd_adapter_t Hdd adapter.
738 *
739 * This function sets the IBSS power save config parameters to WMA
740 * which will send it to firmware if FW supports IBSS power save
741 * before vdev start.
742 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530743 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744 * on failure.
745 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530746QDF_STATUS hdd_set_ibss_power_save_params(hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747{
748 int ret;
749 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
750
751 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700752 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530753 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754 }
755
Naveen Rawat247a8682017-06-05 15:00:31 -0700756 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
758 hdd_ctx->config->ibssATIMWinSize,
759 VDEV_CMD);
760 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700761 hdd_err("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530762 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763 }
764
Naveen Rawat247a8682017-06-05 15:00:31 -0700765 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
767 hdd_ctx->config->isIbssPowerSaveAllowed,
768 VDEV_CMD);
769 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700770 hdd_err("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d",
771 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530772 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 }
774
Naveen Rawat247a8682017-06-05 15:00:31 -0700775 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
777 hdd_ctx->config->
778 isIbssPowerCollapseAllowed, VDEV_CMD);
779 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700780 hdd_err("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d",
781 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530782 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 }
784
Naveen Rawat247a8682017-06-05 15:00:31 -0700785 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
787 hdd_ctx->config->isIbssAwakeOnTxRx,
788 VDEV_CMD);
789 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700790 hdd_err("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530791 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 }
793
Naveen Rawat247a8682017-06-05 15:00:31 -0700794 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
796 hdd_ctx->config->ibssInactivityCount,
797 VDEV_CMD);
798 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700799 hdd_err("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530800 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 }
802
Naveen Rawat247a8682017-06-05 15:00:31 -0700803 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
805 hdd_ctx->config->ibssTxSpEndInactivityTime,
806 VDEV_CMD);
807 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700808 hdd_err("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d",
809 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530810 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 }
812
Naveen Rawat247a8682017-06-05 15:00:31 -0700813 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
815 hdd_ctx->config->ibssPsWarmupTime,
816 VDEV_CMD);
817 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700818 hdd_err("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d",
819 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530820 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 }
822
Naveen Rawat247a8682017-06-05 15:00:31 -0700823 ret = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
825 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
826 VDEV_CMD);
827 if (0 != ret) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -0700828 hdd_err("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d",
829 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530830 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 }
832
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530833 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834}
835
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836#define INTF_MACADDR_MASK 0x7
837
838/**
839 * hdd_update_macaddr() - update mac address
840 * @config: hdd configuration
841 * @hw_macaddr: mac address
842 *
843 * Mac address for multiple virtual interface is found as following
844 * i) The mac address of the first interface is just the actual hw mac address.
845 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
846 * define the mac address for the remaining interfaces and locally
847 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
848 * supported virtual interfaces, right now this is 0x07 (meaning 8
849 * interface).
850 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
851 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
852 *
853 * Return: None
854 */
855void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530856 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800857{
858 int8_t i;
859 uint8_t macaddr_b3, tmp_br3;
860
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530861 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530862 QDF_MAC_ADDR_SIZE);
863 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530864 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530865 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 macaddr_b3 = config->intfMacAddr[i].bytes[3];
867 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
868 INTF_MACADDR_MASK;
869 macaddr_b3 += tmp_br3;
870
871 /* XOR-ing bit-24 of the mac address. This will give enough
872 * mac address range before collision
873 */
874 macaddr_b3 ^= (1 << 7);
875
876 /* Set locally administered bit */
877 config->intfMacAddr[i].bytes[0] |= 0x02;
878 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800879 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 MAC_ADDRESS_STR, i,
881 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
882 }
883}
884
885static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
886 struct wma_tgt_services *cfg)
887{
888 struct hdd_config *config = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889
890 /* Set up UAPSD */
891 config->apUapsdEnabled &= cfg->uapsd;
892
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800893 /* 11AX mode support */
894 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
895 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
896 config->dot11Mode = eHDD_DOT11_MODE_11ac;
897
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898 /* 11AC mode support */
899 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
900 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
901 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902
903 /* ARP offload: override user setting if invalid */
904 config->fhostArpOffload &= cfg->arp_offload;
905
906#ifdef FEATURE_WLAN_SCAN_PNO
907 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -0800908 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 if (cfg->pno_offload)
910 config->PnoOffload = true;
911#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912#ifdef FEATURE_WLAN_TDLS
913 config->fEnableTDLSSupport &= cfg->en_tdls;
Manjeet Singhfdd2ac72016-09-02 18:11:43 +0530914 config->fEnableTDLSOffChannel = config->fEnableTDLSOffChannel &&
915 cfg->en_tdls_offchan;
916 config->fEnableTDLSBufferSta = config->fEnableTDLSBufferSta &&
917 cfg->en_tdls_uapsd_buf_sta;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700918 if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919 config->fEnableTDLSSleepSta = true;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700920 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800921 config->fEnableTDLSSleepSta = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800922#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923#ifdef WLAN_FEATURE_ROAM_OFFLOAD
924 config->isRoamOffloadEnabled &= cfg->en_roam_offload;
925#endif
Krishna Kumaar Natarajan052c6e62015-09-28 15:32:55 -0700926 sme_update_tgt_services(hdd_ctx->hHal, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927
928}
929
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700930/**
931 * hdd_update_vdev_nss() - sets the vdev nss
932 * @hdd_ctx: HDD context
933 *
934 * Sets the Nss per vdev type based on INI
935 *
936 * Return: None
937 */
938static void hdd_update_vdev_nss(hdd_context_t *hdd_ctx)
939{
940 struct hdd_config *cfg_ini = hdd_ctx->config;
941 uint8_t max_supp_nss = 1;
942
Naveen Rawat10b1c152017-01-18 11:16:06 -0800943 if (cfg_ini->enable2x2 && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700944 max_supp_nss = 2;
945
946 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
947 cfg_ini->vdev_type_nss_2g, eCSR_BAND_24);
948
949 sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
950 cfg_ini->vdev_type_nss_5g, eCSR_BAND_5G);
951}
952
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +0530953/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +0530954 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
955 * @hdd_ctx: HDD context
956 *
957 * Updates wiphy vhtcap fields
958 *
959 * Return: None
960 */
961static void hdd_update_wiphy_vhtcap(hdd_context_t *hdd_ctx)
962{
963 struct ieee80211_supported_band *band_5g =
964 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
965 uint32_t val;
966
967 if (!band_5g) {
968 hdd_debug("5GHz band disabled, skipping capability population");
969 return;
970 }
971
972 val = hdd_ctx->config->txBFCsnValue;
973 band_5g->vht_cap.cap |= (val << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
974
975 val = NUM_OF_SOUNDING_DIMENSIONS;
976 band_5g->vht_cap.cap |=
977 (val << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
978
979 hdd_info("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
980 band_5g->vht_cap.cap, hdd_ctx->config->txBFCsnValue, val);
981}
982
983/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +0530984 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
985 * @hdd_ctx: HDD context
986 *
987 * Sets the DBS capability as per INI and firmware capability
988 *
989 * Return: None
990 */
991static void hdd_update_hw_dbs_capable(hdd_context_t *hdd_ctx)
992{
993 struct hdd_config *cfg_ini = hdd_ctx->config;
994 uint8_t hw_dbs_capable = 0;
995
996 if ((!cfg_ini->dual_mac_feature_disable)
Archana Ramachandran62886ce2017-03-24 14:46:32 -0700997 && policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +0530998 hw_dbs_capable = 1;
999
1000 sme_update_hw_dbs_capable(hdd_ctx->hHal, hw_dbs_capable);
1001}
1002
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
1004 struct wma_tgt_ht_cap *cfg)
1005{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301006 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 uint32_t value, val32;
1008 uint16_t val16;
1009 struct hdd_config *pconfig = hdd_ctx->config;
1010 tSirMacHTCapabilityInfo *phtCapInfo;
1011 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
1012 uint8_t enable_tx_stbc;
1013
1014 /* check and update RX STBC */
1015 if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
1016 pconfig->enableRxSTBC = cfg->ht_rx_stbc;
1017
1018 /* get the MPDU density */
1019 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);
1020
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301021 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001022 hdd_err("could not get MPDU DENSITY");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023 value = 0;
1024 }
1025
1026 /*
1027 * MPDU density:
1028 * override user's setting if value is larger
1029 * than the one supported by target
1030 */
1031 if (value > cfg->mpdu_density) {
1032 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
1033 cfg->mpdu_density);
1034
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301035 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001036 hdd_err("could not set MPDU DENSITY to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037 }
1038
1039 /* get the HT capability info */
1040 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301041 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001042 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 return;
1044 }
1045 val16 = (uint16_t) val32;
1046 phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;
1047
1048 /* Set the LDPC capability */
1049 phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;
1050
1051 if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
1052 pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;
1053
1054 if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
1055 pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;
1056
1057 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1058 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1059
1060 enable_tx_stbc = pconfig->enableTxSTBC;
1061
1062 if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
1063 pconfig->enable2x2 = 1;
1064 } else {
1065 pconfig->enable2x2 = 0;
1066 enable_tx_stbc = 0;
1067
1068 /* 1x1 */
1069 /* Update Rx Highest Long GI data Rate */
1070 if (sme_cfg_set_int(hdd_ctx->hHal,
1071 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001072 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301073 == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001074 hdd_err("Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075 }
1076
1077 /* Update Tx Highest Long GI data Rate */
1078 if (sme_cfg_set_int
1079 (hdd_ctx->hHal,
1080 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001081 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301082 QDF_STATUS_E_FAILURE) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001083 hdd_err("VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084 }
1085 }
1086 if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
1087 enable_tx_stbc = 0;
1088 phtCapInfo->txSTBC = enable_tx_stbc;
1089
1090 val32 = val16;
1091 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301092 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001093 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001094#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
1095 value = SIZE_OF_SUPPORTED_MCS_SET;
1096 if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301097 &value) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001098 hdd_debug("Read MCS rate set");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099
1100 if (pconfig->enable2x2) {
1101 for (value = 0; value < cfg->num_rf_chains; value++)
1102 mcs_set[value] =
1103 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1104
1105 status =
1106 sme_cfg_set_str(hdd_ctx->hHal,
1107 WNI_CFG_SUPPORTED_MCS_SET,
1108 mcs_set,
1109 SIZE_OF_SUPPORTED_MCS_SET);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301110 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001111 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001112 }
1113 }
1114#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1115}
1116
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
1118 struct wma_tgt_vht_cap *cfg)
1119{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 uint32_t value = 0;
1122 struct hdd_config *pconfig = hdd_ctx->config;
1123 struct wiphy *wiphy = hdd_ctx->wiphy;
1124 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001125 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001126 uint32_t temp = 0;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001127 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128
Dustin Brown5e06bd32016-10-04 12:49:10 -07001129 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001130 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001131 return;
1132 }
1133
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 /* Get the current MPDU length */
1135 status =
1136 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
1137 &value);
1138
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301139 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001140 hdd_err("could not get MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001141 value = 0;
1142 }
1143
1144 /*
1145 * VHT max MPDU length:
1146 * override if user configured value is too high
1147 * that the target cannot support
1148 */
1149 if (value > cfg->vht_max_mpdu) {
1150 status = sme_cfg_set_int(hdd_ctx->hHal,
1151 WNI_CFG_VHT_MAX_MPDU_LENGTH,
1152 cfg->vht_max_mpdu);
1153
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001154 if (status == QDF_STATUS_E_FAILURE)
1155 hdd_err("could not set VHT MAX MPDU LENGTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 }
1157
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001158 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
1159 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1160
1161 if (pconfig->enable2x2)
1162 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1163
1164 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) ==
1165 QDF_STATUS_E_FAILURE) {
1166 hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM");
1167 }
1168
1169 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
1170 temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
1171 if (pconfig->enable2x2)
1172 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
1173
1174 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) ==
1175 QDF_STATUS_E_FAILURE) {
1176 hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM");
1177 }
1178
1179 sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
1180 temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
1181 if (pconfig->enable2x2)
1182 temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
1183
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001184 hdd_debug("vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001185 pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
1186
1187 if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) ==
1188 QDF_STATUS_E_FAILURE) {
1189 hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM");
1190 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001191 /* Get the current RX LDPC setting */
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001192 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001193 &value);
1194
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001196 hdd_err("could not get VHT LDPC CODING CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 value = 0;
1198 }
1199
1200 /* Set the LDPC capability */
1201 if (value && !cfg->vht_rx_ldpc) {
1202 status = sme_cfg_set_int(hdd_ctx->hHal,
1203 WNI_CFG_VHT_LDPC_CODING_CAP,
1204 cfg->vht_rx_ldpc);
1205
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001206 if (status == QDF_STATUS_E_FAILURE)
1207 hdd_err("could not set VHT LDPC CODING CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208 }
1209
1210 /* Get current GI 80 value */
1211 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
1212 &value);
1213
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301214 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001215 hdd_err("could not get SHORT GI 80MHZ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 value = 0;
1217 }
1218
1219 /* set the Guard interval 80MHz */
1220 if (value && !cfg->vht_short_gi_80) {
1221 status = sme_cfg_set_int(hdd_ctx->hHal,
1222 WNI_CFG_VHT_SHORT_GI_80MHZ,
1223 cfg->vht_short_gi_80);
1224
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001225 if (status == QDF_STATUS_E_FAILURE)
1226 hdd_err("could not set SHORT GI 80MHZ to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001227 }
1228
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001229 /* Get VHT TX STBC cap */
1230 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);
1231
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301232 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001233 hdd_err("could not get VHT TX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 value = 0;
1235 }
1236
1237 /* VHT TX STBC cap */
1238 if (value && !cfg->vht_tx_stbc) {
1239 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
1240 cfg->vht_tx_stbc);
1241
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001242 if (status == QDF_STATUS_E_FAILURE)
1243 hdd_err("could not set the VHT TX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244 }
1245
1246 /* Get VHT RX STBC cap */
1247 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);
1248
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301249 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001250 hdd_err("could not get VHT RX STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001251 value = 0;
1252 }
1253
1254 /* VHT RX STBC cap */
1255 if (value && !cfg->vht_rx_stbc) {
1256 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
1257 cfg->vht_rx_stbc);
1258
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001259 if (status == QDF_STATUS_E_FAILURE)
1260 hdd_err("could not set the VHT RX STBC to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001261 }
1262
1263 /* Get VHT SU Beamformer cap */
1264 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1265 &value);
1266
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301267 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001268 hdd_err("could not get VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 value = 0;
1270 }
1271
1272 /* set VHT SU Beamformer cap */
1273 if (value && !cfg->vht_su_bformer) {
1274 status = sme_cfg_set_int(hdd_ctx->hHal,
1275 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1276 cfg->vht_su_bformer);
1277
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001278 if (status == QDF_STATUS_E_FAILURE)
1279 hdd_err("could not set VHT SU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 }
1281
1282 /* check and update SU BEAMFORMEE capabality */
1283 if (pconfig->enableTxBF && !cfg->vht_su_bformee)
1284 pconfig->enableTxBF = cfg->vht_su_bformee;
1285
1286 status = sme_cfg_set_int(hdd_ctx->hHal,
1287 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1288 pconfig->enableTxBF);
1289
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001290 if (status == QDF_STATUS_E_FAILURE)
1291 hdd_err("could not set VHT SU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292
1293 /* Get VHT MU Beamformer cap */
1294 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1295 &value);
1296
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301297 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001298 hdd_err("could not get VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 value = 0;
1300 }
1301
1302 /* set VHT MU Beamformer cap */
1303 if (value && !cfg->vht_mu_bformer) {
1304 status = sme_cfg_set_int(hdd_ctx->hHal,
1305 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1306 cfg->vht_mu_bformer);
1307
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001308 if (status == QDF_STATUS_E_FAILURE)
1309 hdd_err("could not set the VHT MU BEAMFORMER CAP to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 }
1311
1312 /* Get VHT MU Beamformee cap */
1313 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1314 &value);
1315
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301316 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001317 hdd_err("could not get VHT MU BEAMFORMEE CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001318 value = 0;
1319 }
1320
1321 /* set VHT MU Beamformee cap */
1322 if (value && !cfg->vht_mu_bformee) {
1323 status = sme_cfg_set_int(hdd_ctx->hHal,
1324 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1325 cfg->vht_mu_bformee);
1326
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001327 if (status == QDF_STATUS_E_FAILURE)
1328 hdd_err("could not set VHT MU BEAMFORMER CAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 }
1330
1331 /* Get VHT MAX AMPDU Len exp */
1332 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1333 &value);
1334
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301335 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001336 hdd_err("could not get VHT AMPDU LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001337 value = 0;
1338 }
1339
1340 /*
1341 * VHT max AMPDU len exp:
1342 * override if user configured value is too high
1343 * that the target cannot support.
1344 * Even though Rome publish ampdu_len=7, it can
1345 * only support 4 because of some h/w bug.
1346 */
1347
1348 if (value > cfg->vht_max_ampdu_len_exp) {
1349 status = sme_cfg_set_int(hdd_ctx->hHal,
1350 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1351 cfg->vht_max_ampdu_len_exp);
1352
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001353 if (status == QDF_STATUS_E_FAILURE)
1354 hdd_err("could not set the VHT AMPDU LEN EXP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 }
1356
1357 /* Get VHT TXOP PS CAP */
1358 status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);
1359
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301360 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001361 hdd_err("could not get VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 value = 0;
1363 }
1364
1365 /* set VHT TXOP PS cap */
1366 if (value && !cfg->vht_txop_ps) {
1367 status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
1368 cfg->vht_txop_ps);
1369
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001370 if (status == QDF_STATUS_E_FAILURE)
1371 hdd_err("could not set the VHT TXOP PS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372 }
1373
1374 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1375 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1376 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1377 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1378 else
1379 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1380
1381
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001382 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
1383 status = sme_cfg_set_int(hdd_ctx->hHal,
1384 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1385 VHT_CAP_160_AND_80P80_SUPP);
1386 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001387 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 band_5g->vht_cap.cap |=
1389 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001390 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1391 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
1392 status = sme_cfg_set_int(hdd_ctx->hHal,
1393 WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
1394 VHT_CAP_160_SUPP);
1395 if (status == QDF_STATUS_E_FAILURE)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001396 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397 band_5g->vht_cap.cap |=
1398 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001399 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1400 }
1401 pconfig->vhtChannelWidth = QDF_MIN(pconfig->vhtChannelWidth,
1402 ch_width);
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301403 /* Get the current GI 160 value */
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001404 status = sme_cfg_get_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301405 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001406 &value);
1407 if (status != QDF_STATUS_SUCCESS) {
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301408 hdd_err("could not get GI 80 & 160");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001409 value = 0;
1410 }
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301411 /* set the Guard interval 160MHz */
1412 if (value && !cfg->vht_short_gi_160) {
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001413 status = sme_cfg_set_int(hdd_ctx->hHal,
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301414 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
1415 cfg->vht_short_gi_160);
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001416
1417 if (status == QDF_STATUS_E_FAILURE)
Ashish Kumar Dhanotiya7ebf5692017-04-12 20:04:47 +05301418 hdd_err("failed to set SHORT GI 160MHZ");
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001419 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001420
1421 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC)
1422 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1423
1424 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1425 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1426 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1427 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1428
1429 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1430 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1431
1432 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1433 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1434 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1435 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1436 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1437 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1438
1439 band_5g->vht_cap.cap |=
1440 (cfg->vht_max_ampdu_len_exp <<
1441 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1442
1443 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1444 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1445 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1446 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1447 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1448 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1449 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1450 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1451
1452 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1453 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1454
1455}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001457/**
1458 * hdd_generate_macaddr_auto() - Auto-generate mac address
1459 * @hdd_ctx: Pointer to the HDD context
1460 *
1461 * Auto-generate mac address using device serial number.
1462 * Keep the first 3 bytes of OUI as before and replace
1463 * the last 3 bytes with the lower 3 bytes of serial number.
1464 *
1465 * Return: 0 for success
1466 * Non zero failure code for errors
1467 */
1468static int hdd_generate_macaddr_auto(hdd_context_t *hdd_ctx)
1469{
1470 unsigned int serialno = 0;
1471 struct qdf_mac_addr mac_addr = {
1472 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1473 };
1474
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001475 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001476 if (serialno == 0)
1477 return -EINVAL;
1478
1479 serialno &= 0x00ffffff;
1480
1481 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1482 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1483 mac_addr.bytes[5] = serialno & 0xff;
1484
1485 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1486 return 0;
1487}
1488
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301489/**
1490 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1491 * configuration to cfg_ini in HDD
1492 * @hdd_ctx: Pointer to hdd_ctx
1493 * @cfg: target configuration
1494 *
1495 * Return: None
1496 */
1497#ifdef FEATURE_WLAN_RA_FILTERING
1498static void hdd_update_ra_rate_limit(hdd_context_t *hdd_ctx,
1499 struct wma_tgt_cfg *cfg)
1500{
1501 hdd_ctx->config->IsRArateLimitEnabled = cfg->is_ra_rate_limit_enabled;
1502}
1503#else
1504static void hdd_update_ra_rate_limit(hdd_context_t *hdd_ctx,
1505 struct wma_tgt_cfg *cfg)
1506{
1507}
1508#endif
1509
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510void hdd_update_tgt_cfg(void *context, void *param)
1511{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001512 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001513 hdd_context_t *hdd_ctx = (hdd_context_t *) context;
1514 struct wma_tgt_cfg *cfg = param;
1515 uint8_t temp_band_cap;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001516 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301517 uint8_t antenna_mode;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301518
Yue Mae3e86ab2017-05-08 10:48:24 -07001519 /* Reuse same pdev for module start/stop or SSR */
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07001520 if ((hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) ||
Yue Mae3e86ab2017-05-08 10:48:24 -07001521 !cds_is_driver_loading()) {
1522 hdd_err("Reuse pdev for module start/stop or SSR");
1523 /* Restore pdev to MAC/WMA contexts */
1524 sme_store_pdev(hdd_ctx->hHal, hdd_ctx->hdd_pdev);
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07001525 } else {
1526 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1527 if (ret) {
1528 hdd_err("pdev creation fails!");
1529 QDF_BUG(0);
1530 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301531 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001532
Naveen Rawat64e477e2016-05-20 10:34:56 -07001533 if (cds_cfg) {
1534 if (hdd_ctx->config->enable_sub_20_channel_width !=
1535 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
1536 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1537 cds_cfg->sub_20_channel_width =
1538 WLAN_SUB_20_CH_WIDTH_NONE;
1539 } else {
1540 cds_cfg->sub_20_channel_width =
1541 hdd_ctx->config->enable_sub_20_channel_width;
1542 }
1543 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544
1545 /* first store the INI band capability */
1546 temp_band_cap = hdd_ctx->config->nBandCapability;
1547
1548 hdd_ctx->config->nBandCapability = cfg->band_cap;
1549
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001550 /*
1551 * now overwrite the target band capability with INI
1552 * setting if INI setting is a subset
1553 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554
1555 if ((hdd_ctx->config->nBandCapability == eCSR_BAND_ALL) &&
1556 (temp_band_cap != eCSR_BAND_ALL))
1557 hdd_ctx->config->nBandCapability = temp_band_cap;
1558 else if ((hdd_ctx->config->nBandCapability != eCSR_BAND_ALL) &&
1559 (temp_band_cap != eCSR_BAND_ALL) &&
1560 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001561 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001562 }
1563
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301564 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565 hdd_ctx->reg.reg_domain = cfg->reg_domain;
1566 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
1567 }
1568
1569 /* This can be extended to other configurations like ht, vht cap... */
1570
Anurag Chouhanc5548422016-02-24 18:33:27 +05301571 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001573 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001574 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001575 static struct qdf_mac_addr default_mac_addr = {
1576 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
1577 };
1578 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
1579 &default_mac_addr)) {
1580 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
1581 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
1582 MAC_ADDRESS_STR,
1583 MAC_ADDR_ARRAY(hdd_ctx->config->
1584 intfMacAddr[0].bytes));
1585 } else {
1586 hdd_err("Invalid MAC passed from target, using MAC from ini file "
1587 MAC_ADDRESS_STR,
1588 MAC_ADDR_ARRAY(hdd_ctx->config->
1589 intfMacAddr[0].bytes));
1590 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07001591 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 }
1593
1594 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07001595 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596
1597 hdd_ctx->max_intf_count = cfg->max_intf_count;
1598
Jeff Johnsonc875e242016-09-23 18:12:34 -07001599 hdd_lpass_target_config(hdd_ctx, cfg);
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07001600 hdd_green_ap_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001601
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
1603 hdd_update_tgt_services(hdd_ctx, &cfg->services);
1604
1605 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
1606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07001608 if (cfg->services.en_11ax) {
1609 hdd_info("11AX: 11ax is enabled - update HDD config");
1610 hdd_update_tgt_he_cap(hdd_ctx, cfg);
1611 }
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07001612
1613 hdd_update_vdev_nss(hdd_ctx);
1614
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301615 hdd_update_hw_dbs_capable(hdd_ctx);
1616
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08001617 hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
Krunal Sonie3531942016-04-12 17:43:53 -07001618 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001619 hdd_debug("fine_time_meas_cap: 0x%x",
Krishna Kumaar Natarajan1ae49112015-11-24 21:43:22 -08001620 hdd_ctx->config->fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001621
Nitesh Shahe50711f2017-04-26 16:30:45 +05301622 antenna_mode = (hdd_ctx->config->enable2x2 == 0x01) ?
1623 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
1624 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001625 hdd_debug("Init current antenna mode: %d",
Archana Ramachandran393f3792015-11-13 17:13:21 -08001626 hdd_ctx->current_antenna_mode);
1627
Rajeev Kumardd3bc602016-08-16 14:21:05 -07001628 hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
1629 hdd_ctx->config->bpf_packet_filter_enable);
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301630 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301631
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05301632 if ((hdd_ctx->config->txBFCsnValue >
1633 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
1634 !cfg->tx_bfee_8ss_enabled)
1635 hdd_ctx->config->txBFCsnValue =
1636 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF;
1637
1638 if (sme_cfg_set_int(hdd_ctx->hHal,
1639 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
1640 hdd_ctx->config->txBFCsnValue) == QDF_STATUS_E_FAILURE)
1641 hdd_err("fw update WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED to CFG fails");
1642
1643
1644 hdd_debug("Target BPF %d Host BPF %d 8ss fw support %d txBFCsnValue %d",
1645 cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable,
1646 cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301647
1648 /*
1649 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
1650 */
1651 hdd_update_wiphy_vhtcap(hdd_ctx);
Arun Khandavallid454d422016-08-17 12:47:05 +05301652 /*
1653 * If BPF is enabled, maxWowFilters set to WMA_STA_WOW_DEFAULT_PTRN_MAX
1654 * because we need atleast WMA_STA_WOW_DEFAULT_PTRN_MAX free slots to
1655 * configure the STA mode wow pattern.
1656 */
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301657 if (hdd_ctx->bpf_enabled)
Arun Khandavallid454d422016-08-17 12:47:05 +05301658 hdd_ctx->config->maxWoWFilters = WMA_STA_WOW_DEFAULT_PTRN_MAX;
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301659
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05301660 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
1661
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07001662 /* Configure NAN datapath features */
1663 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07001664 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665}
1666
Arif Hussaincd151632017-02-11 16:57:19 -08001667bool hdd_dfs_indicate_radar(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
1670 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301671 QDF_STATUS status;
Manishekar Chandrasekaran11ecd552016-08-31 12:44:05 +05301672 hdd_ap_ctx_t *ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673
Arif Hussaincd151632017-02-11 16:57:19 -08001674 if (!hdd_ctx || hdd_ctx->config->disableDFSChSwitch) {
1675 hdd_info("skip tx block hdd_ctx=%p, disableDFSChSwitch=%d",
1676 hdd_ctx, hdd_ctx->config->disableDFSChSwitch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301677 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08001678 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679
Arif Hussaincd151632017-02-11 16:57:19 -08001680 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
1681 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
1682 adapter = adapterNode->pAdapter;
1683 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
1684
1685 if ((QDF_SAP_MODE == adapter->device_mode ||
1686 QDF_P2P_GO_MODE == adapter->device_mode) &&
1687 (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
1688 ap_ctx->operatingChannel))) {
1689 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
1690 true;
1691 hdd_info("tx blocked for session: %d",
1692 adapter->sessionId);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301693 }
Arif Hussaincd151632017-02-11 16:57:19 -08001694 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
1695 adapterNode = pNext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001696 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301697
1698 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700
1701/**
1702 * hdd_is_valid_mac_address() - validate MAC address
1703 * @pMacAddr: Pointer to the input MAC address
1704 *
1705 * This function validates whether the given MAC address is valid or not
1706 * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
1707 * where X is the hexa decimal digit character and separated by ':'
1708 * This algorithm works even if MAC address is not separated by ':'
1709 *
1710 * This code checks given input string mac contains exactly 12 hexadecimal
1711 * digits and a separator colon : appears in the input string only after
1712 * an even number of hex digits.
1713 *
1714 * Return: 1 for valid and 0 for invalid
1715 */
1716bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
1717{
1718 int xdigit = 0;
1719 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001720
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 while (*pMacAddr) {
1722 if (isxdigit(*pMacAddr)) {
1723 xdigit++;
1724 } else if (':' == *pMacAddr) {
1725 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
1726 break;
1727
1728 ++separator;
1729 } else {
1730 /* Invalid MAC found */
1731 return 0;
1732 }
1733 ++pMacAddr;
1734 }
1735 return xdigit == 12 && (separator == 5 || separator == 0);
1736}
1737
1738/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05301739 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
1740 * @dev: Handle to struct net_device to be updated.
1741 *
1742 * Return: None
1743 */
1744static void hdd_mon_mode_ether_setup(struct net_device *dev)
1745{
1746 dev->header_ops = NULL;
1747 dev->type = ARPHRD_IEEE80211_RADIOTAP;
1748 dev->hard_header_len = ETH_HLEN;
1749 dev->mtu = ETH_DATA_LEN;
1750 dev->addr_len = ETH_ALEN;
1751 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
1752 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
1753 dev->priv_flags |= IFF_TX_SKB_SHARING;
1754
1755 memset(dev->broadcast, 0xFF, ETH_ALEN);
1756}
1757
1758/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07001759 * __hdd__mon_open() - HDD Open function
1760 * @dev: Pointer to net_device structure
1761 *
1762 * This is called in response to ifconfig up
1763 *
1764 * Return: 0 for success; non-zero for failure
1765 */
1766static int __hdd_mon_open(struct net_device *dev)
1767{
1768 int ret;
1769
1770 ENTER_DEV(dev);
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05301771 hdd_mon_mode_ether_setup(dev);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07001772 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07001773
1774 if (!ret)
1775 ret = hdd_enable_monitor_mode(dev);
1776
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07001777 return ret;
1778}
1779
1780/**
1781 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
1782 * @dev: Pointer to net_device structure
1783 *
1784 * This is called in response to ifconfig up
1785 *
1786 * Return: 0 for success; non-zero for failure
1787 */
Jeff Johnson590e2012016-10-05 16:16:24 -07001788static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07001789{
1790 int ret;
1791
1792 cds_ssr_protect(__func__);
1793 ret = __hdd_mon_open(dev);
1794 cds_ssr_unprotect(__func__);
1795
1796 return ret;
1797}
1798
1799/**
Arun Khandavallifae92942016-08-01 13:31:08 +05301800 * hdd_start_adapter() - Wrapper function for device specific adapter
1801 * @adapter: pointer to HDD adapter
1802 *
1803 * This function is called to start the device specific adapter for
1804 * the mode passed in the adapter's device_mode.
1805 *
1806 * Return: 0 for success; non-zero for failure
1807 */
1808int hdd_start_adapter(hdd_adapter_t *adapter)
1809{
1810
1811 int ret;
1812 enum tQDF_ADAPTER_MODE device_mode = adapter->device_mode;
1813
1814 ENTER_DEV(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001815 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05301816
1817 switch (device_mode) {
1818 case QDF_P2P_CLIENT_MODE:
1819 case QDF_P2P_DEVICE_MODE:
1820 case QDF_OCB_MODE:
1821 case QDF_STA_MODE:
1822 case QDF_MONITOR_MODE:
1823 ret = hdd_start_station_adapter(adapter);
1824 if (ret)
1825 goto err_start_adapter;
1826 break;
1827 case QDF_P2P_GO_MODE:
1828 case QDF_SAP_MODE:
1829 ret = hdd_start_ap_adapter(adapter);
1830 if (ret)
1831 goto err_start_adapter;
1832 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05301833 case QDF_IBSS_MODE:
1834 /*
1835 * For IBSS interface is initialized as part of
1836 * hdd_init_station_mode()
1837 */
1838 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05301839 case QDF_FTM_MODE:
1840 ret = hdd_start_ftm_adapter(adapter);
1841 if (ret)
1842 goto err_start_adapter;
1843 break;
1844 default:
1845 hdd_err("Invalid session type %d", device_mode);
1846 QDF_ASSERT(0);
1847 goto err_start_adapter;
1848 }
1849 if (hdd_set_fw_params(adapter))
1850 hdd_err("Failed to set the FW params for the adapter!");
1851
1852 /*
1853 * Action frame registered in one adapter which will
1854 * applicable to all interfaces
1855 */
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05301856 ret = wlan_hdd_cfg80211_register_frames(adapter);
1857 if (ret < 0) {
1858 hdd_err("Failed to register frames - ret %d", ret);
1859 goto err_start_adapter;
1860 }
1861
Arun Khandavallifae92942016-08-01 13:31:08 +05301862 EXIT();
1863 return 0;
1864err_start_adapter:
1865 return -EINVAL;
1866}
1867
1868/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05301869 * hdd_enable_power_management() - API to Enable Power Management
1870 *
1871 * API invokes Bus Interface Layer power management functionality
1872 *
1873 * Return: None
1874 */
1875static void hdd_enable_power_management(void)
1876{
1877 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1878
1879 if (!hif_ctx) {
1880 hdd_err("Bus Interface Context is Invalid");
1881 return;
1882 }
1883
1884 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
1885}
1886
1887/**
1888 * hdd_disable_power_management() - API to disable Power Management
1889 *
1890 * API disable Bus Interface Layer Power management functionality
1891 *
1892 * Return: None
1893 */
1894static void hdd_disable_power_management(void)
1895{
1896 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1897
1898 if (!hif_ctx) {
1899 hdd_err("Bus Interface Context is Invalid");
1900 return;
1901 }
1902
1903 hif_disable_power_management(hif_ctx);
1904}
1905
1906/**
Arunk Khandavalli67193d52017-02-21 12:03:48 +05301907 * hdd_update_hw_sw_info() - API to update the HW/SW information
1908 *
1909 * API to update the HW and SW information in the driver
1910 *
1911 * Return: None
1912 */
1913static void hdd_update_hw_sw_info(hdd_context_t *hdd_ctx)
1914{
1915 void *hif_sc;
1916
1917 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
1918 if (!hif_sc) {
1919 hdd_err("HIF context is NULL");
1920 return;
1921 }
1922
1923 /*
1924 * target hw version/revision would only be retrieved after firmware
1925 * download
1926 */
1927 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
1928 &hdd_ctx->target_hw_revision,
1929 &hdd_ctx->target_hw_name);
1930
1931 /* Get the wlan hw/fw version */
1932 hdd_wlan_get_version(hdd_ctx, NULL, NULL);
1933
1934 return;
1935}
1936
1937/**
gbian62edd7e2017-03-07 13:12:13 +08001938 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
1939 * @hdd_ctx: Pointer to hdd context
1940 *
1941 * Return: none
1942 */
1943static void
1944hdd_update_cds_ac_specs_params(hdd_context_t *hdd_ctx)
1945{
1946 uint8_t num_entries = 0;
1947 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM];
1948 uint8_t *tx_sched_wrr_ac;
1949 int i;
1950 cds_context_type *cds_ctx;
1951
1952 if (NULL == hdd_ctx)
1953 return;
1954
1955 if (NULL == hdd_ctx->config) {
1956 /* Do nothing if hdd_ctx is invalid */
1957 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
1958 return;
1959 }
1960
1961 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
1962
1963 if (!cds_ctx) {
1964 hdd_err("Invalid CDS Context");
1965 return;
1966 }
1967
1968 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
1969 switch (i) {
1970 case OL_TX_WMM_AC_BE:
1971 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_be;
1972 break;
1973 case OL_TX_WMM_AC_BK:
1974 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_bk;
1975 break;
1976 case OL_TX_WMM_AC_VI:
1977 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vi;
1978 break;
1979 case OL_TX_WMM_AC_VO:
1980 tx_sched_wrr_ac = hdd_ctx->config->tx_sched_wrr_vo;
1981 break;
1982 default:
1983 tx_sched_wrr_ac = NULL;
1984 break;
1985 }
1986
1987 hdd_string_to_u8_array(tx_sched_wrr_ac,
1988 tx_sched_wrr_param,
1989 &num_entries,
1990 sizeof(tx_sched_wrr_param));
1991
1992 if (num_entries == TX_SCHED_WRR_PARAMS_NUM) {
1993 cds_ctx->ac_specs[i].wrr_skip_weight =
1994 tx_sched_wrr_param[0];
1995 cds_ctx->ac_specs[i].credit_threshold =
1996 tx_sched_wrr_param[1];
1997 cds_ctx->ac_specs[i].send_limit =
1998 tx_sched_wrr_param[2];
1999 cds_ctx->ac_specs[i].credit_reserve =
2000 tx_sched_wrr_param[3];
2001 cds_ctx->ac_specs[i].discard_weight =
2002 tx_sched_wrr_param[4];
2003 }
2004
2005 num_entries = 0;
2006 }
2007}
2008
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002009#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002010static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2011 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2012{
2013 hdd_adapter_t *adapter = NULL;
2014 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2015
2016 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2017 if (!adapter) {
2018 hdd_err("Adapter is NULL");
2019 return PM_MAX_NUM_OF_MODE;
2020 }
2021
2022 return policy_mgr_convert_device_mode_to_qdf_type(
2023 adapter->device_mode);
2024}
2025
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002026static void hdd_register_policy_manager_callback(
2027 struct wlan_objmgr_psoc *psoc)
2028{
2029 struct policy_mgr_hdd_cbacks hdd_cbacks;
2030 hdd_cbacks.sap_restart_chan_switch_cb =
2031 sap_restart_chan_switch_cb;
2032 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2033 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002034 hdd_cbacks.get_mode_for_non_connected_vdev =
2035 wlan_hdd_get_mode_for_non_connected_vdev;
2036
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002037 if (QDF_STATUS_SUCCESS !=
2038 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2039 hdd_err("HDD callback registration with policy manager failed");
2040 }
2041}
2042#else
2043static void hdd_register_policy_manager_callback(
2044 struct wlan_objmgr_psoc *psoc)
2045{
2046}
2047#endif
2048
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002049#ifdef WLAN_FEATURE_NAN_CONVERGENCE
2050static void hdd_nan_register_callbacks(hdd_context_t *hdd_ctx)
2051{
2052 struct nan_callbacks cb_obj = {0};
2053
2054 cb_obj.ndi_open = hdd_ndi_open;
2055 cb_obj.ndi_close = hdd_ndi_close;
2056 cb_obj.ndi_start = hdd_ndi_start;
2057 cb_obj.ndi_delete = hdd_ndi_delete;
2058 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2059 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2060
Naveen Rawat37f62c82017-03-26 22:24:43 -07002061 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2062 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002063 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002064
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002065 os_if_nan_register_hdd_callbacks(hdd_ctx->hdd_psoc, &cb_obj);
2066}
2067#else
2068static void hdd_nan_register_callbacks(hdd_context_t *hdd_ctx)
2069{
2070}
2071#endif
2072
gbian62edd7e2017-03-07 13:12:13 +08002073/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302074 * hdd_wlan_start_modules() - Single driver state machine for starting modules
2075 * @hdd_ctx: HDD context
2076 * @adapter: HDD adapter
2077 * @reinit: flag to indicate from SSR or normal path
2078 *
2079 * This function maintains the driver state machine it will be invoked from
2080 * startup, reinit and change interface. Depending on the driver state shall
2081 * perform the opening of the modules.
2082 *
2083 * Return: 0 for success; non-zero for failure
2084 */
2085int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
2086 bool reinit)
2087{
2088 int ret;
2089 qdf_device_t qdf_dev;
2090 QDF_STATUS status;
2091 p_cds_contextType p_cds_context;
2092 bool unint = false;
2093 void *hif_ctx;
2094
2095 ENTER();
2096
2097 p_cds_context = cds_get_global_context();
2098 if (!p_cds_context) {
2099 hdd_err("Global Context is NULL");
2100 QDF_ASSERT(0);
2101 return -EINVAL;
2102 }
2103
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002104 hdd_debug("start modules called in state! :%d reinit: %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05302105 hdd_ctx->driver_status, reinit);
2106
2107 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2108 if (!qdf_dev) {
2109 hdd_err("QDF Device Context is Invalid return");
2110 return -EINVAL;
2111 }
2112
2113 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302114 hdd_ctx->start_modules_in_progress = true;
Arun Khandavallifae92942016-08-01 13:31:08 +05302115
2116 if (QDF_TIMER_STATE_RUNNING ==
2117 qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
2118
2119 hdd_set_idle_ps_config(hdd_ctx, false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002120 hdd_debug("Interface change Timer running Stop timer");
Arun Khandavallifae92942016-08-01 13:31:08 +05302121 qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
2122 }
2123
2124 switch (hdd_ctx->driver_status) {
2125 case DRIVER_MODULES_UNINITIALIZED:
2126 unint = true;
2127 /* Fall through dont add break here */
2128 case DRIVER_MODULES_CLOSED:
2129 if (!reinit && !unint) {
2130 ret = pld_power_on(qdf_dev->dev);
2131 if (ret) {
2132 hdd_err("Failed to Powerup the device: %d", ret);
2133 goto release_lock;
2134 }
2135 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002136
2137 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2138 hdd_ctx->config->enable_fw_log);
2139
Arun Khandavallifae92942016-08-01 13:31:08 +05302140 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2141 qdf_dev->bus_type,
2142 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2143 HIF_ENABLE_TYPE_PROBE);
2144 if (ret) {
2145 hdd_err("Failed to open hif: %d", ret);
2146 goto power_down;
2147 }
2148
2149 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302150 if (!hif_ctx) {
2151 hdd_err("hif context is null!!");
2152 goto power_down;
2153 }
2154
Arun Khandavallifae92942016-08-01 13:31:08 +05302155 status = ol_cds_init(qdf_dev, hif_ctx);
2156 if (status != QDF_STATUS_SUCCESS) {
2157 hdd_err("No Memory to Create BMI Context :%d", status);
2158 goto hif_close;
2159 }
2160
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002161 ret = hdd_update_config(hdd_ctx);
2162 if (ret) {
2163 hdd_err("Failed to update configuration :%d", ret);
Abhishek Singhe9068f12017-03-31 14:14:52 +05302164 goto ol_cds_free;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08002165 }
2166
gbian62edd7e2017-03-07 13:12:13 +08002167 hdd_update_cds_ac_specs_params(hdd_ctx);
2168
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302169 status = cds_open(hdd_ctx->hdd_psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05302170 if (!QDF_IS_STATUS_SUCCESS(status)) {
2171 hdd_err("Failed to Open CDS: %d", status);
Abhishek Singhe9068f12017-03-31 14:14:52 +05302172 goto ol_cds_free;
Arun Khandavallifae92942016-08-01 13:31:08 +05302173 }
2174
Mukul Sharma9d797a02017-01-05 20:26:03 +05302175 /* initalize components configurations after psoc open */
2176 ret = hdd_update_components_config(hdd_ctx);
2177 if (ret) {
2178 hdd_err("Failed to update components configs :%d",
2179 ret);
2180 goto close;
2181 }
2182
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002183 /*
2184 * NAN compoenet requires certian operations like, open adapter,
2185 * close adapter, etc. to be initiated by HDD, for those
2186 * register HDD callbacks with UMAC's NAN componenet.
2187 */
2188 hdd_nan_register_callbacks(hdd_ctx);
2189
Arun Khandavallifae92942016-08-01 13:31:08 +05302190 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
2191
2192 status = cds_pre_enable(hdd_ctx->pcds_context);
2193 if (!QDF_IS_STATUS_SUCCESS(status)) {
2194 hdd_err("Failed to pre-enable CDS: %d", status);
2195 goto close;
2196 }
2197
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002198 hdd_register_policy_manager_callback(
2199 hdd_ctx->hdd_psoc);
2200
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302201 hdd_update_hw_sw_info(hdd_ctx);
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05302202 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302203
Arun Khandavallifae92942016-08-01 13:31:08 +05302204 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2205 sme_register_ftm_msg_processor(hdd_ctx->hHal,
2206 hdd_ftm_mc_process_msg);
2207 break;
2208 }
2209 if (unint) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002210 hdd_debug("In phase-1 initialization don't enable modules");
Arun Khandavallifae92942016-08-01 13:31:08 +05302211 break;
2212 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302213
2214 if (reinit) {
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08002215 if (hdd_ipa_uc_ssr_reinit(hdd_ctx)) {
2216 hdd_err("HDD IPA UC reinit failed");
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002217 goto post_disable;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08002218 }
Arun Khandavallicc544b32017-01-30 19:52:16 +05302219 }
2220
Arun Khandavallifae92942016-08-01 13:31:08 +05302221 /* Fall through dont add break here */
2222 case DRIVER_MODULES_OPENED:
2223 if (!adapter) {
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002224 hdd_alert("adapter is Null");
2225 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302226 }
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302227 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2228 hdd_err("in ftm mode, no need to configure cds modules");
2229 break;
2230 }
Arun Khandavallifae92942016-08-01 13:31:08 +05302231 if (hdd_configure_cds(hdd_ctx, adapter)) {
2232 hdd_err("Failed to Enable cds modules");
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002233 goto post_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05302234 }
Komal Seelamf2136bb2016-09-28 18:30:44 +05302235 hdd_enable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +05302236 hdd_info("Driver Modules Successfully Enabled");
2237 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
2238 break;
2239 case DRIVER_MODULES_ENABLED:
2240 hdd_info("Driver modules already Enabled");
2241 break;
2242 default:
2243 hdd_err("WLAN start invoked in wrong state! :%d\n",
2244 hdd_ctx->driver_status);
2245 goto release_lock;
2246 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302247 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302248 mutex_unlock(&hdd_ctx->iface_change_lock);
2249 EXIT();
2250 return 0;
2251
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002252post_disable:
Rajeev Kumarbe021242017-02-16 16:12:23 -08002253 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002254
Arun Khandavallifae92942016-08-01 13:31:08 +05302255close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002256 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302257 cds_close(hdd_ctx->hdd_psoc, p_cds_context);
Arun Khandavallifae92942016-08-01 13:31:08 +05302258
2259ol_cds_free:
2260 ol_cds_free();
2261
2262hif_close:
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05302263 hdd_hif_close(hdd_ctx, p_cds_context->pHIFContext);
Arun Khandavallifae92942016-08-01 13:31:08 +05302264power_down:
2265 if (!reinit && !unint)
2266 pld_power_off(qdf_dev->dev);
2267release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302268 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05302269 mutex_unlock(&hdd_ctx->iface_change_lock);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05302270 EXIT();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002271
Arun Khandavallifae92942016-08-01 13:31:08 +05302272 return -EINVAL;
2273}
2274
Naveen Rawat910726a2017-03-06 11:42:51 -08002275#ifdef WIFI_POS_CONVERGED
2276static int hdd_activate_wifi_pos(hdd_context_t *hdd_ctx)
2277{
2278 int ret = os_if_wifi_pos_register_nl();
2279
2280 if (ret)
2281 hdd_err("os_if_wifi_pos_register_nl failed");
2282
2283 return ret;
2284}
2285
2286static int hdd_deactivate_wifi_pos(void)
2287{
2288 int ret = os_if_wifi_pos_deregister_nl();
2289
2290 if (ret)
2291 hdd_err("os_if_wifi_pos_deregister_nl failed");
2292
2293 return ret;
2294}
2295
2296/**
2297 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
2298 * @hdd_ctx: hdd context
2299 *
2300 * Return: status of operation
2301 */
2302static void hdd_populate_wifi_pos_cfg(hdd_context_t *hdd_ctx)
2303{
2304 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
2305 struct hdd_config *cfg = hdd_ctx->config;
2306
2307 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
2308 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
2309 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
2310 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
2311 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
2312 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
2313 wifi_pos_set_dwell_time_min(psoc, cfg->nNeighborScanMinChanTime);
2314 wifi_pos_set_dwell_time_max(psoc, cfg->nNeighborScanMaxChanTime);
2315}
2316#else
2317static int hdd_activate_wifi_pos(hdd_context_t *hdd_ctx)
2318{
2319 return oem_activate_service(hdd_ctx);
2320}
2321
2322static int hdd_deactivate_wifi_pos(void)
2323{
2324 return 0;
2325}
2326
2327static void hdd_populate_wifi_pos_cfg(hdd_context_t *hdd_ctx)
2328{
2329}
2330#endif
2331
Arun Khandavallifae92942016-08-01 13:31:08 +05302332/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 * __hdd_open() - HDD Open function
2334 * @dev: Pointer to net_device structure
2335 *
2336 * This is called in response to ifconfig up
2337 *
2338 * Return: 0 for success; non-zero for failure
2339 */
2340static int __hdd_open(struct net_device *dev)
2341{
2342 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2343 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2344 int ret;
2345
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002346 ENTER_DEV(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302347 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Arun Khandavallifae92942016-08-01 13:31:08 +05302348 adapter->sessionId, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349
2350 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302351 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352 return ret;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302353
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002354
Arun Khandavallifae92942016-08-01 13:31:08 +05302355 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
2356 if (ret) {
2357 hdd_err("Failed to start WLAN modules return");
2358 return -ret;
2359 }
2360
2361
2362 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2363 ret = hdd_start_adapter(adapter);
2364 if (ret) {
2365 hdd_err("Failed to start adapter :%d",
2366 adapter->device_mode);
2367 return ret;
2368 }
2369 }
2370
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002371 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2372 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002373 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374 /* Enable TX queues only when we are connected */
2375 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05302376 WLAN_START_ALL_NETIF_QUEUE,
2377 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 }
2379
Naveen Rawat286def52016-09-23 15:38:02 -07002380 /* Enable carrier and transmit queues for NDI */
2381 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002382 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07002383 wlan_hdd_netif_queue_control(adapter,
2384 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2385 WLAN_CONTROL_PATH);
2386 }
2387
Naveen Rawat910726a2017-03-06 11:42:51 -08002388 hdd_populate_wifi_pos_cfg(hdd_ctx);
2389
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 return ret;
2391}
2392
Arun Khandavallifae92942016-08-01 13:31:08 +05302393
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394/**
2395 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
2396 * @dev: Pointer to net_device structure
2397 *
2398 * This is called in response to ifconfig up
2399 *
2400 * Return: 0 for success; non-zero for failure
2401 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002402static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403{
2404 int ret;
2405
2406 cds_ssr_protect(__func__);
2407 ret = __hdd_open(dev);
2408 cds_ssr_unprotect(__func__);
2409
2410 return ret;
2411}
2412
2413/**
2414 * __hdd_stop() - HDD stop function
2415 * @dev: Pointer to net_device structure
2416 *
2417 * This is called in response to ifconfig down
2418 *
2419 * Return: 0 for success; non-zero for failure
2420 */
2421static int __hdd_stop(struct net_device *dev)
2422{
2423 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2424 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2425 int ret;
2426
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002427 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002428
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302429 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002430 adapter->sessionId, adapter->device_mode));
2431
2432 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302433 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002434 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435
2436 /* Nothing to be done if the interface is not opened */
2437 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07002438 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002439 return -ENODEV;
2440 }
2441
2442 /* Make sure the interface is marked as closed */
2443 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002444 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05302445 wlan_hdd_netif_queue_control(adapter,
2446 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2447 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448
2449 /*
Naveen Rawat286def52016-09-23 15:38:02 -07002450 * NAN data interface is different in some sense. The traffic on NDI is
2451 * bursty in nature and depends on the need to transfer. The service
2452 * layer may down the interface after the usage and up again when
2453 * required. In some sense, the NDI is expected to be available
2454 * (like SAP) iface until NDI delete request is issued by the service
2455 * layer. Skip BSS termination and adapter deletion for NAN Data
2456 * interface (NDI).
2457 */
2458 if (WLAN_HDD_IS_NDI(adapter))
2459 return 0;
2460
2461 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 * The interface is marked as down for outside world (aka kernel)
2463 * But the driver is pretty much alive inside. The driver needs to
2464 * tear down the existing connection on the netdev (session)
2465 * cleanup the data pipes and wait until the control plane is stabilized
2466 * for this interface. The call also needs to wait until the above
2467 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002468 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 * That is intentional to be able to scan if it is a STA/P2P interface
2470 */
Arun Khandavallifae92942016-08-01 13:31:08 +05302471 hdd_stop_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472
2473 /* DeInit the adapter. This ensures datapath cleanup as well */
2474 hdd_deinit_adapter(hdd_ctx, adapter, true);
2475
Arun Khandavallifae92942016-08-01 13:31:08 +05302476
2477 /*
2478 * Find if any iface is up. If any iface is up then can't put device to
2479 * sleep/power save mode
2480 */
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05302481 if (hdd_check_for_opened_interfaces(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002482 hdd_debug("Closing all modules from the hdd_stop");
Arun Khandavallifae92942016-08-01 13:31:08 +05302483 qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
Hanumanth Reddy Pothula42e714a2016-12-21 19:33:57 +05302484 hdd_ctx->config->iface_change_wait_time);
Arun Khandavallifae92942016-08-01 13:31:08 +05302485 }
2486
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002487 EXIT();
2488 return 0;
2489}
2490
2491/**
2492 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
2493 * @dev: pointer to net_device structure
2494 *
2495 * This is called in response to ifconfig down
2496 *
2497 * Return: 0 for success and error number for failure
2498 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002499static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500{
2501 int ret;
2502
2503 cds_ssr_protect(__func__);
2504 ret = __hdd_stop(dev);
2505 cds_ssr_unprotect(__func__);
2506
2507 return ret;
2508}
2509
2510/**
2511 * __hdd_uninit() - HDD uninit function
2512 * @dev: Pointer to net_device structure
2513 *
2514 * This is called during the netdev unregister to uninitialize all data
2515 * associated with the device
2516 *
2517 * Return: None
2518 */
2519static void __hdd_uninit(struct net_device *dev)
2520{
2521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2522
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002523 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524
2525 do {
2526 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002527 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 break;
2529 }
2530
2531 if (NULL == adapter->pHddCtx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002532 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002533 break;
2534 }
2535
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002536 if (dev != adapter->dev)
2537 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538
2539 hdd_deinit_adapter(adapter->pHddCtx, adapter, true);
2540
2541 /* after uninit our adapter structure will no longer be valid */
2542 adapter->dev = NULL;
2543 adapter->magic = 0;
2544 } while (0);
2545
2546 EXIT();
2547}
2548
2549/**
2550 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
2551 * @dev: pointer to net_device structure
2552 *
2553 * This is called during the netdev unregister to uninitialize all data
2554 * associated with the device
2555 *
2556 * Return: none
2557 */
2558static void hdd_uninit(struct net_device *dev)
2559{
2560 cds_ssr_protect(__func__);
2561 __hdd_uninit(dev);
2562 cds_ssr_unprotect(__func__);
2563}
2564
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08002565static int hdd_open_cesium_nl_sock(void)
2566{
2567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2568 struct netlink_kernel_cfg cfg = {
2569 .groups = WLAN_NLINK_MCAST_GRP_ID,
2570 .input = NULL
2571 };
2572#endif
2573 int ret = 0;
2574
2575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2576 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2577#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
2578 THIS_MODULE,
2579#endif
2580 &cfg);
2581#else
2582 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2583 WLAN_NLINK_MCAST_GRP_ID,
2584 NULL, NULL, THIS_MODULE);
2585#endif
2586
2587 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07002588 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08002589 ret = -ECONNREFUSED;
2590 }
2591
2592 return ret;
2593}
2594
2595static void hdd_close_cesium_nl_sock(void)
2596{
2597 if (NULL != cesium_nl_srv_sock) {
2598 netlink_kernel_release(cesium_nl_srv_sock);
2599 cesium_nl_srv_sock = NULL;
2600 }
2601}
2602
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603/**
2604 * __hdd_set_mac_address() - set the user specified mac address
2605 * @dev: Pointer to the net device.
2606 * @addr: Pointer to the sockaddr.
2607 *
2608 * This function sets the user specified mac address using
2609 * the command ifconfig wlanX hw ether <mac adress>.
2610 *
2611 * Return: 0 for success, non zero for failure
2612 */
2613static int __hdd_set_mac_address(struct net_device *dev, void *addr)
2614{
2615 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2616 hdd_context_t *hdd_ctx;
2617 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302618 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002619 int ret;
2620
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002621 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002622
2623 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2624 ret = wlan_hdd_validate_context(hdd_ctx);
2625 if (0 != ret)
2626 return ret;
2627
2628 memcpy(&adapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
2629 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
2630
2631 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302632 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633}
2634
2635/**
2636 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
2637 * function from SSR
2638 * @dev: pointer to net_device structure
2639 * @addr: Pointer to the sockaddr
2640 *
2641 * This function sets the user specified mac address using
2642 * the command ifconfig wlanX hw ether <mac adress>.
2643 *
2644 * Return: 0 for success.
2645 */
2646static int hdd_set_mac_address(struct net_device *dev, void *addr)
2647{
2648 int ret;
2649
2650 cds_ssr_protect(__func__);
2651 ret = __hdd_set_mac_address(dev, addr);
2652 cds_ssr_unprotect(__func__);
2653
2654 return ret;
2655}
2656
2657uint8_t *wlan_hdd_get_intf_addr(hdd_context_t *hdd_ctx)
2658{
2659 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002660
Anurag Chouhan6d760662016-02-20 16:05:43 +05302661 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002662 if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
2663 break;
2664 }
2665
Anurag Chouhan6d760662016-02-20 16:05:43 +05302666 if (QDF_MAX_CONCURRENCY_PERSONA == i)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 return NULL;
2668
2669 hdd_ctx->config->intfAddrMask |= (1 << i);
2670 return &hdd_ctx->config->intfMacAddr[i].bytes[0];
2671}
2672
2673void wlan_hdd_release_intf_addr(hdd_context_t *hdd_ctx, uint8_t *releaseAddr)
2674{
2675 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002676
Anurag Chouhan6d760662016-02-20 16:05:43 +05302677 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678 if (!memcmp(releaseAddr,
2679 &hdd_ctx->config->intfMacAddr[i].bytes[0],
2680 6)) {
2681 hdd_ctx->config->intfAddrMask &= ~(1 << i);
2682 break;
2683 }
2684 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002685}
2686
2687#ifdef WLAN_FEATURE_PACKET_FILTERING
2688/**
2689 * __hdd_set_multicast_list() - set the multicast address list
2690 * @dev: Pointer to the WLAN device.
2691 * @skb: Pointer to OS packet (sk_buff).
2692 *
2693 * This funciton sets the multicast address list.
2694 *
2695 * Return: None
2696 */
2697static void __hdd_set_multicast_list(struct net_device *dev)
2698{
2699 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700 int i = 0, status;
2701 struct netdev_hw_addr *ha;
2702 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302703 struct pmo_mc_addr_list_params *mc_list_request = NULL;
2704 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
2705 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002706
Jeff Johnson3c3994a2016-02-11 08:12:30 -08002707 ENTER_DEV(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302708 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302709 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05302710
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302712 if (0 != status)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302713 goto out;
2714
2715 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
2716 if (!mc_list_request) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002717 hdd_err("Cannot allocate mc_list_request");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302718 goto out;
2719 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05302721 /* Delete already configured multicast address list */
2722 if (adapter->mc_addr_list.mc_cnt > 0) {
2723 hdd_info("clear previously configured MC address list");
2724 hdd_disable_and_flush_mc_addr_list(adapter,
2725 pmo_mc_list_change_notify);
2726 }
2727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002729 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302730 hdd_disable_and_flush_mc_addr_list(adapter,
2731 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002732 } else {
2733 mc_count = netdev_mc_count(dev);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302734 if (mc_count > pmo_ucfg_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002735 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302736 pmo_ucfg_max_mc_addr_supported(psoc));
2737 hdd_disable_and_flush_mc_addr_list(adapter,
2738 pmo_mc_list_change_notify);
2739 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002740 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002742 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05302743 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002744 if (i == mc_count)
2745 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302746 memset(&(mc_list_request->mc_addr[i].bytes),
2747 0, ETH_ALEN);
2748 memcpy(&(mc_list_request->mc_addr[i].bytes),
2749 ha->addr, ETH_ALEN);
2750 hdd_info("mlist[%d] = %pM", i,
2751 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002752 i++;
2753 }
2754 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302755
2756 mc_list_request->psoc = psoc;
2757 mc_list_request->vdev_id = adapter->sessionId;
2758 mc_list_request->count = mc_count;
2759 status = hdd_cache_mc_addr_list(mc_list_request);
2760 if (status == 0) {
2761 hdd_enable_mc_addr_filtering(adapter,
2762 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002763 } else {
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302764 hdd_err("error while caching mc list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002765 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302766out:
2767 if (mc_list_request)
2768 qdf_mem_free(mc_list_request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302769 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002770}
2771
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05302772
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773/**
2774 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
2775 * @dev: pointer to net_device
2776 *
2777 * Return: none
2778 */
2779static void hdd_set_multicast_list(struct net_device *dev)
2780{
2781 cds_ssr_protect(__func__);
2782 __hdd_set_multicast_list(dev);
2783 cds_ssr_unprotect(__func__);
2784}
2785#endif
2786
2787/**
2788 * hdd_select_queue() - used by Linux OS to decide which queue to use first
2789 * @dev: Pointer to the WLAN device.
2790 * @skb: Pointer to OS packet (sk_buff).
2791 *
2792 * This function is registered with the Linux OS for network
2793 * core to decide which queue to use first.
2794 *
2795 * Return: ac, Queue Index/access category corresponding to UP in IP header
2796 */
2797static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
2798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
2799 , void *accel_priv
2800#endif
2801#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
2802 , select_queue_fallback_t fallback
2803#endif
2804)
2805{
2806 return hdd_wmm_select_queue(dev, skb);
2807}
2808
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002809static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810 .ndo_open = hdd_open,
2811 .ndo_stop = hdd_stop,
2812 .ndo_uninit = hdd_uninit,
2813 .ndo_start_xmit = hdd_hard_start_xmit,
2814 .ndo_tx_timeout = hdd_tx_timeout,
2815 .ndo_get_stats = hdd_get_stats,
2816 .ndo_do_ioctl = hdd_ioctl,
2817 .ndo_set_mac_address = hdd_set_mac_address,
2818 .ndo_select_queue = hdd_select_queue,
2819#ifdef WLAN_FEATURE_PACKET_FILTERING
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002821#endif
2822};
2823
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002824/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002825static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002826 .ndo_open = hdd_mon_open,
2827 .ndo_stop = hdd_stop,
2828 .ndo_get_stats = hdd_get_stats,
2829};
2830
2831/**
2832 * hdd_set_station_ops() - update net_device ops for monitor mode
2833 * @pWlanDev: Handle to struct net_device to be updated.
2834 * Return: None
2835 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002836void hdd_set_station_ops(struct net_device *pWlanDev)
2837{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002838 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
2839 pWlanDev->netdev_ops = &wlan_mon_drv_ops;
2840 else
2841 pWlanDev->netdev_ops = &wlan_drv_ops;
2842}
2843
Komal Seelama89be8d2016-09-29 11:09:26 +05302844#ifdef FEATURE_RUNTIME_PM
Komal Seelam8634b772016-09-29 12:12:24 +05302845/**
2846 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
2847 * @hdd_ctx: HDD context
2848 *
2849 * Return: None
2850 */
2851static void hdd_runtime_suspend_context_init(hdd_context_t *hdd_ctx)
2852{
2853 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
2854
Komal Seelamaa75f262016-09-29 12:32:13 +05302855 ctx->roc = qdf_runtime_lock_init("roc");
Komal Seelam81cb1662016-09-29 12:39:08 +05302856 ctx->dfs = qdf_runtime_lock_init("dfs");
Komal Seelam8634b772016-09-29 12:12:24 +05302857}
2858
2859/**
2860 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
2861 * @hdd_ctx: HDD Context
2862 *
2863 * Return: None
2864 */
2865static void hdd_runtime_suspend_context_deinit(hdd_context_t *hdd_ctx)
2866{
2867 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
2868
Komal Seelamaa75f262016-09-29 12:32:13 +05302869 qdf_runtime_lock_deinit(ctx->roc);
2870 ctx->roc = NULL;
Komal Seelam81cb1662016-09-29 12:39:08 +05302871 qdf_runtime_lock_deinit(ctx->dfs);
2872 ctx->dfs = NULL;
Sravan Kumar Kairam64574952017-06-22 11:48:18 +05302873
2874 wlan_scan_runtime_pm_deinit(hdd_ctx->hdd_pdev);
Komal Seelam8634b772016-09-29 12:12:24 +05302875}
2876
Komal Seelama89be8d2016-09-29 11:09:26 +05302877static void hdd_adapter_runtime_suspend_init(hdd_adapter_t *adapter)
2878{
2879 struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
2880
2881 ctx->connect = qdf_runtime_lock_init("connect");
2882}
2883
2884static void hdd_adapter_runtime_suspend_denit(hdd_adapter_t *adapter)
2885{
2886 struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
2887
2888 qdf_runtime_lock_deinit(ctx->connect);
2889 ctx->connect = NULL;
2890}
2891#else /* FEATURE_RUNTIME_PM */
Komal Seelam8634b772016-09-29 12:12:24 +05302892static void hdd_runtime_suspend_context_init(hdd_context_t *hdd_ctx) {}
2893static void hdd_runtime_suspend_context_deinit(hdd_context_t *hdd_ctx) {}
Komal Seelama89be8d2016-09-29 11:09:26 +05302894static inline void hdd_adapter_runtime_suspend_init(hdd_adapter_t *adapter) {}
2895static inline void hdd_adapter_runtime_suspend_denit(hdd_adapter_t *adapter) {}
2896#endif /* FEATURE_RUNTIME_PM */
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002897/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08002898 * hdd_alloc_station_adapter() - allocate the station hdd adapter
2899 * @hdd_ctx: global hdd context
2900 * @macAddr: mac address to assign to the interface
2901 * @name: User-visible name of the interface
2902 *
2903 * hdd adapter pointer would point to the netdev->priv space, this function
2904 * would retrive the pointer, and setup the hdd adapter configuration.
2905 *
2906 * Return: the pointer to hdd adapter, otherwise NULL
2907 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
2909 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08002910 unsigned char name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911 const char *name)
2912{
2913 struct net_device *pWlanDev = NULL;
2914 hdd_adapter_t *adapter = NULL;
Hanumanth Reddy Pothula18553ae2017-04-28 15:03:10 +05302915 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002916 /*
2917 * cfg80211 initialization and registration....
2918 */
Ryan Hsu07495ea2016-01-21 15:25:39 -08002919 pWlanDev = alloc_netdev_mq(sizeof(hdd_adapter_t), name,
2920#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
2921 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002922#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002923 (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
2924 hdd_mon_mode_ether_setup : ether_setup),
2925 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002926
2927 if (pWlanDev != NULL) {
2928
2929 /* Save the pointer to the net_device in the HDD adapter */
2930 adapter = (hdd_adapter_t *) netdev_priv(pWlanDev);
2931
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302932 qdf_mem_zero(adapter, sizeof(hdd_adapter_t));
Hanumanth Reddy Pothula18553ae2017-04-28 15:03:10 +05302933 sta_ctx = &adapter->sessionCtx.station;
2934 qdf_mem_set(sta_ctx->conn_info.staId,
2935 sizeof(sta_ctx->conn_info.staId),
2936 HDD_WLAN_INVALID_STA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937 adapter->dev = pWlanDev;
2938 adapter->pHddCtx = hdd_ctx;
2939 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Arun Khandavalli9ad88f02016-09-01 19:03:37 +05302940 adapter->sessionId = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002941
2942 init_completion(&adapter->session_open_comp_var);
2943 init_completion(&adapter->session_close_comp_var);
2944 init_completion(&adapter->disconnect_comp_var);
Abhishek Singh533c9da2017-05-04 10:23:34 +05302945 init_completion(&adapter->roaming_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002946 init_completion(&adapter->linkup_event_var);
2947 init_completion(&adapter->cancel_rem_on_chan_var);
2948 init_completion(&adapter->rem_on_chan_ready_event);
2949 init_completion(&adapter->sta_authorized_event);
2950 init_completion(&adapter->offchannel_tx_event);
2951 init_completion(&adapter->tx_action_cnf_event);
2952#ifdef FEATURE_WLAN_TDLS
2953 init_completion(&adapter->tdls_add_station_comp);
2954 init_completion(&adapter->tdls_del_station_comp);
2955 init_completion(&adapter->tdls_mgmt_comp);
2956 init_completion(&adapter->tdls_link_establish_req_comp);
2957#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08002958 init_completion(&adapter->ibss_peer_info_comp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002959 init_completion(&adapter->change_country_code);
2960
2961
2962 init_completion(&adapter->scan_info.abortscan_event_var);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05302963 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964
2965 adapter->offloads_configured = false;
2966 adapter->isLinkUpSvcNeeded = false;
2967 adapter->higherDtimTransition = true;
2968 /* Init the net_device structure */
2969 strlcpy(pWlanDev->name, name, IFNAMSIZ);
2970
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302971 qdf_mem_copy(pWlanDev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002972 sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302973 qdf_mem_copy(adapter->macAddressCurrent.bytes, macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002974 sizeof(tSirMacAddr));
2975 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002976
2977 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
2978 pWlanDev->features |=
2979 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
2980 pWlanDev->features |= NETIF_F_RXCSUM;
2981
Dhanashri Atre83d373d2015-07-28 16:45:59 -07002982 hdd_set_tso_flags(hdd_ctx, pWlanDev);
2983
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002984 hdd_set_station_ops(adapter->dev);
2985
2986 pWlanDev->destructor = free_netdev;
2987 pWlanDev->ieee80211_ptr = &adapter->wdev;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08002988 pWlanDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989 adapter->wdev.wiphy = hdd_ctx->wiphy;
2990 adapter->wdev.netdev = pWlanDev;
2991 /* set pWlanDev's parent to underlying device */
2992 SET_NETDEV_DEV(pWlanDev, hdd_ctx->parent_dev);
2993 hdd_wmm_init(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05302994 hdd_adapter_runtime_suspend_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002995 spin_lock_init(&adapter->pause_map_lock);
Nirav Shah617cff92016-04-25 10:24:24 +05302996 adapter->start_time = adapter->last_time = qdf_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002997 }
2998
2999 return adapter;
3000}
3001
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003002static QDF_STATUS hdd_register_interface(hdd_adapter_t *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003003{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003004 struct net_device *dev = adapter->dev;
3005 int ret;
3006
3007 ENTER();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003008
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003009 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003010 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3011
3012 ret = dev_alloc_name(dev, dev->name);
3013 if (ret < 0) {
3014 hdd_err(
3015 "unable to get dev name: %s, err = 0x%x",
3016 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303017 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003018 }
3019 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003020
3021 ret = register_netdevice(dev);
3022 if (ret) {
3023 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3024 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303025 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003026 }
3027 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003028 ret = register_netdev(dev);
3029 if (ret) {
3030 hdd_err("register_netdev(%s) failed, err = 0x%x",
3031 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303032 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003033 }
3034 }
3035 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3036
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003037 EXIT();
3038
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303039 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003040}
3041
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07003042QDF_STATUS hdd_sme_close_session_callback(void *pContext)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003043{
3044 hdd_adapter_t *adapter = pContext;
3045
3046 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003047 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303048 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003049 }
3050
3051 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003052 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303053 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003054 }
3055
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003056 /*
3057 * For NAN Data interface, the close session results in the final
3058 * indication to the userspace
3059 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003060 if (adapter->device_mode == QDF_NDI_MODE)
3061 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003062
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3064
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065 /*
3066 * We can be blocked while waiting for scheduled work to be
3067 * flushed, and the adapter structure can potentially be freed, in
3068 * which case the magic will have been reset. So make sure the
3069 * magic is still good, and hence the adapter structure is still
3070 * valid, before signaling completion
3071 */
3072 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
3073 complete(&adapter->session_close_comp_var);
3074
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303075 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003076}
3077
Krunal Soni8c37e322016-02-03 16:08:37 -08003078/**
3079 * hdd_check_and_init_tdls() - check and init TDLS operation for desired mode
3080 * @adapter: pointer to device adapter
Krunal Soni8c37e322016-02-03 16:08:37 -08003081 *
3082 * This routine will check the mode of adapter and if it is required then it
3083 * will initialize the TDLS operations
3084 *
3085 * Return: QDF_STATUS
3086 */
3087#ifdef FEATURE_WLAN_TDLS
Dustin Brownd28772b2017-03-17 14:16:07 -07003088static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter)
Krunal Soni8c37e322016-02-03 16:08:37 -08003089{
Dustin Brownd28772b2017-03-17 14:16:07 -07003090 if (adapter->device_mode == QDF_IBSS_MODE)
3091 return QDF_STATUS_SUCCESS;
3092
3093 if (wlan_hdd_tdls_init(adapter)) {
3094 hdd_err("wlan_hdd_tdls_init failed");
3095 return QDF_STATUS_E_FAILURE;
Krunal Soni8c37e322016-02-03 16:08:37 -08003096 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003097 set_bit(TDLS_INIT_DONE, &adapter->event_flags);
3098
Krunal Soni8c37e322016-02-03 16:08:37 -08003099 return QDF_STATUS_SUCCESS;
3100}
3101#else
Dustin Brownd28772b2017-03-17 14:16:07 -07003102static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter)
Krunal Soni8c37e322016-02-03 16:08:37 -08003103{
3104 return QDF_STATUS_SUCCESS;
3105}
3106#endif
3107
Dustin Brownd28772b2017-03-17 14:16:07 -07003108int hdd_vdev_ready(hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003109{
Dustin Brownd28772b2017-03-17 14:16:07 -07003110 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003111
Dustin Brownd28772b2017-03-17 14:16:07 -07003112 status = pmo_vdev_ready(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003113 if (QDF_IS_STATUS_ERROR(status))
3114 return qdf_status_to_os_return(status);
3115
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003116 status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003117 if (QDF_IS_STATUS_ERROR(status))
3118 return qdf_status_to_os_return(status);
3119
3120 if (wma_capability_enhanced_mcast_filter())
3121 status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev);
3122 else
3123 status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07003124
3125 return qdf_status_to_os_return(status);
3126}
3127
3128int hdd_vdev_destroy(hdd_adapter_t *adapter)
3129{
3130 QDF_STATUS status;
3131 int errno;
3132 hdd_context_t *hdd_ctx;
3133 unsigned long rc;
3134
3135 hdd_info("destroying vdev %d", adapter->sessionId);
3136
3137 /* vdev created sanity check */
3138 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3139 hdd_err("vdev for Id %d does not exist", adapter->sessionId);
3140 return -EINVAL;
3141 }
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -07003142 status = ucfg_reg_11d_vdev_delete_update(adapter->hdd_vdev);
Dustin Brown0d2eeae2017-03-24 15:21:32 -07003143 /* do vdev logical destroy via objmgr */
3144 errno = hdd_objmgr_destroy_vdev(adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07003145 if (errno) {
3146 hdd_err("failed to destroy objmgr vdev: %d", errno);
3147 return errno;
3148 }
3149
Yue Maf9782842017-05-08 12:49:49 -07003150 /*
3151 * In SSR case, there is no need to destroy vdev in firmware since
3152 * it has already asserted. vdev can be released directly.
3153 */
3154 if (cds_is_driver_recovering())
3155 goto release_vdev;
3156
Dustin Brownd28772b2017-03-17 14:16:07 -07003157 /* close sme session (destroy vdev in firmware via legacy API) */
3158 INIT_COMPLETION(adapter->session_close_comp_var);
3159 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3160 status = sme_close_session(hdd_ctx->hHal, adapter->sessionId,
3161 hdd_sme_close_session_callback, adapter);
3162 if (QDF_IS_STATUS_ERROR(status)) {
3163 hdd_err("failed to close sme session: %d", status);
3164 return qdf_status_to_os_return(status);
3165 }
3166
3167 /* block on a completion variable until sme session is closed */
3168 rc = wait_for_completion_timeout(
3169 &adapter->session_close_comp_var,
3170 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
3171 if (!rc) {
3172 hdd_err("timed out waiting for close sme session: %ld", rc);
3173 if (adapter->device_mode == QDF_NDI_MODE)
3174 hdd_ndp_session_end_handler(adapter);
3175 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3176 return -ETIMEDOUT;
3177 }
3178
Yue Maf9782842017-05-08 12:49:49 -07003179release_vdev:
Dustin Brown0d2eeae2017-03-24 15:21:32 -07003180 /* now that sme session is closed, allow physical vdev destroy */
3181 errno = hdd_objmgr_release_vdev(adapter);
3182 if (errno) {
3183 hdd_err("failed to release objmgr vdev: %d", errno);
3184 return errno;
3185 }
3186
Dustin Brownd28772b2017-03-17 14:16:07 -07003187 hdd_info("vdev destroyed successfully");
3188
3189 return 0;
3190}
3191
3192int hdd_vdev_create(hdd_adapter_t *adapter)
3193{
3194 QDF_STATUS status;
3195 int errno;
3196 hdd_context_t *hdd_ctx;
3197 uint32_t type;
3198 uint32_t sub_type;
3199 unsigned long rc;
3200
3201 hdd_info("creating new vdev");
3202
3203 /* determine vdev (sub)type */
3204 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303205 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003206 hdd_err("failed to get vdev type: %d", status);
3207 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003208 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003209
3210 /* do vdev create via objmgr */
3211 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown7d043f62017-03-27 12:07:36 -07003212 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07003213 if (errno) {
3214 hdd_err("failed to create objmgr vdev: %d", errno);
3215 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216 }
Dustin Brownd28772b2017-03-17 14:16:07 -07003217
3218 /* Open a SME session (prepare vdev in firmware via legacy API) */
3219 INIT_COMPLETION(adapter->session_open_comp_var);
3220 status = sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback, adapter,
3221 (uint8_t *)&adapter->macAddressCurrent,
3222 adapter->sessionId, type, sub_type);
3223 if (QDF_IS_STATUS_ERROR(status)) {
3224 hdd_err("failed to open sme session: %d", status);
3225 errno = qdf_status_to_os_return(status);
3226 goto objmgr_vdev_destroy;
3227 }
3228
3229 /* block on a completion variable until sme session is opened */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003230 rc = wait_for_completion_timeout(
3231 &adapter->session_open_comp_var,
3232 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
3233 if (!rc) {
Dustin Brownd28772b2017-03-17 14:16:07 -07003234 hdd_err("timed out waiting for open sme session: %ld", rc);
3235 errno = -ETIMEDOUT;
Abhishek Singh7e95dbc2017-07-06 17:57:50 +05303236 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3237 goto hdd_vdev_destroy;
Dustin Brownd28772b2017-03-17 14:16:07 -07003238 }
3239
3240 /* firmware ready for component communication, raise vdev_ready event */
3241 errno = hdd_vdev_ready(adapter);
3242 if (errno) {
3243 hdd_err("failed to dispatch vdev ready event: %d", errno);
3244 goto hdd_vdev_destroy;
3245 }
3246
3247 hdd_info("vdev %d created successfully", adapter->sessionId);
3248
3249 return 0;
3250
3251 /*
3252 * Due to legacy constraints, we need to destroy in the same order as
3253 * create. So, split error handling into 2 cases to accommodate.
3254 */
3255
3256objmgr_vdev_destroy:
Dustin Brown7d043f62017-03-27 12:07:36 -07003257 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07003258
3259 return errno;
3260
3261hdd_vdev_destroy:
3262 QDF_BUG(!hdd_vdev_destroy(adapter));
3263
3264 return errno;
3265}
3266
3267QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
3268{
3269 hdd_station_ctx_t *pHddStaCtx = &adapter->sessionCtx.station;
3270 hdd_context_t *hdd_ctx;
3271 QDF_STATUS status;
3272 int ret_val;
3273
3274 ret_val = hdd_vdev_create(adapter);
3275 if (ret_val) {
3276 hdd_err("failed to create vdev: %d", ret_val);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05303277 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 }
3279
Dustin Brownd28772b2017-03-17 14:16:07 -07003280 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3281 sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
3282 sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
Naveen Rawata410c5a2016-09-19 14:22:33 -07003283 sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->sessionId);
Dustin Brownd28772b2017-03-17 14:16:07 -07003284
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003285 /* Register wireless extensions */
Dustin Brownd28772b2017-03-17 14:16:07 -07003286 status = hdd_register_wext(adapter->dev);
3287 if (QDF_IS_STATUS_ERROR(status)) {
3288 hdd_err("failed to register wireless extensions: %d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289 goto error_register_wext;
3290 }
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07003291 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003292
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05303293 qdf_mem_set(pHddStaCtx->conn_info.staId,
3294 sizeof(pHddStaCtx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
3295
Deepak Dhamdherea2785822016-11-17 01:17:45 -08003296 /* set fast roaming capability in sme session */
3297 status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
3298 adapter->fast_roaming_allowed);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299 /* Set the default operation channel */
3300 pHddStaCtx->conn_info.operationChannel =
3301 hdd_ctx->config->OperatingChannel;
3302
3303 /* Make the default Auth Type as OPEN */
3304 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3305
3306 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303307 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003308 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003309 status, status);
3310 goto error_init_txrx;
3311 }
3312
3313 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3314
3315 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303316 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003317 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003318 status, status);
3319 goto error_wmm_init;
3320 }
3321
3322 set_bit(WMM_INIT_DONE, &adapter->event_flags);
3323
Naveen Rawat247a8682017-06-05 15:00:31 -07003324 ret_val = sme_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325 WMI_PDEV_PARAM_BURST_ENABLE,
3326 hdd_ctx->config->enableSifsBurst,
3327 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07003328 if (ret_val)
3329 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003330
Dustin Brownd28772b2017-03-17 14:16:07 -07003331 status = hdd_check_and_init_tdls(adapter);
Krunal Soni8c37e322016-02-03 16:08:37 -08003332 if (status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003333 goto error_tdls_init;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003334
Dhanashri Atre1a6a4ce2017-05-03 19:40:33 -07003335 adapter->dev->features |= NETIF_F_LRO;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303336 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003338error_tdls_init:
3339 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3340 hdd_wmm_adapter_close(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341error_wmm_init:
3342 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3343 hdd_deinit_tx_rx(adapter);
3344error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07003345 hdd_unregister_wext(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003346error_register_wext:
Dustin Brownd28772b2017-03-17 14:16:07 -07003347 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003349 return status;
3350}
3351
3352void hdd_cleanup_actionframe(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
3353{
3354 hdd_cfg80211_state_t *cfgState;
3355
3356 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
3357
3358 if (NULL != cfgState->buf) {
3359 unsigned long rc;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003360
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 rc = wait_for_completion_timeout(
3362 &adapter->tx_action_cnf_event,
3363 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
3364 if (!rc) {
Jeff Johnson5880d792016-08-15 13:32:30 -07003365 hdd_err("HDD Wait for Action Confirmation Failed!!");
Masti, Narayanraddif8f6e7e2015-08-25 10:22:46 +05303366 /*
3367 * Inform tx status as FAILURE to upper layer and free
3368 * cfgState->buf
3369 */
3370 hdd_send_action_cnf(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003371 }
3372 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003373}
3374
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303375/**
3376 * hdd_station_adapter_deinit() - De-initialize the station adapter
3377 * @hdd_ctx: global hdd context
3378 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07003379 * @rtnl_held: Used to indicate whether or not the caller is holding
3380 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303381 *
3382 * This function De-initializes the STA/P2P/OCB adapter.
3383 *
3384 * Return: None.
3385 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003386static void hdd_station_adapter_deinit(hdd_context_t *hdd_ctx,
3387 hdd_adapter_t *adapter,
3388 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303389{
3390 ENTER_DEV(adapter->dev);
3391
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05303392 if (adapter->dev) {
3393 if (rtnl_held)
3394 adapter->dev->wireless_handlers = NULL;
3395 else {
3396 rtnl_lock();
3397 adapter->dev->wireless_handlers = NULL;
3398 rtnl_unlock();
3399 }
3400 }
3401
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303402 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
3403 hdd_deinit_tx_rx(adapter);
3404 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
3405 }
3406
3407 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
3408 hdd_wmm_adapter_close(adapter);
3409 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3410 }
3411
3412 hdd_cleanup_actionframe(hdd_ctx, adapter);
3413 wlan_hdd_tdls_exit(adapter);
3414
3415 EXIT();
3416}
3417
3418/**
3419 * hdd_ap_adapter_deinit() - De-initialize the ap adapter
3420 * @hdd_ctx: global hdd context
3421 * @adapter: HDD adapter
3422 * @rtnl_held: the rtnl lock hold flag
3423 * This function De-initializes the AP/P2PGo adapter.
3424 *
3425 * Return: None.
3426 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003427static void hdd_ap_adapter_deinit(hdd_context_t *hdd_ctx,
3428 hdd_adapter_t *adapter,
3429 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303430{
3431 ENTER_DEV(adapter->dev);
3432
3433 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
3434 hdd_wmm_adapter_close(adapter);
3435 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3436 }
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003437 wlan_hdd_undo_acs(adapter);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303438
3439 hdd_cleanup_actionframe(hdd_ctx, adapter);
3440
3441 hdd_unregister_hostapd(adapter, rtnl_held);
3442
3443 EXIT();
3444}
3445
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003446void hdd_deinit_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
3447 bool rtnl_held)
3448{
3449 ENTER();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303450
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003451 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003452 case QDF_STA_MODE:
3453 case QDF_P2P_CLIENT_MODE:
3454 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003455 {
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05303456 hdd_station_adapter_deinit(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457 break;
3458 }
3459
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003460 case QDF_SAP_MODE:
3461 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003462 {
3463
Arun Khandavalli7e857c32016-06-26 12:07:16 +05303464 hdd_ap_adapter_deinit(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003465 break;
3466 }
3467
3468 default:
3469 break;
3470 }
3471
3472 EXIT();
3473}
3474
Jeff Johnson590e2012016-10-05 16:16:24 -07003475static void hdd_cleanup_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
3476 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003477{
3478 struct net_device *pWlanDev = NULL;
3479
3480 if (adapter)
3481 pWlanDev = adapter->dev;
3482 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07003483 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003484 return;
3485 }
3486
Rajeev Kumardca5f812016-02-04 17:28:06 -08003487 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05303488
3489 if (adapter->scan_info.default_scan_ies) {
3490 qdf_mem_free(adapter->scan_info.default_scan_ies);
3491 adapter->scan_info.default_scan_ies = NULL;
3492 }
3493
Komal Seelama89be8d2016-09-29 11:09:26 +05303494 hdd_adapter_runtime_suspend_denit(adapter);
3495
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003496 /*
3497 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
3498 * the driver is almost closed and cannot handle either control
3499 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003500 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
3501 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003502 * is not right. Setting this flag helps hdd_stop() to recognize that
3503 * the interface is closed and restricts any operations on that
3504 */
3505 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3506
3507 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003508 if (rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003509 unregister_netdevice(pWlanDev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003510 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003511 unregister_netdev(pWlanDev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003512 /*
3513 * Note that the adapter is no longer valid at this point
3514 * since the memory has been reclaimed
3515 */
3516 }
3517}
3518
Jeff Johnson590e2012016-10-05 16:16:24 -07003519static QDF_STATUS hdd_check_for_existing_macaddr(hdd_context_t *hdd_ctx,
3520 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003521{
3522 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
3523 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303524 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003525
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003526 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303527 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003528 adapter = adapterNode->pAdapter;
3529 if (adapter
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303530 && !qdf_mem_cmp(adapter->macAddressCurrent.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003531 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303532 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003533 }
3534 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
3535 adapterNode = pNext;
3536 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303537 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003538}
Ryan Hsu07495ea2016-01-21 15:25:39 -08003539
Arun Khandavalli2358d522016-05-16 18:05:37 +05303540#ifdef CONFIG_FW_LOGS_BASED_ON_INI
3541/**
3542 * hdd_set_fw_log_params() - Set log parameters to FW
3543 * @hdd_ctx: HDD Context
3544 * @adapter: HDD Adapter
3545 *
3546 * This function set the FW Debug log level based on the INI.
3547 *
3548 * Return: None
3549 */
3550static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
3551 hdd_adapter_t *adapter)
3552{
3553 uint8_t count = 0, numentries = 0,
3554 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
3555 uint32_t value = 0;
3556 int ret;
3557
Arun Khandavallifae92942016-08-01 13:31:08 +05303558 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
3559 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003560 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05303561 return;
3562 }
3563
Arun Khandavallifae92942016-08-01 13:31:08 +05303564 /* Enable FW logs based on INI configuration */
Arun Khandavalli2358d522016-05-16 18:05:37 +05303565 hdd_ctx->fw_log_settings.dl_type =
3566 hdd_ctx->config->enableFwLogType;
Naveen Rawat247a8682017-06-05 15:00:31 -07003567 ret = sme_cli_set_command(adapter->sessionId,
Arun Khandavallifae92942016-08-01 13:31:08 +05303568 WMI_DBGLOG_TYPE,
3569 hdd_ctx->config->enableFwLogType,
3570 DBG_CMD);
3571 if (ret != 0)
3572 hdd_err("Failed to enable FW log type ret %d",
3573 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05303574
3575 hdd_ctx->fw_log_settings.dl_loglevel =
Arun Khandavallifae92942016-08-01 13:31:08 +05303576 hdd_ctx->config->enableFwLogLevel;
Naveen Rawat247a8682017-06-05 15:00:31 -07003577 ret = sme_cli_set_command(adapter->sessionId,
Arun Khandavallifae92942016-08-01 13:31:08 +05303578 WMI_DBGLOG_LOG_LEVEL,
3579 hdd_ctx->config->enableFwLogLevel,
3580 DBG_CMD);
3581 if (ret != 0)
3582 hdd_err("Failed to enable FW log level ret %d",
3583 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05303584
3585 hdd_string_to_u8_array(
3586 hdd_ctx->config->enableFwModuleLogLevel,
3587 moduleloglevel,
3588 &numentries,
3589 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
3590
3591 while (count < numentries) {
3592 /*
3593 * FW module log level input string looks like
3594 * below:
3595 * gFwDebugModuleLoglevel=<FW Module ID>,
3596 * <Log Level>,...
3597 * For example:
3598 * gFwDebugModuleLoglevel=
3599 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
3600 * Above input string means :
3601 * For FW module ID 1 enable log level 0
3602 * For FW module ID 2 enable log level 1
3603 * For FW module ID 3 enable log level 2
3604 * For FW module ID 4 enable log level 3
3605 * For FW module ID 5 enable log level 4
3606 * For FW module ID 6 enable log level 5
3607 * For FW module ID 7 enable log level 6
3608 */
3609
Nishank Aggarwale239d962017-03-03 12:26:02 +05303610 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
3611 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
3612 hdd_err("Module id %d and dbglog level %d input length is more than max",
3613 moduleloglevel[count],
3614 moduleloglevel[count + 1]);
3615 return;
3616 }
3617
3618 value = moduleloglevel[count] << 16;
3619 value |= moduleloglevel[count + 1];
Naveen Rawat247a8682017-06-05 15:00:31 -07003620 ret = sme_cli_set_command(adapter->sessionId,
Arun Khandavallifae92942016-08-01 13:31:08 +05303621 WMI_DBGLOG_MOD_LOG_LEVEL,
3622 value, DBG_CMD);
3623 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05303624 hdd_err("Failed to enable FW module log level %d ret %d",
3625 value, ret);
3626
3627 count += 2;
3628 }
Arun Khandavallifae92942016-08-01 13:31:08 +05303629
Arun Khandavalli2358d522016-05-16 18:05:37 +05303630}
3631#else
3632static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
3633 hdd_adapter_t *adapter)
3634{
3635}
3636
3637#endif
3638
3639/**
3640 * hdd_set_fw_params() - Set parameters to firmware
3641 * @adapter: HDD adapter
3642 *
3643 * This function Sets various parameters to fw once the
3644 * adapter is started.
3645 *
3646 * Return: 0 on success or errno on failure
3647 */
3648int hdd_set_fw_params(hdd_adapter_t *adapter)
3649{
3650 int ret;
3651 hdd_context_t *hdd_ctx;
3652
3653 ENTER_DEV(adapter->dev);
3654
3655 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3656 if (!hdd_ctx)
3657 return -EINVAL;
3658
Dustin Brown732ab9c2017-06-15 13:24:09 -07003659 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
3660 hdd_debug("FTM Mode is active; nothing to do");
3661 return 0;
3662 }
3663
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05303664 ret = sme_cli_set_command(adapter->sessionId,
3665 WMI_PDEV_PARAM_DTIM_SYNTH,
3666 hdd_ctx->config->enable_lprx, PDEV_CMD);
3667 if (ret) {
3668 hdd_err("Failed to set LPRx");
3669 goto error;
3670 }
3671
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05303672 if (adapter->device_mode == QDF_STA_MODE) {
3673 sme_set_smps_cfg(adapter->sessionId,
3674 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
3675 hdd_ctx->config->upper_brssi_thresh);
3676
3677 sme_set_smps_cfg(adapter->sessionId,
3678 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
3679 hdd_ctx->config->lower_brssi_thresh);
3680
3681 sme_set_smps_cfg(adapter->sessionId,
3682 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
3683 hdd_ctx->config->enable_dtim_1chrx);
3684 }
3685
Dustin Brown732ab9c2017-06-15 13:24:09 -07003686 if (hdd_ctx->config->enable2x2) {
3687 hdd_debug("configuring 2x2 mode fw params");
3688
Naveen Rawat247a8682017-06-05 15:00:31 -07003689 ret = sme_cli_set_command(adapter->sessionId,
Dustin Brown732ab9c2017-06-15 13:24:09 -07003690 WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE,
3691 hdd_ctx->config->enable_cck_tx_fir_override,
3692 PDEV_CMD);
3693 if (ret) {
3694 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
3695 ret);
3696 goto error;
3697 }
3698 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05303699#define HDD_DTIM_1CHAIN_RX_ID 0x5
3700#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07003701 hdd_debug("configuring 1x1 mode fw params");
3702
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07003703 /*
3704 * Disable DTIM 1 chain Rx when in 1x1,
3705 * we are passing two value
3706 * as param_id << 29 | param_value.
3707 * Below param_value = 0(disable)
3708 */
Naveen Rawat247a8682017-06-05 15:00:31 -07003709 ret = sme_cli_set_command(adapter->sessionId,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07003710 WMI_STA_SMPS_PARAM_CMDID,
3711 HDD_DTIM_1CHAIN_RX_ID <<
3712 HDD_SMPS_PARAM_VALUE_S,
3713 VDEV_CMD);
3714 if (ret) {
3715 hdd_err("DTIM 1 chain set failed %d", ret);
3716 goto error;
3717 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05303718
Naveen Rawat247a8682017-06-05 15:00:31 -07003719 ret = sme_cli_set_command(adapter->sessionId,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07003720 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3721 hdd_ctx->config->txchainmask1x1,
3722 PDEV_CMD);
3723 if (ret) {
3724 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK set failed %d",
3725 ret);
3726 goto error;
3727 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05303728
Naveen Rawat247a8682017-06-05 15:00:31 -07003729 ret = sme_cli_set_command(adapter->sessionId,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07003730 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3731 hdd_ctx->config->rxchainmask1x1,
3732 PDEV_CMD);
3733 if (ret) {
3734 hdd_err("WMI_PDEV_PARAM_RX_CHAIN_MASK set failed %d",
3735 ret);
3736 goto error;
3737 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05303738#undef HDD_DTIM_1CHAIN_RX_ID
3739#undef HDD_SMPS_PARAM_VALUE_S
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07003740 }
3741
Naveen Rawat247a8682017-06-05 15:00:31 -07003742 ret = sme_cli_set_command(adapter->sessionId,
Dustin Brown732ab9c2017-06-15 13:24:09 -07003743 WMI_PDEV_PARAM_HYST_EN,
3744 hdd_ctx->config->enableMemDeepSleep,
3745 PDEV_CMD);
3746 if (ret) {
3747 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
3748 goto error;
3749 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05303750
Naveen Rawat247a8682017-06-05 15:00:31 -07003751 ret = sme_cli_set_command(adapter->sessionId,
Dustin Brown732ab9c2017-06-15 13:24:09 -07003752 WMI_VDEV_PARAM_ENABLE_RTSCTS,
3753 hdd_ctx->config->rts_profile,
3754 VDEV_CMD);
3755 if (ret) {
3756 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
3757 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05303758 }
3759
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07003760 hdd_debug("SET AMSDU num %d", hdd_ctx->config->max_amsdu_num);
3761
3762 ret = wma_cli_set_command(adapter->sessionId,
3763 GEN_VDEV_PARAM_AMSDU,
3764 hdd_ctx->config->max_amsdu_num,
3765 GEN_CMD);
3766 if (ret != 0) {
3767 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
3768 goto error;
3769 }
3770
Arun Khandavalli2358d522016-05-16 18:05:37 +05303771 hdd_set_fw_log_params(hdd_ctx, adapter);
Arun Khandavalli2358d522016-05-16 18:05:37 +05303772 EXIT();
Dustin Brown732ab9c2017-06-15 13:24:09 -07003773
Arun Khandavalli2358d522016-05-16 18:05:37 +05303774 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05303775
Arun Khandavalli2358d522016-05-16 18:05:37 +05303776error:
3777 return -EINVAL;
3778}
3779
Ryan Hsu07495ea2016-01-21 15:25:39 -08003780/**
3781 * hdd_open_adapter() - open and setup the hdd adatper
3782 * @hdd_ctx: global hdd context
3783 * @session_type: type of the interface to be created
3784 * @iface_name: User-visible name of the interface
3785 * @macAddr: MAC address to assign to the interface
3786 * @name_assign_type: the name of assign type of the netdev
3787 * @rtnl_held: the rtnl lock hold flag
3788 *
3789 * This function open and setup the hdd adpater according to the device
3790 * type request, assign the name, the mac address assigned, and then prepared
3791 * the hdd related parameters, queue, lock and ready to start.
3792 *
3793 * Return: the pointer of hdd adapter, otherwise NULL.
3794 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
3796 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003797 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003798 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003799{
3800 hdd_adapter_t *adapter = NULL;
3801 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303802 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003803 hdd_cfg80211_state_t *cfgState;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003805
3806 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
3807 /*
3808 * Max limit reached on the number of vdevs configured by the
3809 * host. Return error
3810 */
Arun Khandavallifae92942016-08-01 13:31:08 +05303811 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
3812 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003813 return NULL;
3814 }
3815
3816 if (macAddr == NULL) {
3817 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05303818 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003819 return NULL;
3820 }
3821 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303822 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05303823 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
3824 " already exists",
3825 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003826 return NULL;
3827 }
3828
3829 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003830 case QDF_STA_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003831 /* Reset locally administered bit if the device mode is STA */
3832 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
3833 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003834 case QDF_P2P_CLIENT_MODE:
3835 case QDF_P2P_DEVICE_MODE:
3836 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07003837 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05303838 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08003839 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
3840 name_assign_type,
3841 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003842
3843 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05303844 hdd_err("failed to allocate adapter for session %d",
3845 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003846 return NULL;
3847 }
3848
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003849 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003851 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003852 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05303853 else if (QDF_MONITOR_MODE == session_type)
3854 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003855 else
3856 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
3857
3858 adapter->device_mode = session_type;
3859
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003861 /*
3862 * Workqueue which gets scheduled in IPv4 notification
3863 * callback
3864 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865 INIT_WORK(&adapter->ipv4NotifierWorkQueue,
3866 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867
3868#ifdef WLAN_NS_OFFLOAD
3869 /*
3870 * Workqueue which gets scheduled in IPv6
3871 * notification callback.
3872 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 INIT_WORK(&adapter->ipv6NotifierWorkQueue,
3874 hdd_ipv6_notifier_work_queue);
3875#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876 status = hdd_register_interface(adapter, rtnl_held);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303877 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003878 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05303879 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003880 }
3881
3882 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003883 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003884 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303885 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3886 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05303887
Ravi Joshi1a292562017-05-18 16:28:54 -07003888 /* Initialize NAN Data Interface */
3889 if (QDF_NDI_MODE == session_type) {
3890 status = hdd_init_nan_data_mode(adapter);
3891 if (QDF_STATUS_SUCCESS != status)
3892 goto err_free_netdev;
3893 }
3894
3895 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003897 case QDF_P2P_GO_MODE:
3898 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08003899 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
3900 name_assign_type,
3901 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003902 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003903 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05303904 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905 return NULL;
3906 }
3907
3908 adapter->wdev.iftype =
3909 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08003910 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003911 NL80211_IFTYPE_P2P_GO;
3912 adapter->device_mode = session_type;
3913
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003914 status = hdd_register_interface(adapter, rtnl_held);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303915 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003916 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3917 goto err_free_netdev;
3918 }
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003919 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003920 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303921 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3922 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003923 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05303924 case QDF_FTM_MODE:
3925 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
3926 name_assign_type,
3927 "wlan0");
3928 if (NULL == adapter) {
3929 hdd_err("Failed to allocate adapter for FTM mode");
3930 return NULL;
3931 }
3932 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
3933 adapter->device_mode = session_type;
3934 status = hdd_register_interface(adapter, rtnl_held);
3935 if (QDF_STATUS_SUCCESS != status) {
3936 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3937 goto err_free_netdev;
3938 }
3939 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003940 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05303941 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303942 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3943 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05303944 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003945 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003946 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303947 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003948 return NULL;
3949 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003950
hqueaa33ee2017-05-04 17:56:35 +08003951 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
3952
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003953 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
3954 mutex_init(&cfgState->remain_on_chan_ctx_lock);
3955
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303956 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003957 /* Add it to the hdd's session list. */
3958 pHddAdapterNode =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303959 qdf_mem_malloc(sizeof(hdd_adapter_list_node_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960 if (NULL == pHddAdapterNode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303961 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003962 } else {
3963 pHddAdapterNode->pAdapter = adapter;
3964 status = hdd_add_adapter_back(hdd_ctx, pHddAdapterNode);
3965 }
3966 }
3967
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303968 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003969 if (NULL != adapter) {
3970 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
3971 adapter = NULL;
3972 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003973 if (NULL != pHddAdapterNode)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303974 qdf_mem_free(pHddAdapterNode);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003975
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003976 return NULL;
3977 }
3978
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303979 if (QDF_STATUS_SUCCESS == status) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08003980 policy_mgr_set_concurrency_mode(hdd_ctx->hdd_psoc,
3981 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003982
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003983 /* Adapter successfully added. Increment the vdev count */
3984 hdd_ctx->current_intf_count++;
3985
Jeff Johnson5880d792016-08-15 13:32:30 -07003986 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003987 hdd_ctx->current_intf_count);
3988
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08003989 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003990 }
3991
Rajeev Kumardca5f812016-02-04 17:28:06 -08003992 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07003993 hdd_err("Interface %s wow debug_fs init failed",
3994 netdev_name(adapter->dev));
3995
3996 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
3997 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003998
3999 return adapter;
4000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001err_free_netdev:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004002 wlan_hdd_release_intf_addr(hdd_ctx, adapter->macAddressCurrent.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05304003 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004004
4005 return NULL;
4006}
4007
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304008QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004009 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010{
4011 hdd_adapter_list_node_t *adapterNode, *pCurrent, *pNext;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304012 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004013
4014 status = hdd_get_front_adapter(hdd_ctx, &pCurrent);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304015 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004016 hdd_warn("adapter list empty %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004017 status);
4018 return status;
4019 }
4020
4021 while (pCurrent->pAdapter != adapter) {
4022 status = hdd_get_next_adapter(hdd_ctx, pCurrent, &pNext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304023 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004024 break;
4025
4026 pCurrent = pNext;
4027 }
4028 adapterNode = pCurrent;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304029 if (QDF_STATUS_SUCCESS == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004030 hdd_debug("wait for bus bw work to flush");
Dustin Brown5ec6b552017-03-31 12:11:40 -07004031 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05304032 cancel_work_sync(&hdd_ctx->bus_bw_work);
Dustin Brown5ec6b552017-03-31 12:11:40 -07004033
4034 /* cleanup adapter */
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004035 policy_mgr_clear_concurrency_mode(hdd_ctx->hdd_psoc,
4036 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004037 hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038 hdd_remove_adapter(hdd_ctx, adapterNode);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304039 qdf_mem_free(adapterNode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004040 adapterNode = NULL;
4041
Dustin Brown5ec6b552017-03-31 12:11:40 -07004042 /* conditionally restart the bw timer */
4043 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
4044
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004045 /* Adapter removed. Decrement vdev count */
4046 if (hdd_ctx->current_intf_count != 0)
4047 hdd_ctx->current_intf_count--;
4048
4049 /* Fw will take care incase of concurrency */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304050 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304052
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304053 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004054}
4055
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004056/**
4057 * hdd_close_all_adapters - Close all open adapters
4058 * @hdd_ctx: Hdd context
4059 * rtnl_held: True if RTNL lock held
4060 *
4061 * Close all open adapters.
4062 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304063 * Return: QDF status code
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004064 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304065QDF_STATUS hdd_close_all_adapters(hdd_context_t *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066{
4067 hdd_adapter_list_node_t *pHddAdapterNode;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304068 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004069
4070 ENTER();
4071
4072 do {
4073 status = hdd_remove_front_adapter(hdd_ctx, &pHddAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304074 if (pHddAdapterNode && QDF_STATUS_SUCCESS == status) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304075 wlan_hdd_release_intf_addr(hdd_ctx,
4076 pHddAdapterNode->pAdapter->macAddressCurrent.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077 hdd_cleanup_adapter(hdd_ctx, pHddAdapterNode->pAdapter,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004078 rtnl_held);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304079 qdf_mem_free(pHddAdapterNode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05304080 /* Adapter removed. Decrement vdev count */
4081 if (hdd_ctx->current_intf_count != 0)
4082 hdd_ctx->current_intf_count--;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004083 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304084 } while (NULL != pHddAdapterNode && QDF_STATUS_E_EMPTY != status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004085
4086 EXIT();
4087
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304088 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004089}
4090
4091void wlan_hdd_reset_prob_rspies(hdd_adapter_t *pHostapdAdapter)
4092{
Anurag Chouhan6d760662016-02-20 16:05:43 +05304093 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004094 tSirUpdateIE updateIE;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004095
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004096 switch (pHostapdAdapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004097 case QDF_STA_MODE:
4098 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004099 {
4100 hdd_station_ctx_t *pHddStaCtx =
4101 WLAN_HDD_GET_STATION_CTX_PTR(pHostapdAdapter);
Srinivas Girigowda8b983962015-11-18 22:14:34 -08004102 bssid = &pHddStaCtx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004103 break;
4104 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004105 case QDF_SAP_MODE:
4106 case QDF_P2P_GO_MODE:
4107 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004108 {
Srinivas Girigowda8b983962015-11-18 22:14:34 -08004109 bssid = &pHostapdAdapter->macAddressCurrent;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004110 break;
4111 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004112 case QDF_FTM_MODE:
4113 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114 default:
4115 /*
4116 * wlan_hdd_reset_prob_rspies should not have been called
4117 * for these kind of devices
4118 */
Jeff Johnson5880d792016-08-15 13:32:30 -07004119 hdd_err("Unexpected request for the current device type %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004120 pHostapdAdapter->device_mode);
4121 return;
4122 }
4123
Anurag Chouhanc5548422016-02-24 18:33:27 +05304124 qdf_copy_macaddr(&updateIE.bssid, bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 updateIE.smeSessionId = pHostapdAdapter->sessionId;
4126 updateIE.ieBufferlength = 0;
4127 updateIE.pAdditionIEBuffer = NULL;
4128 updateIE.append = true;
4129 updateIE.notify = false;
4130 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
4131 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304132 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004133 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004134 }
4135}
4136
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304137QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138 const bool bCloseSession)
4139{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304140 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
4142 union iwreq_data wrqu;
4143 tSirUpdateIE updateIE;
4144 unsigned long rc;
Sachin Ahuja988fd102016-09-15 17:16:25 +05304145 hdd_scaninfo_t *scan_info = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146
4147 ENTER();
4148
Sachin Ahuja988fd102016-09-15 17:16:25 +05304149 scan_info = &adapter->scan_info;
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004150 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304151 wlan_hdd_netif_queue_control(adapter,
4152 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
4153 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004154 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004155 case QDF_STA_MODE:
4156 case QDF_P2P_CLIENT_MODE:
4157 case QDF_IBSS_MODE:
4158 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004159 case QDF_NDI_MODE:
4160 if ((QDF_NDI_MODE == adapter->device_mode) ||
4161 hdd_conn_is_connected(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004162 WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
4163 hdd_is_connecting(
4164 WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004165 INIT_COMPLETION(adapter->disconnect_comp_var);
4166 /*
4167 * For NDI do not use pWextState from sta_ctx, if needed
4168 * extract from ndi_ctx.
4169 */
4170 if (QDF_NDI_MODE == adapter->device_mode)
4171 qdf_ret_status = sme_roam_disconnect(
4172 hdd_ctx->hHal,
4173 adapter->sessionId,
4174 eCSR_DISCONNECT_REASON_NDI_DELETE);
4175 else if (pWextState->roamProfile.BSSType ==
4176 eCSR_BSS_TYPE_START_IBSS)
4177 qdf_ret_status = sme_roam_disconnect(
4178 hdd_ctx->hHal,
4179 adapter->sessionId,
4180 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004181 else if (QDF_STA_MODE == adapter->device_mode)
4182 qdf_ret_status =
4183 wlan_hdd_try_disconnect(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 else
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004185 qdf_ret_status = sme_roam_disconnect(
4186 hdd_ctx->hHal,
4187 adapter->sessionId,
4188 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004189 /* success implies disconnect command got
4190 * queued up successfully
4191 */
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004192 if (qdf_ret_status == QDF_STATUS_SUCCESS &&
4193 QDF_STA_MODE != adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004194 rc = wait_for_completion_timeout(
4195 &adapter->disconnect_comp_var,
4196 msecs_to_jiffies
4197 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004198 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004199 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004200 }
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07004201 if (qdf_ret_status != QDF_STATUS_SUCCESS)
4202 hdd_warn("failed to post disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004203 memset(&wrqu, '\0', sizeof(wrqu));
4204 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4205 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
4206 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
4207 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05304208 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004209 if (scan_info != NULL && scan_info->mScanPending)
Mahesh A Saptasagarebb47fa2016-07-21 18:11:38 +05304210 wlan_hdd_scan_abort(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004211
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05304212 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213
4214#ifdef WLAN_OPEN_SOURCE
4215 cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
4216#endif
4217
4218 hdd_deregister_tx_flow_control(adapter);
4219
4220#ifdef WLAN_NS_OFFLOAD
4221#ifdef WLAN_OPEN_SOURCE
4222 cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
4223#endif
4224#endif
4225
Hanumanth Reddy Pothula05860142017-07-26 18:45:27 +05304226 if (adapter->device_mode == QDF_STA_MODE)
4227 wlan_cfg80211_sched_scan_stop(hdd_ctx->hdd_pdev,
4228 adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004229 /*
4230 * It is possible that the caller of this function does not
4231 * wish to close the session
4232 */
Krunal Soni985b8132017-02-10 18:49:08 -08004233 if (true == bCloseSession) {
4234 if (0 != wlan_hdd_try_disconnect(adapter)) {
4235 hdd_err("Error: Can't disconnect adapter");
4236 return QDF_STATUS_E_FAILURE;
4237 }
Dustin Brown0d2eeae2017-03-24 15:21:32 -07004238 hdd_vdev_destroy(adapter);
Krunal Soni985b8132017-02-10 18:49:08 -08004239 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004240 break;
4241
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004242 case QDF_SAP_MODE:
4243 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004244 /* Any softap specific cleanup here... */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004245 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004246 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
4247
4248 hdd_deregister_tx_flow_control(adapter);
4249
Kapil Guptac1224bf2017-06-22 21:22:40 +05304250 hdd_destroy_acs_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251 mutex_lock(&hdd_ctx->sap_lock);
4252 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304253 QDF_STATUS status;
Anurag Chouhance0dc992016-02-16 18:18:03 +05304254 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004255
4256 /* Stop Bss. */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004257 status = wlansap_stop_bss(
4258 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004259
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304260 if (QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261 hdd_hostapd_state_t *hostapd_state =
4262 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05304263 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304264 qdf_stop_bss_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05304265 qdf_status =
4266 qdf_wait_single_event(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -08004267 qdf_stop_bss_event,
4268 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004269
Anurag Chouhance0dc992016-02-16 18:18:03 +05304270 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004271 hdd_err("failure waiting for wlansap_stop_bss %d",
4272 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004273 }
4274 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004275 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004276 }
4277 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004278 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
4279 adapter->device_mode,
4280 adapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281
Anurag Chouhanc5548422016-02-24 18:33:27 +05304282 qdf_copy_macaddr(&updateIE.bssid,
Srinivas Girigowda8b983962015-11-18 22:14:34 -08004283 &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004284 updateIE.smeSessionId = adapter->sessionId;
4285 updateIE.ieBufferlength = 0;
4286 updateIE.pAdditionIEBuffer = NULL;
4287 updateIE.append = false;
4288 updateIE.notify = false;
4289 /* Probe bcn reset */
4290 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
4291 &updateIE, eUPDATE_IE_PROBE_BCN)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304292 == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004293 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004294 }
4295 /* Assoc resp reset */
4296 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
4297 &updateIE,
4298 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304299 QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07004300 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004301 }
4302 /* Reset WNI_CFG_PROBE_RSP Flags */
4303 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004304 }
Manikandan Mohan3dad1a42017-06-14 10:50:18 -07004305 qdf_mem_free(adapter->sessionCtx.ap.beacon);
4306 adapter->sessionCtx.ap.beacon = NULL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05304307 /*
4308 * If Do_Not_Break_Stream was enabled clear avoid channel list.
4309 */
4310 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev))
4311 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
4312
Peng Xu66162de2016-02-11 17:01:20 -08004313 if (true == bCloseSession)
Dustin Brown0d2eeae2017-03-24 15:21:32 -07004314 hdd_vdev_destroy(adapter);
Manikandan Mohan5df78272017-03-22 16:28:50 -07004315 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004316 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004317 case QDF_OCB_MODE:
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08004318 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004319 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
Leo Changfdb45c32016-10-28 11:09:23 -07004320 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.staId[0]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004321 break;
4322 default:
4323 break;
4324 }
4325
4326 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304327 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004328}
4329
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05304330/**
4331 * hdd_deinit_all_adapters - deinit all adapters
4332 * @hdd_ctx: HDD context
4333 * @rtnl_held: True if RTNL lock held
4334 *
4335 */
4336void hdd_deinit_all_adapters(hdd_context_t *hdd_ctx, bool rtnl_held)
4337{
4338 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
4339 QDF_STATUS status;
4340 hdd_adapter_t *adapter;
4341
4342 ENTER();
4343
4344 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
4345
4346 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
4347 adapter = adapter_node->pAdapter;
4348 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
4349 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
4350 adapter_node = next;
4351 }
4352
4353 EXIT();
4354}
4355
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304356QDF_STATUS hdd_stop_all_adapters(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357{
4358 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304359 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004360 hdd_adapter_t *adapter;
4361
4362 ENTER();
4363
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304364 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
4365
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004366 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4367
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304368 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004369 adapter = adapterNode->pAdapter;
4370 hdd_stop_adapter(hdd_ctx, adapter, true);
4371 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4372 adapterNode = pNext;
4373 }
4374
4375 EXIT();
4376
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304377 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004378}
4379
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304380QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004381{
4382 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304383 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004384 hdd_adapter_t *adapter;
Yue Mad5b4b9f2017-05-26 16:23:40 -07004385 hdd_station_ctx_t *pHddStaCtx;
4386 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004387
4388 ENTER();
4389
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304390 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
4391
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004392 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4393
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304394 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004395 adapter = adapterNode->pAdapter;
Yue Mad5b4b9f2017-05-26 16:23:40 -07004396 hdd_notice("Disabling queues for adapter type: %d",
4397 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304398
4399 if ((adapter->device_mode == QDF_STA_MODE) ||
Kabilan Kannan00d20412017-06-04 14:20:32 -07004400 (adapter->device_mode == QDF_P2P_CLIENT_MODE))
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304401 /* Stop tdls timers */
Kabilan Kannan00d20412017-06-04 14:20:32 -07004402 hdd_notify_tdls_reset_adapter(adapter->hdd_vdev);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05304403
Arun Khandavallicc544b32017-01-30 19:52:16 +05304404 if (hdd_ctx->config->sap_internal_restart &&
4405 adapter->device_mode == QDF_SAP_MODE) {
4406 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304407 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05304408 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004409 if (test_bit(SOFTAP_BSS_STARTED,
4410 &adapter->event_flags)) {
4411 hdd_sap_indicate_disconnect_for_sta(adapter);
4412 hdd_cleanup_actionframe(hdd_ctx, adapter);
4413 hdd_sap_destroy_events(adapter);
4414 }
4415 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
4416 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05304417 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05304418 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004419 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08004420 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004421
4422 adapter->sessionCtx.station.hdd_ReassocScenario = false;
4423
4424 hdd_deinit_tx_rx(adapter);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004425 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
4426 adapter->device_mode, adapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004427 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4428 hdd_wmm_adapter_close(adapter);
4429 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4430 }
4431
Wu Gao3545e642017-07-14 19:24:41 +08004432 if (adapter->device_mode == QDF_SAP_MODE) {
4433 /*
4434 * If adapter is SAP, set session ID to invalid
4435 * since SAP session will be cleanup during SSR.
4436 */
Wu Gao36717432016-11-21 15:09:48 +08004437 wlansap_set_invalid_session(
4438 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
4439
Wu Gao3545e642017-07-14 19:24:41 +08004440 wlansap_cleanup_cac_timer(
4441 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
4442 }
4443
Yue Mad5b4b9f2017-05-26 16:23:40 -07004444 /* Delete peers if any for STA and P2P client modes */
4445 if (adapter->device_mode == QDF_STA_MODE ||
4446 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4447 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
4448 qdf_copy_macaddr(&peerMacAddr,
4449 &pHddStaCtx->conn_info.bssId);
4450
4451 hdd_objmgr_remove_peer_object(adapter->hdd_vdev,
4452 peerMacAddr.bytes);
4453 }
4454
Yue Maf9782842017-05-08 12:49:49 -07004455 /* Destroy vdev which will be recreated during reinit. */
4456 hdd_vdev_destroy(adapter);
4457
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004458 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4459 adapterNode = pNext;
4460 }
4461
4462 EXIT();
4463
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304464 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004465}
4466
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304467bool hdd_check_for_opened_interfaces(hdd_context_t *hdd_ctx)
4468{
4469 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
4470 QDF_STATUS status;
4471 bool close_modules = true;
4472
4473 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
4474 while ((NULL != adapter_node) && (QDF_STATUS_SUCCESS == status)) {
4475 if (test_bit(DEVICE_IFACE_OPENED,
4476 &adapter_node->pAdapter->event_flags)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004477 hdd_debug("Still other ifaces are up cannot close modules");
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05304478 close_modules = false;
4479 break;
4480 }
4481 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
4482 adapter_node = next;
4483 }
4484
4485 return close_modules;
4486}
4487
Arun Khandavallifae92942016-08-01 13:31:08 +05304488/**
4489 * hdd_is_interface_up()- Checkfor interface up before ssr
4490 * @hdd_ctx: HDD context
4491 *
4492 * check if there are any wlan interfaces before SSR accordingly start
4493 * the interface.
4494 *
4495 * Return: 0 if interface was opened else false
4496 */
4497static bool hdd_is_interface_up(hdd_adapter_t *adapter)
4498{
4499 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
4500 return true;
4501 else
4502 return false;
4503}
4504
Anurag Chouhanc4092922016-09-08 15:56:11 +05304505#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08004506 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05304507struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
4508 struct ieee80211_channel *channel,
4509 const u8 *bssid, const u8 *ssid,
4510 size_t ssid_len)
4511{
4512 return cfg80211_get_bss(wiphy, channel, bssid,
4513 ssid, ssid_len,
4514 WLAN_CAPABILITY_ESS,
4515 WLAN_CAPABILITY_ESS);
4516}
4517#else
4518struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
4519 struct ieee80211_channel *channel,
4520 const u8 *bssid, const u8 *ssid,
4521 size_t ssid_len)
4522{
4523 return cfg80211_get_bss(wiphy, channel, bssid,
4524 ssid, ssid_len,
4525 IEEE80211_BSS_TYPE_ESS,
4526 IEEE80211_PRIVACY_ANY);
4527}
4528#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05304529
Abhishek Singha84d3952016-09-13 13:45:05 +05304530#if defined CFG80211_CONNECT_BSS
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304531#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
4532 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
4533/**
4534 * hdd_convert_timeout_reason() - Convert to kernel specific enum
4535 * @timeout_reason: reason for connect timeout
4536 *
4537 * This function is used to convert host timeout
4538 * reason enum to kernel specific enum.
4539 *
4540 * Return: nl timeout enum
4541 */
4542static enum nl80211_timeout_reason hdd_convert_timeout_reason(
4543 tSirResultCodes timeout_reason)
4544{
4545 switch (timeout_reason) {
4546 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
4547 return NL80211_TIMEOUT_SCAN;
4548 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
4549 return NL80211_TIMEOUT_AUTH;
4550 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
4551 return NL80211_TIMEOUT_ASSOC;
4552 default:
4553 return NL80211_TIMEOUT_UNSPECIFIED;
4554 }
4555}
4556
4557/**
4558 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
4559 * @dev: network device
4560 * @bssid: bssid to which we want to associate
4561 * @timeout_reason: reason for connect timeout
4562 *
4563 * This API is used to send connection timeout reason to supplicant
4564 *
4565 * Return: void
4566 */
4567static void hdd_cfg80211_connect_timeout(struct net_device *dev,
4568 const u8 *bssid,
4569 tSirResultCodes timeout_reason)
4570{
4571 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004572
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304573 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
4574
4575 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
4576 nl_timeout_reason);
4577}
4578
4579/**
4580 * __hdd_connect_bss() - API to send connection status to supplicant
4581 * @dev: network device
4582 * @bssid: bssid to which we want to associate
4583 * @req_ie: Request Information Element
4584 * @req_ie_len: len of the req IE
4585 * @resp_ie: Response IE
4586 * @resp_ie_len: len of ht response IE
4587 * @status: status
4588 * @gfp: Kernel Flag
4589 * @timeout_reason: reason for connect timeout
4590 *
4591 * Return: void
4592 */
4593static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
4594 struct cfg80211_bss *bss, const u8 *req_ie,
4595 size_t req_ie_len, const u8 *resp_ie,
4596 size_t resp_ie_len, int status, gfp_t gfp,
4597 tSirResultCodes timeout_reason)
4598{
4599 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004600
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304601 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
4602
4603 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
4604 resp_ie, resp_ie_len, status, gfp,
4605 nl_timeout_reason);
4606}
4607#else
4608#if defined CFG80211_CONNECT_TIMEOUT
4609static void hdd_cfg80211_connect_timeout(struct net_device *dev,
4610 const u8 *bssid,
4611 tSirResultCodes timeout_reason)
4612{
4613 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
4614}
4615#endif
4616
4617static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
4618 struct cfg80211_bss *bss, const u8 *req_ie,
4619 size_t req_ie_len, const u8 *resp_ie,
4620 size_t resp_ie_len, int status, gfp_t gfp,
4621 tSirResultCodes timeout_reason)
4622{
4623 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
4624 resp_ie, resp_ie_len, status, gfp);
4625}
4626#endif
4627
Abhishek Singha84d3952016-09-13 13:45:05 +05304628/**
4629 * hdd_connect_bss() - API to send connection status to supplicant
4630 * @dev: network device
4631 * @bssid: bssid to which we want to associate
4632 * @req_ie: Request Information Element
4633 * @req_ie_len: len of the req IE
4634 * @resp_ie: Response IE
4635 * @resp_ie_len: len of ht response IE
4636 * @status: status
4637 * @gfp: Kernel Flag
4638 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304639 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05304640 *
4641 * The API is a wrapper to send connection status to supplicant
4642 *
4643 * Return: Void
4644 */
4645#if defined CFG80211_CONNECT_TIMEOUT
4646static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
4647 struct cfg80211_bss *bss, const u8 *req_ie,
4648 size_t req_ie_len, const u8 *resp_ie,
4649 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304650 bool connect_timeout,
4651 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05304652{
4653 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304654 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05304655 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304656 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
4657 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05304658}
4659#else
4660static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
4661 struct cfg80211_bss *bss, const u8 *req_ie,
4662 size_t req_ie_len, const u8 *resp_ie,
4663 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304664 bool connect_timeout,
4665 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05304666{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304667 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
4668 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05304669}
4670#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05304671
4672/**
4673 * hdd_connect_result() - API to send connection status to supplicant
4674 * @dev: network device
4675 * @bssid: bssid to which we want to associate
4676 * @roam_info: information about connected bss
4677 * @req_ie: Request Information Element
4678 * @req_ie_len: len of the req IE
4679 * @resp_ie: Response IE
4680 * @resp_ie_len: len of ht response IE
4681 * @status: status
4682 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05304683 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304684 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05304685 *
4686 * The API is a wrapper to send connection status to supplicant
4687 * and allow runtime suspend
4688 *
4689 * Return: Void
4690 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05304691void hdd_connect_result(struct net_device *dev, const u8 *bssid,
4692 tCsrRoamInfo *roam_info, const u8 *req_ie,
4693 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05304694 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304695 bool connect_timeout,
4696 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05304697{
4698 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
4699 struct cfg80211_bss *bss = NULL;
4700
4701 if (WLAN_STATUS_SUCCESS == status) {
4702 struct ieee80211_channel *chan;
4703 int freq;
4704 int chan_no = roam_info->pBssDesc->channelId;
4705
4706 if (chan_no <= 14)
4707 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07004708 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05304709 else
4710 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07004711 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05304712
4713 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
4714 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
4715 roam_info->u.pConnectedProfile->SSID.ssId,
4716 roam_info->u.pConnectedProfile->SSID.length);
4717 }
Komal Seelama89be8d2016-09-29 11:09:26 +05304718
Abhishek Singha84d3952016-09-13 13:45:05 +05304719 hdd_connect_bss(dev, bssid, bss, req_ie,
4720 req_ie_len, resp_ie, resp_ie_len,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304721 status, gfp, connect_timeout, timeout_reason);
Komal Seelama89be8d2016-09-29 11:09:26 +05304722
4723 qdf_runtime_pm_allow_suspend(padapter->connect_rpm_ctx.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07004724 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05304725}
4726#else
4727void hdd_connect_result(struct net_device *dev, const u8 *bssid,
4728 tCsrRoamInfo *roam_info, const u8 *req_ie,
4729 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05304730 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304731 bool connect_timeout,
4732 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05304733{
Komal Seelama89be8d2016-09-29 11:09:26 +05304734 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
4735
Anurag Chouhanc4092922016-09-08 15:56:11 +05304736 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
4737 resp_ie, resp_ie_len, status, gfp);
Komal Seelama89be8d2016-09-29 11:09:26 +05304738 qdf_runtime_pm_allow_suspend(padapter->connect_rpm_ctx.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07004739 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05304740}
4741#endif
4742
4743
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304744QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004745{
4746 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304747 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004748 hdd_adapter_t *adapter;
4749#ifndef MSM_PLATFORM
Anurag Chouhan6d760662016-02-20 16:05:43 +05304750 struct qdf_mac_addr bcastMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004751#endif
4752 eConnectionState connState;
4753
4754 ENTER();
4755
4756 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304757 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004758 adapter = adapterNode->pAdapter;
4759
Arun Khandavallifae92942016-08-01 13:31:08 +05304760 if (!hdd_is_interface_up(adapter))
Hanumanth Reddy Pothulac1c4d2b2016-09-22 15:45:16 +05304761 goto get_adapter;
Arun Khandavallifae92942016-08-01 13:31:08 +05304762
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004763 hdd_wmm_init(adapter);
4764
Dustin Browna7e6a5c2017-07-07 12:52:24 -07004765 adapter->scan_info.mScanPending = false;
4766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004767 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004768 case QDF_STA_MODE:
4769 case QDF_P2P_CLIENT_MODE:
4770 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004771
4772 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
4773 ->conn_info.connState;
4774
4775 hdd_init_station_mode(adapter);
4776 /* Open the gates for HDD to receive Wext commands */
4777 adapter->isLinkUpSvcNeeded = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004778
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004779 /* Indicate disconnect event to supplicant
4780 * if associated previously
4781 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004782 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07004783 eConnectionState_IbssConnected == connState ||
4784 eConnectionState_NotConnected == connState ||
4785 eConnectionState_IbssDisconnected == connState ||
4786 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004787 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004788
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004789 memset(&wrqu, '\0', sizeof(wrqu));
4790 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4791 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
4792 wireless_send_event(adapter->dev, SIOCGIWAP,
4793 &wrqu, NULL);
4794 adapter->sessionCtx.station.
4795 hdd_ReassocScenario = false;
4796
4797 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05304798 wlan_hdd_cfg80211_indicate_disconnect(
4799 adapter->dev, false,
4800 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004801 } else if (eConnectionState_Connecting == connState) {
4802 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004803 * Indicate connect failure to supplicant if we
4804 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004805 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05304806 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05304807 NULL, 0, NULL, 0,
4808 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004809 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004810 }
4811
4812 hdd_register_tx_flow_control(adapter,
4813 hdd_tx_resume_timer_expired_handler,
4814 hdd_tx_resume_cb);
4815
4816 break;
4817
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004818 case QDF_SAP_MODE:
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004819 if (hdd_ctx->config->sap_internal_restart)
Arun Khandavallicc544b32017-01-30 19:52:16 +05304820 hdd_init_ap_mode(adapter, true);
4821
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004822 break;
4823
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004824 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004825#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004826 hdd_debug("[SSR] send stop ap to supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004827 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
4828#else
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004829 hdd_debug("[SSR] send restart supplicant");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004830 /* event supplicant to restart */
4831 cfg80211_del_sta(adapter->dev,
4832 (const u8 *)&bcastMac.bytes[0],
4833 GFP_KERNEL);
4834#endif
4835 break;
4836
4837 default:
4838 break;
4839 }
Hanumanth Reddy Pothulac1c4d2b2016-09-22 15:45:16 +05304840get_adapter:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004841 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4842 adapterNode = pNext;
4843 }
4844
4845 EXIT();
4846
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304847 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848}
4849
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304850QDF_STATUS hdd_get_front_adapter(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851 hdd_adapter_list_node_t **padapterNode)
4852{
Anurag Chouhanffb21542016-02-17 14:33:03 +05304853 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004854
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004855 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304856 status = qdf_list_peek_front(&hdd_ctx->hddAdapters,
4857 (qdf_list_node_t **) padapterNode);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004858 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004859 return status;
4860}
4861
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304862QDF_STATUS hdd_get_next_adapter(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004863 hdd_adapter_list_node_t *adapterNode,
4864 hdd_adapter_list_node_t **pNextAdapterNode)
4865{
Anurag Chouhanffb21542016-02-17 14:33:03 +05304866 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004867
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004868 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304869 status = qdf_list_peek_next(&hdd_ctx->hddAdapters,
4870 (qdf_list_node_t *) adapterNode,
4871 (qdf_list_node_t **) pNextAdapterNode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004872
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004873 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004874 return status;
4875}
4876
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304877QDF_STATUS hdd_remove_adapter(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 hdd_adapter_list_node_t *adapterNode)
4879{
Anurag Chouhanffb21542016-02-17 14:33:03 +05304880 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004881
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004882 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304883 status = qdf_list_remove_node(&hdd_ctx->hddAdapters,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004884 &adapterNode->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004885 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004886 return status;
4887}
4888
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304889QDF_STATUS hdd_remove_front_adapter(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004890 hdd_adapter_list_node_t **padapterNode)
4891{
Anurag Chouhanffb21542016-02-17 14:33:03 +05304892 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004893
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004894 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304895 status = qdf_list_remove_front(&hdd_ctx->hddAdapters,
4896 (qdf_list_node_t **) padapterNode);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004897 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004898 return status;
4899}
4900
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304901QDF_STATUS hdd_add_adapter_back(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004902 hdd_adapter_list_node_t *adapterNode)
4903{
Anurag Chouhanffb21542016-02-17 14:33:03 +05304904 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004905
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004906 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304907 status = qdf_list_insert_back(&hdd_ctx->hddAdapters,
4908 (qdf_list_node_t *) adapterNode);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004909 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004910 return status;
4911}
4912
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304913QDF_STATUS hdd_add_adapter_front(hdd_context_t *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004914 hdd_adapter_list_node_t *adapterNode)
4915{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304916 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004917
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004918 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +05304919 status = qdf_list_insert_front(&hdd_ctx->hddAdapters,
4920 (qdf_list_node_t *) adapterNode);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08004921 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004922 return status;
4923}
4924
4925hdd_adapter_t *hdd_get_adapter_by_macaddr(hdd_context_t *hdd_ctx,
4926 tSirMacAddr macAddr)
4927{
4928 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4929 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304930 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004931
4932 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4933
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304934 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004935 adapter = adapterNode->pAdapter;
4936
4937 if (adapter
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304938 && !qdf_mem_cmp(adapter->macAddressCurrent.bytes,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004939 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004940 return adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004941
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004942 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4943 adapterNode = pNext;
4944 }
4945
4946 return NULL;
4947
4948}
4949
4950hdd_adapter_t *hdd_get_adapter_by_vdev(hdd_context_t *hdd_ctx,
4951 uint32_t vdev_id)
4952{
4953 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4954 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304955 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004956
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304957 qdf_status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004958
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304959 while ((NULL != adapterNode) && (QDF_STATUS_SUCCESS == qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004960 adapter = adapterNode->pAdapter;
4961
4962 if (adapter->sessionId == vdev_id)
4963 return adapter;
4964
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304965 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004966 hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4967 adapterNode = pNext;
4968 }
4969
Jeff Johnson5880d792016-08-15 13:32:30 -07004970 hdd_err("vdev_id %d does not exist with host", vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004971
4972 return NULL;
4973}
4974
Abhishek Singh7996eb72015-12-30 17:24:02 +05304975/**
4976 * hdd_get_adapter_by_sme_session_id() - Return adapter with
4977 * the sessionid
4978 * @hdd_ctx: hdd context.
4979 * @sme_session_id: sme session is for the adapter to get.
4980 *
4981 * This function is used to get the adapter with provided session id
4982 *
4983 * Return: adapter pointer if found
4984 *
4985 */
4986hdd_adapter_t *hdd_get_adapter_by_sme_session_id(hdd_context_t *hdd_ctx,
4987 uint32_t sme_session_id)
4988{
4989 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
4990 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304991 QDF_STATUS qdf_status;
Abhishek Singh7996eb72015-12-30 17:24:02 +05304992
4993
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304994 qdf_status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
Abhishek Singh7996eb72015-12-30 17:24:02 +05304995
4996 while ((NULL != adapter_node) &&
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304997 (QDF_STATUS_SUCCESS == qdf_status)) {
Abhishek Singh7996eb72015-12-30 17:24:02 +05304998 adapter = adapter_node->pAdapter;
4999
5000 if (adapter &&
5001 adapter->sessionId == sme_session_id)
5002 return adapter;
5003
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305004 qdf_status =
Abhishek Singh7996eb72015-12-30 17:24:02 +05305005 hdd_get_next_adapter(hdd_ctx,
5006 adapter_node, &next);
5007 adapter_node = next;
5008 }
5009 return NULL;
5010}
5011
Naveen Rawat4edb6822017-04-12 10:09:17 -07005012hdd_adapter_t *hdd_get_adapter_by_iface_name(hdd_context_t *hdd_ctx,
5013 const char *iface_name)
5014{
5015 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
5016 hdd_adapter_t *adapter;
5017 QDF_STATUS qdf_status;
5018
5019 qdf_status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
5020
5021 while ((NULL != adapter_node) &&
5022 (QDF_STATUS_SUCCESS == qdf_status)) {
5023 adapter = adapter_node->pAdapter;
5024
5025 if (adapter &&
5026 !qdf_str_cmp(adapter->dev->name, iface_name))
5027 return adapter;
5028
5029 qdf_status =
5030 hdd_get_next_adapter(hdd_ctx,
5031 adapter_node, &next);
5032 adapter_node = next;
5033 }
5034 return NULL;
5035}
5036
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005037/**
5038 * hdd_get_adapter() - to get adapter matching the mode
5039 * @hdd_ctx: hdd context
5040 * @mode: adapter mode
5041 *
5042 * This routine will return the pointer to adapter matching
5043 * with the passed mode.
5044 *
5045 * Return: pointer to adapter or null
5046 */
5047hdd_adapter_t *hdd_get_adapter(hdd_context_t *hdd_ctx,
5048 enum tQDF_ADAPTER_MODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005049{
5050 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
5051 hdd_adapter_t *adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305052 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005053
5054 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
5055
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305056 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057 adapter = adapterNode->pAdapter;
5058
5059 if (adapter && (mode == adapter->device_mode))
5060 return adapter;
5061
5062 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
5063 adapterNode = pNext;
5064 }
5065
5066 return NULL;
5067
5068}
5069
5070/**
5071 * hdd_get_operating_channel() - return operating channel of the device mode
5072 * @hdd_ctx: Pointer to the HDD context.
5073 * @mode: Device mode for which operating channel is required.
5074 * Suported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005075 * QDF_STA_MODE,
5076 * QDF_P2P_CLIENT_MODE,
5077 * QDF_SAP_MODE,
5078 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005079 *
5080 * This API returns the operating channel of the requested device mode
5081 *
5082 * Return: channel number. "0" id the requested device is not found OR it is
5083 * not connected.
5084 */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005085uint8_t hdd_get_operating_channel(hdd_context_t *hdd_ctx,
5086 enum tQDF_ADAPTER_MODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005087{
5088 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305089 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090 hdd_adapter_t *adapter;
5091 uint8_t operatingChannel = 0;
5092
5093 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
5094
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305095 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005096 adapter = adapterNode->pAdapter;
5097
5098 if (mode == adapter->device_mode) {
5099 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005100 case QDF_STA_MODE:
5101 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005102 if (hdd_conn_is_connected
5103 (WLAN_HDD_GET_STATION_CTX_PTR
5104 (adapter))) {
5105 operatingChannel =
5106 (WLAN_HDD_GET_STATION_CTX_PTR
5107 (adapter))->conn_info.
5108 operationChannel;
5109 }
5110 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005111 case QDF_SAP_MODE:
5112 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005113 /* softap connection info */
5114 if (test_bit
5115 (SOFTAP_BSS_STARTED,
5116 &adapter->event_flags))
5117 operatingChannel =
5118 (WLAN_HDD_GET_AP_CTX_PTR
5119 (adapter))->operatingChannel;
5120 break;
5121 default:
5122 break;
5123 }
5124
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005125 /* Found the device of interest. break the loop */
5126 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005127 }
5128
5129 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
5130 adapterNode = pNext;
5131 }
5132 return operatingChannel;
5133}
5134
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305135static inline QDF_STATUS hdd_unregister_wext_all_adapters(hdd_context_t *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005136 hdd_ctx)
5137{
5138 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305139 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005140 hdd_adapter_t *adapter;
5141
5142 ENTER();
5143
5144 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
5145
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305146 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147 adapter = adapterNode->pAdapter;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005148 if ((adapter->device_mode == QDF_STA_MODE) ||
5149 (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
5150 (adapter->device_mode == QDF_IBSS_MODE) ||
5151 (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
5152 (adapter->device_mode == QDF_SAP_MODE) ||
5153 (adapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005154 wlan_hdd_cfg80211_deregister_frames(adapter);
5155 hdd_unregister_wext(adapter->dev);
5156 }
5157 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
5158 adapterNode = pNext;
5159 }
5160
5161 EXIT();
5162
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305163 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005164}
5165
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305166QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005167{
5168 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305169 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005170 hdd_adapter_t *adapter;
5171
5172 ENTER();
5173
5174 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
5175
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305176 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005177 adapter = adapterNode->pAdapter;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005178 if ((adapter->device_mode == QDF_STA_MODE) ||
5179 (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
5180 (adapter->device_mode == QDF_IBSS_MODE) ||
5181 (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
5182 (adapter->device_mode == QDF_SAP_MODE) ||
5183 (adapter->device_mode == QDF_P2P_GO_MODE)) {
Abhishek Singh69ccb512017-04-25 11:58:16 +05305184 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
5185 adapter->sessionId, INVALID_SCAN_ID, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005186 }
5187 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
5188 adapterNode = pNext;
5189 }
5190
5191 EXIT();
5192
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305193 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005194}
5195
Dustin Brownf27bce82016-11-03 12:52:27 -07005196/**
5197 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
5198 * adapters
5199 * @hdd_ctx: The HDD context containing the adapters to operate on
5200 *
5201 * return: QDF_STATUS_SUCCESS
5202 */
5203static QDF_STATUS hdd_abort_sched_scan_all_adapters(hdd_context_t *hdd_ctx)
5204{
5205 hdd_adapter_list_node_t *adapter_node = NULL, *next_node = NULL;
5206 QDF_STATUS status;
5207 hdd_adapter_t *adapter;
5208 int err;
5209
5210 ENTER();
5211
5212 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
5213
5214 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
5215 adapter = adapter_node->pAdapter;
5216 if ((adapter->device_mode == QDF_STA_MODE) ||
5217 (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
5218 (adapter->device_mode == QDF_IBSS_MODE) ||
5219 (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
5220 (adapter->device_mode == QDF_SAP_MODE) ||
5221 (adapter->device_mode == QDF_P2P_GO_MODE)) {
5222 err = wlan_hdd_sched_scan_stop(adapter->dev);
5223 if (err)
5224 hdd_err("Unable to stop scheduled scan");
5225 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005226 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
5227 &next_node);
Dustin Brownf27bce82016-11-03 12:52:27 -07005228 adapter_node = next_node;
5229 }
5230
5231 EXIT();
5232
5233 return QDF_STATUS_SUCCESS;
5234}
5235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005236#ifdef WLAN_NS_OFFLOAD
5237/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005238 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005239 * @hdd_ctx: Pointer to hdd context
5240 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005241 * Unregister for IPv6 address change notifications.
5242 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005243 * Return: None
5244 */
5245static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
5246{
5247 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005248}
5249
5250/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005251 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005252 * @hdd_ctx: Pointer to hdd context
5253 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005254 * Register for IPv6 address change notifications.
5255 *
5256 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005257 */
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005258static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005259{
5260 int ret;
5261
5262 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
5263 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005264 if (ret) {
5265 hdd_err("Failed to register IPv6 notifier: %d", ret);
5266 goto out;
5267 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005268
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005269 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005270out:
5271 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005272}
5273#else
5274/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005275 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005276 * @hdd_ctx: Pointer to hdd context
5277 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005278 * Unregister for IPv6 address change notifications.
5279 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005280 * Return: None
5281 */
5282static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
5283{
5284}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005285
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005286/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005287 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005288 * @hdd_ctx: Pointer to hdd context
5289 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005290 * Register for IPv6 address change notifications.
5291 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005292 * Return: None
5293 */
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005294static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005295{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005296 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005297}
5298#endif
5299
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305300#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
5301/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005302 * hdd_logging_sock_activate_svc() - Activate logging
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305303 * @hdd_ctx: HDD context
5304 *
5305 * Activates the logging service
5306 *
5307 * Return: Zero in case of success, negative value otherwise
5308 */
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005309static int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305310{
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005311 int ret;
5312 struct hdd_config *config = hdd_ctx->config;
5313
5314 if (!config->wlanLoggingEnable)
5315 return 0;
5316
Srinivas Girigowda8187e792017-03-03 11:50:59 -08005317 ret = wlan_logging_sock_activate_svc(config->wlanLoggingToConsole,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005318 config->wlanLoggingNumBuf);
5319 if (ret)
5320 hdd_err("wlan_logging_sock_activate_svc failed: %d", ret);
5321 return ret;
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305322}
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005323
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305324/**
5325 * wlan_hdd_logging_sock_deactivate_svc() - Deactivate logging
5326 * @hdd_ctx: HDD context
5327 *
5328 * Deactivates the logging service
5329 *
5330 * Return: 0 on deactivating the logging service
5331 */
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005332static int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305333{
5334 if (hdd_ctx && hdd_ctx->config->wlanLoggingEnable)
5335 return wlan_logging_sock_deactivate_svc();
5336
5337 return 0;
5338}
5339#else
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005340static inline int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305341{
5342 return 0;
5343}
5344
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005345static inline int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
Chandrasekaran, Manishekar3cc29cb2016-01-16 17:28:11 +05305346{
5347 return 0;
5348}
5349#endif
5350
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005351/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005352 * hdd_register_notifiers - Register netdev notifiers.
5353 * @hdd_ctx: HDD context
5354 *
5355 * Register netdev notifiers like IPv4 and IPv6.
5356 *
5357 * Return: 0 on success and errno on failure
5358 */
5359static int hdd_register_notifiers(hdd_context_t *hdd_ctx)
5360{
5361 int ret;
5362
5363 ret = register_netdevice_notifier(&hdd_netdev_notifier);
5364 if (ret) {
5365 hdd_err("register_netdevice_notifier failed: %d", ret);
5366 goto out;
5367 }
5368
5369 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
5370 if (ret)
5371 goto unregister_notifier;
5372
5373 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
5374 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
5375 if (ret) {
5376 hdd_err("Failed to register IPv4 notifier: %d", ret);
5377 goto unregister_ip6_notifier;
5378 }
5379
5380 return 0;
5381
5382unregister_ip6_notifier:
5383 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
5384unregister_notifier:
5385 unregister_netdevice_notifier(&hdd_netdev_notifier);
5386out:
5387 return ret;
5388
5389}
5390
5391/**
5392 * hdd_unregister_notifiers - Unregister netdev notifiers.
5393 * @hdd_ctx: HDD context
5394 *
5395 * Unregister netdev notifiers like IPv4 and IPv6.
5396 *
5397 * Return: None.
5398 */
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05305399void hdd_unregister_notifiers(hdd_context_t *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005400{
5401 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
5402
5403 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
5404
5405 unregister_netdevice_notifier(&hdd_netdev_notifier);
5406}
5407
5408/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005409 * hdd_exit_netlink_services - Exit netlink services
5410 * @hdd_ctx: HDD context
5411 *
5412 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
5413 * nl service.
5414 *
5415 * Return: None.
5416 */
5417static void hdd_exit_netlink_services(hdd_context_t *hdd_ctx)
5418{
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005419 hdd_close_cesium_nl_sock();
Naveen Rawat910726a2017-03-06 11:42:51 -08005420 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005421 ptt_sock_deactivate_svc();
5422
5423 nl_srv_exit();
5424}
5425
5426/**
5427 * hdd_init_netlink_services- Init netlink services
5428 * @hdd_ctx: HDD context
5429 *
5430 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
5431 * nl service.
5432 *
5433 * Return: 0 on success and errno on failure.
5434 */
5435static int hdd_init_netlink_services(hdd_context_t *hdd_ctx)
5436{
5437 int ret;
5438
Ryan Hsuceddceb2016-04-28 10:20:14 -07005439 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005440 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005441 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005442 goto out;
5443 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07005444 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005445
Naveen Rawat910726a2017-03-06 11:42:51 -08005446 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005447 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005448 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005449 goto err_nl_srv;
5450 }
5451
5452 ret = ptt_sock_activate_svc();
5453 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005454 hdd_err("ptt_sock_activate_svc failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005455 goto err_nl_srv;
5456 }
5457
5458 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07005459 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005460 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005461
5462 ret = cnss_diag_activate_service();
5463 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005464 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005465 goto err_close_cesium;
5466 }
5467
5468 return 0;
5469
5470err_close_cesium:
5471 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005472 ptt_sock_deactivate_svc();
5473err_nl_srv:
5474 nl_srv_exit();
5475out:
5476 return ret;
5477}
5478
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005479/**
5480 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
5481 * @hdd_ctx: HDD context.
5482 *
5483 * Destroy RX wakelock.
5484 *
5485 * Return: None.
5486 */
5487static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx)
5488{
5489 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
5490}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08005491
5492/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005493 * hdd_rx_wake_lock_create() - Create RX wakelock
5494 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005495 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005496 * Create RX wakelock.
5497 *
5498 * Return: None.
5499 */
5500static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx)
5501{
5502 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
5503}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005504
5505/**
5506 * hdd_roc_context_init() - Init ROC context
5507 * @hdd_ctx: HDD context.
5508 *
5509 * Initialize ROC context.
5510 *
5511 * Return: 0 on success and errno on failure.
5512 */
5513static int hdd_roc_context_init(hdd_context_t *hdd_ctx)
5514{
5515 qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock);
5516 qdf_list_create(&hdd_ctx->hdd_roc_req_q, MAX_ROC_REQ_QUEUE_ENTRY);
5517
5518 INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue);
5519
5520 return 0;
5521}
5522
5523/**
Nachiket Kukade223ad8c2017-04-19 16:42:29 +05305524 * hdd_destroy_roc_req_q() - Free allocations in ROC Req Queue
5525 * @hdd_ctx: HDD context.
5526 *
5527 * Free memory allocations made in ROC Req Queue nodes.
5528 *
5529 * Return: None.
5530 */
5531static void hdd_destroy_roc_req_q(hdd_context_t *hdd_ctx)
5532{
5533 hdd_roc_req_t *hdd_roc_req;
5534 QDF_STATUS status;
5535
5536 qdf_spin_lock(&hdd_ctx->hdd_roc_req_q_lock);
5537
5538 while (!qdf_list_empty(&hdd_ctx->hdd_roc_req_q)) {
5539 status = qdf_list_remove_front(&hdd_ctx->hdd_roc_req_q,
5540 (qdf_list_node_t **) &hdd_roc_req);
5541
5542 if (QDF_STATUS_SUCCESS != status) {
Nachiket Kukaded45ab8c2017-05-08 16:12:02 +05305543 qdf_spin_unlock(&hdd_ctx->hdd_roc_req_q_lock);
5544 hdd_debug("unable to remove roc element from list");
Nachiket Kukade223ad8c2017-04-19 16:42:29 +05305545 QDF_ASSERT(0);
5546 return;
5547 }
5548
5549 if (hdd_roc_req->pRemainChanCtx)
5550 qdf_mem_free(hdd_roc_req->pRemainChanCtx);
5551
5552 qdf_mem_free(hdd_roc_req);
5553 }
5554
5555 qdf_spin_unlock(&hdd_ctx->hdd_roc_req_q_lock);
5556}
5557
5558/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005559 * hdd_roc_context_destroy() - Destroy ROC context
5560 * @hdd_ctx: HDD context.
5561 *
5562 * Destroy roc list and flush the pending roc work.
5563 *
5564 * Return: None.
5565 */
5566static void hdd_roc_context_destroy(hdd_context_t *hdd_ctx)
5567{
5568 flush_delayed_work(&hdd_ctx->roc_req_work);
Nachiket Kukade223ad8c2017-04-19 16:42:29 +05305569 hdd_destroy_roc_req_q(hdd_ctx);
Houston Hoffman2eac7c42016-12-12 12:22:52 -08005570 qdf_spinlock_destroy(&hdd_ctx->hdd_roc_req_q_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005571}
5572
5573/**
Houston Hoffman160db392016-10-10 17:37:51 -07005574 * hdd_context_deinit() - Deinitialize HDD context
5575 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005576 *
Houston Hoffman160db392016-10-10 17:37:51 -07005577 * Deinitialize HDD context along with all the feature specific contexts but
5578 * do not free hdd context itself. Caller of this API is supposed to free
5579 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005580 *
Houston Hoffman160db392016-10-10 17:37:51 -07005581 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005582 */
Houston Hoffman160db392016-10-10 17:37:51 -07005583static int hdd_context_deinit(hdd_context_t *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005584{
Houston Hoffman160db392016-10-10 17:37:51 -07005585 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005586
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005587 hdd_roc_context_destroy(hdd_ctx);
5588
5589 hdd_sap_context_destroy(hdd_ctx);
5590
5591 hdd_rx_wake_lock_destroy(hdd_ctx);
5592
5593 hdd_tdls_context_destroy(hdd_ctx);
5594
5595 hdd_scan_context_destroy(hdd_ctx);
5596
5597 qdf_list_destroy(&hdd_ctx->hddAdapters);
5598
Houston Hoffman160db392016-10-10 17:37:51 -07005599 return 0;
5600}
5601
5602/**
5603 * hdd_context_destroy() - Destroy HDD context
5604 * @hdd_ctx: HDD context to be destroyed.
5605 *
5606 * Free config and HDD context as well as destroy all the resources.
5607 *
5608 * Return: None
5609 */
5610static void hdd_context_destroy(hdd_context_t *hdd_ctx)
5611{
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05305612
5613 hdd_logging_sock_deactivate_svc(hdd_ctx);
Houston Hoffman160db392016-10-10 17:37:51 -07005614
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05305615 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
5616
Houston Hoffman160db392016-10-10 17:37:51 -07005617 hdd_context_deinit(hdd_ctx);
5618
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305619 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08005620 hdd_ctx->config = NULL;
5621
5622 wiphy_free(hdd_ctx->wiphy);
5623}
5624
5625/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05305626 * wlan_destroy_bug_report_lock() - Destroy bug report lock
5627 *
5628 * This function is used to destroy bug report lock
5629 *
5630 * Return: None
5631 */
5632static void wlan_destroy_bug_report_lock(void)
5633{
5634 p_cds_contextType p_cds_context;
5635
5636 p_cds_context = cds_get_global_context();
5637 if (!p_cds_context) {
5638 hdd_err("cds context is NULL");
5639 return;
5640 }
5641
5642 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
5643}
5644
5645/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005646 * hdd_wlan_exit() - HDD WLAN exit function
5647 * @hdd_ctx: Pointer to the HDD Context
5648 *
5649 * This is the driver exit point (invoked during rmmod)
5650 *
5651 * Return: None
5652 */
Jeff Johnson590e2012016-10-05 16:16:24 -07005653static void hdd_wlan_exit(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005654{
5655 v_CONTEXT_t p_cds_context = hdd_ctx->pcds_context;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305656 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005657 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05305658 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005659
5660 ENTER();
5661
Arun Khandavallifae92942016-08-01 13:31:08 +05305662 if (QDF_TIMER_STATE_RUNNING ==
5663 qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005664 hdd_debug("Stop interface change timer");
Arun Khandavallifae92942016-08-01 13:31:08 +05305665 qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005666 }
5667
Arun Khandavallifae92942016-08-01 13:31:08 +05305668 if (!QDF_IS_STATUS_SUCCESS
5669 (qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer)))
5670 hdd_err("Cannot delete interface change timer");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07005671
Arun Khandavallifae92942016-08-01 13:31:08 +05305672
5673 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005674
Nitesh Shah61c10d92016-10-19 19:29:15 +05305675 qdf_mc_timer_destroy(&hdd_ctx->tdls_source_timer);
5676
Prashanth Bhattaab004382016-10-11 16:08:11 -07005677 hdd_bus_bandwidth_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005678
5679#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05305680 if (QDF_TIMER_STATE_RUNNING ==
5681 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
5682 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005683 }
5684
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305685 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05305686 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005687 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005688 }
Liangwei Dongaef84342016-10-21 05:28:00 -04005689 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
5690 qdf_mem_free(hdd_ctx->last_acs_channel_list);
5691 hdd_ctx->last_acs_channel_list = NULL;
5692 hdd_ctx->num_of_channels = 0;
5693 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005694#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005695
Arun Khandavallifae92942016-08-01 13:31:08 +05305696 mutex_lock(&hdd_ctx->iface_change_lock);
5697 driver_status = hdd_ctx->driver_status;
5698 mutex_unlock(&hdd_ctx->iface_change_lock);
5699
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005700 /*
5701 * Powersave Offload Case
5702 * Disable Idle Power Save Mode
5703 */
5704 hdd_set_idle_ps_config(hdd_ctx, false);
5705
Arun Khandavallifae92942016-08-01 13:31:08 +05305706 if (driver_status != DRIVER_MODULES_CLOSED) {
5707 hdd_unregister_wext_all_adapters(hdd_ctx);
5708 /*
5709 * Cancel any outstanding scan requests. We are about to close
5710 * all of our adapters, but an adapter structure is what SME
5711 * passes back to our callback function. Hence if there
5712 * are any outstanding scan requests then there is a
5713 * race condition between when the adapter is closed and
5714 * when the callback is invoked. We try to resolve that
5715 * race condition here by canceling any outstanding scans
5716 * before we close the adapters.
5717 * Note that the scans may be cancelled in an asynchronous
5718 * manner, so ideally there needs to be some kind of
5719 * synchronization. Rather than introduce a new
5720 * synchronization here, we will utilize the fact that we are
5721 * about to Request Full Power, and since that is synchronized,
5722 * the expectation is that by the time Request Full Power has
5723 * completed, all scans will be cancelled
5724 */
Sandeep Puligilla8de3c1c2017-04-13 17:56:18 -07005725 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
Arun Khandavallifae92942016-08-01 13:31:08 +05305726 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07005727 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05305728 hdd_stop_all_adapters(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005729 }
5730
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05305731 wlan_destroy_bug_report_lock();
5732
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005733 /*
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05305734 * Close the scheduler before calling cds_close to make sure
5735 * no thread is scheduled after the each module close is
5736 * is called i.e after all the data structures are freed.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005737 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305738 qdf_status = cds_sched_close(p_cds_context);
5739 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05305740 hdd_alert("Failed to close CDS Scheduler");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305741 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005742 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005743
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07005744 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05305745
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05305746 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
5747 qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
5748 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
5749
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005750 /*
5751 * Close CDS
5752 * This frees pMac(HAL) context. There should not be any call
5753 * that requires pMac access after this.
5754 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005755
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07005756 hdd_green_ap_deinit(hdd_ctx);
Jeff Johnsonce0032c2017-01-20 07:18:27 -08005757 hdd_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005758
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005759 hdd_close_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005760
5761 hdd_ipa_cleanup(hdd_ctx);
5762
5763 /* Free up RoC request queue and flush workqueue */
5764 cds_flush_work(&hdd_ctx->roc_req_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005765
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05305766 wlansap_global_deinit();
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05305767 wlan_hdd_deinit_chan_info(hdd_ctx);
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05305768 /*
5769 * If there is re_init failure wiphy would have already de-registered
5770 * check the wiphy status before un-registering again
5771 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05305772 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05305773 wiphy_unregister(wiphy);
5774 wlan_hdd_cfg80211_deinit(wiphy);
5775 hdd_lpass_notify_stop(hdd_ctx);
5776 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07005777
Arun Khandavallifae92942016-08-01 13:31:08 +05305778 hdd_exit_netlink_services(hdd_ctx);
5779 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05305780#ifdef FEATURE_WLAN_CH_AVOID
5781 mutex_destroy(&hdd_ctx->avoid_freq_lock);
5782#endif
Abhishek Singhe9068f12017-03-31 14:14:52 +05305783
5784 driver_status = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
5785 if (driver_status)
5786 hdd_err("Pdev delete failed");
5787
5788 driver_status = hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
5789 if (driver_status)
5790 hdd_err("Psoc delete failed");
Prashanth Bhatta527fd752016-04-28 12:35:23 -07005791 hdd_context_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005792}
5793
5794void __hdd_wlan_exit(void)
5795{
5796 hdd_context_t *hdd_ctx;
5797
5798 ENTER();
5799
Anurag Chouhan6d760662016-02-20 16:05:43 +05305800 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005801 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005802 hdd_err("Invalid HDD Context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005803 EXIT();
5804 return;
5805 }
5806
Prashanth Bhatta5da711e2015-11-30 14:28:52 -08005807 memdump_deinit();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05305808 hdd_driver_memdump_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -08005809
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005810 /* Do all the cleanup before deregistering the driver */
5811 hdd_wlan_exit(hdd_ctx);
Mohit Khannaebf8a862016-04-28 17:53:59 -07005812
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005813 EXIT();
5814}
5815
5816#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04005817/**
5818 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
5819 * @data: pointer to hdd_context_t
5820 *
5821 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
5822 * Then new ACS request will do a fresh scan without reusing the cached
5823 * scan information.
5824 *
5825 * Return: void
5826 */
Tang Yingying523322d2017-01-17 23:28:43 +08005827static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005828{
5829 hdd_context_t *hdd_ctx = (hdd_context_t *) data;
5830
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005831 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005832 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04005833 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
5834 qdf_mem_free(hdd_ctx->last_acs_channel_list);
5835 hdd_ctx->last_acs_channel_list = NULL;
5836 hdd_ctx->num_of_channels = 0;
5837 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005838
5839 if (!hdd_ctx->hHal)
5840 return;
5841 sme_scan_flush_result(hdd_ctx->hHal);
5842}
5843#endif
5844
5845#ifdef QCA_HT_2040_COEX
5846/**
5847 * hdd_wlan_set_ht2040_mode() - notify FW with HT20/HT40 mode
5848 * @adapter: pointer to adapter
5849 * @staId: station id
5850 * @macAddrSTA: station MAC address
5851 * @channel_type: channel type
5852 *
5853 * This function notifies FW with HT20/HT40 mode
5854 *
5855 * Return: 0 if successful, error number otherwise
5856 */
5857int hdd_wlan_set_ht2040_mode(hdd_adapter_t *adapter, uint16_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305858 struct qdf_mac_addr macAddrSTA, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005859{
5860 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305861 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005862 hdd_context_t *hdd_ctx = NULL;
5863
5864 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5865
5866 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305867 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005868 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305869
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005870 if (!hdd_ctx->hHal)
5871 return -EINVAL;
5872
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305873 qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, staId, macAddrSTA,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005874 adapter->sessionId, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305875 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07005876 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005877 return -EINVAL;
5878 }
5879
5880 return 0;
5881}
5882#endif
5883
5884/**
5885 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
5886 * @state: state
5887 *
5888 * This function notifies FW with modem power status
5889 *
5890 * Return: 0 if successful, error number otherwise
5891 */
5892int hdd_wlan_notify_modem_power_state(int state)
5893{
5894 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305895 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005896 hdd_context_t *hdd_ctx;
5897
Anurag Chouhan6d760662016-02-20 16:05:43 +05305898 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005899 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305900 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005901 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305902
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005903 if (!hdd_ctx->hHal)
5904 return -EINVAL;
5905
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305906 qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
5907 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07005908 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005909 state);
5910 return -EINVAL;
5911 }
5912 return 0;
5913}
5914
5915/**
5916 *
5917 * hdd_post_cds_enable_config() - HDD post cds start config helper
5918 * @adapter - Pointer to the HDD
5919 *
5920 * Return: None
5921 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305922QDF_STATUS hdd_post_cds_enable_config(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005923{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305924 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005925
5926 /*
5927 * Send ready indication to the HDD. This will kick off the MAC
5928 * into a 'running' state and should kick off an initial scan.
5929 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305930 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
5931 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07005932 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
5933 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305934 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005935 }
5936
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305937 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005938}
5939
5940/* wake lock APIs for HDD */
5941void hdd_prevent_suspend(uint32_t reason)
5942{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305943 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005944}
5945
5946void hdd_allow_suspend(uint32_t reason)
5947{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05305948 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005949}
5950
5951void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
5952{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05305953 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
5954 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005955}
5956
5957/**
5958 * hdd_exchange_version_and_caps() - exchange version and capability with target
5959 * @hdd_ctx: Pointer to HDD context
5960 *
5961 * This is the HDD function to exchange version and capability information
5962 * between Host and Target
5963 *
5964 * This function gets reported version of FW.
5965 * It also finds the version of target headers used to compile the host;
5966 * It compares the above two and prints a warning if they are different;
5967 * It gets the SW and HW version string;
5968 * Finally, it exchanges capabilities between host and target i.e. host
5969 * and target exchange a msg indicating the features they support through a
5970 * bitmap
5971 *
5972 * Return: None
5973 */
5974void hdd_exchange_version_and_caps(hdd_context_t *hdd_ctx)
5975{
5976
5977 tSirVersionType versionCompiled;
5978 tSirVersionType versionReported;
5979 tSirVersionString versionString;
5980 uint8_t fwFeatCapsMsgSupported = 0;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305981 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005982
5983 memset(&versionCompiled, 0, sizeof(versionCompiled));
5984 memset(&versionReported, 0, sizeof(versionReported));
5985
5986 /* retrieve and display WCNSS version information */
5987 do {
5988
5989 vstatus = sme_get_wcnss_wlan_compiled_version(hdd_ctx->hHal,
5990 &versionCompiled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305991 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005992 hdd_err("unable to retrieve WCNSS WLAN compiled version");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005993 break;
5994 }
5995
5996 vstatus = sme_get_wcnss_wlan_reported_version(hdd_ctx->hHal,
5997 &versionReported);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305998 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005999 hdd_err("unable to retrieve WCNSS WLAN reported version");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006000 break;
6001 }
6002
6003 if ((versionCompiled.major != versionReported.major) ||
6004 (versionCompiled.minor != versionReported.minor) ||
6005 (versionCompiled.version != versionReported.version) ||
6006 (versionCompiled.revision != versionReported.revision)) {
6007 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
6008 "Host expected %u.%u.%u.%u\n",
6009 WLAN_MODULE_NAME,
6010 (int)versionReported.major,
6011 (int)versionReported.minor,
6012 (int)versionReported.version,
6013 (int)versionReported.revision,
6014 (int)versionCompiled.major,
6015 (int)versionCompiled.minor,
6016 (int)versionCompiled.version,
6017 (int)versionCompiled.revision);
6018 } else {
6019 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
6020 WLAN_MODULE_NAME,
6021 (int)versionReported.major,
6022 (int)versionReported.minor,
6023 (int)versionReported.version,
6024 (int)versionReported.revision);
6025 }
6026
6027 vstatus = sme_get_wcnss_software_version(hdd_ctx->hHal,
6028 versionString,
6029 sizeof(versionString));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306030 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006031 hdd_err("unable to retrieve WCNSS software version string");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006032 break;
6033 }
6034
6035 pr_info("%s: WCNSS software version %s\n",
6036 WLAN_MODULE_NAME, versionString);
6037
6038 vstatus = sme_get_wcnss_hardware_version(hdd_ctx->hHal,
6039 versionString,
6040 sizeof(versionString));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306041 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006042 hdd_err("unable to retrieve WCNSS hardware version string");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006043 break;
6044 }
6045
6046 pr_info("%s: WCNSS hardware version %s\n",
6047 WLAN_MODULE_NAME, versionString);
6048
6049 /*
6050 * 1.Check if FW version is greater than 0.1.1.0. Only then
6051 * send host-FW capability exchange message
6052 * 2.Host-FW capability exchange message is only present on
6053 * target 1.1 so send the message only if it the target is 1.1
6054 * minor numbers for different target branches:
6055 * 0 -> (1.0)Mainline Build
6056 * 1 -> (1.1)Mainline Build
6057 * 2->(1.04) Stability Build
6058 */
6059 if (((versionReported.major > 0) || (versionReported.minor > 1)
6060 || ((versionReported.minor >= 1)
6061 && (versionReported.version >= 1)))
6062 && ((versionReported.major == 1)
6063 && (versionReported.minor >= 1)))
6064 fwFeatCapsMsgSupported = 1;
6065
6066 if (fwFeatCapsMsgSupported) {
6067 /*
6068 * Indicate if IBSS heartbeat monitoring needs to be
6069 * offloaded
6070 */
6071 if (!hdd_ctx->config->enableIbssHeartBeatOffload) {
6072 sme_disable_feature_capablity
6073 (IBSS_HEARTBEAT_OFFLOAD);
6074 }
6075
6076 sme_feature_caps_exchange(hdd_ctx->hHal);
6077 }
6078
6079 } while (0);
6080
6081}
6082
6083/* Initialize channel list in sme based on the country code */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306084QDF_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006085{
Amar Singhal5cccafe2017-02-15 12:42:58 -08006086
Amar Singhal6f8592b2017-04-26 14:31:58 -07006087 return sme_init_chan_list(hdd_ctx->hHal,
6088 hdd_ctx->reg.alpha2,
6089 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006090}
6091
6092/**
6093 * hdd_is_5g_supported() - check if hardware supports 5GHz
6094 * @hdd_ctx: Pointer to the hdd context
6095 *
6096 * HDD function to know if hardware supports 5GHz
6097 *
6098 * Return: true if hardware supports 5GHz
6099 */
6100bool hdd_is_5g_supported(hdd_context_t *hdd_ctx)
6101{
zdingf54169a2016-10-12 17:08:45 +08006102 if (!hdd_ctx || !hdd_ctx->config)
6103 return true;
6104
6105 if (hdd_ctx->config->nBandCapability != eCSR_BAND_24)
6106 return true;
6107 else
6108 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006109}
6110
Amar Singhale4f28ee2015-10-21 14:36:56 -07006111static int hdd_wiphy_init(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006112{
6113 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07006114 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006115
6116 wiphy = hdd_ctx->wiphy;
6117
6118 /*
6119 * The channel information in
6120 * wiphy needs to be initialized before wiphy registration
6121 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006122 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
6123 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006124 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07006125 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006126 }
6127
6128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
6129 wiphy->wowlan = &wowlan_support_reg_init;
6130#else
6131 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
6132 WIPHY_WOWLAN_MAGIC_PKT |
6133 WIPHY_WOWLAN_DISCONNECT |
6134 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
6135 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
6136 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
6137 WIPHY_WOWLAN_4WAY_HANDSHAKE |
6138 WIPHY_WOWLAN_RFKILL_RELEASE;
6139
6140 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
6141 WOW_MAX_FILTERS_PER_LIST);
6142 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
6143 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
6144#endif
6145
6146 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07006147 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306148 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07006149 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05306150 return ret_val;
6151 }
6152
Amar Singhal5cccafe2017-02-15 12:42:58 -08006153 if (!hdd_ctx->reg_offload)
6154 hdd_program_country_code(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006155
Amar Singhale4f28ee2015-10-21 14:36:56 -07006156 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006157}
6158
Ravi Joshie2331e82015-07-01 18:18:54 -07006159/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07006160 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07006161 * @hdd_ctx - handle to hdd context
6162 * @tx_packets - transmit packet count
6163 * @rx_packets - receive packet count
6164 *
6165 * The function controls the bus bandwidth and dynamic control of
6166 * tcp delayed ack configuration
6167 *
6168 * Returns: None
6169 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006170#ifdef MSM_PLATFORM
Jeff Johnson590e2012016-10-05 16:16:24 -07006171static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx,
6172 const uint64_t tx_packets,
6173 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006174{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006175 uint64_t total = tx_packets + rx_packets;
Mohit Khannae71e2262015-11-10 09:37:24 -08006176 uint64_t temp_rx = 0;
6177 uint64_t temp_tx = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07006178 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08006179 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08006180 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07006181 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006182 uint16_t index = 0;
6183 bool vote_level_change = false;
6184 bool rx_level_change = false;
6185 bool tx_level_change = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006186
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006187 if (total > hdd_ctx->config->busBandwidthHighThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006188 next_vote_level = PLD_BUS_WIDTH_HIGH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006189 else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006190 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
Yue Mad6478e42015-10-20 18:49:24 -07006191 else if (total > hdd_ctx->config->busBandwidthLowThreshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07006192 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07006193 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07006194 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006195
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006196 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07006197 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
6198 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006199 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006200 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07006201 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Nirav Shah3bbfa512016-05-12 16:43:49 +05306202 if (next_vote_level == PLD_BUS_WIDTH_LOW) {
Nirav Shahffc6a092016-06-09 16:09:08 +05306203 if (hdd_ctx->hbw_requested) {
6204 pld_remove_pm_qos(hdd_ctx->parent_dev);
6205 hdd_ctx->hbw_requested = false;
6206 }
Nirav Shah3bbfa512016-05-12 16:43:49 +05306207 if (cds_sched_handle_throughput_req(false))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006208 hdd_warn("low bandwidth set rx affinity fail");
Nirav Shah3bbfa512016-05-12 16:43:49 +05306209 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05306210 if (!hdd_ctx->hbw_requested) {
6211 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
6212 hdd_ctx->hbw_requested = true;
6213 }
6214
Nirav Shah3bbfa512016-05-12 16:43:49 +05306215 if (cds_sched_handle_throughput_req(true))
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006216 hdd_warn("high bandwidth set rx affinity fail");
Nirav Shah3bbfa512016-05-12 16:43:49 +05306217 }
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -07006218 hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006219 }
Mohit Khannae71e2262015-11-10 09:37:24 -08006220
6221 /* fine-tuning parameters for RX Flows */
6222 temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
6223
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006224 hdd_ctx->prev_rx = rx_packets;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08006225
Ravi Joshifed83572016-10-07 16:20:37 -07006226 if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) {
6227 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
6228 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
6229 next_rx_level = WLAN_SVC_TP_HIGH;
6230 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07006231 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07006232 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08006233 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07006234 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006236 if (hdd_ctx->cur_rx_level != next_rx_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07006237 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006238 next_rx_level, temp_rx);
6239 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006240 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07006241 /* Send throughput indication only if it is enabled.
6242 * Disabling tcp_del_ack will revert the tcp stack behavior
6243 * to default delayed ack. Note that this will disable the
6244 * dynamic delayed ack mechanism across the system
6245 */
6246 if (hdd_ctx->config->enable_tcp_delack)
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05306247 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
6248 WLAN_SVC_WLAN_TP_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006249 &next_rx_level,
6250 sizeof(next_rx_level));
6251 }
6252
Mohit Khannae71e2262015-11-10 09:37:24 -08006253 /* fine-tuning parameters for TX Flows */
6254 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
6255 hdd_ctx->prev_tx = tx_packets;
6256 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
6257 next_tx_level = WLAN_SVC_TP_HIGH;
6258 else
6259 next_tx_level = WLAN_SVC_TP_LOW;
6260
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006261 if (hdd_ctx->cur_tx_level != next_tx_level) {
Mohit Khannae71e2262015-11-10 09:37:24 -08006262 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
6263 next_tx_level, temp_tx);
6264 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006265 tx_level_change = true;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05306266 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
6267 WLAN_SVC_WLAN_TP_TX_IND,
Mohit Khannae71e2262015-11-10 09:37:24 -08006268 &next_tx_level,
6269 sizeof(next_tx_level));
6270 }
6271
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006272 index = hdd_ctx->hdd_txrx_hist_idx;
6273
6274 if (vote_level_change || tx_level_change || rx_level_change) {
6275 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
6276 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
6277 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
6278 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
6279 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
6280 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
6281 hdd_ctx->hdd_txrx_hist_idx++;
6282 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
6283 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006284}
6285
6286#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306287static void hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006288{
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306289 hdd_context_t *hdd_ctx = container_of(work, hdd_context_t,
6290 bus_bw_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006291 hdd_adapter_t *adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306292 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05306293 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
6294 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006295 uint64_t total_tx = 0, total_rx = 0;
6296 hdd_adapter_list_node_t *adapterNode = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306297 QDF_STATUS status = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306298 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006299 bool connected = false;
6300 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
6301
Prashanth Bhattaab004382016-10-11 16:08:11 -07006302 if (wlan_hdd_validate_context(hdd_ctx))
6303 return;
6304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006305 for (status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306306 NULL != adapterNode && QDF_STATUS_SUCCESS == status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006307 status =
6308 hdd_get_next_adapter(hdd_ctx, adapterNode, &adapterNode)) {
6309
6310 if (adapterNode->pAdapter == NULL)
6311 continue;
6312 adapter = adapterNode->pAdapter;
Manjeet Singh01327cc2016-09-03 12:14:25 +05306313 /*
6314 * Validate magic so we don't end up accessing
6315 * an invalid adapter.
6316 */
6317 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
6318 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006319
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006320 if ((adapter->device_mode == QDF_STA_MODE ||
6321 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006322 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
6323 != eConnectionState_Associated) {
6324
6325 continue;
6326 }
6327
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006328 if ((adapter->device_mode == QDF_SAP_MODE ||
6329 adapter->device_mode == QDF_P2P_GO_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006330 WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive == false) {
6331
6332 continue;
6333 }
6334
6335 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
6336 adapter->prev_tx_packets);
6337 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
6338 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306339
6340 if (adapter->device_mode == QDF_SAP_MODE ||
6341 adapter->device_mode == QDF_P2P_GO_MODE ||
6342 adapter->device_mode == QDF_IBSS_MODE) {
6343
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08006344 ret = cdp_get_intra_bss_fwd_pkts_count(
6345 cds_get_context(QDF_MODULE_ID_SOC),
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306346 adapter->sessionId,
6347 &fwd_tx_packets, &fwd_rx_packets);
6348 if (ret == A_OK) {
6349 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
6350 fwd_tx_packets,
6351 adapter->prev_fwd_tx_packets);
6352 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
6353 fwd_tx_packets,
6354 adapter->prev_fwd_rx_packets);
6355 }
6356 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006357
6358 total_rx += adapter->stats.rx_packets;
6359 total_tx += adapter->stats.tx_packets;
6360
6361 spin_lock_bh(&hdd_ctx->bus_bw_lock);
6362 adapter->prev_tx_packets = adapter->stats.tx_packets;
6363 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306364 adapter->prev_fwd_tx_packets = fwd_tx_packets;
6365 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006366 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
6367 connected = true;
6368 }
6369
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05306370 /* add intra bss forwarded tx and rx packets */
6371 tx_packets += fwd_tx_packets_diff;
6372 rx_packets += fwd_rx_packets_diff;
6373
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006374 hdd_ipa_uc_stat_query(hdd_ctx, &ipa_tx_packets, &ipa_rx_packets);
6375 tx_packets += (uint64_t)ipa_tx_packets;
6376 rx_packets += (uint64_t)ipa_rx_packets;
6377
6378 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006379 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006380 return;
6381 }
6382
Yuanyuan Liu13738502016-04-06 17:41:37 -07006383 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006384
6385 hdd_ipa_set_perf_level(hdd_ctx, tx_packets, rx_packets);
6386 hdd_ipa_uc_stat_request(adapter, 2);
6387
Dustin Brown2ed60362017-01-18 12:25:50 -08006388 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08006389 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08006390 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05306391 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
Dustin Brownfce08d12017-01-17 16:29:38 -08006392 hdd_ctx->config->busBandwidthComputeInterval);
Dustin Brownfce08d12017-01-17 16:29:38 -08006393 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006394}
Prashanth Bhattaab004382016-10-11 16:08:11 -07006395
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306396/**
6397 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
6398 * @arg: Argument of timer function
6399 *
6400 * Schedule a workqueue in this function where all the processing is done.
6401 *
6402 * Return: None.
6403 */
6404static void __hdd_bus_bw_cbk(void *arg)
6405{
6406 hdd_context_t *hdd_ctx = (hdd_context_t *) arg;
6407
6408 if (wlan_hdd_validate_context(hdd_ctx))
6409 return;
6410
6411 schedule_work(&hdd_ctx->bus_bw_work);
6412}
6413
6414/**
6415 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
6416 * @arg: Argument of timer function
6417 *
6418 * Return: None.
6419 */
6420static void hdd_bus_bw_cbk(void *arg)
6421{
6422 cds_ssr_protect(__func__);
6423 __hdd_bus_bw_cbk(arg);
6424 cds_ssr_unprotect(__func__);
6425}
6426
Prashanth Bhattaab004382016-10-11 16:08:11 -07006427int hdd_bus_bandwidth_init(hdd_context_t *hdd_ctx)
6428{
6429 spin_lock_init(&hdd_ctx->bus_bw_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306430 INIT_WORK(&hdd_ctx->bus_bw_work,
6431 hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08006432 hdd_ctx->bus_bw_timer_running = false;
6433 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306434 qdf_timer_init(NULL,
6435 &hdd_ctx->bus_bw_timer,
6436 hdd_bus_bw_cbk, (void *)hdd_ctx,
6437 QDF_TIMER_TYPE_SW);
Prashanth Bhattaab004382016-10-11 16:08:11 -07006438
6439 return 0;
6440}
6441
6442void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx)
6443{
Dustin Brownfce08d12017-01-17 16:29:38 -08006444 if (hdd_ctx->bus_bw_timer_running)
Prashanth Bhattaab004382016-10-11 16:08:11 -07006445 hdd_reset_tcp_delack(hdd_ctx);
6446
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006447 hdd_debug("wait for bus bw work to flush");
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05306448 cancel_work_sync(&hdd_ctx->bus_bw_work);
6449 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08006450 hdd_ctx->bus_bw_timer_running = false;
6451 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Prashanth Bhattaab004382016-10-11 16:08:11 -07006452}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006453#endif
6454
6455/**
Nirav Shahed34b212016-04-25 10:59:16 +05306456 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
6457 * @hdd_ctx: hdd context
6458 *
6459 * Return: 0 for success or error code
6460 */
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07006461static int wlan_hdd_init_tx_rx_histogram(hdd_context_t *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05306462{
6463 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
6464 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
6465 if (hdd_ctx->hdd_txrx_hist == NULL) {
Jeff Johnson760350b2016-08-15 14:01:52 -07006466 hdd_err("Failed malloc for hdd_txrx_hist");
Nirav Shahed34b212016-04-25 10:59:16 +05306467 return -ENOMEM;
6468 }
6469 return 0;
6470}
6471
6472/**
6473 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
6474 * @hdd_ctx: hdd context
6475 *
6476 * Return: none
6477 */
6478void wlan_hdd_deinit_tx_rx_histogram(hdd_context_t *hdd_ctx)
6479{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05306480 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
6481 return;
6482
6483 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
6484 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05306485}
6486
Nirav Shahda008342016-05-17 18:50:40 +05306487static uint8_t *convert_level_to_string(uint32_t level)
6488{
6489 switch (level) {
6490 /* initialize the wlan sub system */
6491 case WLAN_SVC_TP_NONE:
6492 return "NONE";
6493 case WLAN_SVC_TP_LOW:
6494 return "LOW";
6495 case WLAN_SVC_TP_MEDIUM:
6496 return "MED";
6497 case WLAN_SVC_TP_HIGH:
6498 return "HIGH";
6499 default:
6500 return "INVAL";
6501 }
6502}
6503
Nirav Shahed34b212016-04-25 10:59:16 +05306504
6505/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006506 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
6507 * @hdd_ctx: hdd context
6508 *
6509 * Return: none
6510 */
6511void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx)
6512{
6513 int i;
6514
6515#ifdef MSM_PLATFORM
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006516 hdd_debug("BW compute Interval: %dms",
Nirav Shahda008342016-05-17 18:50:40 +05306517 hdd_ctx->config->busBandwidthComputeInterval);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006518 hdd_debug("BW High TH: %d BW Med TH: %d BW Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006519 hdd_ctx->config->busBandwidthHighThreshold,
6520 hdd_ctx->config->busBandwidthMediumThreshold,
6521 hdd_ctx->config->busBandwidthLowThreshold);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006522 hdd_debug("Enable TCP DEL ACK: %d",
Nirav Shahda008342016-05-17 18:50:40 +05306523 hdd_ctx->config->enable_tcp_delack);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006524 hdd_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006525 hdd_ctx->config->tcpDelackThresholdHigh,
6526 hdd_ctx->config->tcpDelackThresholdLow);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006527 hdd_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
Nirav Shahda008342016-05-17 18:50:40 +05306528 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006529#endif
6530
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006531 hdd_debug("Total entries: %d Current index: %d",
Nirav Shahda008342016-05-17 18:50:40 +05306532 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
6533
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006534 hdd_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006535
6536 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006537 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006538 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006539 hdd_log(QDF_TRACE_LEVEL_ERROR,
Mohit Khannaafff9fb2016-11-16 20:22:03 -08006540 "[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
6541 i, hdd_ctx->hdd_txrx_hist[i].qtime,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006542 hdd_ctx->hdd_txrx_hist[i].interval_rx,
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006543 hdd_ctx->hdd_txrx_hist[i].interval_tx,
6544 convert_level_to_string(
6545 hdd_ctx->hdd_txrx_hist[i].
6546 next_vote_level),
6547 convert_level_to_string(
6548 hdd_ctx->hdd_txrx_hist[i].
6549 next_rx_level),
6550 convert_level_to_string(
6551 hdd_ctx->hdd_txrx_hist[i].
6552 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006553 }
Mohit Khannac68622e2017-01-31 21:07:12 -08006554
6555 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006556}
6557
6558/**
6559 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
6560 * @hdd_ctx: hdd context
6561 *
6562 * Return: none
6563 */
6564void wlan_hdd_clear_tx_rx_histogram(hdd_context_t *hdd_ctx)
6565{
6566 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05306567 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
6568 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006569}
6570
6571/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006572 * wlan_hdd_display_netif_queue_history() - display netif queue history
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006573 * @pHddCtx: hdd context
6574 *
6575 * Return: none
6576 */
6577void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx)
6578{
6579
6580 hdd_adapter_t *adapter = NULL;
6581 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306582 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006583 int i;
Nirav Shahda008342016-05-17 18:50:40 +05306584 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006585
6586 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306587 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006588 adapter = adapter_node->pAdapter;
6589
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006590 hdd_debug("Netif queue operation statistics:");
6591 hdd_debug("Session_id %d device mode %d",
Nirav Shah617cff92016-04-25 10:24:24 +05306592 adapter->sessionId, adapter->device_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006593 hdd_debug("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05306594 curr_time = qdf_system_ticks();
6595 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05306596 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05306597 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05306598 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05306599 unpause = adapter->total_unpause_time;
6600 } else {
Nirav Shahda008342016-05-17 18:50:40 +05306601 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05306602 pause = adapter->total_pause_time;
6603 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006604 hdd_debug("Total: %ums Pause: %ums Unpause: %ums",
Nirav Shah617cff92016-04-25 10:24:24 +05306605 qdf_system_ticks_to_msecs(total),
6606 qdf_system_ticks_to_msecs(pause),
6607 qdf_system_ticks_to_msecs(unpause));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006608 hdd_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006609
Nirav Shahda008342016-05-17 18:50:40 +05306610 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
6611 qdf_time_t pause_delta = 0;
6612
6613 if (adapter->pause_map & (1 << i))
6614 pause_delta = delta;
6615
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006616 /* using hdd_log to avoid printing function name */
6617 hdd_log(QDF_TRACE_LEVEL_ERROR,
6618 "%s: %d: %d: %ums",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006619 hdd_reason_type_to_string(i),
6620 adapter->queue_oper_stats[i].pause_count,
Nirav Shahda008342016-05-17 18:50:40 +05306621 adapter->queue_oper_stats[i].unpause_count,
6622 qdf_system_ticks_to_msecs(
6623 adapter->queue_oper_stats[i].total_pause_time +
6624 pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006625 }
6626
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006627 hdd_debug("Netif queue operation history:");
6628 hdd_debug("Total entries: %d current index %d",
Nirav Shahda008342016-05-17 18:50:40 +05306629 WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index);
6630
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006631 hdd_debug("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006632
6633 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07006634 /* using hdd_log to avoid printing function name */
6635 if (adapter->queue_oper_history[i].time == 0)
6636 continue;
6637 hdd_log(QDF_TRACE_LEVEL_ERROR,
6638 "%d: %u: %s: %s: %x",
Anurag Chouhan50220ce2016-02-18 20:11:33 +05306639 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006640 adapter->queue_oper_history[i].time),
6641 hdd_action_type_to_string(
6642 adapter->queue_oper_history[i].netif_action),
6643 hdd_reason_type_to_string(
6644 adapter->queue_oper_history[i].netif_reason),
6645 adapter->queue_oper_history[i].pause_map);
6646 }
6647
6648 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
6649 adapter_node = next;
6650 }
6651
6652
6653}
6654
6655/**
6656 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
6657 * @hdd_ctx: hdd context
6658 *
6659 * Return: none
6660 */
6661void wlan_hdd_clear_netif_queue_history(hdd_context_t *hdd_ctx)
6662{
6663 hdd_adapter_t *adapter = NULL;
6664 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306665 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006666
6667 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306668 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006669 adapter = adapter_node->pAdapter;
6670
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306671 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006672 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306673 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006674 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05306675 adapter->history_index = 0;
6676 adapter->start_time = adapter->last_time = qdf_system_ticks();
6677 adapter->total_pause_time = 0;
6678 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006679 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
6680 adapter_node = next;
6681 }
6682}
6683
6684/**
6685 * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
6686 * @halHandle: Hal handle
6687 * @pContext: Pointer to the context
6688 * @sessionId: Session ID
6689 * @scanId: Scan ID
6690 * @status: Status
6691 *
6692 * This is the callback to be executed when 11d scan is completed to flush out
6693 * the scan results
6694 *
6695 * 11d scan is done during driver load and is a passive scan on all
6696 * channels supported by the device, 11d scans may find some APs on
6697 * frequencies which are forbidden to be used in the regulatory domain
6698 * the device is operating in. If these APs are notified to the supplicant
6699 * it may try to connect to these APs, thus flush out all the scan results
6700 * which are present in SME after 11d scan is done.
6701 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306702 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006703 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306704static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006705 uint8_t sessionId, uint32_t scanId,
6706 eCsrScanStatus status)
6707{
6708 ENTER();
6709
6710 sme_scan_flush_result(halHandle);
6711
6712 EXIT();
6713
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306714 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006715}
6716
6717#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6718/**
6719 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
6720 * @hdd_ctx: hdd global context
6721 *
6722 * Return: none
6723 */
6724static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
6725{
6726 uint8_t i;
6727
6728 mutex_init(&hdd_ctx->op_ctx.op_lock);
6729 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
6730 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
6731 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
6732 }
6733}
6734#else
6735static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
6736{
6737}
6738#endif
6739
Yingying Tang95409972016-10-20 15:16:15 +08006740#ifdef WLAN_FEATURE_WOW_PULSE
6741/**
6742 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
6743 * @phddctx: hdd_context_t structure pointer
6744 * @enable: enable or disable this behaviour
6745 *
6746 * Return: int
6747 */
6748static int wlan_hdd_set_wow_pulse(hdd_context_t *phddctx, bool enable)
6749{
6750 struct hdd_config *pcfg_ini = phddctx->config;
6751 struct wow_pulse_mode wow_pulse_set_info;
6752 QDF_STATUS status;
6753
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006754 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08006755
6756 if (false == phddctx->config->wow_pulse_support)
6757 return 0;
6758
6759 /* prepare the request to send to SME */
6760 if (enable == true) {
6761 wow_pulse_set_info.wow_pulse_enable = true;
6762 wow_pulse_set_info.wow_pulse_pin =
6763 pcfg_ini->wow_pulse_pin;
6764 wow_pulse_set_info.wow_pulse_interval_low =
6765 pcfg_ini->wow_pulse_interval_low;
6766 wow_pulse_set_info.wow_pulse_interval_high =
6767 pcfg_ini->wow_pulse_interval_high;
6768 } else {
6769 wow_pulse_set_info.wow_pulse_enable = false;
6770 wow_pulse_set_info.wow_pulse_pin = 0;
6771 wow_pulse_set_info.wow_pulse_interval_low = 0;
6772 wow_pulse_set_info.wow_pulse_interval_high = 0;
6773 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006774 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08006775 wow_pulse_set_info.wow_pulse_enable,
6776 wow_pulse_set_info.wow_pulse_pin,
6777 wow_pulse_set_info.wow_pulse_interval_low,
6778 wow_pulse_set_info.wow_pulse_interval_high);
6779
6780 status = sme_set_wow_pulse(&wow_pulse_set_info);
6781 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006782 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08006783 return -EIO;
6784 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006785 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08006786 return 0;
6787}
6788#else
6789static inline int wlan_hdd_set_wow_pulse(hdd_context_t *phddctx, bool enable)
6790{
6791 return 0;
6792}
6793#endif
6794
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006795#ifdef WLAN_FEATURE_FASTPATH
6796/**
6797 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
6798 * @hdd_cfg: hdd config
6799 * @context: lower layer context
6800 *
6801 * Return: none
6802 */
Arun Khandavallifae92942016-08-01 13:31:08 +05306803void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006804 void *context)
6805{
6806 if (hdd_cfg->fastpath_enable)
6807 hif_enable_fastpath(context);
6808}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006809#endif
6810
Yuanyuan Liu13738502016-04-06 17:41:37 -07006811#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006812/**
6813 * hdd_set_thermal_level_cb() - set thermal level callback function
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08006814 * @context: hdd context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006815 * @level: thermal level
6816 *
6817 * Change IPA data path to SW path when the thermal throttle level greater
6818 * than 0, and restore the original data path when throttle level is 0
6819 *
6820 * Return: none
6821 */
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08006822static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006823{
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08006824 hdd_context_t *hdd_ctx = context;
6825
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006826 /* Change IPA to SW path when throttle level greater than 0 */
6827 if (level > THROTTLE_LEVEL_0)
6828 hdd_ipa_send_mcc_scc_msg(hdd_ctx, true);
6829 else
6830 /* restore original concurrency mode */
6831 hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode);
6832}
6833
6834/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306835 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
6836 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05306837 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006838 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306839 * Get a safe channel to restart SAP. PCL already takes into account the
6840 * unsafe channels. So, the PCL is validated with the ACS range to provide
6841 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006842 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306843 * Return: Channel number to restart SAP in case of success. In case of any
6844 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006845 */
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306846static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range(
6847 hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006848{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306849 struct sir_pcl_list pcl;
6850 QDF_STATUS status;
6851 uint32_t i, j;
6852 tHalHandle *hal_handle;
6853 hdd_context_t *hdd_ctx;
6854 bool found = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006855
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306856 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6857 if (!hdd_ctx) {
6858 hdd_err("invalid HDD context");
6859 return INVALID_CHANNEL_ID;
6860 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006861
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05306862 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
6863 if (!hal_handle) {
6864 hdd_err("invalid HAL handle");
6865 return INVALID_CHANNEL_ID;
6866 }
6867
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08006868 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->hdd_psoc,
6869 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306870 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
6871 if (QDF_IS_STATUS_ERROR(status)) {
6872 hdd_err("Get PCL failed");
6873 return INVALID_CHANNEL_ID;
6874 }
6875
Frank Liudc2cefb2017-06-21 15:38:18 +08006876 /*
6877 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
6878 * channel is unsafe channel, the pcl may be empty, instead of return,
6879 * try to choose a safe channel from acs range.
6880 */
6881 if (!pcl.pcl_len)
6882 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306883
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006884 hdd_debug("start:%d end:%d",
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306885 adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch,
6886 adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch);
6887
6888 /* PCL already takes unsafe channel into account */
6889 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006890 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306891 if ((pcl.pcl_list[i] >=
6892 adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch) &&
6893 (pcl.pcl_list[i] <=
6894 adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006895 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306896 return pcl.pcl_list[i];
6897 }
6898 }
6899
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006900 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306901
6902 /* Try for safe channel from all valid channel */
6903 pcl.pcl_len = MAX_NUM_CHAN;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08006904 status = sme_get_cfg_valid_channels(pcl.pcl_list,
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306905 &pcl.pcl_len);
6906 if (QDF_IS_STATUS_ERROR(status)) {
6907 hdd_err("error in getting valid channel list");
6908 return INVALID_CHANNEL_ID;
6909 }
6910
6911 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006912 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306913 found = false;
6914 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
Krunal Soni15f0db12016-10-11 18:53:37 -07006915 if (pcl.pcl_list[i] ==
6916 hdd_ctx->unsafe_channel_list[j]) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006917 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306918 found = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006919 break;
6920 }
6921 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306922
6923 if (found)
6924 continue;
6925
6926 if ((pcl.pcl_list[i] >=
6927 adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch) &&
6928 (pcl.pcl_list[i] <=
6929 adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006930 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306931 return pcl.pcl_list[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006932 }
6933 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306934
6935 return INVALID_CHANNEL_ID;
6936}
6937
6938/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08006939 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306940 * @adapter: AP adapter
6941 * @channel: Channel
6942 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08006943 * Moves the SAP interface by invoking the function which
6944 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306945 *
6946 * Return: None
6947 */
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08006948void hdd_switch_sap_channel(hdd_adapter_t *adapter, uint8_t channel)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306949{
6950 hdd_ap_ctx_t *hdd_ap_ctx;
6951 tHalHandle *hal_handle;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08006952 hdd_context_t *hdd_ctx;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306953
6954 if (!adapter) {
6955 hdd_err("invalid adapter");
6956 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006957 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306958
6959 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
6960
6961 hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
6962 if (!hal_handle) {
6963 hdd_err("invalid HAL handle");
6964 return;
6965 }
6966
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08006967 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6968
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306969 hdd_ap_ctx->sapConfig.channel = channel;
6970 hdd_ap_ctx->sapConfig.ch_params.ch_width =
6971 hdd_ap_ctx->sapConfig.ch_width_orig;
6972
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006973 hdd_debug("chan:%d width:%d",
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306974 channel, hdd_ap_ctx->sapConfig.ch_width_orig);
6975
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07006976 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
6977 hdd_ap_ctx->sapConfig.channel,
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05306978 hdd_ap_ctx->sapConfig.sec_ch,
6979 &hdd_ap_ctx->sapConfig.ch_params);
6980
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08006981 policy_mgr_change_sap_channel_with_csa(hdd_ctx->hdd_psoc,
6982 adapter->sessionId, channel,
6983 hdd_ap_ctx->sapConfig.ch_width_orig);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006984}
Kapil Gupta8878ad92017-02-13 11:56:04 +05306985
6986int hdd_update_acs_timer_reason(hdd_adapter_t *adapter, uint8_t reason)
6987{
6988 struct hdd_external_acs_timer_context *timer_context;
6989
6990 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
6991
6992 if (QDF_TIMER_STATE_RUNNING ==
6993 qdf_mc_timer_get_current_state(&adapter->sessionCtx.
6994 ap.vendor_acs_timer)) {
6995 qdf_mc_timer_stop(&adapter->sessionCtx.ap.vendor_acs_timer);
6996 }
6997 timer_context = (struct hdd_external_acs_timer_context *)
6998 adapter->sessionCtx.ap.vendor_acs_timer.user_data;
6999 timer_context->reason = reason;
7000 qdf_mc_timer_start(&adapter->sessionCtx.ap.vendor_acs_timer,
7001 WLAN_VENDOR_ACS_WAIT_TIME);
7002 /* Update config to application */
7003 hdd_cfg80211_update_acs_config(adapter, reason);
7004 hdd_notice("Updated ACS config to nl with reason %d", reason);
7005
7006 return 0;
7007}
7008
Agrawal Ashish467dde42016-09-08 18:44:22 +05307009/**
7010 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
7011 * @hdd_ctx: hdd context pointer
7012 *
7013 * hdd_unsafe_channel_restart_sap check all unsafe channel list
7014 * and if ACS is enabled, driver will ask userspace to restart the
7015 * sap. User space on LTE coex indication restart driver.
7016 *
7017 * Return - none
7018 */
7019void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctxt)
7020{
7021 QDF_STATUS status;
7022 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
7023 hdd_adapter_t *adapter_temp;
7024 uint32_t i;
7025 bool found = false;
7026 uint8_t restart_chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007027
Agrawal Ashish467dde42016-09-08 18:44:22 +05307028 status = hdd_get_front_adapter(hdd_ctxt, &adapter_node);
7029 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
7030 adapter_temp = adapter_node->pAdapter;
7031
7032 if (!adapter_temp) {
7033 hdd_err("adapter is NULL, moving to next one");
7034 goto next_adapater;
7035 }
7036
7037 if (!((adapter_temp->device_mode == QDF_SAP_MODE) &&
7038 (adapter_temp->sessionCtx.ap.sapConfig.acs_cfg.acs_mode))) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007039 hdd_debug("skip device mode:%d acs:%d",
Agrawal Ashish467dde42016-09-08 18:44:22 +05307040 adapter_temp->device_mode,
7041 adapter_temp->sessionCtx.ap.sapConfig.
7042 acs_cfg.acs_mode);
7043 goto next_adapater;
7044 }
7045
7046 found = false;
7047 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
Krunal Soni15f0db12016-10-11 18:53:37 -07007048 if (adapter_temp->sessionCtx.ap.operatingChannel ==
Agrawal Ashish467dde42016-09-08 18:44:22 +05307049 hdd_ctxt->unsafe_channel_list[i]) {
7050 found = true;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007051 hdd_debug("operating ch:%d is unsafe",
Agrawal Ashish467dde42016-09-08 18:44:22 +05307052 adapter_temp->sessionCtx.ap.operatingChannel);
7053 break;
7054 }
7055 }
7056
7057 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007058 hdd_debug("ch:%d is safe. no need to change channel",
Agrawal Ashish467dde42016-09-08 18:44:22 +05307059 adapter_temp->sessionCtx.ap.operatingChannel);
7060 goto next_adapater;
7061 }
7062
Kapil Gupta8878ad92017-02-13 11:56:04 +05307063 if (hdd_ctxt->config->vendor_acs_support &&
7064 hdd_ctxt->config->acs_support_for_dfs_ltecoex) {
7065 hdd_update_acs_timer_reason(adapter_temp,
7066 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
7067 goto next_adapater;
7068 } else
7069 restart_chan =
7070 hdd_get_safe_channel_from_pcl_and_acs_range(
Agrawal Ashish467dde42016-09-08 18:44:22 +05307071 adapter_temp);
7072 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007073 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05307074 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08007075 /*
7076 * SAP restart due to unsafe channel. While
7077 * restarting the SAP, make sure to clear
7078 * acs_channel, channel to reset to
7079 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05307080 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08007081 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05307082 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
7083 adapter_temp->sessionCtx.ap.sapConfig.channel =
7084 AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007085 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05307086 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
7087 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007088 hdd_switch_sap_channel(adapter_temp, restart_chan);
Agrawal Ashish467dde42016-09-08 18:44:22 +05307089 }
7090
7091next_adapater:
7092 status = hdd_get_next_adapter(hdd_ctxt, adapter_node, &next);
7093 adapter_node = next;
7094 }
7095}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307096
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007097/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007098 * hdd_init_channel_avoidance() - Initialize channel avoidance
7099 * @hdd_ctx: HDD global context
7100 *
7101 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07007102 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007103 * down to the lower layers. Then subscribe to subsequent channel
7104 * avoidance events.
7105 *
7106 * Return: None
7107 */
7108static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
7109{
7110 uint16_t unsafe_channel_count;
7111 int index;
7112
Yuanyuan Liu13738502016-04-06 17:41:37 -07007113 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
7114 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007115 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08007116 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007117
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007118 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007119 hdd_ctx->unsafe_channel_count);
7120
Anurag Chouhan6d760662016-02-20 16:05:43 +05307121 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08007122 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007123
7124 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007125 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007126 hdd_ctx->unsafe_channel_list[index]);
7127
7128 }
7129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007130}
7131#else
7132static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
7133{
7134}
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007135static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007136{
7137}
Yuanyuan Liu13738502016-04-06 17:41:37 -07007138#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007139
7140/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08007141 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
7142 * user space
7143 * @frame_ind: Management frame data to be informed.
7144 *
7145 * This function is used to indicate management frame to
7146 * user space
7147 *
7148 * Return: None
7149 *
7150 */
7151void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
7152{
7153 hdd_context_t *hdd_ctx = NULL;
7154 hdd_adapter_t *adapter = NULL;
7155 void *cds_context = NULL;
7156 int i;
7157
7158 /* Get the global VOSS context.*/
7159 cds_context = cds_get_global_context();
7160 if (!cds_context) {
7161 hdd_err("Global CDS context is Null");
7162 return;
7163 }
7164 /* Get the HDD context.*/
7165 hdd_ctx = (hdd_context_t *)cds_get_context(QDF_MODULE_ID_HDD);
7166
7167 if (0 != wlan_hdd_validate_context(hdd_ctx))
7168 return;
7169
7170 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
7171 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
7172 adapter =
7173 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
7174 if (adapter)
7175 break;
7176 }
7177 } else {
7178 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
7179 frame_ind->sessionId);
7180 }
7181
7182 if ((NULL != adapter) &&
7183 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
7184 __hdd_indicate_mgmt_frame(adapter,
7185 frame_ind->frame_len,
7186 frame_ind->frameBuf,
7187 frame_ind->frameType,
7188 frame_ind->rxChan,
7189 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08007190}
7191
Kapil Gupta8878ad92017-02-13 11:56:04 +05307192static void hdd_lte_coex_restart_sap(hdd_adapter_t *adapter,
7193 hdd_context_t *hdd_ctx)
7194{
7195 uint8_t restart_chan = 0;
7196
7197 restart_chan =
7198 hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
7199 if (!restart_chan) {
7200 hdd_alert("fail to restart SAP");
7201 } else {
7202 /* SAP restart due to unsafe channel. While restarting
7203 * the SAP, make sure to clear acs_channel, channel to
7204 * reset to 0. Otherwise these settings will override
7205 * the ACS while restart.
7206 */
7207 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
7208 adapter->sessionCtx.ap.sapConfig.channel =
7209 AUTO_CHANNEL_SELECT;
7210 hdd_info("sending coex indication");
7211 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
7212 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08007213 hdd_switch_sap_channel(adapter, restart_chan);
Kapil Gupta8878ad92017-02-13 11:56:04 +05307214 }
7215}
7216
7217void hdd_acs_response_timeout_handler(void *context)
7218{
7219 struct hdd_external_acs_timer_context *timer_context =
7220 (struct hdd_external_acs_timer_context *)context;
7221 hdd_adapter_t *adapter;
7222 hdd_context_t *hdd_ctx;
7223 uint8_t reason;
7224
7225 ENTER();
7226 if (!timer_context) {
7227 hdd_err("invlaid timer context");
7228 return;
7229 }
7230 adapter = timer_context->adapter;
7231 reason = timer_context->reason;
7232
7233
7234 if ((!adapter) ||
7235 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
7236 hdd_err("invalid adapter or adapter has invalid magic");
7237 return;
7238 }
7239 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7240 if (wlan_hdd_validate_context(hdd_ctx))
7241 return;
7242
7243 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
7244 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
7245 else
7246 return;
7247
7248 hdd_err("ACS timeout happened for %s reason %d",
7249 adapter->dev->name, reason);
7250 switch (reason) {
7251 /* SAP init case */
7252 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
7253 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
7254 false);
7255 wlan_hdd_cfg80211_start_acs(adapter);
7256 break;
7257 /* DFS detected on current channel */
7258 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
7259 wlan_sap_update_next_channel(
7260 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
7261 sme_update_new_channel_event(WLAN_HDD_GET_HAL_CTX(adapter),
7262 adapter->sessionId);
7263 break;
7264 /* LTE coex event on current channel */
7265 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
7266 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
7267 break;
7268 default:
7269 hdd_info("invalid reason for timer invoke");
7270
7271 }
7272}
7273
Rajeev Kumard004abc2016-02-17 12:09:56 -08007274/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007275 * wlan_hdd_disable_all_dual_mac_features() - Disable dual mac features
7276 * @hdd_ctx: HDD context
7277 *
7278 * Disables all the dual mac features like DBS, Agile DFS etc.
7279 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307280 * Return: QDF_STATUS_SUCCESS on success
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007281 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307282static QDF_STATUS wlan_hdd_disable_all_dual_mac_features(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007283{
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007284 struct policy_mgr_dual_mac_config cfg = {0};
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307285 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007286
7287 if (!hdd_ctx) {
7288 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307289 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007290 }
7291
7292 cfg.scan_config = 0;
7293 cfg.fw_mode_config = 0;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007294 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007295
7296 hdd_debug("Disabling all dual mac features...");
7297
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08007298 status = sme_soc_set_dual_mac_config(cfg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307299 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007300 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
7301 return status;
7302 }
7303
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307304 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007305}
7306
7307/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007308 * hdd_override_ini_config - Override INI config
7309 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007310 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007311 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007312 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007313 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007314 */
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007315static void hdd_override_ini_config(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007316{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007317
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007318 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
7319 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007320 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007321 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007322 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007323 if (0 == enable_11d || 1 == enable_11d) {
7324 hdd_ctx->config->Is11dSupportEnabled = enable_11d;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007325 hdd_debug("Module enable_11d set to %d", enable_11d);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007326 }
Leo Chang11545d62016-10-17 14:53:50 -07007327
7328 if (!hdd_ipa_is_present(hdd_ctx))
7329 hdd_ctx->config->IpaConfig = 0;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007330}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007331
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007332/**
7333 * hdd_set_trace_level_for_each - Set trace level for each INI config
7334 * @hdd_ctx - HDD context
7335 *
7336 * Set trace level for each module based on INI config.
7337 *
7338 * Return: None
7339 */
7340static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx)
7341{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307342 hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
7343 hdd_ctx->config->qdf_trace_enable_wdi);
7344 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
7345 hdd_ctx->config->qdf_trace_enable_hdd);
7346 hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
7347 hdd_ctx->config->qdf_trace_enable_sme);
7348 hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
7349 hdd_ctx->config->qdf_trace_enable_pe);
7350 hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
7351 hdd_ctx->config->qdf_trace_enable_wma);
7352 hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
7353 hdd_ctx->config->qdf_trace_enable_sys);
7354 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
7355 hdd_ctx->config->qdf_trace_enable_qdf);
7356 hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
7357 hdd_ctx->config->qdf_trace_enable_sap);
7358 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
7359 hdd_ctx->config->qdf_trace_enable_hdd_sap);
7360 hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
7361 hdd_ctx->config->qdf_trace_enable_bmi);
7362 hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
7363 hdd_ctx->config->qdf_trace_enable_cfg);
7364 hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
7365 hdd_ctx->config->qdf_trace_enable_epping);
7366 hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
7367 hdd_ctx->config->qdf_trace_enable_qdf_devices);
7368 hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
Bhargav Shah480a90f2015-06-24 15:10:14 +05307369 hdd_ctx->config->cfd_trace_enable_txrx);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307370 hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
7371 hdd_ctx->config->qdf_trace_enable_htc);
7372 hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
7373 hdd_ctx->config->qdf_trace_enable_hif);
7374 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
7375 hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
7376 hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
7377 hdd_ctx->config->qdf_trace_enable_hdd_data);
Naveen Rawat7df31862017-03-01 17:09:30 -08007378 hdd_qdf_trace_enable(QDF_MODULE_ID_WIFIPOS,
7379 hdd_ctx->config->qdf_trace_enable_wifi_pos);
Naveen Rawatf2b0dbd2017-03-27 10:00:15 -07007380 hdd_qdf_trace_enable(QDF_MODULE_ID_NAN,
7381 hdd_ctx->config->qdf_trace_enable_nan);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07007382 hdd_qdf_trace_enable(QDF_MODULE_ID_REGULATORY,
7383 hdd_ctx->config->qdf_trace_enable_regulatory);
7384
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007385 hdd_cfg_print(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007386}
7387
7388/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007389 * hdd_context_init() - Initialize HDD context
7390 * @hdd_ctx: HDD context.
7391 *
7392 * Initialize HDD context along with all the feature specific contexts.
7393 *
7394 * return: 0 on success and errno on failure.
7395 */
7396static int hdd_context_init(hdd_context_t *hdd_ctx)
7397{
7398 int ret;
7399
7400 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
7401 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
7402
7403 hdd_init_ll_stats_ctx();
7404
7405 init_completion(&hdd_ctx->mc_sus_event_var);
7406 init_completion(&hdd_ctx->ready_to_suspend);
7407
7408 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307409 qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007410 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307411
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007412 qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS);
7413
7414 init_completion(&hdd_ctx->set_antenna_mode_cmpl);
7415
7416 ret = hdd_scan_context_init(hdd_ctx);
7417 if (ret)
7418 goto list_destroy;
7419
Nitesh Shahd1266d72017-01-25 22:07:07 +05307420 hdd_tdls_context_init(hdd_ctx, false);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007421
7422 hdd_rx_wake_lock_create(hdd_ctx);
7423
7424 ret = hdd_sap_context_init(hdd_ctx);
7425 if (ret)
7426 goto scan_destroy;
7427
7428 ret = hdd_roc_context_init(hdd_ctx);
7429 if (ret)
7430 goto sap_destroy;
7431
7432 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
7433
7434 hdd_init_offloaded_packets_ctx(hdd_ctx);
7435
7436 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
7437 hdd_ctx->config);
7438 if (ret)
7439 goto roc_destroy;
7440
7441 return 0;
7442
7443roc_destroy:
7444 hdd_roc_context_destroy(hdd_ctx);
7445
7446sap_destroy:
7447 hdd_sap_context_destroy(hdd_ctx);
7448
7449scan_destroy:
7450 hdd_scan_context_destroy(hdd_ctx);
7451 hdd_rx_wake_lock_destroy(hdd_ctx);
7452 hdd_tdls_context_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007453list_destroy:
7454 qdf_list_destroy(&hdd_ctx->hddAdapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08007455
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007456 return ret;
7457}
7458
7459/**
7460 * hdd_context_create() - Allocate and inialize HDD context.
Arun Khandavallifae92942016-08-01 13:31:08 +05307461 * @dev: Device Pointer to the underlying device
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007462 *
7463 * Allocate and initialize HDD context. HDD context is allocated as part of
7464 * wiphy allocation and then context is initialized.
7465 *
7466 * Return: HDD context on success and ERR_PTR on failure
7467 */
Jeff Johnson590e2012016-10-05 16:16:24 -07007468static hdd_context_t *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007469{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307470 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007471 int ret = 0;
7472 hdd_context_t *hdd_ctx;
7473 v_CONTEXT_t p_cds_context;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05307474 int qdf_print_idx = -1;
7475
7476 struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
7477 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
7478 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
7479 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
7480 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
7481 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
7482 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
7483 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
7484 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
7485 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
7486 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
7487 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
7488 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
7489 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
7490 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
7491 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
7492 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
7493 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
7494 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
7495 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
7496 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiyaf928edf2017-02-06 14:43:24 +05307497 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
7498 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
7499 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
7500 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
7501 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
7502 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
Mukul Sharma4d7d6b02017-02-13 20:45:22 +05307503 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh9679dbf2017-02-15 11:35:41 +05307504 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
Tushnim Bhattacharyya6796d8d2017-03-17 11:06:03 -07007505 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
7506 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
Wu Gao9a704f42017-03-10 18:42:11 +08007507 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
Frank Liud4b2fa02017-03-29 11:46:48 +08007508 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07007509 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
Varun Reddy Yeturu3fb61712017-08-10 14:48:02 -07007510 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05307511 };
7512
7513 status = qdf_print_setup();
7514 if (status != QDF_STATUS_SUCCESS) {
7515 pr_err("QDF print control object setup failed\n");
7516 ret = -EINVAL;
7517 goto err_out;
7518 }
7519 /* Register the module here with QDF */
7520 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL,
7521 "MCL_WLAN");
7522
7523 /* if qdf_print_idx is negative */
7524 if (qdf_print_idx < 0) {
7525 pr_err("QDF print control can not be registered %d\n",
7526 qdf_print_idx);
7527 ret = -EINVAL;
7528 goto err_out;
7529 }
7530
7531 /* Store the qdf_pidx information into qdf module */
7532 qdf_set_pidx(qdf_print_idx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007533
7534 ENTER();
7535
7536 p_cds_context = cds_get_global_context();
7537 if (p_cds_context == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007538 hdd_err("Failed to get CDS global context");
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007539 ret = -EINVAL;
7540 goto err_out;
7541 }
7542
7543 hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t));
7544
7545 if (hdd_ctx == NULL) {
7546 ret = -ENOMEM;
7547 goto err_out;
7548 }
7549
7550 hdd_ctx->pcds_context = p_cds_context;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007551 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05307552 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007553
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307554 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007555 if (hdd_ctx->config == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007556 hdd_err("Failed to alloc memory for HDD config!");
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007557 ret = -ENOMEM;
7558 goto err_free_hdd_context;
7559 }
7560
7561 /* Read and parse the qcom_cfg.ini file */
7562 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307563 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05307564 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007565 WLAN_INI_FILE);
7566 ret = -EINVAL;
7567 goto err_free_config;
7568 }
7569
Dustin Brown7f939932017-05-18 15:02:17 -07007570 hdd_debug("setting timer multiplier: %u",
7571 hdd_ctx->config->timer_multiplier);
7572 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
7573
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007574
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05307575 if (hdd_ctx->config->fhostNSOffload)
7576 hdd_ctx->ns_offload_enable = true;
7577
Abhishek Singh5ea86532016-04-27 14:10:53 +05307578 cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
7579
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007580 hdd_override_ini_config(hdd_ctx);
7581
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007582 ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007583
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007584 ret = hdd_context_init(hdd_ctx);
7585
7586 if (ret)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007587 goto err_free_config;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007588
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007589 /* Uses to enabled logging after SSR */
Komal Seelamc11bb222016-01-27 18:57:10 +05307590 hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007591
Anurag Chouhan6d760662016-02-20 16:05:43 +05307592 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007593 goto skip_multicast_logging;
7594
7595 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
7596
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07007597 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
7598 if (ret)
7599 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05307600
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007601 ret = hdd_logging_sock_activate_svc(hdd_ctx);
7602 if (ret)
Nirav Shahed34b212016-04-25 10:59:16 +05307603 goto err_free_histogram;
7604
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007605skip_multicast_logging:
7606 hdd_set_trace_level_for_each(hdd_ctx);
7607
7608 return hdd_ctx;
7609
Nirav Shahed34b212016-04-25 10:59:16 +05307610err_free_histogram:
7611 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
7612
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07007613err_deinit_hdd_context:
7614 hdd_context_deinit(hdd_ctx);
7615
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007616err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307617 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007618
7619err_free_hdd_context:
7620 wiphy_free(hdd_ctx->wiphy);
7621
7622err_out:
7623 return ERR_PTR(ret);
7624}
7625
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007626#ifdef WLAN_OPEN_P2P_INTERFACE
7627/**
7628 * hdd_open_p2p_interface - Open P2P interface
7629 * @hdd_ctx: HDD context
7630 * @rtnl_held: True if RTNL lock held
7631 *
7632 * Open P2P interface during probe. This function called to open the P2P
7633 * interface at probe along with STA interface.
7634 *
7635 * Return: 0 on success and errno on failure
7636 */
7637static int hdd_open_p2p_interface(hdd_context_t *hdd_ctx, bool rtnl_held)
7638{
7639 hdd_adapter_t *adapter;
7640 uint8_t *p2p_dev_addr;
7641
7642 if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
7643 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307644 qdf_mem_copy(hdd_ctx->p2pDeviceAddress.bytes,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007645 hdd_ctx->config->intfMacAddr[0].bytes,
7646 sizeof(tSirMacAddr));
7647
7648 /*
7649 * Generate the P2P Device Address. This consists of
7650 * the device's primary MAC address with the locally
7651 * administered bit set.
7652 */
7653 hdd_ctx->p2pDeviceAddress.bytes[0] |= 0x02;
7654 } else {
7655 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
7656 if (p2p_dev_addr == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007657 hdd_err("Failed to allocate mac_address for p2p_device");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007658 return -ENOSPC;
7659 }
7660
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307661 qdf_mem_copy(&hdd_ctx->p2pDeviceAddress.bytes[0], p2p_dev_addr,
Anurag Chouhan6d760662016-02-20 16:05:43 +05307662 QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007663 }
7664
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007665 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007666 &hdd_ctx->p2pDeviceAddress.bytes[0],
Ryan Hsu07495ea2016-01-21 15:25:39 -08007667 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007668
7669 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007670 hdd_err("Failed to do hdd_open_adapter for P2P Device Interface");
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007671 return -ENOSPC;
7672 }
7673
7674 return 0;
7675}
7676#else
Manishekar Chandrasekaranc81ba242016-07-18 17:44:44 +05307677static inline int hdd_open_p2p_interface(hdd_context_t *hdd_ctx,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007678 bool rtnl_held)
7679{
7680 return 0;
7681}
7682#endif
7683
Jeff Johnson957bc272017-02-02 08:54:48 -08007684static int hdd_open_ocb_interface(hdd_context_t *hdd_ctx, bool rtnl_held)
7685{
7686 hdd_adapter_t *adapter;
7687 int ret = 0;
7688
7689 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
7690 wlan_hdd_get_intf_addr(hdd_ctx),
7691 NET_NAME_UNKNOWN, rtnl_held);
7692 if (adapter == NULL) {
7693 hdd_err("Failed to open 802.11p interface");
7694 ret = -ENOSPC;
7695 }
7696
7697 return ret;
7698}
7699
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007700/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05307701 * hdd_start_station_adapter()- Start the Station Adapter
7702 * @adapter: HDD adapter
7703 *
7704 * This function initializes the adapter for the station mode.
7705 *
7706 * Return: 0 on success or errno on failure.
7707 */
7708int hdd_start_station_adapter(hdd_adapter_t *adapter)
7709{
7710 QDF_STATUS status;
7711
7712 ENTER_DEV(adapter->dev);
7713
7714 status = hdd_init_station_mode(adapter);
7715
7716 if (QDF_STATUS_SUCCESS != status) {
7717 hdd_err("Error Initializing station mode: %d", status);
7718 return qdf_status_to_os_return(status);
7719 }
7720
Arun Khandavallifae92942016-08-01 13:31:08 +05307721 hdd_register_tx_flow_control(adapter,
7722 hdd_tx_resume_timer_expired_handler,
7723 hdd_tx_resume_cb);
7724
Arun Khandavalli7e857c32016-06-26 12:07:16 +05307725 EXIT();
7726 return 0;
7727}
7728
7729/**
7730 * hdd_start_ap_adapter()- Start AP Adapter
7731 * @adapter: HDD adapter
7732 *
7733 * This function initializes the adapter for the AP mode.
7734 *
7735 * Return: 0 on success errno on failure.
7736 */
7737int hdd_start_ap_adapter(hdd_adapter_t *adapter)
7738{
7739 QDF_STATUS status;
7740
7741 ENTER();
7742
Arun Khandavallicc544b32017-01-30 19:52:16 +05307743 status = hdd_init_ap_mode(adapter, false);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05307744
7745 if (QDF_STATUS_SUCCESS != status) {
7746 hdd_err("Error Initializing the AP mode: %d", status);
7747 return qdf_status_to_os_return(status);
7748 }
7749
Arun Khandavallifae92942016-08-01 13:31:08 +05307750 hdd_register_tx_flow_control(adapter,
7751 hdd_softap_tx_resume_timer_expired_handler,
7752 hdd_softap_tx_resume_cb);
7753
Arun Khandavalli7e857c32016-06-26 12:07:16 +05307754 EXIT();
7755 return 0;
7756}
7757
7758/**
7759 * hdd_start_ftm_adapter()- Start FTM adapter
7760 * @adapter: HDD adapter
7761 *
7762 * This function initializes the adapter for the FTM mode.
7763 *
7764 * Return: 0 on success or errno on failure.
7765 */
7766int hdd_start_ftm_adapter(hdd_adapter_t *adapter)
7767{
7768 QDF_STATUS qdf_status;
7769
7770 ENTER_DEV(adapter->dev);
7771
7772 qdf_status = hdd_init_tx_rx(adapter);
7773
7774 if (QDF_STATUS_SUCCESS != qdf_status) {
7775 hdd_err("Failed to start FTM adapter: %d", qdf_status);
7776 return qdf_status_to_os_return(qdf_status);
7777 }
7778
7779 return 0;
7780 EXIT();
7781}
7782
7783/**
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007784 * hdd_open_interfaces - Open all required interfaces
7785 * hdd_ctx: HDD context
7786 * rtnl_held: True if RTNL lock is held
7787 *
7788 * Open all the interfaces like STA, P2P and OCB based on the configuration.
7789 *
Jeff Johnson957bc272017-02-02 08:54:48 -08007790 * Return: 0 if all interfaces were created, otherwise negative errno
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007791 */
Jeff Johnson957bc272017-02-02 08:54:48 -08007792static int hdd_open_interfaces(hdd_context_t *hdd_ctx, bool rtnl_held)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007793{
Jeff Johnson957bc272017-02-02 08:54:48 -08007794 hdd_adapter_t *adapter;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007795 int ret;
7796
Jeff Johnson957bc272017-02-02 08:54:48 -08007797 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE)
Arun Khandavallifae92942016-08-01 13:31:08 +05307798 /* Create only 802.11p interface */
Jeff Johnson957bc272017-02-02 08:54:48 -08007799 return hdd_open_ocb_interface(hdd_ctx, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007800
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007801 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007802 wlan_hdd_get_intf_addr(hdd_ctx),
Ryan Hsu07495ea2016-01-21 15:25:39 -08007803 NET_NAME_UNKNOWN, rtnl_held);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007804
7805 if (adapter == NULL)
Jeff Johnson957bc272017-02-02 08:54:48 -08007806 return -ENOSPC;
7807
Deepak Dhamdherea2785822016-11-17 01:17:45 -08007808 /* fast roaming is allowed only on first STA, i.e. wlan adapter */
7809 adapter->fast_roaming_allowed = true;
7810
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007811 ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
7812 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -08007813 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007814
7815 /* Open 802.11p Interface */
7816 if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
Jeff Johnson957bc272017-02-02 08:54:48 -08007817 ret = hdd_open_ocb_interface(hdd_ctx, rtnl_held);
7818 if (ret)
7819 goto err_close_adapters;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007820 }
7821
Jeff Johnson957bc272017-02-02 08:54:48 -08007822 return 0;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007823
Jeff Johnson957bc272017-02-02 08:54:48 -08007824err_close_adapters:
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007825 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Jeff Johnson957bc272017-02-02 08:54:48 -08007826 return ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08007827}
7828
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007829/**
7830 * hdd_update_country_code - Update country code
7831 * @hdd_ctx: HDD context
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007832 *
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07007833 * Update country code based on module parameter country_code
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007834 *
7835 * Return: 0 on success and errno on failure
7836 */
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07007837static int hdd_update_country_code(hdd_context_t *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007838{
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07007839 if (!country_code)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007840 return 0;
7841
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07007842 return hdd_reg_set_country(hdd_ctx, country_code);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08007843}
7844
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307845#ifdef QCA_LL_TX_FLOW_CONTROL_V2
7846/**
7847 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
7848 * @cds_cfg: CDS Configuration
7849 * @hdd_ctx: Pointer to hdd context
7850 *
7851 * Return: none
7852 */
7853static inline void hdd_txrx_populate_cds_config(struct cds_config_info
7854 *cds_cfg,
7855 hdd_context_t *hdd_ctx)
7856{
7857 cds_cfg->tx_flow_stop_queue_th =
7858 hdd_ctx->config->TxFlowStopQueueThreshold;
7859 cds_cfg->tx_flow_start_queue_offset =
7860 hdd_ctx->config->TxFlowStartQueueOffset;
7861}
7862#else
7863static inline void hdd_txrx_populate_cds_config(struct cds_config_info
7864 *cds_cfg,
7865 hdd_context_t *hdd_ctx)
7866{
7867}
7868#endif
7869
7870#ifdef FEATURE_WLAN_RA_FILTERING
7871/**
7872 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
7873 * @cds_cfg: CDS Configuration
7874 * @hdd_ctx: Pointer to hdd context
7875 *
7876 * Return: none
7877 */
Anand Kumar3b92a912016-12-05 12:01:26 +05307878static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307879 hdd_context_t *hdd_ctx)
7880{
7881 cds_cfg->ra_ratelimit_interval =
7882 hdd_ctx->config->RArateLimitInterval;
7883 cds_cfg->is_ra_ratelimit_enabled =
7884 hdd_ctx->config->IsRArateLimitEnabled;
7885}
7886#else
Anand Kumar3b92a912016-12-05 12:01:26 +05307887static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307888 hdd_context_t *hdd_ctx)
7889{
7890}
7891#endif
7892
7893/**
7894 * hdd_update_cds_config() - API to update cds configuration parameters
7895 * @hdd_ctx: HDD Context
7896 *
7897 * Return: 0 for Success, errno on failure
7898 */
Jeff Johnson590e2012016-10-05 16:16:24 -07007899static int hdd_update_cds_config(hdd_context_t *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307900{
7901 struct cds_config_info *cds_cfg;
7902
7903 cds_cfg = (struct cds_config_info *)qdf_mem_malloc(sizeof(*cds_cfg));
7904 if (!cds_cfg) {
7905 hdd_err("failed to allocate cds config");
7906 return -ENOMEM;
7907 }
7908
Srinivas Girigowda35b00312017-06-27 21:52:03 -07007909 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -08007910 if (!hdd_ctx->config->nMaxPsPoll ||
7911 !hdd_ctx->config->enablePowersaveOffload) {
7912 cds_cfg->powersave_offload_enabled =
7913 hdd_ctx->config->enablePowersaveOffload;
7914 } else {
7915 if ((hdd_ctx->config->enablePowersaveOffload ==
7916 PS_QPOWER_NODEEPSLEEP) ||
7917 (hdd_ctx->config->enablePowersaveOffload ==
7918 PS_LEGACY_NODEEPSLEEP))
7919 cds_cfg->powersave_offload_enabled =
7920 PS_LEGACY_NODEEPSLEEP;
7921 else
7922 cds_cfg->powersave_offload_enabled =
7923 PS_LEGACY_DEEPSLEEP;
7924 hdd_info("Qpower disabled in cds config, %d",
7925 cds_cfg->powersave_offload_enabled);
7926 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307927 cds_cfg->sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
7928 cds_cfg->sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
7929 cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
7930 cds_cfg->wow_enable = hdd_ctx->config->wowEnable;
7931 cds_cfg->max_wow_filters = hdd_ctx->config->maxWoWFilters;
7932
7933 /* Here ol_ini_info is used to store ini status of arp offload
7934 * ns offload and others. Currently 1st bit is used for arp
7935 * off load and 2nd bit for ns offload currently, rest bits are unused
7936 */
7937 if (hdd_ctx->config->fhostArpOffload)
7938 cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x1;
7939 if (hdd_ctx->config->fhostNSOffload)
7940 cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x2;
7941
7942 /*
7943 * Copy the DFS Phyerr Filtering Offload status.
7944 * This parameter reflects the value of the
7945 * dfs_phyerr_filter_offload flag as set in the ini.
7946 */
7947 cds_cfg->dfs_phyerr_filter_offload =
7948 hdd_ctx->config->fDfsPhyerrFilterOffload;
7949 if (hdd_ctx->config->ssdp)
7950 cds_cfg->ssdp = hdd_ctx->config->ssdp;
7951
7952 cds_cfg->enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
7953 cds_cfg->ap_maxoffload_peers = hdd_ctx->config->apMaxOffloadPeers;
7954
7955 cds_cfg->ap_maxoffload_reorderbuffs =
7956 hdd_ctx->config->apMaxOffloadReorderBuffs;
7957
7958 cds_cfg->ap_disable_intrabss_fwd =
7959 hdd_ctx->config->apDisableIntraBssFwd;
7960
7961 cds_cfg->dfs_pri_multiplier =
7962 hdd_ctx->config->dfsRadarPriMultiplier;
7963 cds_cfg->reorder_offload =
7964 hdd_ctx->config->reorderOffloadSupport;
7965
7966 /* IPA micro controller data path offload resource config item */
7967 cds_cfg->uc_offload_enabled = hdd_ipa_uc_is_enabled(hdd_ctx);
Yun Parkde380782016-08-17 16:26:54 -07007968 if (!is_power_of_2(hdd_ctx->config->IpaUcTxBufCount)) {
7969 /* IpaUcTxBufCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007970 hdd_debug("Round down IpaUcTxBufCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07007971 hdd_ctx->config->IpaUcTxBufCount);
7972 hdd_ctx->config->IpaUcTxBufCount =
7973 rounddown_pow_of_two(
7974 hdd_ctx->config->IpaUcTxBufCount);
7975 if (!hdd_ctx->config->IpaUcTxBufCount) {
7976 hdd_err("Failed to round down IpaUcTxBufCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05307977 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07007978 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007979 hdd_debug("IpaUcTxBufCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07007980 hdd_ctx->config->IpaUcTxBufCount);
7981 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307982 cds_cfg->uc_txbuf_count = hdd_ctx->config->IpaUcTxBufCount;
7983 cds_cfg->uc_txbuf_size = hdd_ctx->config->IpaUcTxBufSize;
Yun Parkde380782016-08-17 16:26:54 -07007984 if (!is_power_of_2(hdd_ctx->config->IpaUcRxIndRingCount)) {
7985 /* IpaUcRxIndRingCount should be power of 2 */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007986 hdd_debug("Round down IpaUcRxIndRingCount %d to nearest power of 2",
Yun Parkde380782016-08-17 16:26:54 -07007987 hdd_ctx->config->IpaUcRxIndRingCount);
7988 hdd_ctx->config->IpaUcRxIndRingCount =
7989 rounddown_pow_of_two(
7990 hdd_ctx->config->IpaUcRxIndRingCount);
7991 if (!hdd_ctx->config->IpaUcRxIndRingCount) {
7992 hdd_err("Failed to round down IpaUcRxIndRingCount");
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05307993 goto exit;
Yun Parkde380782016-08-17 16:26:54 -07007994 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007995 hdd_debug("IpaUcRxIndRingCount rounded down to %d",
Yun Parkde380782016-08-17 16:26:54 -07007996 hdd_ctx->config->IpaUcRxIndRingCount);
7997 }
Arun Khandavallic811dcc2016-06-26 07:37:21 +05307998 cds_cfg->uc_rxind_ringcount =
Yun Parkde380782016-08-17 16:26:54 -07007999 hdd_ctx->config->IpaUcRxIndRingCount;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308000 cds_cfg->uc_tx_partition_base =
8001 hdd_ctx->config->IpaUcTxPartitionBase;
8002 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
8003
8004 cds_cfg->ip_tcp_udp_checksum_offload =
8005 hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
Nirav Shahbd36b062016-07-18 11:12:59 +05308006 cds_cfg->enable_rxthread = hdd_ctx->enableRxThread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308007 cds_cfg->ce_classify_enabled =
8008 hdd_ctx->config->ce_classify_enabled;
Dustin Brownd3fc9ee2016-09-14 13:57:27 -07008009 cds_cfg->bpf_packet_filter_enable =
8010 hdd_ctx->config->bpf_packet_filter_enable;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308011 cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
8012 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
8013 cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
Naveen Rawat64e477e2016-05-20 10:34:56 -07008014 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Manjunathappa Prakashfff753c2016-09-01 19:34:56 -07008015 cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
Naveen Rawat91df30a2016-10-12 21:26:18 -07008016 cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
Sandeep Puligillaafa52892016-10-26 19:03:16 -07008017 cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05308018 cds_cfg->active_uc_bpf_mode = hdd_ctx->config->active_uc_bpf_mode;
8019 cds_cfg->active_mc_bc_bpf_mode = hdd_ctx->config->active_mc_bc_bpf_mode;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05308020 cds_cfg->auto_power_save_fail_mode =
8021 hdd_ctx->config->auto_pwr_save_fail_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308022
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05308023 cds_cfg->ito_repeat_count = hdd_ctx->config->ito_repeat_count;
8024
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308025 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
8026 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
8027 hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07008028 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308029 cds_init_ini_config(cds_cfg);
8030 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05308031
8032exit:
8033 qdf_mem_free(cds_cfg);
8034 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05308035}
8036
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008037/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08008038 * hdd_update_user_config() - API to update user configuration
8039 * parameters to obj mgr which are used by multiple components
8040 * @hdd_ctx: HDD Context
8041 *
8042 * Return: 0 for Success, errno on failure
8043 */
8044static int hdd_update_user_config(hdd_context_t *hdd_ctx)
8045{
8046 struct wlan_objmgr_psoc_user_config *user_config;
8047
8048 user_config = qdf_mem_malloc(sizeof(*user_config));
8049 if (user_config == NULL) {
8050 hdd_alert("Failed to alloc memory for user_config!");
8051 return -ENOMEM;
8052 }
8053
8054 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
8055 user_config->dual_mac_feature_disable =
8056 hdd_ctx->config->dual_mac_feature_disable;
8057 user_config->indoor_channel_support =
8058 hdd_ctx->config->indoor_channel_support;
8059 user_config->is_11d_support_enabled =
8060 hdd_ctx->config->Is11dSupportEnabled;
8061 user_config->is_11h_support_enabled =
8062 hdd_ctx->config->Is11hSupportEnabled;
8063 user_config->optimize_chan_avoid_event =
8064 hdd_ctx->config->goptimize_chan_avoid_event;
8065 user_config->skip_dfs_chnl_in_p2p_search =
8066 hdd_ctx->config->skipDfsChnlInP2pSearch;
Naveen Rawat222b2e92017-03-16 09:52:21 -07008067 user_config->band_capability = hdd_ctx->config->nBandCapability;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08008068 wlan_objmgr_psoc_set_user_config(hdd_ctx->hdd_psoc, user_config);
8069
8070 qdf_mem_free(user_config);
8071 return 0;
8072}
8073
8074/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008075 * hdd_init_thermal_info - Initialize thermal level
8076 * @hdd_ctx: HDD context
8077 *
8078 * Initialize thermal level at SME layer and set the thermal level callback
8079 * which would be called when a configured thermal threshold is hit.
8080 *
8081 * Return: 0 on success and errno on failure
8082 */
8083static int hdd_init_thermal_info(hdd_context_t *hdd_ctx)
8084{
8085 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308086 QDF_STATUS status;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008087
8088 thermal_param.smeThermalMgmtEnabled =
8089 hdd_ctx->config->thermalMitigationEnable;
8090 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
8091
Poddar, Siddarth83905022016-04-16 17:56:08 -07008092 thermal_param.sme_throttle_duty_cycle_tbl[0] =
8093 hdd_ctx->config->throttle_dutycycle_level0;
8094 thermal_param.sme_throttle_duty_cycle_tbl[1] =
8095 hdd_ctx->config->throttle_dutycycle_level1;
8096 thermal_param.sme_throttle_duty_cycle_tbl[2] =
8097 hdd_ctx->config->throttle_dutycycle_level2;
8098 thermal_param.sme_throttle_duty_cycle_tbl[3] =
8099 hdd_ctx->config->throttle_dutycycle_level3;
8100
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008101 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
8102 hdd_ctx->config->thermalTempMinLevel0;
8103 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
8104 hdd_ctx->config->thermalTempMaxLevel0;
8105 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
8106 hdd_ctx->config->thermalTempMinLevel1;
8107 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
8108 hdd_ctx->config->thermalTempMaxLevel1;
8109 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
8110 hdd_ctx->config->thermalTempMinLevel2;
8111 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
8112 hdd_ctx->config->thermalTempMaxLevel2;
8113 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
8114 hdd_ctx->config->thermalTempMinLevel3;
8115 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
8116 hdd_ctx->config->thermalTempMaxLevel3;
8117
8118 status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);
8119
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308120 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05308121 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008122
8123 sme_add_set_thermal_level_callback(hdd_ctx->hHal,
8124 hdd_set_thermal_level_cb);
8125
8126 return 0;
8127
8128}
8129
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08008130#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
8131/**
8132 * hdd_hold_rtnl_lock - Hold RTNL lock
8133 *
8134 * Hold RTNL lock
8135 *
8136 * Return: True if held and false otherwise
8137 */
8138static inline bool hdd_hold_rtnl_lock(void)
8139{
8140 rtnl_lock();
8141 return true;
8142}
8143
8144/**
8145 * hdd_release_rtnl_lock - Release RTNL lock
8146 *
8147 * Release RTNL lock
8148 *
8149 * Return: None
8150 */
8151static inline void hdd_release_rtnl_lock(void)
8152{
8153 rtnl_unlock();
8154}
8155#else
8156static inline bool hdd_hold_rtnl_lock(void) { return false; }
8157static inline void hdd_release_rtnl_lock(void) { }
8158#endif
8159
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008160#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008161
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308162/* MAX iwpriv command support */
8163#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308164#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308165#define MAX_PKTLOG_SIZE 16
8166
8167/**
8168 * hdd_pktlog_set_buff_size() - set pktlog buffer size
8169 * @hdd_ctx: hdd context
8170 * @set_value2: pktlog buffer size value
8171 *
8172 *
8173 * Return: 0 for success or error.
8174 */
8175static int hdd_pktlog_set_buff_size(hdd_context_t *hdd_ctx, int set_value2)
8176{
8177 struct sir_wifi_start_log start_log = { 0 };
8178 QDF_STATUS status;
8179
8180 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8181 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
8182 start_log.ini_triggered = cds_is_packet_log_enabled();
8183 start_log.user_triggered = 1;
8184 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308185 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308186
8187 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8188 if (!QDF_IS_STATUS_SUCCESS(status)) {
8189 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8190 EXIT();
8191 return -EINVAL;
8192 }
8193
8194 return 0;
8195}
8196
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008197/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308198 * hdd_pktlog_clear_buff() - clear pktlog buffer
8199 * @hdd_ctx: hdd context
8200 *
8201 * Return: 0 for success or error.
8202 */
8203static int hdd_pktlog_clear_buff(hdd_context_t *hdd_ctx)
8204{
8205 struct sir_wifi_start_log start_log;
8206 QDF_STATUS status;
8207
8208 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8209 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
8210 start_log.ini_triggered = cds_is_packet_log_enabled();
8211 start_log.user_triggered = 1;
8212 start_log.size = 0;
8213 start_log.is_pktlog_buff_clear = true;
8214
8215 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8216 if (!QDF_IS_STATUS_SUCCESS(status)) {
8217 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8218 EXIT();
8219 return -EINVAL;
8220 }
8221
8222 return 0;
8223}
8224
8225
8226/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008227 * hdd_process_pktlog_command() - process pktlog command
8228 * @hdd_ctx: hdd context
8229 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308230 * @set_value2: pktlog buffer size value
8231 *
8232 * This function process pktlog command.
8233 * set_value2 only matters when set_value is 3 (set buff size)
8234 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008235 *
8236 * Return: 0 for success or error.
8237 */
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308238int hdd_process_pktlog_command(hdd_context_t *hdd_ctx, uint32_t set_value,
8239 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008240{
8241 int ret;
8242 bool enable;
8243 uint8_t user_triggered = 0;
8244
8245 ret = wlan_hdd_validate_context(hdd_ctx);
8246 if (0 != ret)
8247 return ret;
8248
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008249 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008250
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308251 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008252 hdd_err("invalid pktlog value %d", set_value);
8253 return -EINVAL;
8254 }
8255
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308256 if (set_value == PKTLOG_SET_BUFF_SIZE) {
8257 if (set_value2 <= 0) {
8258 hdd_err("invalid pktlog size %d", set_value2);
8259 return -EINVAL;
8260 } else if (set_value2 > MAX_PKTLOG_SIZE) {
8261 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
8262 return -EINVAL;
8263 }
8264 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308265 } else if (set_value == PKTLOG_CLEAR_BUFF) {
8266 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308267 }
8268
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008269 /*
8270 * set_value = 0 then disable packetlog
8271 * set_value = 1 enable packetlog forcefully
8272 * set_vlaue = 2 then disable packetlog if disabled through ini or
8273 * enable packetlog with AUTO type.
8274 */
8275 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
8276 true : false;
8277
8278 if (1 == set_value) {
8279 enable = true;
8280 user_triggered = 1;
8281 }
8282
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308283 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008284}
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008285/**
8286 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
8287 * @hdd_ctx: HDD context
8288 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308289 * @user_triggered: triggered through iwpriv
8290 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008291 *
8292 * Return: 0 on success; error number otherwise
8293 */
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008294int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308295 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008296{
8297 struct sir_wifi_start_log start_log;
8298 QDF_STATUS status;
8299
8300 start_log.ring_id = RING_ID_PER_PACKET_STATS;
8301 start_log.verbose_level =
8302 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08008303 start_log.ini_triggered = cds_is_packet_log_enabled();
8304 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05308305 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05308306 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +05308307 /*
8308 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
8309 * commands. Host uses this flag to decide whether to send pktlog
8310 * disable command to fw without sending pktlog enable command
8311 * previously. For eg, If vendor sends pktlog disable command without
8312 * sending pktlog enable command, then host discards the packet
8313 * but for iwpriv command, host will send it to fw.
8314 */
8315 start_log.is_iwpriv_command = 1;
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08008316 status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
8317 if (!QDF_IS_STATUS_SUCCESS(status)) {
8318 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
8319 EXIT();
8320 return -EINVAL;
8321 }
8322
8323 return 0;
8324}
8325#endif /* REMOVE_PKT_LOG */
8326
Komal Seelam92fff912016-03-24 11:51:41 +05308327/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008328 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
8329 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +05308330 * @dev: Device Pointer
8331 * @num: Number of Valid Mac address
8332 *
8333 * Return: Pointer to MAC address buffer
8334 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008335static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
8336 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +05308337{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008338 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +05308339}
Komal Seelam92fff912016-03-24 11:51:41 +05308340
8341/**
8342 * hdd_populate_random_mac_addr() - API to populate random mac addresses
8343 * @hdd_ctx: HDD Context
8344 * @num: Number of random mac addresses needed
8345 *
8346 * Generate random addresses using bit manipulation on the base mac address
8347 *
8348 * Return: None
8349 */
Nachiket Kukadee4d86442017-06-23 16:57:00 +05308350void hdd_populate_random_mac_addr(hdd_context_t *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +05308351{
8352 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
8353 uint32_t iter;
8354 struct hdd_config *ini = hdd_ctx->config;
8355 uint8_t *buf = NULL;
8356 uint8_t macaddr_b3, tmp_br3;
8357 uint8_t *src = ini->intfMacAddr[0].bytes;
8358
8359 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
8360 buf = ini->intfMacAddr[iter].bytes;
8361 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
8362 macaddr_b3 = buf[3];
8363 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
8364 INTF_MACADDR_MASK;
8365 macaddr_b3 += tmp_br3;
8366 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
8367 buf[0] |= 0x02;
8368 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008369 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05308370 }
8371}
8372
8373/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008374 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +05308375 * @hdd_ctx: HDD Context
8376 *
8377 * API to get mac addresses from platform driver and update the driver
8378 * structures and configure FW with the base mac address.
8379 * Return: int
8380 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008381static int hdd_platform_wlan_mac(hdd_context_t *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +05308382{
8383 uint32_t no_of_mac_addr, iter;
8384 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
8385 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
8386 uint8_t *addr, *buf;
8387 struct device *dev = hdd_ctx->parent_dev;
8388 struct hdd_config *ini = hdd_ctx->config;
8389 tSirMacAddr mac_addr;
8390 QDF_STATUS status;
8391
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008392 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +05308393
8394 if (no_of_mac_addr == 0 || !addr) {
8395 hdd_warn("Platform Driver Doesn't have wlan mac addresses");
8396 return -EINVAL;
8397 }
8398
8399 if (no_of_mac_addr > max_mac_addr)
8400 no_of_mac_addr = max_mac_addr;
8401
8402 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
8403
8404 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
8405 buf = ini->intfMacAddr[iter].bytes;
8406 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008407 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +05308408 }
8409
8410 status = sme_set_custom_mac_addr(mac_addr);
8411
8412 if (!QDF_IS_STATUS_SUCCESS(status))
8413 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008414
Komal Seelam92fff912016-03-24 11:51:41 +05308415 if (no_of_mac_addr < max_mac_addr)
8416 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
8417 no_of_mac_addr);
8418 return 0;
8419}
8420
8421/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07008422 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
8423 * @hdd_ctx: HDD Context
8424 *
8425 * Update MAC address to FW. If MAC address passed by FW is invalid, host
8426 * will generate its own MAC and update it to FW.
8427 *
8428 * Return: 0 for success
8429 * Non-zero error code for failure
8430 */
8431static int hdd_update_mac_addr_to_fw(hdd_context_t *hdd_ctx)
8432{
8433 tSirMacAddr customMacAddr;
8434 QDF_STATUS status;
8435
8436 qdf_mem_copy(&customMacAddr,
8437 &hdd_ctx->config->intfMacAddr[0].bytes[0],
8438 sizeof(tSirMacAddr));
8439 status = sme_set_custom_mac_addr(customMacAddr);
8440 if (!QDF_IS_STATUS_SUCCESS(status))
8441 return -EAGAIN;
8442 return 0;
8443}
8444
8445/**
Komal Seelam92fff912016-03-24 11:51:41 +05308446 * hdd_initialize_mac_address() - API to get wlan mac addresses
8447 * @hdd_ctx: HDD Context
8448 *
8449 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
8450 * is provisioned with mac addresses, driver uses it, else it will use
8451 * wlan_mac.bin to update HW MAC addresses.
8452 *
8453 * Return: None
8454 */
8455static void hdd_initialize_mac_address(hdd_context_t *hdd_ctx)
8456{
8457 QDF_STATUS status;
8458 int ret;
8459
Yuanyuan Liu7145eb22016-12-01 10:59:29 -08008460 ret = hdd_platform_wlan_mac(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +05308461 if (ret == 0)
8462 return;
8463
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07008464 hdd_info("MAC is not programmed in platform driver ret: %d, use wlan_mac.bin",
8465 ret);
Komal Seelam92fff912016-03-24 11:51:41 +05308466
8467 status = hdd_update_mac_config(hdd_ctx);
8468
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07008469 if (QDF_IS_STATUS_SUCCESS(status))
8470 return;
8471
Yuanyuan Liu3d62f6a2017-06-08 11:08:46 -07008472 hdd_info("MAC is not programmed in wlan_mac.bin ret %d, use default MAC",
8473 status);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07008474
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08008475 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07008476 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -08008477 if (ret != 0) {
8478 hdd_err("MAC address out-of-sync, ret:%d", ret);
8479 QDF_ASSERT(ret);
8480 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07008481 }
Komal Seelam92fff912016-03-24 11:51:41 +05308482}
8483
Jeff Johnsona89e25d2017-02-24 12:25:07 -08008484static int hdd_set_smart_chainmask_enabled(hdd_context_t *hdd_ctx)
8485{
8486 int vdev_id = 0;
8487 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
8488 int value = hdd_ctx->config->smart_chainmask_enabled;
8489 int vpdev = PDEV_CMD;
8490 int ret;
8491
Naveen Rawat247a8682017-06-05 15:00:31 -07008492 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08008493 if (ret)
8494 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
8495
8496 return ret;
8497}
8498
8499static int hdd_set_alternative_chainmask_enabled(hdd_context_t *hdd_ctx)
8500{
8501 int vdev_id = 0;
8502 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
8503 int value = hdd_ctx->config->alternative_chainmask_enabled;
8504 int vpdev = PDEV_CMD;
8505 int ret;
8506
Naveen Rawat247a8682017-06-05 15:00:31 -07008507 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -08008508 if (ret)
8509 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
8510 ret);
8511
8512 return ret;
8513}
8514
Jeff Johnson12a744b2017-04-04 08:19:37 -07008515static int hdd_set_ani_enabled(hdd_context_t *hdd_ctx)
8516{
8517 int vdev_id = 0;
8518 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
8519 int value = hdd_ctx->config->ani_enabled;
8520 int vpdev = PDEV_CMD;
8521 int ret;
8522
Naveen Rawat247a8682017-06-05 15:00:31 -07008523 ret = sme_cli_set_command(vdev_id, param_id, value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -07008524 if (ret)
8525 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
8526
8527 return ret;
8528}
8529
Jeff Johnson89c66ff2016-04-22 15:21:37 -07008530/**
Prashanth Bhatta07998752016-04-28 12:35:33 -07008531 * hdd_pre_enable_configure() - Configurations prior to cds_enable
8532 * @hdd_ctx: HDD context
8533 *
8534 * Pre configurations to be done at lower layer before calling cds enable.
8535 *
8536 * Return: 0 on success and errno on failure.
8537 */
8538static int hdd_pre_enable_configure(hdd_context_t *hdd_ctx)
8539{
8540 int ret;
8541 QDF_STATUS status;
8542 tSirRetStatus hal_status;
Leo Changfdb45c32016-10-28 11:09:23 -07008543 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -07008544
Leo Changfdb45c32016-10-28 11:09:23 -07008545 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -07008546 /*
8547 * Set 802.11p config
8548 * TODO-OCB: This has been temporarily added here to ensure this
8549 * parameter is set in CSR when we init the channel list. This should
8550 * be removed once the 5.9 GHz channels are added to the regulatory
8551 * domain.
8552 */
8553 hdd_set_dot11p_config(hdd_ctx);
8554
8555 /*
8556 * Note that the cds_pre_enable() sequence triggers the cfg download.
8557 * The cfg download must occur before we update the SME config
8558 * since the SME config operation must access the cfg database
8559 */
8560 status = hdd_set_sme_config(hdd_ctx);
8561
8562 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008563 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07008564 ret = qdf_status_to_os_return(status);
8565 goto out;
8566 }
8567
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -07008568 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
8569 if (QDF_STATUS_SUCCESS != status) {
8570 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
8571 ret = qdf_status_to_os_return(status);
8572 goto out;
8573 }
8574
Naveen Rawat247a8682017-06-05 15:00:31 -07008575 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
Prashanth Bhatta07998752016-04-28 12:35:33 -07008576 hdd_ctx->config->tx_chain_mask_1ss,
8577 PDEV_CMD);
8578 if (0 != ret) {
8579 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
8580 goto out;
8581 }
8582
Jeff Johnsona89e25d2017-02-24 12:25:07 -08008583 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
8584 if (ret)
8585 goto out;
8586
8587 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
8588 if (ret)
8589 goto out;
8590
Jeff Johnson12a744b2017-04-04 08:19:37 -07008591 ret = hdd_set_ani_enabled(hdd_ctx);
8592 if (ret)
8593 goto out;
8594
Naveen Rawat247a8682017-06-05 15:00:31 -07008595 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -08008596 hdd_ctx->config->arp_ac_category,
8597 PDEV_CMD);
8598 if (0 != ret) {
8599 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
8600 hdd_ctx->config->arp_ac_category, ret);
8601 goto out;
8602 }
8603
8604
Prashanth Bhatta07998752016-04-28 12:35:33 -07008605 status = hdd_set_sme_chan_list(hdd_ctx);
8606 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008607 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -07008608 ret = qdf_status_to_os_return(status);
8609 goto out;
8610 }
8611
8612 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -07008613 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008614 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -07008615 ret = -EINVAL;
8616 goto out;
8617 }
8618
Prashanth Bhatta07998752016-04-28 12:35:33 -07008619 /*
8620 * Set the MAC Address Currently this is used by HAL to add self sta.
8621 * Remove this once self sta is added as part of session open.
8622 */
8623 hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
8624 hdd_ctx->config->intfMacAddr[0].bytes,
8625 sizeof(hdd_ctx->config->intfMacAddr[0]));
8626
8627 if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
8628 hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
8629 hal_status, hal_status);
8630 ret = -EINVAL;
8631 goto out;
8632 }
8633
8634 hdd_init_channel_avoidance(hdd_ctx);
8635
8636out:
8637 return ret;
8638}
8639
8640/**
Peng Xu8fdaa492016-06-22 10:20:47 -07008641 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
8642 * @context_ptr - hdd context pointer
8643 * @event_ptr - event structure pointer
8644 *
8645 * This is the p2p listen offload stop event handler, it sends vendor
8646 * event back to supplicant to notify the stop reason.
8647 *
8648 * Return: None
8649 */
8650static void wlan_hdd_p2p_lo_event_callback(void *context_ptr,
8651 void *event_ptr)
8652{
8653 hdd_context_t *hdd_ctx = (hdd_context_t *)context_ptr;
8654 struct sir_p2p_lo_event *evt = event_ptr;
8655 struct sk_buff *vendor_event;
Peng Xu5c682812017-08-06 07:39:13 -07008656 hdd_adapter_t *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -07008657
8658 ENTER();
8659
8660 if (hdd_ctx == NULL) {
8661 hdd_err("Invalid HDD context pointer");
8662 return;
8663 }
8664
Peng Xu5c682812017-08-06 07:39:13 -07008665 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
8666 if (!adapter) {
8667 hdd_err("Cannot find adapter by vdev_id = %d",
8668 evt->vdev_id);
8669 return;
8670 }
8671
Peng Xu8fdaa492016-06-22 10:20:47 -07008672 vendor_event =
8673 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -07008674 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -07008675 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
8676 GFP_KERNEL);
8677
8678 if (!vendor_event) {
8679 hdd_err("cfg80211_vendor_event_alloc failed");
8680 return;
8681 }
8682
8683 if (nla_put_u32(vendor_event,
8684 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
8685 evt->reason_code)) {
8686 hdd_err("nla put failed");
8687 kfree_skb(vendor_event);
8688 return;
8689 }
8690
8691 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -07008692 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
8693 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -07008694}
8695
8696/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05308697 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
8698 * @hdd_ctx: HDD context
8699 *
8700 * This function sends the adaptive dwell time config configuration to the
8701 * firmware via WMA
8702 *
8703 * Return: 0 - success, < 0 - failure
8704 */
8705static int hdd_adaptive_dwelltime_init(hdd_context_t *hdd_ctx)
8706{
8707 QDF_STATUS status;
8708 struct adaptive_dwelltime_params dwelltime_params;
8709
8710 dwelltime_params.is_enabled =
8711 hdd_ctx->config->adaptive_dwell_mode_enabled;
8712 dwelltime_params.dwelltime_mode =
8713 hdd_ctx->config->global_adapt_dwelltime_mode;
8714 dwelltime_params.lpf_weight =
8715 hdd_ctx->config->adapt_dwell_lpf_weight;
8716 dwelltime_params.passive_mon_intval =
8717 hdd_ctx->config->adapt_dwell_passive_mon_intval;
8718 dwelltime_params.wifi_act_threshold =
8719 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
8720
8721 status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
8722 &dwelltime_params);
8723
8724 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
8725 if (!QDF_IS_STATUS_SUCCESS(status)) {
8726 hdd_err("Failed to send Adaptive Dwelltime configuration!");
8727 return -EAGAIN;
8728 }
8729 return 0;
8730}
8731
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05308732int hdd_dbs_scan_selection_init(hdd_context_t *hdd_ctx)
8733{
8734 QDF_STATUS status;
8735 struct wmi_dbs_scan_sel_params dbs_scan_params;
8736 uint32_t i = 0;
8737 uint8_t count = 0, numentries = 0;
8738 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
8739 * CDS_DBS_SCAN_CLIENTS_MAX];
8740
8741 /* check if DBS is enabled or supported */
8742 if ((hdd_ctx->config->dual_mac_feature_disable)
8743 || (!policy_mgr_is_hw_dbs_capable(hdd_ctx->hdd_psoc)))
8744 return -EINVAL;
8745
8746 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
8747 dbs_scan_config, &numentries,
8748 (CDS_DBS_SCAN_PARAM_PER_CLIENT
8749 * CDS_DBS_SCAN_CLIENTS_MAX));
8750
8751 hdd_info("numentries %hu", numentries);
8752 if (!numentries) {
8753 hdd_info("Donot send scan_selection_config");
8754 return 0;
8755 }
8756
8757 /* hdd_set_fw_log_params */
8758 dbs_scan_params.num_clients = 0;
8759 while (count < (numentries - 2)) {
8760 dbs_scan_params.module_id[i] = dbs_scan_config[count];
8761 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
8762 dbs_scan_params.num_non_dbs_scans[i] =
8763 dbs_scan_config[count + 2];
8764 dbs_scan_params.num_clients++;
8765 hdd_debug("module:%d NDS:%d NNDS:%d",
8766 dbs_scan_params.module_id[i],
8767 dbs_scan_params.num_dbs_scans[i],
8768 dbs_scan_params.num_non_dbs_scans[i]);
8769 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
8770 i++;
8771 }
8772
8773 dbs_scan_params.pdev_id = 0;
8774
8775 hdd_debug("clients:%d pdev:%d",
8776 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
8777
8778 status = sme_set_dbs_scan_selection_config(hdd_ctx->hHal,
8779 &dbs_scan_params);
8780 hdd_debug("Sending DBS Scan Selection Configuration to fw");
8781 if (!QDF_IS_STATUS_SUCCESS(status)) {
8782 hdd_err("Failed to send DBS Scan selection configuration!");
8783 return -EAGAIN;
8784 }
8785 return 0;
8786}
8787
Arun Khandavallid4349a92016-07-25 11:10:43 +05308788#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
8789/**
8790 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
8791 * @hdd_ctx: HDD context
8792 *
8793 * Set auto shutdown callback to get indications from firmware to indicate
8794 * userspace to shutdown WLAN after a configured amount of inactivity.
8795 *
8796 * Return: 0 on success and errno on failure.
8797 */
8798static int hdd_set_auto_shutdown_cb(hdd_context_t *hdd_ctx)
8799{
8800 QDF_STATUS status;
8801
8802 if (!hdd_ctx->config->WlanAutoShutdown)
8803 return 0;
8804
8805 status = sme_set_auto_shutdown_cb(hdd_ctx->hHal,
8806 wlan_hdd_auto_shutdown_cb);
8807 if (status != QDF_STATUS_SUCCESS)
8808 hdd_err("Auto shutdown feature could not be enabled: %d",
8809 status);
8810
8811 return qdf_status_to_os_return(status);
8812}
8813#else
8814static int hdd_set_auto_shutdown_cb(hdd_context_t *hdd_ctx)
8815{
8816 return 0;
8817}
8818#endif
8819
8820/**
8821 * hdd_features_init() - Init features
8822 * @hdd_ctx: HDD context
8823 * @adapter: Primary adapter context
8824 *
8825 * Initialize features and their feature context after WLAN firmware is up.
8826 *
8827 * Return: 0 on success and errno on failure.
8828 */
8829static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
8830{
8831 tSirTxPowerLimit hddtxlimit;
8832 QDF_STATUS status;
Manjeet Singha9cae432017-02-28 11:58:22 +05308833 struct sme_5g_band_pref_params band_pref_params;
Arun Khandavallid4349a92016-07-25 11:10:43 +05308834 int ret;
8835
8836 ENTER();
8837
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07008838 ret = hdd_update_country_code(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +05308839 if (ret) {
8840 hdd_err("Failed to update country code: %d", ret);
8841 goto out;
8842 }
8843
8844 /* FW capabilities received, Set the Dot11 mode */
8845 sme_setdef_dot11mode(hdd_ctx->hHal);
Kiran Kumar Lokere1aa9c9a2016-10-05 18:50:59 -07008846 sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal,
8847 hdd_ctx->config->sta_prefer_80MHz_over_160MHz);
Arun Khandavallid4349a92016-07-25 11:10:43 +05308848
Arun Khandavallid4349a92016-07-25 11:10:43 +05308849
8850 if (hdd_ctx->config->fIsImpsEnabled)
8851 hdd_set_idle_ps_config(hdd_ctx, true);
8852 else
8853 hdd_set_idle_ps_config(hdd_ctx, false);
8854
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05308855 if (hdd_ctx->config->enable_go_cts2self_for_sta)
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008856 sme_set_cts2self_for_p2p_go(hdd_ctx->hHal);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +05308857
Arun Khandavallid4349a92016-07-25 11:10:43 +05308858 if (hdd_lro_init(hdd_ctx))
8859 hdd_err("Unable to initialize LRO in fw");
8860
8861 if (hdd_adaptive_dwelltime_init(hdd_ctx))
8862 hdd_err("Unable to send adaptive dwelltime setting to FW");
8863
Nitesh Shahf9a09ff2017-05-22 15:46:25 +05308864 if (hdd_dbs_scan_selection_init(hdd_ctx))
8865 hdd_err("Unable to send DBS scan selection setting to FW");
8866
Arun Khandavallid4349a92016-07-25 11:10:43 +05308867 ret = hdd_init_thermal_info(hdd_ctx);
8868 if (ret) {
8869 hdd_err("Error while initializing thermal information");
8870 goto deregister_frames;
8871 }
8872
Poddar, Siddarth66a46592017-02-22 11:44:44 +05308873 if (cds_is_packet_log_enabled())
8874 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
8875
Arun Khandavallid4349a92016-07-25 11:10:43 +05308876 hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
8877 hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
8878 status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
8879 if (!QDF_IS_STATUS_SUCCESS(status))
8880 hdd_err("Error setting txlimit in sme: %d", status);
8881
Yu Wangf5d5b5f2017-05-25 22:38:32 +08008882 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +05308883
Arun Khandavallid4349a92016-07-25 11:10:43 +05308884 ret = hdd_register_cb(hdd_ctx);
8885 if (ret) {
8886 hdd_err("Failed to register HDD callbacks!");
8887 goto deregister_frames;
8888 }
8889
8890 if (hdd_ctx->config->dual_mac_feature_disable) {
8891 status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx);
8892 if (status != QDF_STATUS_SUCCESS) {
8893 hdd_err("Failed to disable dual mac features");
8894 goto deregister_cb;
8895 }
8896 }
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +05308897 if (hdd_ctx->config->goptimize_chan_avoid_event) {
8898 status = sme_enable_disable_chanavoidind_event(
8899 hdd_ctx->hHal, 0);
8900 if (!QDF_IS_STATUS_SUCCESS(status)) {
8901 hdd_err("Failed to disable Chan Avoidance Indication");
8902 goto deregister_cb;
8903 }
8904 }
Arun Khandavallid4349a92016-07-25 11:10:43 +05308905
Manjeet Singha9cae432017-02-28 11:58:22 +05308906 if (hdd_ctx->config->enable_5g_band_pref) {
8907 band_pref_params.rssi_boost_threshold_5g =
8908 hdd_ctx->config->rssi_boost_threshold_5g;
8909 band_pref_params.rssi_boost_factor_5g =
8910 hdd_ctx->config->rssi_boost_factor_5g;
8911 band_pref_params.max_rssi_boost_5g =
8912 hdd_ctx->config->max_rssi_boost_5g;
8913 band_pref_params.rssi_penalize_threshold_5g =
8914 hdd_ctx->config->rssi_penalize_threshold_5g;
8915 band_pref_params.rssi_penalize_factor_5g =
8916 hdd_ctx->config->rssi_penalize_factor_5g;
8917 band_pref_params.max_rssi_penalize_5g =
8918 hdd_ctx->config->max_rssi_penalize_5g;
8919 sme_set_5g_band_pref(hdd_ctx->hHal, &band_pref_params);
8920 }
8921
Arun Khandavallid4349a92016-07-25 11:10:43 +05308922 /* register P2P Listen Offload event callback */
8923 if (wma_is_p2p_lo_capable())
8924 sme_register_p2p_lo_event(hdd_ctx->hHal, hdd_ctx,
8925 wlan_hdd_p2p_lo_event_callback);
8926
8927 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
8928
8929 if (ret)
8930 goto deregister_cb;
8931
8932 EXIT();
8933 return 0;
8934
8935deregister_cb:
8936 hdd_deregister_cb(hdd_ctx);
8937deregister_frames:
8938 wlan_hdd_cfg80211_deregister_frames(adapter);
8939out:
8940 return -EINVAL;
8941
8942}
8943
Yu Wangf5d5b5f2017-05-25 22:38:32 +08008944/**
8945 * hdd_features_deinit() - Deinit features
8946 * @hdd_ctx: HDD context
8947 *
8948 * De-Initialize features and their feature context.
8949 *
8950 * Return: none.
8951 */
8952static void hdd_features_deinit(hdd_context_t *hdd_ctx)
8953{
8954 wlan_hdd_tsf_deinit(hdd_ctx);
8955}
8956
Abhishek Singh6092fbb2017-01-25 18:10:31 +05308957#ifdef NAPIER_SCAN
8958/**
Abhishek Singh6092fbb2017-01-25 18:10:31 +05308959 * hdd_post_cds_enable_config() - HDD post cds start config helper
8960 * @adapter - Pointer to the HDD
8961 *
8962 * Return: None
8963 */
8964static inline QDF_STATUS hdd_register_bcn_cb(hdd_context_t *hdd_ctx)
8965{
8966 QDF_STATUS status;
8967
8968 status = ucfg_scan_register_bcn_cb(hdd_ctx->hdd_psoc,
8969 wlan_cfg80211_inform_bss_frame,
8970 SCAN_CB_TYPE_INFORM_BCN);
8971 if (!QDF_IS_STATUS_SUCCESS(status)) {
8972 hdd_err("failed with status code %08d [x%08x]",
8973 status, status);
8974 return status;
8975 }
8976
8977 return QDF_STATUS_SUCCESS;
8978}
8979#else
8980static inline QDF_STATUS hdd_register_bcn_cb(hdd_context_t *hdd_ctx)
8981{
8982 return QDF_STATUS_SUCCESS;
8983}
8984
8985#endif
Arun Khandavallid4349a92016-07-25 11:10:43 +05308986
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05308987/**
Arun Khandavallifae92942016-08-01 13:31:08 +05308988 * hdd_configure_cds() - Configure cds modules
8989 * @hdd_ctx: HDD context
8990 * @adapter: Primary adapter context
8991 *
8992 * Enable Cds modules after WLAN firmware is up.
8993 *
8994 * Return: 0 on success and errno on failure.
8995 */
8996int hdd_configure_cds(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
8997{
8998 int ret;
8999 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05309000
9001 ret = hdd_pre_enable_configure(hdd_ctx);
9002 if (ret) {
9003 hdd_err("Failed to pre-configure cds");
9004 goto out;
9005 }
9006
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08009007 /* Always get latest IPA resources allocated from cds_open and configure
9008 * IPA module before configuring them to FW. Sequence required as crash
9009 * observed otherwise.
9010 */
Manikandan Mohan2e803a02017-02-14 14:57:53 -08009011 if (hdd_ipa_uc_ol_init(hdd_ctx)) {
9012 hdd_err("Failed to setup pipes");
9013 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -08009014 }
9015
Arun Khandavallifae92942016-08-01 13:31:08 +05309016 /*
9017 * Start CDS which starts up the SME/MAC/HAL modules and everything
9018 * else
9019 */
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05309020 status = cds_enable(hdd_ctx->hdd_psoc, hdd_ctx->pcds_context);
Arun Khandavallifae92942016-08-01 13:31:08 +05309021
9022 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009023 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +05309024 goto out;
9025 }
9026
9027 status = hdd_post_cds_enable_config(hdd_ctx);
9028 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009029 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009030 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05309031 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +05309032 status = hdd_register_bcn_cb(hdd_ctx);
9033 if (!QDF_IS_STATUS_SUCCESS(status)) {
9034 hdd_alert("hdd_post_cds_enable_config failed");
9035 goto cds_disable;
9036 }
Arun Khandavallifae92942016-08-01 13:31:08 +05309037
9038 ret = hdd_features_init(hdd_ctx, adapter);
9039 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009040 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +05309041
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +05309042 if (hdd_enable_egap(hdd_ctx))
9043 hdd_debug("enhance green ap is not enabled");
9044
Arun Khandavallifae92942016-08-01 13:31:08 +05309045 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009046
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009047cds_disable:
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05309048 cds_disable(hdd_ctx->hdd_psoc, hdd_ctx->pcds_context);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -07009049
Arun Khandavallifae92942016-08-01 13:31:08 +05309050out:
9051 return -EINVAL;
9052}
9053
9054/**
9055 * hdd_deconfigure_cds() -De-Configure cds
9056 * @hdd_ctx: HDD context
9057 *
9058 * Deconfigure Cds modules before WLAN firmware is down.
9059 *
9060 * Return: 0 on success and errno on failure.
9061 */
Jeff Johnson590e2012016-10-05 16:16:24 -07009062static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +05309063{
9064 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -07009065 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05309066
9067 ENTER();
Yu Wangf5d5b5f2017-05-25 22:38:32 +08009068
9069 /* De-init features */
9070 hdd_features_deinit(hdd_ctx);
9071
Arun Khandavallifae92942016-08-01 13:31:08 +05309072 /* De-register the SME callbacks */
9073 hdd_deregister_cb(hdd_ctx);
9074
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05309075 qdf_status = cds_disable(hdd_ctx->hdd_psoc, hdd_ctx->pcds_context);
Arun Khandavallifae92942016-08-01 13:31:08 +05309076 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
9077 hdd_err("Failed to Disable the CDS Modules! :%d",
9078 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -07009079 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309080 }
9081
Sravan Kumar Kairam71121712017-04-15 00:34:42 +05309082 if (hdd_ipa_uc_ol_deinit(hdd_ctx)) {
9083 hdd_err("Failed to disconnect pipes");
9084 ret = -EINVAL;
9085 }
9086
Arun Khandavallifae92942016-08-01 13:31:08 +05309087 EXIT();
Houston Hoffman6640cf32016-10-10 16:44:29 -07009088 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05309089}
9090
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07009091#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
9092static void hdd_deregister_policy_manager_callback(
9093 struct wlan_objmgr_psoc *psoc)
9094{
9095 if (QDF_STATUS_SUCCESS !=
9096 policy_mgr_deregister_hdd_cb(psoc)) {
9097 hdd_err("HDD callback deregister with policy manager failed");
9098 }
9099}
9100#else
9101static void hdd_deregister_policy_manager_callback(
9102 struct wlan_objmgr_psoc *psoc)
9103{
9104}
9105#endif
Arun Khandavallifae92942016-08-01 13:31:08 +05309106
9107/**
9108 * hdd_wlan_stop_modules - Single driver state machine for stoping modules
9109 * @hdd_ctx: HDD context
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009110 * @ftm_mode: ftm mode
Arun Khandavallifae92942016-08-01 13:31:08 +05309111 *
9112 * This function maintains the driver state machine it will be invoked from
9113 * exit, shutdown and con_mode change handler. Depending on the driver state
9114 * shall perform the stopping/closing of the modules.
9115 *
9116 * Return: 0 for success; non-zero for failure
9117 */
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009118int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +05309119{
9120 void *hif_ctx;
9121 qdf_device_t qdf_ctx;
9122 QDF_STATUS qdf_status;
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309123 int ret = 0;
Dustin Brown70111822017-03-30 15:31:40 -07009124 bool is_idle_stop = !cds_is_driver_unloading() &&
9125 !cds_is_driver_recovering();
9126 int active_threads;
Arun Khandavallifae92942016-08-01 13:31:08 +05309127
9128 ENTER();
9129
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07009130 hdd_deregister_policy_manager_callback(hdd_ctx->hdd_psoc);
9131
Arun Khandavallifae92942016-08-01 13:31:08 +05309132 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
9133 if (!qdf_ctx) {
9134 hdd_err("QDF device context NULL");
9135 return -EINVAL;
9136 }
9137
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309138 mutex_lock(&hdd_ctx->iface_change_lock);
9139 hdd_ctx->stop_modules_in_progress = true;
Arun Khandavallifae92942016-08-01 13:31:08 +05309140
Dustin Brown70111822017-03-30 15:31:40 -07009141 active_threads = cds_return_external_threads_count();
9142 if (active_threads > 0 || hdd_ctx->isWiphySuspended) {
Rajeev Kumar86177c22017-03-16 19:44:39 -07009143 hdd_warn("External threads %d wiphy suspend %d",
Dustin Brown70111822017-03-30 15:31:40 -07009144 active_threads, hdd_ctx->isWiphySuspended);
9145
9146 cds_print_external_threads();
9147
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009148 if (is_idle_stop && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -07009149 mutex_unlock(&hdd_ctx->iface_change_lock);
9150 qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009151 hdd_ctx->config->iface_change_wait_time);
9152 hdd_ctx->stop_modules_in_progress = false;
Dustin Brown70111822017-03-30 15:31:40 -07009153 return 0;
9154 }
Rajeev Kumar86177c22017-03-16 19:44:39 -07009155 }
9156
Arun Khandavallifae92942016-08-01 13:31:08 +05309157 hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
9158
9159 switch (hdd_ctx->driver_status) {
9160 case DRIVER_MODULES_UNINITIALIZED:
9161 hdd_info("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309162 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309163 case DRIVER_MODULES_CLOSED:
9164 hdd_info("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309165 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309166 case DRIVER_MODULES_ENABLED:
Komal Seelamf2136bb2016-09-28 18:30:44 +05309167 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +05309168 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009169 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +05309170 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309171 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309172 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009173 hdd_debug("successfully Disabled the CDS modules!");
Arun Khandavallifae92942016-08-01 13:31:08 +05309174 hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
9175 break;
9176 case DRIVER_MODULES_OPENED:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009177 hdd_debug("Closing CDS modules!");
Arun Khandavallifae92942016-08-01 13:31:08 +05309178 break;
9179 default:
9180 hdd_err("Trying to stop wlan in a wrong state: %d",
9181 hdd_ctx->driver_status);
9182 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309183 ret = -EINVAL;
9184 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +05309185 }
9186
Rajeev Kumarbe021242017-02-16 16:12:23 -08009187 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +05309188 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
9189 hdd_err("Failed to process post CDS disable Modules! :%d",
9190 qdf_status);
9191 ret = -EINVAL;
9192 QDF_ASSERT(0);
9193 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05309194 qdf_status = cds_close(hdd_ctx->hdd_psoc, hdd_ctx->pcds_context);
Arun Khandavallifae92942016-08-01 13:31:08 +05309195 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009196 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +05309197 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309198 QDF_ASSERT(0);
9199 }
Krunal Sonid32c6bc2016-10-18 18:00:21 -07009200
Arun Khandavallifae92942016-08-01 13:31:08 +05309201 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
9202 if (!hif_ctx) {
9203 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309204 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05309205 }
9206
Sravan Kumar Kairam64574952017-06-22 11:48:18 +05309207 hdd_runtime_suspend_context_deinit(hdd_ctx);
9208
Sravan Kumar Kairam27296782017-04-21 22:04:18 +05309209 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05309210
9211 ol_cds_free();
9212
Dustin Brown70111822017-03-30 15:31:40 -07009213 if (is_idle_stop) {
Arun Khandavallifae92942016-08-01 13:31:08 +05309214 ret = pld_power_off(qdf_ctx->dev);
9215 if (ret)
9216 hdd_err("CNSS power down failed put device into Low power mode:%d",
9217 ret);
9218 }
9219 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Sandeep Puligilla1cf6ebe2017-04-04 14:40:27 -07009220 /*
9221 * Reset total mac phy during module stop such that during
9222 * next module start same psoc is used to populate new service
9223 * ready data
9224 */
9225 hdd_ctx->hdd_psoc->total_mac_phy = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05309226
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309227done:
9228 hdd_ctx->stop_modules_in_progress = false;
9229 mutex_unlock(&hdd_ctx->iface_change_lock);
Arun Khandavallifae92942016-08-01 13:31:08 +05309230 EXIT();
9231
Arun Khandavallia172c3e2016-08-26 17:33:13 +05309232 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05309233
9234}
9235
9236/**
9237 * hdd_iface_change_callback() - Function invoked when stop modules expires
9238 * @priv: pointer to hdd context
9239 *
9240 * This function is invoked when the timer waiting for the interface change
9241 * expires, it shall cut-down the power to wlan and stop all the modules.
9242 *
9243 * Return: void
9244 */
9245static void hdd_iface_change_callback(void *priv)
9246{
9247 hdd_context_t *hdd_ctx = (hdd_context_t *) priv;
9248 int ret;
9249 int status = wlan_hdd_validate_context(hdd_ctx);
9250
9251 if (status)
9252 return;
9253
9254 ENTER();
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009255 hdd_debug("Interface change timer expired close the modules!");
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009256 ret = hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05309257 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009258 hdd_err("Failed to stop modules");
Arun Khandavallifae92942016-08-01 13:31:08 +05309259 EXIT();
9260}
9261
9262/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309263 * hdd_state_info_dump() - prints state information of hdd layer
9264 * @buf: buffer pointer
9265 * @size: size of buffer to be filled
9266 *
9267 * This function is used to dump state information of hdd layer
9268 *
9269 * Return: None
9270 */
9271static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
9272{
9273 hdd_context_t *hdd_ctx;
9274 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
9275 QDF_STATUS status;
9276 hdd_station_ctx_t *hdd_sta_ctx;
9277 hdd_adapter_t *adapter;
9278 uint16_t len = 0;
9279 char *buf = *buf_ptr;
9280
9281 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9282 if (!hdd_ctx) {
9283 hdd_err("Failed to get hdd context ");
9284 return;
9285 }
9286
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009287 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309288
9289 len += scnprintf(buf + len, *size - len,
9290 "\n isWiphySuspended %d", hdd_ctx->isWiphySuspended);
9291 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -08009292 "\n is_scheduler_suspended %d",
9293 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309294
9295 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9296
9297 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
9298 adapter = adapter_node->pAdapter;
9299 if (adapter->dev)
9300 len += scnprintf(buf + len, *size - len,
9301 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +08009302 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309303 "\n device_mode: %d", adapter->device_mode);
9304 switch (adapter->device_mode) {
9305 case QDF_STA_MODE:
9306 case QDF_P2P_CLIENT_MODE:
9307 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
9308 len += scnprintf(buf + len, *size - len,
9309 "\n connState: %d",
9310 hdd_sta_ctx->conn_info.connState);
9311 break;
9312
9313 default:
9314 break;
9315 }
9316 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
9317 adapter_node = next;
9318 }
9319
9320 *size -= len;
9321 *buf_ptr += len;
9322}
9323
9324/**
9325 * hdd_register_debug_callback() - registration function for hdd layer
9326 * to print hdd state information
9327 *
9328 * Return: None
9329 */
9330static void hdd_register_debug_callback(void)
9331{
9332 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
9333}
9334
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05309335/*
9336 * wlan_init_bug_report_lock() - Initialize bug report lock
9337 *
9338 * This function is used to create bug report lock
9339 *
9340 * Return: None
9341 */
9342static void wlan_init_bug_report_lock(void)
9343{
9344 p_cds_contextType p_cds_context;
9345
9346 p_cds_context = cds_get_global_context();
9347 if (!p_cds_context) {
9348 hdd_err("cds context is NULL");
9349 return;
9350 }
9351
9352 qdf_spinlock_create(&p_cds_context->bug_report_lock);
9353}
9354
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309355/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009356 * hdd_wlan_startup() - HDD init function
9357 * @dev: Pointer to the underlying device
9358 *
9359 * This is the driver startup code executed once a WLAN device has been detected
9360 *
9361 * Return: 0 for success, < 0 for failure
9362 */
Arun Khandavallifae92942016-08-01 13:31:08 +05309363int hdd_wlan_startup(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009364{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309365 QDF_STATUS status;
Jeff Johnson957bc272017-02-02 08:54:48 -08009366 hdd_context_t *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009367 int ret;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009368 bool rtnl_held;
Manjeet Singhe7ecb7c2016-09-03 12:34:53 +05309369 int set_value;
Naveen Rawat247a8682017-06-05 15:00:31 -07009370 uint32_t num_abg_tx_chains = 0;
9371 uint32_t num_11b_tx_chains = 0;
9372 uint32_t num_11ag_tx_chains = 0;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009373
9374 ENTER();
9375
Arun Khandavallifae92942016-08-01 13:31:08 +05309376 hdd_ctx = hdd_context_create(dev);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009377
9378 if (IS_ERR(hdd_ctx))
9379 return PTR_ERR(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009380
Abhishek Singhe9068f12017-03-31 14:14:52 +05309381 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx,
9382 DEFAULT_PSOC_ID);
9383 if (ret) {
9384 hdd_err("Psoc creation fails!");
9385 QDF_BUG(0);
9386 goto err_hdd_free_context;
9387 }
9388
Arun Khandavallifae92942016-08-01 13:31:08 +05309389 qdf_mc_timer_init(&hdd_ctx->iface_change_timer, QDF_TIMER_TYPE_SW,
9390 hdd_iface_change_callback, (void *)hdd_ctx);
9391
9392 mutex_init(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05309393#ifdef FEATURE_WLAN_CH_AVOID
9394 mutex_init(&hdd_ctx->avoid_freq_lock);
9395#endif
Arun Khandavallifae92942016-08-01 13:31:08 +05309396
Ryan Hsucfef0ae2016-04-28 10:20:46 -07009397 ret = hdd_init_netlink_services(hdd_ctx);
9398 if (ret)
Dustin Brown20912462017-06-07 13:48:25 -07009399 goto err_hdd_free_psoc;
Ryan Hsucfef0ae2016-04-28 10:20:46 -07009400
Jeff Johnsonce0032c2017-01-20 07:18:27 -08009401 hdd_request_manager_init();
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07009402 hdd_green_ap_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05309403
Jeff Johnson957bc272017-02-02 08:54:48 -08009404 ret = hdd_wlan_start_modules(hdd_ctx, NULL, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05309405 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009406 hdd_err("Failed to start modules: %d", ret);
Ryan Hsucfef0ae2016-04-28 10:20:46 -07009407 goto err_exit_nl_srv;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009408 }
9409
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05309410 wlan_init_bug_report_lock();
9411
Yingying Tang80e15f32016-09-27 18:23:01 +08009412 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009413
Yingying Tang95409972016-10-20 15:16:15 +08009414 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009415 hdd_debug("Failed to set wow pulse");
Yingying Tang95409972016-10-20 15:16:15 +08009416
Anurag Chouhan6d760662016-02-20 16:05:43 +05309417 hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009418
9419 if (NULL == hdd_ctx->hHal) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009420 hdd_err("HAL context is null");
Arun Khandavallifae92942016-08-01 13:31:08 +05309421 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009422 }
9423
Prashanth Bhatta07998752016-04-28 12:35:33 -07009424 ret = hdd_wiphy_init(hdd_ctx);
9425 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009426 hdd_err("Failed to initialize wiphy: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05309427 goto err_stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009428 }
9429
Nirav Shahcc1f1ae2016-04-26 11:41:29 +05309430 if (hdd_ctx->config->enable_dp_trace)
9431 qdf_dp_trace_init();
9432
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309433 if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009434 goto err_wiphy_unregister;
9435
Kapil Gupta4f0c0c12017-02-07 15:21:15 +05309436 wlan_hdd_init_chan_info(hdd_ctx);
9437
Yuanyuan Liuc98370e2016-10-13 11:22:13 -07009438 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -08009439
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009440 rtnl_held = hdd_hold_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009441
Jeff Johnson957bc272017-02-02 08:54:48 -08009442 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
9443 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009444 hdd_err("Failed to open interfaces: %d", ret);
Jeff Johnson46bde382017-02-01 15:31:16 -08009445 goto err_release_rtnl_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009446 }
9447
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009448 hdd_release_rtnl_lock();
9449 rtnl_held = false;
9450
Yingying Tang3ba3dbc2016-09-27 16:36:58 +08009451 wlan_hdd_update_11n_mode(hdd_ctx->config);
9452
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009453#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05309454 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +05309455 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009456 hdd_skip_acs_scan_timer_handler,
9457 (void *)hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309458 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -07009459 hdd_err("Failed to init ACS Skip timer");
Liangwei Dongaef84342016-10-21 05:28:00 -04009460 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009461#endif
9462
Nitesh Shah61c10d92016-10-19 19:29:15 +05309463 qdf_mc_timer_init(&hdd_ctx->tdls_source_timer,
9464 QDF_TIMER_TYPE_SW,
9465 wlan_hdd_change_tdls_mode,
9466 hdd_ctx);
9467
Prashanth Bhattaab004382016-10-11 16:08:11 -07009468 hdd_bus_bandwidth_init(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009469
Jeff Johnson9afc5012016-09-23 13:56:27 -07009470 hdd_lpass_notify_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009471
Nirav Shahbd36b062016-07-18 11:12:59 +05309472 if (hdd_ctx->rps)
9473 hdd_set_rps_cpu_mask(hdd_ctx);
Peng Xu8fdaa492016-06-22 10:20:47 -07009474
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07009475 ret = hdd_register_notifiers(hdd_ctx);
9476 if (ret)
Jeff Johnson957bc272017-02-02 08:54:48 -08009477 goto err_close_adapters;
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05309478
9479 status = wlansap_global_init();
9480 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson957bc272017-02-02 08:54:48 -08009481 goto err_close_adapters;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07009482
Komal Seelam8634b772016-09-29 12:12:24 +05309483 hdd_runtime_suspend_context_init(hdd_ctx);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -08009484 memdump_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +05309485 hdd_driver_memdump_init();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -08009486
Arun Khandavallifae92942016-08-01 13:31:08 +05309487 if (hdd_ctx->config->fIsImpsEnabled)
9488 hdd_set_idle_ps_config(hdd_ctx, true);
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309489
Manjeet Singhe7ecb7c2016-09-03 12:34:53 +05309490 if (hdd_ctx->config->sifs_burst_duration) {
9491 set_value = (SIFS_BURST_DUR_MULTIPLIER) *
9492 hdd_ctx->config->sifs_burst_duration;
9493
9494 if ((set_value > 0) && (set_value <= SIFS_BURST_DUR_MAX))
Naveen Rawat247a8682017-06-05 15:00:31 -07009495 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_BURST_DUR,
Manjeet Singhe7ecb7c2016-09-03 12:34:53 +05309496 set_value, PDEV_CMD);
9497 }
9498
Paul Zhang42dade02017-05-12 19:20:37 +08009499 if (hdd_ctx->config->is_force_1x1)
Naveen Rawat247a8682017-06-05 15:00:31 -07009500 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
Paul Zhang42dade02017-05-12 19:20:37 +08009501 1, PDEV_CMD);
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05309502 /* set chip power save failure detected callback */
9503 sme_set_chip_pwr_save_fail_cb(hdd_ctx->hHal,
9504 hdd_chip_pwr_save_fail_detected_cb);
Paul Zhang42dade02017-05-12 19:20:37 +08009505
lifeng959a04c2017-05-10 14:21:28 +08009506 if (hdd_ctx->config->max_mpdus_inampdu) {
9507 set_value = hdd_ctx->config->max_mpdus_inampdu;
Naveen Rawat247a8682017-06-05 15:00:31 -07009508 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
lifeng959a04c2017-05-10 14:21:28 +08009509 set_value, PDEV_CMD);
9510 }
9511
9512 if (hdd_ctx->config->enable_rts_sifsbursting) {
9513 set_value = hdd_ctx->config->enable_rts_sifsbursting;
Naveen Rawat247a8682017-06-05 15:00:31 -07009514 sme_cli_set_command(0,
lifeng959a04c2017-05-10 14:21:28 +08009515 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
9516 set_value, PDEV_CMD);
9517 }
9518
Naveen Rawat247a8682017-06-05 15:00:31 -07009519 num_11b_tx_chains = hdd_ctx->config->num_11b_tx_chains;
9520 num_11ag_tx_chains = hdd_ctx->config->num_11ag_tx_chains;
9521 if (!hdd_ctx->config->enable2x2) {
9522 if (num_11b_tx_chains > 1)
9523 num_11b_tx_chains = 1;
9524 if (num_11ag_tx_chains > 1)
9525 num_11ag_tx_chains = 1;
9526 }
9527 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
9528 num_11b_tx_chains);
9529 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
9530 num_11ag_tx_chains);
9531 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
9532 num_abg_tx_chains, PDEV_CMD);
9533
Arunk Khandavalliba3d5582017-07-11 19:48:32 +05309534 if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
9535 qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
Hanumanth Reddy Pothula42e714a2016-12-21 19:33:57 +05309536 hdd_ctx->config->iface_change_wait_time);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +05309537
Sachin Ahujadddd2632017-03-07 19:07:24 +05309538 hdd_start_complete(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009539 goto success;
9540
Jeff Johnson957bc272017-02-02 08:54:48 -08009541err_close_adapters:
Jeff Johnson46bde382017-02-01 15:31:16 -08009542 hdd_close_all_adapters(hdd_ctx, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009543
Jeff Johnson46bde382017-02-01 15:31:16 -08009544err_release_rtnl_lock:
Arun Khandavallid4349a92016-07-25 11:10:43 +05309545 if (rtnl_held)
9546 hdd_release_rtnl_lock();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009547
Anurag Chouhance6a4052016-09-14 18:20:42 +05309548 hdd_ipa_cleanup(hdd_ctx);
Yun Park6a46ad82016-01-04 16:48:19 -08009549
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009550err_wiphy_unregister:
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009551 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009552
Arun Khandavallifae92942016-08-01 13:31:08 +05309553err_stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07009554 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05309555
Himanshu Agarwal0b9bbc32017-02-23 16:23:05 +05309556err_exit_nl_srv:
Arunk Khandavallifbc1ef02017-03-14 21:25:05 +05309557 if (DRIVER_MODULES_CLOSED == hdd_ctx->driver_status) {
9558 status = cds_sched_close(hdd_ctx->pcds_context);
9559 if (!QDF_IS_STATUS_SUCCESS(status)) {
9560 hdd_err("Failed to close CDS Scheduler");
9561 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
9562 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009563 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009564
Houston Hoffman47a4a052016-11-14 23:22:44 -08009565 hdd_green_ap_deinit(hdd_ctx);
Jeff Johnsonce0032c2017-01-20 07:18:27 -08009566 hdd_request_manager_deinit();
Ryan Hsucfef0ae2016-04-28 10:20:46 -07009567 hdd_exit_netlink_services(hdd_ctx);
9568
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309569 cds_deinit_ini_config();
Dustin Brown20912462017-06-07 13:48:25 -07009570
9571err_hdd_free_psoc:
9572 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
9573
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009574err_hdd_free_context:
Nachiket Kukade8003d252017-03-30 15:55:58 +05309575 if (cds_is_fw_down())
9576 hdd_err("Not setting the complete event as fw is down");
9577 else
9578 hdd_start_complete(ret);
9579
Arun Khandavallifae92942016-08-01 13:31:08 +05309580 qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer);
9581 mutex_destroy(&hdd_ctx->iface_change_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009582 hdd_context_destroy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009583 return -EIO;
9584
9585success:
9586 EXIT();
9587 return 0;
9588}
9589
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009590/**
Arun Khandavallifae92942016-08-01 13:31:08 +05309591 * hdd_wlan_update_target_info() - update target type info
9592 * @hdd_ctx: HDD context
9593 * @context: hif context
9594 *
9595 * Update target info received from firmware in hdd context
9596 * Return:None
9597 */
9598
9599void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context)
9600{
9601 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
9602
9603 if (!tgt_info) {
9604 hdd_err("Target info is Null");
9605 return;
9606 }
9607
9608 hdd_ctx->target_type = tgt_info->target_type;
9609}
9610
9611/**
9612 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309613 * @hdd_ctx: HDD context
9614 *
9615 * Register the HDD callbacks to CDS/SME.
9616 *
9617 * Return: 0 for success or Error code for failure
9618 */
9619int hdd_register_cb(hdd_context_t *hdd_ctx)
9620{
9621 QDF_STATUS status;
9622 int ret = 0;
9623
9624 ENTER();
9625
9626 sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);
9627
9628 sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
9629 hdd_send_oem_data_rsp_msg);
9630
9631 status = sme_fw_mem_dump_register_cb(hdd_ctx->hHal,
9632 wlan_hdd_cfg80211_fw_mem_dump_cb);
9633 if (!QDF_IS_STATUS_SUCCESS(status)) {
9634 hdd_err("Failed to register memdump callback");
9635 ret = -EINVAL;
9636 return ret;
9637 }
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +05309638 sme_register_mgmt_frame_ind_callback(hdd_ctx->hHal,
9639 hdd_indicate_mgmt_frame);
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309640 sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
9641 sme_nan_register_callback(hdd_ctx->hHal,
9642 wlan_hdd_cfg80211_nan_callback);
9643 sme_stats_ext_register_callback(hdd_ctx->hHal,
9644 wlan_hdd_cfg80211_stats_ext_callback);
9645
9646 sme_ext_scan_register_callback(hdd_ctx->hHal,
9647 wlan_hdd_cfg80211_extscan_callback);
lifeng66831662017-05-19 16:01:35 +08009648 sme_stats_ext2_register_callback(hdd_ctx->hHal,
9649 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309650
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309651 sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
9652 hdd_rssi_threshold_breached);
9653
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309654 sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
9655 wlan_hdd_cfg80211_link_layer_stats_callback);
9656
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05309657 sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb);
9658
Zhang Qianca38fb12016-12-23 11:10:48 +08009659 sme_set_link_layer_ext_cb(hdd_ctx->hHal,
9660 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
9661
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05309662 status = sme_set_lost_link_info_cb(hdd_ctx->hHal,
9663 hdd_lost_link_info_cb);
9664 /* print error and not block the startup process */
9665 if (!QDF_IS_STATUS_SUCCESS(status))
9666 hdd_err("set lost link info callback failed");
9667
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309668 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
9669
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009670 sme_register_set_connection_info_cb(hdd_ctx->hHal,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08009671 hdd_set_connection_in_progress,
9672 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +05309673
9674 status = sme_congestion_register_callback(hdd_ctx->hHal,
9675 hdd_update_cca_info_cb);
9676 if (!QDF_IS_STATUS_SUCCESS(status))
9677 hdd_err("set congestion callback failed");
9678
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +05309679 status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
9680 hdd_bt_activity_cb);
9681 if (!QDF_IS_STATUS_SUCCESS(status))
9682 hdd_err("set bt activity info callback failed");
9683
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309684 EXIT();
9685
9686 return ret;
9687}
9688
9689/**
9690 * hdd_deregister_cb() - De-Register HDD callbacks.
9691 * @hdd_ctx: HDD context
9692 *
9693 * De-Register the HDD callbacks to CDS/SME.
9694 *
9695 * Return: void
9696 */
9697void hdd_deregister_cb(hdd_context_t *hdd_ctx)
9698{
9699 QDF_STATUS status;
9700
9701 ENTER();
9702
9703 status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
9704 if (!QDF_IS_STATUS_SUCCESS(status))
9705 hdd_err("De-register of dcc stats callback failed: %d",
9706 status);
9707
9708 sme_reset_link_layer_stats_ind_cb(hdd_ctx->hHal);
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309709 sme_reset_rssi_threshold_breached_cb(hdd_ctx->hHal);
9710
Arun Khandavalli4b55da72016-07-19 19:55:01 +05309711 sme_stats_ext_register_callback(hdd_ctx->hHal,
9712 wlan_hdd_cfg80211_stats_ext_callback);
9713
9714 sme_nan_deregister_callback(hdd_ctx->hHal);
9715 status = sme_reset_tsfcb(hdd_ctx->hHal);
9716 if (!QDF_IS_STATUS_SUCCESS(status))
9717 hdd_err("Failed to de-register tsfcb the callback:%d",
9718 status);
9719 status = sme_fw_mem_dump_unregister_cb(hdd_ctx->hHal);
9720 if (!QDF_IS_STATUS_SUCCESS(status))
9721 hdd_err("Failed to de-register the fw mem dump callback: %d",
9722 status);
9723
9724 sme_deregister_oem_data_rsp_callback(hdd_ctx->hHal);
9725 sme_deregister11d_scan_done_callback(hdd_ctx->hHal);
9726
9727 EXIT();
9728}
9729
9730/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009731 * hdd_softap_sta_deauth() - handle deauth req from HDD
9732 * @adapter: Pointer to the HDD
9733 * @enable: bool value
9734 *
9735 * This to take counter measure to handle deauth req from HDD
9736 *
9737 * Return: None
9738 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309739QDF_STATUS hdd_softap_sta_deauth(hdd_adapter_t *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009740 struct tagCsrDelStaParams *pDelStaParams)
9741{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309742 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009743
9744 ENTER();
9745
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009746 hdd_debug("hdd_softap_sta_deauth:(%p, false)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009747 (WLAN_HDD_GET_CTX(adapter))->pcds_context);
9748
9749 /* Ignore request to deauth bcmc station */
9750 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309751 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009752
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309753 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009754 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9755 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009756
9757 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309758 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009759}
9760
9761/**
9762 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
9763 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05309764 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009765 *
9766 * This to take counter measure to handle deauth req from HDD
9767 *
9768 * Return: None
9769 */
9770void hdd_softap_sta_disassoc(hdd_adapter_t *adapter,
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05309771 struct tagCsrDelStaParams *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009772{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009773 ENTER();
9774
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009775 hdd_debug("hdd_softap_sta_disassoc:(%p, false)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009776 (WLAN_HDD_GET_CTX(adapter))->pcds_context);
9777
9778 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05309779 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009780 return;
9781
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009782 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05309783 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009784}
9785
9786void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *adapter,
9787 bool enable)
9788{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009789 ENTER();
9790
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009791 hdd_debug("hdd_softap_tkip_mic_fail_counter_measure:(%p, false)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009792 (WLAN_HDD_GET_CTX(adapter))->pcds_context);
9793
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009794 wlansap_set_counter_measure(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9795 (bool) enable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009796}
9797
9798/**
9799 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
9800 * @hdd_ctx: HDD Context
9801 *
9802 * API to find if there is any STA or P2P-Client is connected
9803 *
9804 * Return: true if connected; false otherwise
9805 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309806QDF_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009807{
9808 return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
9809}
9810
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009811/**
9812 * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
9813 * @adapter: HDD adapter pointer
9814 *
9815 * This function loop through each adapter and disable roaming on each STA
9816 * device mode except the input adapter.
9817 *
9818 * Note: On the input adapter roaming is not enabled yet hence no need to
9819 * disable.
9820 *
9821 * Return: None
9822 */
9823void wlan_hdd_disable_roaming(hdd_adapter_t *adapter)
9824{
9825 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9826 hdd_adapter_t *adapterIdx = NULL;
9827 hdd_adapter_list_node_t *adapterNode = NULL;
9828 hdd_adapter_list_node_t *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309829 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009830
9831 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08009832 hdd_ctx->config->isRoamOffloadScanEnabled &&
9833 QDF_STA_MODE == adapter->device_mode &&
9834 policy_mgr_is_sta_active_connection_exists(
9835 hdd_ctx->hdd_psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009836 hdd_debug("Connect received on STA sessionId(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009837 adapter->sessionId);
9838 /*
9839 * Loop through adapter and disable roaming for each STA device
9840 * mode except the input adapter.
9841 */
9842 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
9843
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309844 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009845 adapterIdx = adapterNode->pAdapter;
9846
Krunal Soni9b04c9b2016-03-10 13:08:05 -08009847 if (QDF_STA_MODE == adapterIdx->device_mode
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009848 && adapter->sessionId != adapterIdx->sessionId) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009849 hdd_debug("Disable Roaming on sessionId(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009850 adapterIdx->sessionId);
9851 sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
9852 (adapterIdx),
9853 adapterIdx->sessionId, 0);
9854 }
9855
9856 status = hdd_get_next_adapter(hdd_ctx,
9857 adapterNode,
9858 &pNext);
9859 adapterNode = pNext;
9860 }
9861 }
9862}
9863
9864/**
9865 * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
9866 * @adapter: HDD adapter pointer
9867 *
9868 * This function loop through each adapter and enable roaming on each STA
9869 * device mode except the input adapter.
9870 * Note: On the input adapter no need to enable roaming because link got
9871 * disconnected on this.
9872 *
9873 * Return: None
9874 */
9875void wlan_hdd_enable_roaming(hdd_adapter_t *adapter)
9876{
9877 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9878 hdd_adapter_t *adapterIdx = NULL;
9879 hdd_adapter_list_node_t *adapterNode = NULL;
9880 hdd_adapter_list_node_t *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309881 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009882
9883 if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08009884 hdd_ctx->config->isRoamOffloadScanEnabled &&
9885 QDF_STA_MODE == adapter->device_mode &&
9886 policy_mgr_is_sta_active_connection_exists(
9887 hdd_ctx->hdd_psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009888 hdd_debug("Disconnect received on STA sessionId(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009889 adapter->sessionId);
9890 /*
9891 * Loop through adapter and enable roaming for each STA device
9892 * mode except the input adapter.
9893 */
9894 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
9895
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309896 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009897 adapterIdx = adapterNode->pAdapter;
9898
Krunal Soni9b04c9b2016-03-10 13:08:05 -08009899 if (QDF_STA_MODE == adapterIdx->device_mode
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009900 && adapter->sessionId != adapterIdx->sessionId) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009901 hdd_debug("Enabling Roaming on sessionId(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009902 adapterIdx->sessionId);
9903 sme_start_roaming(WLAN_HDD_GET_HAL_CTX
9904 (adapterIdx),
9905 adapterIdx->sessionId,
9906 REASON_CONNECT);
9907 }
9908
9909 status = hdd_get_next_adapter(hdd_ctx,
9910 adapterNode,
9911 &pNext);
9912 adapterNode = pNext;
9913 }
9914 }
9915}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009916
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +05309917/**
9918 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
9919 * @skb: sk buffer pointer
9920 *
9921 * Sends the bcast message to SVC multicast group with generic nl socket
9922 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
9923 *
9924 * Return: None
9925 */
9926static void nl_srv_bcast_svc(struct sk_buff *skb)
9927{
9928#ifdef CNSS_GENL
9929 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
9930#else
9931 nl_srv_bcast(skb);
9932#endif
9933}
9934
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05309935void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009936{
9937 struct sk_buff *skb;
9938 struct nlmsghdr *nlh;
9939 tAniMsgHdr *ani_hdr;
9940 void *nl_data = NULL;
9941 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05309942 struct radio_index_tlv *radio_info;
9943 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009944
9945 if (in_interrupt() || irqs_disabled() || in_atomic())
9946 flags = GFP_ATOMIC;
9947
9948 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
9949
Srinivas Girigowdab841da72017-03-25 18:04:39 -07009950 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009951 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009952
9953 nlh = (struct nlmsghdr *)skb->data;
9954 nlh->nlmsg_pid = 0; /* from kernel */
9955 nlh->nlmsg_flags = 0;
9956 nlh->nlmsg_seq = 0;
9957 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9958
9959 ani_hdr = NLMSG_DATA(nlh);
9960 ani_hdr->type = type;
9961
9962 switch (type) {
9963 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +05309964 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009965 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009966 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -07009967 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009968 ani_hdr->length = 0;
9969 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009970 break;
9971 case WLAN_SVC_WLAN_STATUS_IND:
9972 case WLAN_SVC_WLAN_VERSION_IND:
9973 case WLAN_SVC_DFS_CAC_START_IND:
9974 case WLAN_SVC_DFS_CAC_END_IND:
9975 case WLAN_SVC_DFS_RADAR_DETECT_IND:
9976 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
9977 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -08009978 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +05309979 case WLAN_SVC_RPS_ENABLE_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009980 ani_hdr->length = len;
9981 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9982 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9983 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009984 break;
9985
9986 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -07009987 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009988 type);
9989 kfree_skb(skb);
9990 return;
9991 }
9992
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05309993 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08009994 * Add radio index at the end of the svc event in TLV format
9995 * to maintain the backward compatibility with userspace
9996 * applications.
9997 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05309998
9999 tlv_len = 0;
10000
10001 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
10002 < WLAN_NL_MAX_PAYLOAD) {
10003 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
10004 sizeof(*ani_hdr) + len);
10005 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
10006 radio_info->length = (unsigned short) sizeof(radio_info->radio);
10007 radio_info->radio = radio;
10008 tlv_len = sizeof(*radio_info);
Srinivas Girigowdac06543c2017-03-09 15:10:03 -080010009 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010010 "Added radio index tlv - radio index %d",
10011 radio_info->radio);
10012 }
10013
10014 nlh->nlmsg_len += tlv_len;
10015 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
10016
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053010017 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010018}
10019
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010020#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10021void wlan_hdd_auto_shutdown_cb(void)
10022{
hque52fdd62017-06-05 11:27:44 +080010023 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010024
10025 if (!hdd_ctx)
10026 return;
10027
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010028 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010029 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
10030 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010031}
10032
10033void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, bool enable)
10034{
10035 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010036 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010037 hdd_adapter_t *adapter;
10038 bool ap_connected = false, sta_connected = false;
10039 tHalHandle hal_handle;
10040
10041 hal_handle = hdd_ctx->hHal;
10042 if (hal_handle == NULL)
10043 return;
10044
10045 if (hdd_ctx->config->WlanAutoShutdown == 0)
10046 return;
10047
10048 if (enable == false) {
10049 if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010050 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010051 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010052 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053010053 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070010054 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010055 return;
10056 }
10057
10058 /* To enable shutdown timer check conncurrency */
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010059 if (policy_mgr_concurrent_open_sessions_running(
10060 hdd_ctx->hdd_psoc)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010061 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
10062
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010063 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010064 adapter = adapterNode->pAdapter;
10065 if (adapter
10066 && adapter->device_mode ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010067 QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010068 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
10069 conn_info.connState ==
10070 eConnectionState_Associated) {
10071 sta_connected = true;
10072 break;
10073 }
10074 }
10075 if (adapter
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010076 && adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010077 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
10078 bApActive == true) {
10079 ap_connected = true;
10080 break;
10081 }
10082 }
10083 status = hdd_get_next_adapter(hdd_ctx,
10084 adapterNode,
10085 &pNext);
10086 adapterNode = pNext;
10087 }
10088 }
10089
10090 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010091 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010092 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010093 }
Jeff Johnson68755312017-02-10 11:46:55 -080010094
10095 if (sme_set_auto_shutdown_timer(hal_handle,
10096 hdd_ctx->config->WlanAutoShutdown)
10097 != QDF_STATUS_SUCCESS)
10098 hdd_err("Failed to start wlan auto shutdown timer");
10099 else
10100 hdd_notice("Auto Shutdown timer for %d seconds enabled",
10101 hdd_ctx->config->WlanAutoShutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010102}
10103#endif
10104
10105hdd_adapter_t *hdd_get_con_sap_adapter(hdd_adapter_t *this_sap_adapter,
10106 bool check_start_bss)
10107{
10108 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
10109 hdd_adapter_t *adapter, *con_sap_adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010110 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010111 hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
10112
10113 con_sap_adapter = NULL;
10114
10115 status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010116 while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010117 adapter = adapterNode->pAdapter;
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010118 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
10119 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010120 adapter != this_sap_adapter) {
10121 if (check_start_bss) {
10122 if (test_bit(SOFTAP_BSS_STARTED,
10123 &adapter->event_flags)) {
10124 con_sap_adapter = adapter;
10125 break;
10126 }
10127 } else {
10128 con_sap_adapter = adapter;
10129 break;
10130 }
10131 }
10132 status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
10133 adapterNode = pNext;
10134 }
10135
10136 return con_sap_adapter;
10137}
10138
10139#ifdef MSM_PLATFORM
Dustin Brown5ec6b552017-03-31 12:11:40 -070010140static inline bool hdd_adapter_is_sta(hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010141{
Dustin Brown5ec6b552017-03-31 12:11:40 -070010142 return adapter->device_mode == QDF_STA_MODE ||
10143 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010144}
10145
Dustin Brown5ec6b552017-03-31 12:11:40 -070010146static inline bool hdd_adapter_is_ap(hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010147{
Dustin Brown5ec6b552017-03-31 12:11:40 -070010148 return adapter->device_mode == QDF_SAP_MODE ||
10149 adapter->device_mode == QDF_P2P_GO_MODE;
10150}
10151
10152static bool hdd_any_adapter_is_assoc(hdd_context_t *hdd_ctx)
10153{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010154 QDF_STATUS status;
Dustin Brown5ec6b552017-03-31 12:11:40 -070010155 hdd_adapter_list_node_t *node;
10156
10157 status = hdd_get_front_adapter(hdd_ctx, &node);
10158 while (QDF_IS_STATUS_SUCCESS(status) && node) {
10159 hdd_adapter_t *adapter = node->pAdapter;
10160
10161 if (adapter &&
10162 hdd_adapter_is_sta(adapter) &&
10163 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
10164 conn_info.connState == eConnectionState_Associated) {
10165 return true;
10166 }
10167
10168 if (adapter &&
10169 hdd_adapter_is_ap(adapter) &&
10170 WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive) {
10171 return true;
10172 }
10173
10174 status = hdd_get_next_adapter(hdd_ctx, node, &node);
10175 }
10176
10177 return false;
10178}
10179
10180static bool hdd_bus_bw_compute_timer_is_running(hdd_context_t *hdd_ctx)
10181{
10182 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010183
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053010184 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070010185 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053010186 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010187
Dustin Brown5ec6b552017-03-31 12:11:40 -070010188 return is_running;
10189}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010190
Dustin Brown5ec6b552017-03-31 12:11:40 -070010191static void __hdd_bus_bw_compute_timer_start(hdd_context_t *hdd_ctx)
10192{
10193 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
10194 hdd_ctx->bus_bw_timer_running = true;
10195 qdf_timer_start(&hdd_ctx->bus_bw_timer,
10196 hdd_ctx->config->busBandwidthComputeInterval);
10197 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
10198}
10199
10200void hdd_bus_bw_compute_timer_start(hdd_context_t *hdd_ctx)
10201{
10202 ENTER();
10203
10204 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
10205 hdd_debug("Bandwidth compute timer already started");
10206 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010207 }
10208
Dustin Brown5ec6b552017-03-31 12:11:40 -070010209 __hdd_bus_bw_compute_timer_start(hdd_ctx);
10210
10211 EXIT();
10212}
10213
10214void hdd_bus_bw_compute_timer_try_start(hdd_context_t *hdd_ctx)
10215{
10216 ENTER();
10217
10218 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
10219 hdd_debug("Bandwidth compute timer already started");
10220 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070010221 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070010222
10223 if (hdd_any_adapter_is_assoc(hdd_ctx))
10224 __hdd_bus_bw_compute_timer_start(hdd_ctx);
10225
10226 EXIT();
10227}
10228
10229static void __hdd_bus_bw_compute_timer_stop(hdd_context_t *hdd_ctx)
10230{
10231 hdd_ipa_set_perf_level(hdd_ctx, 0, 0);
10232
10233 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
10234 qdf_timer_stop(&hdd_ctx->bus_bw_timer);
10235 hdd_ctx->bus_bw_timer_running = false;
10236 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
10237
10238 hdd_reset_tcp_delack(hdd_ctx);
10239}
10240
10241void hdd_bus_bw_compute_timer_stop(hdd_context_t *hdd_ctx)
10242{
10243 ENTER();
10244
10245 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
10246 hdd_debug("Bandwidth compute timer already stopped");
10247 return;
10248 }
10249
10250 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
10251
10252 EXIT();
10253}
10254
10255void hdd_bus_bw_compute_timer_try_stop(hdd_context_t *hdd_ctx)
10256{
10257 ENTER();
10258
10259 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
10260 hdd_debug("Bandwidth compute timer already stopped");
10261 return;
10262 }
10263
10264 if (!hdd_any_adapter_is_assoc(hdd_ctx))
10265 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
10266
10267 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010268}
10269#endif
10270
10271/**
10272 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
10273 * and sta's operating channel.
10274 * @sta_adapter: Describe the first argument to foobar.
10275 * @ap_adapter: Describe the second argument to foobar.
10276 * @roam_profile: Roam profile of AP to which STA wants to connect.
10277 * @concurrent_chnl_same: If both SAP and STA channels are same then
10278 * set this flag to true else false.
10279 *
10280 * This function checks the sap's operating channel and sta's operating channel.
10281 * if both are same then it will return false else it will restart the sap in
10282 * sta's channel and return true.
10283 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010284 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010285 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010286QDF_STATUS wlan_hdd_check_custom_con_channel_rules(hdd_adapter_t *sta_adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010287 hdd_adapter_t *ap_adapter,
10288 tCsrRoamProfile *roam_profile,
10289 tScanResultHandle *scan_cache,
10290 bool *concurrent_chnl_same)
10291{
10292 hdd_ap_ctx_t *hdd_ap_ctx;
10293 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010294 QDF_STATUS status;
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010295 enum tQDF_ADAPTER_MODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010296 *concurrent_chnl_same = true;
10297
10298 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10299 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070010300 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010301 scan_cache,
10302 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010303 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010304 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010305 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
10306 if (hdd_ap_ctx->operatingChannel != channel_id) {
10307 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010308 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010309 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010310 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010311 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
10312 if (hdd_ap_ctx->operatingChannel != channel_id) {
10313 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010314 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010315 }
10316 }
10317 } else {
10318 /*
10319 * Lets handle worst case scenario here, Scan cache lookup is
10320 * failed so we have to stop the SAP to avoid any channel
10321 * discrepancy between SAP's channel and STA's channel.
10322 * Return the status as failure so caller function could know
10323 * that scan look up is failed.
10324 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070010325 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010326 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010327 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010328 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010329}
10330
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010331/**
10332 * wlan_hdd_stop_sap() - This function stops bss of SAP.
10333 * @ap_adapter: SAP adapter
10334 *
10335 * This function will process the stopping of sap adapter.
10336 *
10337 * Return: None
10338 */
10339void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter)
10340{
10341 hdd_ap_ctx_t *hdd_ap_ctx;
10342 hdd_hostapd_state_t *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053010343 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010344 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010345
10346 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010347 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010348 return;
10349 }
10350
10351 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10352 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053010353 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010354 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053010355
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010356 mutex_lock(&hdd_ctx->sap_lock);
10357 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080010358 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010359 hdd_cleanup_actionframe(hdd_ctx, ap_adapter);
10360 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010361 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053010362 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010363 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010364 sapContext)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +053010365 qdf_status = qdf_wait_single_event(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080010366 qdf_stop_bss_event,
10367 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053010368 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010369 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070010370 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010371 return;
10372 }
10373 }
10374 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010375 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
10376 ap_adapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010377 ap_adapter->sessionId);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010378 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010379 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010380 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010381 }
10382 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010383}
10384
10385/**
10386 * wlan_hdd_start_sap() - this function starts bss of SAP.
10387 * @ap_adapter: SAP adapter
10388 *
10389 * This function will process the starting of sap adapter.
10390 *
10391 * Return: None
10392 */
Arun Khandavallicc544b32017-01-30 19:52:16 +053010393void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010394{
10395 hdd_ap_ctx_t *hdd_ap_ctx;
10396 hdd_hostapd_state_t *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053010397 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010398 hdd_context_t *hdd_ctx;
10399 tsap_Config_t *sap_config;
10400
10401 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010402 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010403 return;
10404 }
10405
Krunal Soni9b04c9b2016-03-10 13:08:05 -080010406 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070010407 hdd_err("SoftAp role has not been enabled");
10408 return;
10409 }
10410
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010411 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
10412 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10413 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10414 sap_config = &ap_adapter->sessionCtx.ap.sapConfig;
10415
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010416 mutex_lock(&hdd_ctx->sap_lock);
10417 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
10418 goto end;
10419
10420 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010421 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010422 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
10423 goto end;
10424 }
10425
Wei Song2f76f642016-11-18 16:32:53 +080010426 qdf_event_reset(&hostapd_state->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010427 if (wlansap_start_bss(hdd_ap_ctx->sapContext, hdd_hostapd_sap_event_cb,
10428 &hdd_ap_ctx->sapConfig,
10429 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010430 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010431 goto end;
10432
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010433 hdd_debug("Waiting for SAP to start");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053010434 qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -080010435 SME_CMD_TIMEOUT_VALUE);
Anurag Chouhance0dc992016-02-16 18:18:03 +053010436 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070010437 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010438 goto end;
10439 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070010440 hdd_info("SAP Start Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010441 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Krunal Sonib37bb352016-12-20 14:12:21 -080010442 if (hostapd_state->bssState == BSS_START)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080010443 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
10444 ap_adapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010445 ap_adapter->sessionId);
10446 hostapd_state->bCommit = true;
10447
10448end:
10449 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070010450 /* SAP context and beacon cleanup will happen during driver unload
10451 * in hdd_stop_adapter
10452 */
10453 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
10454
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010455}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010456
10457/**
Archana Ramachandrana20ef812015-11-13 16:12:13 -080010458 * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual
10459 * mac scan config
10460 * @status: Status of set antenna mode
10461 *
10462 * Callback on setting the dual mac configuration
10463 *
10464 * Return: None
10465 */
10466void wlan_hdd_soc_set_antenna_mode_cb(
10467 enum set_antenna_mode_status status)
10468{
10469 hdd_context_t *hdd_ctx;
10470
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010471 hdd_debug("Status: %d", status);
Archana Ramachandrana20ef812015-11-13 16:12:13 -080010472
10473 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10474 if (0 != wlan_hdd_validate_context(hdd_ctx))
10475 return;
10476
10477 /* Signal the completion of set dual mac config */
10478 complete(&hdd_ctx->set_antenna_mode_cmpl);
10479}
10480
10481/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010482 * hdd_get_fw_version() - Get FW version
10483 * @hdd_ctx: pointer to HDD context.
10484 * @major_spid: FW version - major spid.
10485 * @minor_spid: FW version - minor spid
10486 * @ssid: FW version - ssid
10487 * @crmid: FW version - crmid
10488 *
10489 * This function is called to get the firmware build version stored
10490 * as part of the HDD context
10491 *
10492 * Return: None
10493 */
10494void hdd_get_fw_version(hdd_context_t *hdd_ctx,
10495 uint32_t *major_spid, uint32_t *minor_spid,
10496 uint32_t *siid, uint32_t *crmid)
10497{
10498 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
10499 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
10500 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
10501 *crmid = hdd_ctx->target_fw_version & 0x7fff;
10502}
10503
10504#ifdef QCA_CONFIG_SMP
10505/**
10506 * wlan_hdd_get_cpu() - get cpu_index
10507 *
10508 * Return: cpu_index
10509 */
10510int wlan_hdd_get_cpu(void)
10511{
10512 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010513
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010514 put_cpu();
10515 return cpu_index;
10516}
10517#endif
10518
10519/**
10520 * hdd_get_fwpath() - get framework path
10521 *
10522 * This function is used to get the string written by
10523 * userspace to start the wlan driver
10524 *
10525 * Return: string
10526 */
10527const char *hdd_get_fwpath(void)
10528{
10529 return fwpath.string;
10530}
10531
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010532/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010533 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010534 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010535 * This function initilizes CDS global context with the help of cds_init. This
10536 * has to be the first function called after probe to get a valid global
10537 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010538 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010539 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010540 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010541int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010542{
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010543 v_CONTEXT_t p_cds_context = NULL;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010544 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010545
Houston Hoffman9e06e542016-12-12 12:06:26 -080010546 p_cds_context = cds_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010547#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10548 wlan_logging_sock_init_svc();
10549#endif
10550
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010551 if (p_cds_context == NULL) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010552 hdd_err("Failed to allocate CDS context");
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010553 ret = -ENOMEM;
10554 goto err_out;
10555 }
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010556
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010557 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053010558 hdd_register_debug_callback();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010559
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010560err_out:
10561 return ret;
10562}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010563
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010564/**
10565 * hdd_deinit() - Deinitialize Driver
10566 *
10567 * This function frees CDS global context with the help of cds_deinit. This
10568 * has to be the last function call in remove callback to free the global
10569 * context.
10570 */
10571void hdd_deinit(void)
10572{
Dustin Brownedce4a52017-05-10 11:59:15 -070010573 hdd_deinit_wowl();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010574 cds_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010575
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010576#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10577 wlan_logging_sock_deinit_svc();
10578#endif
10579}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010580
Yue Ma6e7b1a02017-04-03 14:17:46 -070010581#ifdef QCA_WIFI_NAPIER_EMULATION
10582#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
10583#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010584#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070010585#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010586
Sachin Ahujadddd2632017-03-07 19:07:24 +053010587static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
10588 struct file *file)
10589{
10590 return 0;
10591}
10592
10593static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
10594 const char __user *user_buf,
10595 size_t count,
10596 loff_t *f_pos)
10597{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053010598 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053010599 static const char wlan_off_str[] = "OFF";
10600 static const char wlan_on_str[] = "ON";
10601 int ret;
10602 unsigned long rc;
10603
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053010604 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053010605 pr_err("Failed to read buffer\n");
10606 return -EINVAL;
10607 }
10608
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053010609 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053010610 pr_debug("Wifi turning off from UI\n");
10611 goto exit;
10612 }
10613
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053010614 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053010615 pr_err("Invalid value received from framework");
10616 goto exit;
10617 }
10618
10619 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053010620 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053010621 rc = wait_for_completion_timeout(&wlan_start_comp,
10622 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
10623 if (!rc) {
10624 hdd_alert("Timed-out waiting in wlan_hdd_state_ctrl_param_write");
10625 ret = -EINVAL;
10626 hdd_start_complete(ret);
10627 return ret;
10628 }
10629
10630 hdd_start_complete(0);
10631 }
10632
10633exit:
10634 return count;
10635}
10636
10637
10638const struct file_operations wlan_hdd_state_fops = {
10639 .owner = THIS_MODULE,
10640 .open = wlan_hdd_state_ctrl_param_open,
10641 .write = wlan_hdd_state_ctrl_param_write,
10642};
10643
10644static int wlan_hdd_state_ctrl_param_create(void)
10645{
10646 unsigned int wlan_hdd_state_major = 0;
10647 int ret;
10648 struct device *dev;
10649
10650 device = MKDEV(wlan_hdd_state_major, 0);
10651
10652 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
10653 if (ret) {
10654 pr_err("Failed to register qcwlanstate");
10655 goto dev_alloc_err;
10656 }
10657 wlan_hdd_state_major = MAJOR(device);
10658
10659 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
10660 if (IS_ERR(class)) {
10661 pr_err("wlan_hdd_state class_create error");
10662 goto class_err;
10663 }
10664
10665 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
10666 if (IS_ERR(dev)) {
10667 pr_err("wlan_hdd_statedevice_create error");
10668 goto err_class_destroy;
10669 }
10670
10671 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
10672 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
10673 if (ret) {
10674 pr_err("Failed to add cdev error");
10675 goto cdev_add_err;
10676 }
10677
10678 pr_info("wlan_hdd_state %s major(%d) initialized",
10679 WLAN_MODULE_NAME, wlan_hdd_state_major);
10680
10681 return 0;
10682
10683cdev_add_err:
10684 device_destroy(class, device);
10685err_class_destroy:
10686 class_destroy(class);
10687class_err:
10688 unregister_chrdev_region(device, dev_num);
10689dev_alloc_err:
10690 return -ENODEV;
10691}
10692
10693static void wlan_hdd_state_ctrl_param_destroy(void)
10694{
10695 cdev_del(&wlan_hdd_state_cdev);
10696 device_destroy(class, device);
10697 class_destroy(class);
10698 unregister_chrdev_region(device, dev_num);
10699
10700 pr_info("Device node unregistered");
10701}
10702
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010703/**
Mukul Sharmad75a6672017-06-22 15:40:53 +053010704 * component_init - API to init cld component's
10705 *
10706 * Return: None
10707 */
10708static void component_init(void)
10709{
10710 pmo_init();
10711}
10712
10713/**
10714 * component_deinit - API to deinit cld component's
10715 *
10716 * Return: None
10717 */
10718static void component_deinit(void)
10719{
10720 pmo_deinit();
10721}
10722
10723/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010724 * __hdd_module_init - Module init helper
10725 *
10726 * Module init helper function used by both module and static driver.
10727 *
10728 * Return: 0 for success, errno on failure
10729 */
10730static int __hdd_module_init(void)
10731{
10732 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010733
Dustin Brownab482ac2017-06-09 17:00:44 -070010734 pr_err("%s: Loading driver v%s (%s)%s\n",
10735 WLAN_MODULE_NAME,
10736 QWLAN_VERSIONSTR,
Naveen Rawat93836252017-06-20 16:30:59 -070010737 g_wlan_driver_timestamp,
Dustin Brownab482ac2017-06-09 17:00:44 -070010738 TIMER_MANAGER_STR MEMORY_DEBUG_STR);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010739
Sachin Ahujadddd2632017-03-07 19:07:24 +053010740 ret = wlan_hdd_state_ctrl_param_create();
10741 if (ret) {
10742 pr_err("wlan_hdd_state_create:%x\n", ret);
10743 goto err_dev_state;
10744 }
10745
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070010746 pld_init();
10747
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053010748 ret = hdd_init();
10749 if (ret) {
10750 pr_err("hdd_init failed %x\n", ret);
10751 goto err_hdd_init;
10752 }
10753
Rajeev Kumar97767a02016-11-30 11:20:40 -080010754 dispatcher_init();
10755
Mukul Sharmad75a6672017-06-22 15:40:53 +053010756 /* Ensure to call post objmgr init */
10757 component_init();
10758
Anurag Chouhana37b5b72016-02-21 14:53:42 +053010759 qdf_wake_lock_create(&wlan_wake_lock, "wlan");
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010760
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010761 hdd_set_conparam((uint32_t) con_mode);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010762
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010763 ret = wlan_hdd_register_driver();
10764 if (ret) {
Mohit Khannafa99aea2016-05-12 21:43:13 -070010765 pr_err("%s: driver load failure, err %d\n", WLAN_MODULE_NAME,
10766 ret);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010767 goto out;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010768 }
10769
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053010770 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010771
10772 return 0;
10773out:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053010774 qdf_wake_lock_destroy(&wlan_wake_lock);
Rajeev Kumar97767a02016-11-30 11:20:40 -080010775 dispatcher_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053010776 hdd_deinit();
Rajeev Kumar97767a02016-11-30 11:20:40 -080010777
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053010778err_hdd_init:
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070010779 pld_deinit();
Sachin Ahujadddd2632017-03-07 19:07:24 +053010780 wlan_hdd_state_ctrl_param_destroy();
10781err_dev_state:
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010782 return ret;
10783}
10784
10785/**
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053010786 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
10787 *
10788 * Block the unloading of the driver until the cds recovery is completed
10789 *
10790 * Return: None
10791 */
10792static void hdd_wait_for_recovery_completion(void)
10793{
10794 int retry = 0;
10795
10796 /* Wait for recovery to complete */
10797 while (cds_is_driver_recovering()) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010798 hdd_err("Recovery in progress; wait here!!!");
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053010799 msleep(1000);
10800 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010801 hdd_err("SSR never completed, error");
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053010802 QDF_BUG(0);
10803 }
10804 }
10805}
10806
10807/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010808 * __hdd_module_exit - Module exit helper
10809 *
10810 * Module exit helper function used by both module and static driver.
10811 */
10812static void __hdd_module_exit(void)
10813{
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053010814 int qdf_print_idx = -1;
10815
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010816 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
10817 QWLAN_VERSIONSTR);
10818
bings6028ee82017-03-29 07:51:40 +080010819 cds_set_unload_in_progress(true);
10820
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053010821 hdd_wait_for_recovery_completion();
10822
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010823 wlan_hdd_unregister_driver();
10824
Anurag Chouhana37b5b72016-02-21 14:53:42 +053010825 qdf_wake_lock_destroy(&wlan_wake_lock);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080010826
Mukul Sharmad75a6672017-06-22 15:40:53 +053010827 /* Ensure to call prior to objmgr deinit */
10828 component_deinit();
10829
Rajeev Kumar97767a02016-11-30 11:20:40 -080010830 dispatcher_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053010831 hdd_deinit();
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070010832 pld_deinit();
10833
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053010834 qdf_print_idx = qdf_get_pidx();
10835 qdf_print_ctrl_cleanup(qdf_print_idx);
Sachin Ahujadddd2632017-03-07 19:07:24 +053010836 wlan_hdd_state_ctrl_param_destroy();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010837}
10838
Arun Khandavallifae92942016-08-01 13:31:08 +053010839#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010840/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010841 * wlan_boot_cb() - Wlan boot callback
10842 * @kobj: object whose directory we're creating the link in.
10843 * @attr: attribute the user is interacting with
10844 * @buff: the buffer containing the user data
10845 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010846 *
Arun Khandavallifae92942016-08-01 13:31:08 +053010847 * This callback is invoked when the fs is ready to start the
10848 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010849 *
Arun Khandavallifae92942016-08-01 13:31:08 +053010850 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010851 */
Arun Khandavallifae92942016-08-01 13:31:08 +053010852static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010853 struct kobj_attribute *attr,
10854 const char *buf,
10855 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010856{
Arun Khandavallifae92942016-08-01 13:31:08 +053010857
Arun Khandavallifae92942016-08-01 13:31:08 +053010858 if (wlan_loader->loaded_state) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010859 pr_err("%s: wlan driver already initialized\n", __func__);
10860 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053010861 }
10862
Arun Khandavallifae92942016-08-01 13:31:08 +053010863 if (__hdd_module_init()) {
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010864 pr_err("%s: wlan driver initialization failed\n", __func__);
10865 return -EIO;
10866 }
10867
10868 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053010869
10870 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010871}
Arun Khandavallifae92942016-08-01 13:31:08 +053010872
10873/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010874 * hdd_sysfs_cleanup() - cleanup sysfs
10875 *
10876 * Return: None
10877 *
10878 */
10879static void hdd_sysfs_cleanup(void)
10880{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010881 /* remove from group */
10882 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
10883 sysfs_remove_group(wlan_loader->boot_wlan_obj,
10884 wlan_loader->attr_group);
10885
10886 /* unlink the object from parent */
10887 kobject_del(wlan_loader->boot_wlan_obj);
10888
10889 /* free the object */
10890 kobject_put(wlan_loader->boot_wlan_obj);
10891
10892 kfree(wlan_loader->attr_group);
10893 kfree(wlan_loader);
10894
10895 wlan_loader = NULL;
10896}
10897
10898/**
Arun Khandavallifae92942016-08-01 13:31:08 +053010899 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
10900 * ready
10901 *
10902 * This is creates the syfs entry boot_wlan. Which shall be invoked
10903 * when the filesystem is ready.
10904 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010905 * QDF API cannot be used here since this function is called even before
10906 * initializing WLAN driver.
10907 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070010908 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053010909 */
10910static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010911{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010912 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053010913
10914 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010915 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010916 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053010917
10918 wlan_loader->boot_wlan_obj = NULL;
10919 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
10920 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010921 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053010922 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053010923
10924 wlan_loader->loaded_state = 0;
10925 wlan_loader->attr_group->attrs = attrs;
10926
10927 wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
10928 kernel_kobj);
10929 if (!wlan_loader->boot_wlan_obj) {
10930 pr_err("%s: sysfs create and add failed\n", __func__);
Arun Khandavallifae92942016-08-01 13:31:08 +053010931 goto error_return;
10932 }
10933
10934 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
10935 wlan_loader->attr_group);
10936 if (ret) {
10937 pr_err("%s: sysfs create group failed %d\n", __func__, ret);
10938 goto error_return;
10939 }
10940
10941 return 0;
10942
10943error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010944 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053010945
10946 return ret;
10947}
10948
10949/**
10950 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
10951 *
10952 * Return: 0 on success or errno on failure
10953 */
10954static int wlan_deinit_sysfs(void)
10955{
Arun Khandavallifae92942016-08-01 13:31:08 +053010956 if (!wlan_loader) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010957 hdd_err("wlan loader context is Null!");
Arun Khandavallifae92942016-08-01 13:31:08 +053010958 return -EINVAL;
10959 }
10960
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010961 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010962 return 0;
10963}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010964
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070010965#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053010966
10967#ifdef MODULE
10968/**
10969 * __hdd_module_init - Module init helper
10970 *
10971 * Module init helper function used by both module and static driver.
10972 *
10973 * Return: 0 for success, errno on failure
10974 */
10975static int hdd_module_init(void)
10976{
Arun Khandavallifae92942016-08-01 13:31:08 +053010977 if (__hdd_module_init()) {
10978 pr_err("%s: Failed to register handler\n", __func__);
Dustin Brownab482ac2017-06-09 17:00:44 -070010979 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053010980 }
10981
Dustin Brownab482ac2017-06-09 17:00:44 -070010982 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053010983}
10984#else
10985static int __init hdd_module_init(void)
10986{
10987 int ret = -EINVAL;
10988
10989 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070010990 if (ret)
Arun Khandavallifae92942016-08-01 13:31:08 +053010991 pr_err("Failed to create sysfs entry for loading wlan");
10992
10993 return ret;
10994}
10995#endif
10996
10997
10998#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080010999/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011000 * hdd_module_exit() - Exit function
11001 *
11002 * This is the driver exit point (invoked when module is unloaded using rmmod)
11003 *
11004 * Return: None
11005 */
11006static void __exit hdd_module_exit(void)
11007{
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011008 __hdd_module_exit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011009}
Arun Khandavallifae92942016-08-01 13:31:08 +053011010#else
11011static void __exit hdd_module_exit(void)
11012{
11013 __hdd_module_exit();
11014 wlan_deinit_sysfs();
11015}
11016#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011017
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011018static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
11019{
11020 return param_set_copystring(kmessage, kp);
11021}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080011022
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011023/**
11024 * is_con_mode_valid() check con mode is valid or not
11025 * @mode: global con mode
11026 *
11027 * Return: TRUE on success FALSE on failure
11028 */
11029static bool is_con_mode_valid(enum tQDF_GLOBAL_CON_MODE mode)
11030{
11031 switch (mode) {
11032 case QDF_GLOBAL_MONITOR_MODE:
11033 case QDF_GLOBAL_FTM_MODE:
11034 case QDF_GLOBAL_EPPING_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011035 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011036 return true;
11037 default:
11038 return false;
11039 }
11040}
11041
11042/**
11043 * hdd_get_adpter_mode() - returns adapter mode based on global con mode
11044 * @mode: global con mode
11045 *
11046 * Return: adapter mode
11047 */
11048static enum tQDF_ADAPTER_MODE hdd_get_adpter_mode(
11049 enum tQDF_GLOBAL_CON_MODE mode)
11050{
11051
11052 switch (mode) {
11053 case QDF_GLOBAL_MISSION_MODE:
11054 return QDF_STA_MODE;
11055 case QDF_GLOBAL_MONITOR_MODE:
11056 return QDF_MONITOR_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011057 case QDF_GLOBAL_EPPING_MODE:
11058 return QDF_EPPING_MODE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011059 case QDF_GLOBAL_FTM_MODE:
11060 return QDF_FTM_MODE;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011061 case QDF_GLOBAL_QVIT_MODE:
11062 return QDF_QVIT_MODE;
11063 default:
11064 return QDF_MAX_NO_OF_MODE;
11065 }
11066}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011067
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011068static void hdd_cleanup_present_mode(hdd_context_t *hdd_ctx,
11069 enum tQDF_GLOBAL_CON_MODE curr_mode)
11070{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053011071 int driver_status;
11072
11073 driver_status = hdd_ctx->driver_status;
11074
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011075 switch (curr_mode) {
11076 case QDF_GLOBAL_MISSION_MODE:
11077 case QDF_GLOBAL_MONITOR_MODE:
11078 case QDF_GLOBAL_FTM_MODE:
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053011079 if (driver_status != DRIVER_MODULES_CLOSED) {
11080 hdd_abort_mac_scan_all_adapters(hdd_ctx);
11081 hdd_stop_all_adapters(hdd_ctx);
11082 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011083 hdd_deinit_all_adapters(hdd_ctx, false);
11084 hdd_close_all_adapters(hdd_ctx, false);
11085 break;
11086 case QDF_GLOBAL_EPPING_MODE:
11087 epping_disable();
11088 epping_close();
11089 break;
11090 default:
11091 return;
11092 }
11093}
11094
11095static int hdd_register_req_mode(hdd_context_t *hdd_ctx,
11096 enum tQDF_GLOBAL_CON_MODE mode)
11097{
11098 hdd_adapter_t *adapter;
11099 int ret = 0;
11100 bool rtnl_held;
11101 qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11102 QDF_STATUS status;
11103
11104 if (!qdf_dev) {
11105 hdd_err("qdf device context is Null return!");
11106 return -EINVAL;
11107 }
11108
11109 rtnl_held = hdd_hold_rtnl_lock();
11110 switch (mode) {
11111 case QDF_GLOBAL_MISSION_MODE:
Jeff Johnson957bc272017-02-02 08:54:48 -080011112 ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
11113 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011114 hdd_err("Failed to open interfaces: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011115 break;
11116 case QDF_GLOBAL_FTM_MODE:
11117 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
11118 wlan_hdd_get_intf_addr(hdd_ctx),
11119 NET_NAME_UNKNOWN, rtnl_held);
11120 if (adapter == NULL)
11121 ret = -EINVAL;
11122 break;
11123 case QDF_GLOBAL_MONITOR_MODE:
11124 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
11125 wlan_hdd_get_intf_addr(hdd_ctx),
11126 NET_NAME_UNKNOWN, rtnl_held);
11127 if (adapter == NULL)
11128 ret = -EINVAL;
11129 break;
11130 case QDF_GLOBAL_EPPING_MODE:
11131 status = epping_open();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011132 if (status != QDF_STATUS_SUCCESS) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011133 hdd_err("Failed to open in eeping mode: %d", status);
11134 ret = -EINVAL;
11135 break;
11136 }
11137 ret = epping_enable(qdf_dev->dev);
11138 if (ret) {
11139 hdd_err("Failed to enable in epping mode : %d", ret);
11140 epping_close();
11141 }
11142 break;
11143 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011144 hdd_err("Mode not supported");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011145 ret = -ENOTSUPP;
11146 break;
11147 }
11148 hdd_release_rtnl_lock();
11149 rtnl_held = false;
11150 return ret;
11151}
11152
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011153/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011154 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011155 * @kmessage: con mode name on which driver to be bring up
11156 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011157 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011158 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011159 * This function is invoked when user updates con mode using sys entry,
11160 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011161 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011162 * Return - 0 on success and failure code on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011163 */
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011164static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
11165 hdd_context_t *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011166{
11167 int ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011168 hdd_adapter_t *adapter;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011169 enum tQDF_GLOBAL_CON_MODE curr_mode;
11170 enum tQDF_ADAPTER_MODE adapter_mode;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011171
Dustin Brownab6029b2017-05-24 13:04:19 -070011172 hdd_info("con_mode handler: %s", kmessage);
11173
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053011174 ret = wlan_hdd_validate_context(hdd_ctx);
11175 if (ret)
11176 return ret;
11177
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011178 cds_set_load_in_progress(true);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011179
11180 ret = param_set_int(kmessage, kp);
Arun Khandavallifae92942016-08-01 13:31:08 +053011181
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011182 if (!(is_con_mode_valid(con_mode))) {
11183 hdd_err("invlaid con_mode %d", con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011184 ret = -EINVAL;
11185 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011186 }
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011187
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011188 curr_mode = hdd_get_conparam();
11189 if (curr_mode == con_mode) {
11190 hdd_err("curr mode: %d is same as user triggered mode %d",
11191 curr_mode, con_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011192 ret = 0;
11193 goto reset_flags;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011194 }
11195
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011196 /* Cleanup present mode before switching to new mode */
11197 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +053011198
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070011199 ret = hdd_wlan_stop_modules(hdd_ctx, true);
Arun Khandavallifae92942016-08-01 13:31:08 +053011200 if (ret) {
11201 hdd_err("Stop wlan modules failed");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011202 goto reset_flags;
11203 }
11204
11205 hdd_set_conparam(con_mode);
11206
11207 /* Register for new con_mode & then kick_start modules again */
11208 ret = hdd_register_req_mode(hdd_ctx, con_mode);
11209 if (ret) {
11210 hdd_err("Failed to register for new mode");
11211 goto reset_flags;
11212 }
11213
11214 adapter_mode = hdd_get_adpter_mode(con_mode);
11215 if (adapter_mode == QDF_MAX_NO_OF_MODE) {
11216 hdd_err("invalid adapter");
11217 ret = -EINVAL;
11218 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053011219 }
11220
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053011221 adapter = hdd_get_adapter(hdd_ctx, adapter_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +053011222 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011223 hdd_err("Failed to get adapter:%d", adapter_mode);
11224 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053011225 }
11226
11227 ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
11228 if (ret) {
11229 hdd_err("Start wlan modules failed: %d", ret);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011230 goto reset_flags;
Arun Khandavallifae92942016-08-01 13:31:08 +053011231 }
11232
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011233 if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
11234 con_mode == QDF_GLOBAL_FTM_MODE) {
11235 if (hdd_start_adapter(adapter)) {
11236 hdd_err("Failed to start %s adapter", kmessage);
11237 ret = -EINVAL;
11238 goto reset_flags;
11239 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011240 }
11241
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053011242 hdd_info("Mode successfully changed to %s", kmessage);
11243 ret = 0;
11244
11245reset_flags:
11246 cds_set_load_in_progress(false);
11247 return ret;
11248}
11249
11250
11251static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
11252{
11253 int ret;
11254 hdd_context_t *hdd_ctx;
11255
11256 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11257 ret = wlan_hdd_validate_context(hdd_ctx);
11258 if (ret)
11259 return ret;
11260
11261 cds_ssr_protect(__func__);
11262 ret = __con_mode_handler(kmessage, kp, hdd_ctx);
11263 cds_ssr_unprotect(__func__);
11264
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011265 return ret;
11266}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011267
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053011268static int con_mode_handler_ftm(const char *kmessage,
11269 struct kernel_param *kp)
11270{
11271 int ret;
11272
11273 ret = param_set_int(kmessage, kp);
11274
11275 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
11276 pr_err("Only FTM mode supported!");
11277 return -ENOTSUPP;
11278 }
11279
11280 hdd_set_conparam(con_mode_ftm);
11281 con_mode = con_mode_ftm;
11282
11283 return ret;
11284}
11285
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011286/**
11287 * hdd_get_conparam() - driver exit point
11288 *
11289 * This is the driver exit point (invoked when module is unloaded using rmmod)
11290 *
Anurag Chouhan6d760662016-02-20 16:05:43 +053011291 * Return: enum tQDF_GLOBAL_CON_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011292 */
Anurag Chouhan6d760662016-02-20 16:05:43 +053011293enum tQDF_GLOBAL_CON_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011294{
Anurag Chouhan6d760662016-02-20 16:05:43 +053011295 return (enum tQDF_GLOBAL_CON_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011296}
11297
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080011298void hdd_set_conparam(uint32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011299{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080011300 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080011301}
11302
Komal Seelamc11bb222016-01-27 18:57:10 +053011303/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053011304 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
11305 * @hdd_ctx: HDD context
11306 *
11307 * Cleans up the pre cac interface, if it exists
11308 *
11309 * Return: None
11310 */
11311void hdd_clean_up_pre_cac_interface(hdd_context_t *hdd_ctx)
11312{
11313 uint8_t session_id;
11314 QDF_STATUS status;
11315 struct hdd_adapter_s *precac_adapter;
11316
11317 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->hHal, &session_id);
11318 if (QDF_IS_STATUS_ERROR(status)) {
11319 hdd_err("failed to get pre cac vdev id");
11320 return;
11321 }
11322
11323 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
11324 if (!precac_adapter) {
11325 hdd_err("invalid pre cac adapater");
11326 return;
11327 }
11328
11329 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
11330 wlan_hdd_sap_pre_cac_failure,
11331 (void *)precac_adapter);
11332 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
11333
11334}
11335
11336/**
Komal Seelamec702b02016-02-24 18:42:16 +053011337 * hdd_update_ol_config - API to update ol configuration parameters
11338 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053011339 *
Komal Seelamc11bb222016-01-27 18:57:10 +053011340 * Return: void
11341 */
Komal Seelamec702b02016-02-24 18:42:16 +053011342static void hdd_update_ol_config(hdd_context_t *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053011343{
Komal Seelamec702b02016-02-24 18:42:16 +053011344 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053011345 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Komal Seelamc11bb222016-01-27 18:57:10 +053011346
Komal Seelamec702b02016-02-24 18:42:16 +053011347 if (!ol_ctx)
11348 return;
11349
11350 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
11351 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
11352 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
11353 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070011354 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053011355
11356 ol_init_ini_config(ol_ctx, &cfg);
11357}
11358
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070011359#ifdef FEATURE_RUNTIME_PM
11360/**
11361 * hdd_populate_runtime_cfg() - populate runtime configuration
11362 * @hdd_ctx: hdd context
11363 * @cfg: pointer to the configuration memory being populated
11364 *
11365 * Return: void
11366 */
11367static void hdd_populate_runtime_cfg(hdd_context_t *hdd_ctx,
11368 struct hif_config_info *cfg)
11369{
11370 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
11371 cfg->runtime_pm_delay = hdd_ctx->config->runtime_pm_delay;
11372}
11373#else
11374static void hdd_populate_runtime_cfg(hdd_context_t *hdd_ctx,
11375 struct hif_config_info *cfg)
11376{
11377}
11378#endif
11379
Komal Seelamec702b02016-02-24 18:42:16 +053011380/**
11381 * hdd_update_hif_config - API to update HIF configuration parameters
11382 * @hdd_ctx: HDD Context
11383 *
11384 * Return: void
11385 */
11386static void hdd_update_hif_config(hdd_context_t *hdd_ctx)
11387{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053011388 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053011389 struct hif_config_info cfg;
11390
11391 if (!scn)
11392 return;
11393
11394 cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070011395 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053011396 hif_init_ini_config(scn, &cfg);
11397}
11398
11399/**
11400 * hdd_update_config() - Initialize driver per module ini parameters
11401 * @hdd_ctx: HDD Context
11402 *
11403 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053011404 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053011405 */
Arun Khandavallic811dcc2016-06-26 07:37:21 +053011406int hdd_update_config(hdd_context_t *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053011407{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053011408 int ret;
11409
Komal Seelamec702b02016-02-24 18:42:16 +053011410 hdd_update_ol_config(hdd_ctx);
11411 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053011412 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
11413 ret = hdd_update_cds_config_ftm(hdd_ctx);
11414 else
11415 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080011416 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053011417
11418 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053011419}
11420
Mukul Sharma9d797a02017-01-05 20:26:03 +053011421#ifdef FEATURE_WLAN_RA_FILTERING
11422/**
11423 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
11424 * @psoc_cfg: pmo psoc Configuration
11425 * @hdd_ctx: Pointer to hdd context
11426 *
11427 * Return: none
11428 */
11429static inline void hdd_ra_populate_pmo_config(
11430 struct pmo_psoc_cfg *psoc_cfg,
11431 hdd_context_t *hdd_ctx)
11432{
11433 psoc_cfg->ra_ratelimit_interval =
11434 hdd_ctx->config->RArateLimitInterval;
11435 psoc_cfg->ra_ratelimit_enable =
11436 hdd_ctx->config->IsRArateLimitEnabled;
11437}
11438#else
11439static inline void hdd_ra_populate_pmo_config(
11440 struct cds_config_info *cds_cfg,
11441 hdd_context_t *hdd_ctx)
11442{
11443}
11444#endif
11445/**
11446 * hdd_update_pmo_config - API to update pmo configuration parameters
11447 * @hdd_ctx: HDD context
11448 *
11449 * Return: void
11450 */
11451static int hdd_update_pmo_config(hdd_context_t *hdd_ctx)
11452{
11453 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
11454 struct pmo_psoc_cfg psoc_cfg;
11455 QDF_STATUS status;
11456
11457 /*
11458 * Value of hdd_ctx->wowEnable can be,
11459 * 0 - Disable both magic pattern match and pattern byte match.
11460 * 1 - Enable magic pattern match on all interfaces.
11461 * 2 - Enable pattern byte match on all interfaces.
11462 * 3 - Enable both magic patter and pattern byte match on
11463 * all interfaces.
11464 */
11465 psoc_cfg.magic_ptrn_enable =
11466 (hdd_ctx->config->wowEnable & 0x01) ? true : false;
11467 psoc_cfg.ptrn_match_enable_all_vdev =
11468 (hdd_ctx->config->wowEnable & 0x02) ? true : false;
11469 psoc_cfg.bpf_enable =
11470 hdd_ctx->config->bpf_packet_filter_enable;
11471 psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
Dustin Brown1224e212017-05-12 14:02:12 -070011472 psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053011473 psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
11474 if (hdd_ctx->config->fhostNSOffload)
11475 psoc_cfg.ns_offload_enable_dynamic = true;
11476 psoc_cfg.ssdp = hdd_ctx->config->ssdp;
11477 psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
11478 psoc_cfg.active_mode_offload =
11479 hdd_ctx->config->active_mode_offload;
11480 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
11481 psoc_cfg.max_wow_filters = hdd_ctx->config->maxWoWFilters;
Mukul Sharma9223f232017-03-08 18:42:27 +053011482 psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
11483 psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
11484 psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
11485 psoc_cfg.power_save_mode =
11486 hdd_ctx->config->enablePowersaveOffload;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +053011487 psoc_cfg.auto_power_save_fail_mode =
11488 hdd_ctx->config->auto_pwr_save_fail_mode;
Mukul Sharma9d797a02017-01-05 20:26:03 +053011489
11490 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053011491 hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx);
11492 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053011493 status = pmo_ucfg_update_psoc_config(psoc, &psoc_cfg);
11494 if (status != QDF_STATUS_SUCCESS) {
11495 hdd_err("failed pmo psoc configuration");
11496 return -EINVAL;
11497 }
11498
11499 return 0;
11500}
11501
Abhishek Singh257a9482017-03-06 16:52:39 +053011502#ifdef NAPIER_SCAN
Abhishek Singhb20db962017-03-03 21:28:46 +053011503
11504#ifdef FEATURE_WLAN_SCAN_PNO
11505static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
11506 struct hdd_config *cfg)
11507{
11508 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
11509 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
11510 pno_cfg->stationary_thresh = cfg->stationary_thresh;
11511 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
11512 pno_cfg->channel_prediction_full_scan =
11513 cfg->channel_prediction_full_scan;
11514}
11515#else
11516static inline void
11517hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
11518 struct hdd_config *cfg)
11519{
11520 return;
11521}
11522#endif
11523
Abhishek Singh257a9482017-03-06 16:52:39 +053011524/**
11525 * hdd_update_scan_config - API to update scan configuration parameters
11526 * @hdd_ctx: HDD context
11527 *
11528 * Return: 0 if success else err
11529 */
11530static int hdd_update_scan_config(hdd_context_t *hdd_ctx)
11531{
11532 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
11533 struct scan_user_cfg scan_cfg;
11534 struct hdd_config *cfg = hdd_ctx->config;
11535 QDF_STATUS status;
11536
11537 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
11538 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
11539 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
11540 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
11541 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
11542 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
11543 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053011544 /* convert to ms */
11545 scan_cfg.scan_cache_aging_time =
11546 cfg->scanAgingTimeout * 1000;
11547 scan_cfg.prefer_5ghz = cfg->nRoamPrefer5GHz;
11548 scan_cfg.select_5ghz_margin = cfg->nSelect5GHzMargin;
11549 scan_cfg.scan_bucket_threshold = cfg->first_scan_bucket_threshold;
11550 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053011551 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053011552 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Abhishek Singh257a9482017-03-06 16:52:39 +053011553
Abhishek Singhb20db962017-03-03 21:28:46 +053011554 hdd_update_pno_config(&scan_cfg.pno_cfg, cfg);
11555
Abhishek Singh257a9482017-03-06 16:52:39 +053011556 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
11557 if (status != QDF_STATUS_SUCCESS) {
11558 hdd_err("failed pmo psoc configuration");
11559 return -EINVAL;
11560 }
11561
11562 return 0;
11563}
11564#else
11565static int hdd_update_scan_config(hdd_context_t *hdd_ctx)
11566{
11567 return 0;
11568}
11569#endif
11570
Frank Liud4b2fa02017-03-29 11:46:48 +080011571#ifdef CONVERGED_TDLS_ENABLE
11572static int hdd_update_tdls_config(hdd_context_t *hdd_ctx)
11573{
11574 struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
11575 struct tdls_start_params tdls_cfg;
11576 struct tdls_user_config *config = &tdls_cfg.config;
11577 struct hdd_config *cfg = hdd_ctx->config;
11578 QDF_STATUS status;
11579
11580 config->tdls_tx_states_period = cfg->fTDLSTxStatsPeriod;
11581 config->tdls_tx_pkt_threshold = cfg->fTDLSTxPacketThreshold;
11582 config->tdls_rx_pkt_threshold = cfg->fTDLSRxFrameThreshold;
11583 config->tdls_max_discovery_attempt = cfg->fTDLSMaxDiscoveryAttempt;
11584 config->tdls_idle_timeout = cfg->tdls_idle_timeout;
11585 config->tdls_idle_pkt_threshold = cfg->fTDLSIdlePacketThreshold;
11586 config->tdls_rssi_trigger_threshold = cfg->fTDLSRSSITriggerThreshold;
11587 config->tdls_rssi_teardown_threshold = cfg->fTDLSRSSITeardownThreshold;
11588 config->tdls_rssi_delta = cfg->fTDLSRSSIDelta;
11589 config->tdls_uapsd_mask = cfg->fTDLSUapsdMask;
11590 config->tdls_uapsd_inactivity_time = cfg->fTDLSPuapsdInactivityTimer;
11591 config->tdls_uapsd_pti_window = cfg->fTDLSPuapsdPTIWindow;
11592 config->tdls_uapsd_ptr_timeout = cfg->fTDLSPuapsdPTRTimeout;
11593 config->tdls_pre_off_chan_num = cfg->fTDLSPrefOffChanNum;
11594 config->tdls_pre_off_chan_bw = cfg->fTDLSPrefOffChanBandwidth;
11595 config->tdls_peer_kickout_threshold = cfg->tdls_peer_kickout_threshold;
11596 config->delayed_trig_framint = cfg->DelayedTriggerFrmInt;
11597 config->tdls_feature_flags = ((cfg->fEnableTDLSOffChannel ?
11598 1 << TDLS_FEATURE_OFF_CHANNEL : 0) |
11599 (cfg->fEnableTDLSWmmMode ? 1 << TDLS_FEATURE_WMM : 0) |
11600 (cfg->fEnableTDLSBufferSta ? 1 << TDLS_FEATURE_BUFFER_STA : 0) |
11601 (cfg->fEnableTDLSSleepSta ? 1 << TDLS_FEATURE_SLEEP_STA : 0) |
11602 (cfg->enable_tdls_scan ? 1 << TDLS_FEATURE_SCAN : 0) |
11603 (cfg->fEnableTDLSSupport ? 1 << TDLS_FEATURE_ENABLE : 0) |
11604 (cfg->fEnableTDLSImplicitTrigger ?
11605 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) |
11606 (cfg->fTDLSExternalControl ?
11607 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0));
11608
11609 tdls_cfg.tdls_send_mgmt_req = eWNI_SME_TDLS_SEND_MGMT_REQ;
11610 tdls_cfg.tdls_add_sta_req = eWNI_SME_TDLS_ADD_STA_REQ;
11611 tdls_cfg.tdls_del_sta_req = eWNI_SME_TDLS_DEL_STA_REQ;
11612 tdls_cfg.tdls_update_peer_state = WMA_UPDATE_TDLS_PEER_STATE;
Kabilan Kannan1c1c4022017-04-06 22:49:26 -070011613 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
Kabilan Kannan256e3182017-05-02 16:02:37 -070011614 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
Frank Liud4b2fa02017-03-29 11:46:48 +080011615 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
11616 tdls_cfg.tdls_evt_cb_data = psoc;
11617 tdls_cfg.tdls_tl_peer_data = hdd_ctx;
11618 tdls_cfg.tdls_reg_tl_peer = hdd_tdls_register_tdls_peer;
11619 tdls_cfg.tdls_dereg_tl_peer = hdd_tdls_deregister_tdl_peer;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -070011620 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
11621 tdls_cfg.tdls_wmm_cb_data = psoc;
11622 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
11623 tdls_cfg.tdls_rx_cb_data = psoc;
Kabilan Kannan256e3182017-05-02 16:02:37 -070011624 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
Frank Liud4b2fa02017-03-29 11:46:48 +080011625
11626 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
11627 if (status != QDF_STATUS_SUCCESS) {
11628 hdd_err("failed pmo psoc configuration");
11629 return -EINVAL;
11630 }
11631
Kabilan Kannan1c1c4022017-04-06 22:49:26 -070011632 hdd_ctx->tdls_umac_comp_active = true;
Kabilan Kannan256e3182017-05-02 16:02:37 -070011633 /* disable napier specific tdls data path */
11634 hdd_ctx->tdls_nap_active = false;
Kabilan Kannan1c1c4022017-04-06 22:49:26 -070011635
Frank Liud4b2fa02017-03-29 11:46:48 +080011636 return 0;
11637}
11638#else
11639static int hdd_update_tdls_config(hdd_context_t *hdd_ctx)
11640{
Kabilan Kannan1c1c4022017-04-06 22:49:26 -070011641 hdd_ctx->tdls_umac_comp_active = false;
Kabilan Kannan256e3182017-05-02 16:02:37 -070011642 /* disable napier specific tdls data path */
11643 hdd_ctx->tdls_nap_active = false;
Frank Liud4b2fa02017-03-29 11:46:48 +080011644 return 0;
11645}
11646#endif
11647
Mukul Sharma9d797a02017-01-05 20:26:03 +053011648int hdd_update_components_config(hdd_context_t *hdd_ctx)
11649{
11650 int ret;
11651
11652 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053011653 if (ret)
11654 return ret;
11655 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080011656 if (ret)
11657 return ret;
11658 ret = hdd_update_tdls_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053011659
11660 return ret;
11661}
11662
Agrawal Ashish65634612016-08-18 13:24:32 +053011663/**
11664 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
11665 * @mode : cfg80211 DFS mode
11666 *
11667 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
11668 */
11669enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
11670{
11671 switch (mode) {
11672 case DFS_MODE_ENABLE:
11673 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053011674 case DFS_MODE_DISABLE:
11675 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053011676 case DFS_MODE_DEPRIORITIZE:
11677 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053011678 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011679 hdd_debug("ACS dfs mode is NONE");
11680 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053011681 }
11682}
11683
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053011684/**
11685 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
11686 * @hddctx: pointer to hdd context
11687 * @set_value: enable/disable
11688 *
11689 * When Host sends vendor command enable, FW will send *ONE* CA ind to
11690 * Host(even though it is duplicate). When Host send vendor command
11691 * disable,FW doesn't perform any action. Whenever any change in
11692 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
11693 *
11694 * return - 0 on success, appropriate error values on failure.
11695 */
11696int hdd_enable_disable_ca_event(hdd_context_t *hddctx, uint8_t set_value)
11697{
11698 QDF_STATUS status;
11699
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011700 if (0 != wlan_hdd_validate_context(hddctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053011701 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053011702
11703 if (!hddctx->config->goptimize_chan_avoid_event) {
11704 hdd_warn("goptimize_chan_avoid_event ini param disabled");
11705 return -EINVAL;
11706 }
11707
11708 status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
11709 if (!QDF_IS_STATUS_SUCCESS(status)) {
11710 hdd_err("Failed to send chan avoid command to SME");
11711 return -EINVAL;
11712 }
11713 return 0;
11714}
Agrawal Ashish65634612016-08-18 13:24:32 +053011715
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011716/**
11717 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
11718 * @value: value to set
11719 *
11720 * This function will set the passed value to roaming in progress flag.
11721 *
11722 * Return: None
11723 */
11724void hdd_set_roaming_in_progress(bool value)
11725{
11726 hdd_context_t *hdd_ctx;
11727
11728 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11729 if (!hdd_ctx) {
11730 hdd_err("HDD context is NULL");
11731 return;
11732 }
11733
11734 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011735 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011736}
11737
11738/**
11739 * hdd_is_roaming_in_progress() - check if roaming is in progress
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011740 * @adapter - HDD adapter
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011741 *
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011742 * Return: true if roaming is in progress for STA type, else false
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011743 */
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011744bool hdd_is_roaming_in_progress(hdd_adapter_t *adapter)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011745{
11746 hdd_context_t *hdd_ctx;
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011747 bool ret_status = false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011748
11749 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11750 if (!hdd_ctx) {
11751 hdd_err("HDD context is NULL");
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011752 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011753 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011754 hdd_debug("dev mode = %d, roaming_in_progress = %d",
11755 adapter->device_mode, hdd_ctx->roaming_in_progress);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080011756 ret_status = ((adapter->device_mode == QDF_STA_MODE) &&
11757 hdd_ctx->roaming_in_progress);
11758
11759 return ret_status;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080011760}
11761
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011762/**
11763 * hdd_is_connection_in_progress() - check if connection is in
11764 * progress
11765 * @session_id: session id
11766 * @reason: scan reject reason
11767 *
11768 * Go through each adapter and check if Connection is in progress
11769 *
11770 * Return: true if connection is in progress else false
11771 */
11772bool hdd_is_connection_in_progress(uint8_t *session_id,
11773 enum scan_reject_states *reason)
11774{
11775 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
11776 hdd_station_ctx_t *hdd_sta_ctx = NULL;
11777 hdd_adapter_t *adapter = NULL;
11778 QDF_STATUS status = 0;
11779 uint8_t sta_id = 0;
11780 uint8_t *sta_mac = NULL;
11781 hdd_context_t *hdd_ctx;
11782
11783 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11784 if (!hdd_ctx) {
11785 hdd_err("HDD context is NULL");
11786 return false;
11787 }
11788
11789 if (true == hdd_ctx->btCoexModeSet) {
11790 hdd_info("BTCoex Mode operation in progress");
11791 return true;
11792 }
11793 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
11794 while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
11795 adapter = adapter_node->pAdapter;
11796 if (!adapter)
11797 goto end;
11798
11799 hdd_info("Adapter with device mode %s(%d) exists",
11800 hdd_device_mode_to_string(adapter->device_mode),
11801 adapter->device_mode);
11802 if (((QDF_STA_MODE == adapter->device_mode)
11803 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
11804 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
11805 && (eConnectionState_Connecting ==
11806 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
11807 conn_info.connState)) {
11808 hdd_err("%p(%d) Connection is in progress",
11809 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
11810 adapter->sessionId);
11811 if (session_id && reason) {
11812 *session_id = adapter->sessionId;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011813 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011814 }
11815 return true;
11816 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070011817 /*
11818 * sme_neighbor_middle_of_roaming is for LFR2
11819 * hdd_is_roaming_in_progress is for LFR3
11820 */
11821 if (((QDF_STA_MODE == adapter->device_mode) &&
11822 sme_neighbor_middle_of_roaming(
11823 WLAN_HDD_GET_HAL_CTX(adapter),
11824 adapter->sessionId)) ||
11825 hdd_is_roaming_in_progress(adapter)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011826 hdd_err("%p(%d) Reassociation in progress",
11827 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
11828 adapter->sessionId);
11829 if (session_id && reason) {
11830 *session_id = adapter->sessionId;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011831 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011832 }
11833 return true;
11834 }
11835 if ((QDF_STA_MODE == adapter->device_mode) ||
11836 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
11837 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
11838 hdd_sta_ctx =
11839 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
11840 if ((eConnectionState_Associated ==
11841 hdd_sta_ctx->conn_info.connState)
11842 && (false ==
11843 hdd_sta_ctx->conn_info.uIsAuthenticated)) {
11844 sta_mac = (uint8_t *)
11845 &(adapter->macAddressCurrent.bytes[0]);
11846 hdd_err("client " MAC_ADDRESS_STR
11847 " is in middle of WPS/EAPOL exchange.",
11848 MAC_ADDR_ARRAY(sta_mac));
11849 if (session_id && reason) {
11850 *session_id = adapter->sessionId;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011851 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011852 }
11853 return true;
11854 }
11855 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
11856 (QDF_P2P_GO_MODE == adapter->device_mode)) {
11857 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
11858 sta_id++) {
11859 if (!((adapter->aStaInfo[sta_id].isUsed)
11860 && (OL_TXRX_PEER_STATE_CONN ==
11861 adapter->aStaInfo[sta_id].tlSTAState)))
11862 continue;
11863
11864 sta_mac = (uint8_t *)
11865 &(adapter->aStaInfo[sta_id].
11866 macAddrSTA.bytes[0]);
11867 hdd_err("client " MAC_ADDRESS_STR
11868 " of SAP/GO is in middle of WPS/EAPOL exchange",
11869 MAC_ADDR_ARRAY(sta_mac));
11870 if (session_id && reason) {
11871 *session_id = adapter->sessionId;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011872 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011873 }
11874 return true;
11875 }
11876 if (hdd_ctx->connection_in_progress) {
11877 hdd_err("AP/GO: connection is in progress");
11878 return true;
11879 }
11880 }
11881end:
11882 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
11883 adapter_node = next;
11884 }
11885 return false;
11886}
11887
11888/**
11889 * hdd_restart_sap() - to restart SAP in driver internally
11890 * @ap_adapter: Pointer to SAP hdd_adapter_t structure
11891 *
11892 * Return: None
11893 */
11894void hdd_restart_sap(hdd_adapter_t *ap_adapter)
11895{
11896 hdd_ap_ctx_t *hdd_ap_ctx;
11897 hdd_hostapd_state_t *hostapd_state;
11898 QDF_STATUS qdf_status;
11899 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
11900 tsap_Config_t *sap_config;
11901 void *sap_ctx;
11902
11903 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
11904 sap_config = &hdd_ap_ctx->sapConfig;
11905 sap_ctx = hdd_ap_ctx->sapContext;
11906
11907 mutex_lock(&hdd_ctx->sap_lock);
11908 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
11909 wlan_hdd_del_station(ap_adapter);
11910 hdd_cleanup_actionframe(hdd_ctx, ap_adapter);
11911 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
11912 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
11913 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
11914 qdf_status =
11915 qdf_wait_single_event(&hostapd_state->
11916 qdf_stop_bss_event,
11917 SME_CMD_TIMEOUT_VALUE);
11918
11919 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11920 cds_err("SAP Stop Failed");
11921 goto end;
11922 }
11923 }
11924 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011925 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011926 ap_adapter->device_mode, ap_adapter->sessionId);
11927 cds_err("SAP Stop Success");
11928
11929 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
11930 cds_err("SAP Not able to set AP IEs");
11931 wlansap_reset_sap_config_add_ie(sap_config,
11932 eUPDATE_IE_ALL);
11933 goto end;
11934 }
11935
11936 qdf_event_reset(&hostapd_state->qdf_event);
11937 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
11938 sap_config,
11939 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
11940 cds_err("SAP Start Bss fail");
11941 wlansap_reset_sap_config_add_ie(sap_config,
11942 eUPDATE_IE_ALL);
11943 goto end;
11944 }
11945
11946 cds_info("Waiting for SAP to start");
11947 qdf_status =
11948 qdf_wait_single_event(&hostapd_state->qdf_event,
11949 SME_CMD_TIMEOUT_VALUE);
11950 wlansap_reset_sap_config_add_ie(sap_config,
11951 eUPDATE_IE_ALL);
11952 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11953 cds_err("SAP Start failed");
11954 goto end;
11955 }
11956 cds_err("SAP Start Success");
11957 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
11958 if (hostapd_state->bssState == BSS_START)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011959 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
11960 ap_adapter->device_mode,
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011961 ap_adapter->sessionId);
11962 hostapd_state->bCommit = true;
11963 }
11964end:
11965 mutex_unlock(&hdd_ctx->sap_lock);
11966 return;
11967}
11968
11969/**
11970 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
11971 * with non dfs acs
11972 *
11973 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
11974 *
11975 * Return: None
11976 */
11977void hdd_check_and_restart_sap_with_non_dfs_acs(void)
11978{
11979 hdd_adapter_t *ap_adapter;
11980 hdd_context_t *hdd_ctx;
11981 cds_context_type *cds_ctx;
11982
11983 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11984 if (!hdd_ctx) {
11985 cds_err("HDD context is NULL");
11986 return;
11987 }
11988
11989 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
11990 if (!cds_ctx) {
11991 cds_err("Invalid CDS Context");
11992 return;
11993 }
11994
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080011995 if (policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc)
11996 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080011997 cds_info("Concurrency mode is not SAP");
11998 return;
11999 }
12000
12001 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070012002 if (ap_adapter != NULL && test_bit(SOFTAP_BSS_STARTED,
12003 &ap_adapter->event_flags) &&
12004 wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
12005 ap_adapter->sessionCtx.ap.operatingChannel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012006
12007 cds_warn("STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS");
12008 ap_adapter->sessionCtx.ap.sapConfig.channel =
12009 AUTO_CHANNEL_SELECT;
12010 ap_adapter->sessionCtx.ap.sapConfig.
12011 acs_cfg.acs_mode = true;
12012
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012013 hdd_restart_sap(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080012014 }
12015}
12016
12017/**
12018 * hdd_set_connection_in_progress() - to set the connection in
12019 * progress flag
12020 * @value: value to set
12021 *
12022 * This function will set the passed value to connection in progress flag.
12023 * If value is previously being set to true then no need to set it again.
12024 *
12025 * Return: true if value is being set correctly and false otherwise.
12026 */
12027bool hdd_set_connection_in_progress(bool value)
12028{
12029 bool status = true;
12030 hdd_context_t *hdd_ctx;
12031
12032 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12033 if (!hdd_ctx) {
12034 cds_err("HDD context is NULL");
12035 return false;
12036 }
12037
12038 qdf_spin_lock(&hdd_ctx->connection_status_lock);
12039 /*
12040 * if the value is set to true previously and if someone is
12041 * trying to make it true again then it could be some race
12042 * condition being triggered. Avoid this situation by returning
12043 * false
12044 */
12045 if (hdd_ctx->connection_in_progress && value)
12046 status = false;
12047 else
12048 hdd_ctx->connection_in_progress = value;
12049 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
12050 return status;
12051}
12052
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070012053int wlan_hdd_send_p2p_quota(hdd_adapter_t *adapter, int set_value)
12054{
12055 if (!adapter) {
12056 hdd_err("Invalid adapter");
12057 return -EINVAL;
12058 }
12059 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Naveen Rawat247a8682017-06-05 15:00:31 -070012060 sme_cli_set_command(adapter->sessionId,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070012061 WMA_VDEV_MCC_SET_TIME_QUOTA,
12062 set_value, VDEV_CMD);
12063 return 0;
12064
12065}
12066
12067int wlan_hdd_send_mcc_latency(hdd_adapter_t *adapter, int set_value)
12068{
12069 if (!adapter) {
12070 hdd_err("Invalid adapter");
12071 return -EINVAL;
12072 }
12073
12074 hdd_info("Send MCC latency WMA: %d", set_value);
Naveen Rawat247a8682017-06-05 15:00:31 -070012075 sme_cli_set_command(adapter->sessionId,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070012076 WMA_VDEV_MCC_SET_TIME_LATENCY,
12077 set_value, VDEV_CMD);
12078 return 0;
12079}
12080
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070012081hdd_adapter_t *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
12082 *psoc, uint8_t vdev_id)
12083{
12084 hdd_adapter_t *adapter = NULL;
12085 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12086
12087 /*
12088 * Currently PSOC is not being used. But this logic will
12089 * change once we have the converged implementation of
12090 * HDD context per PSOC in place. This would break if
12091 * multiple vdev objects reuse the vdev id.
12092 */
12093 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
12094 if (!adapter)
12095 hdd_err("Get adapter by vdev id failed");
12096
12097 return adapter;
12098}
12099
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053012100int hdd_get_rssi_snr_by_bssid(hdd_adapter_t *adapter, const uint8_t *bssid,
12101 int8_t *rssi, int8_t *snr)
12102{
12103 QDF_STATUS status;
12104 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
12105 tCsrRoamProfile *profile = &wext_state->roamProfile;
12106
12107 status = sme_get_rssi_snr_by_bssid(WLAN_HDD_GET_HAL_CTX(adapter),
12108 profile, bssid, rssi, snr);
12109 if (QDF_STATUS_SUCCESS != status) {
12110 hdd_warn("sme_get_rssi_snr_by_bssid failed");
12111 return -EINVAL;
12112 }
12113
12114 return 0;
12115}
12116
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012117/* Register the module init/exit functions */
12118module_init(hdd_module_init);
12119module_exit(hdd_module_exit);
12120
12121MODULE_LICENSE("Dual BSD/GPL");
12122MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12123MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12124
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012125module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12126 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012127
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053012128module_param_call(con_mode_ftm, con_mode_handler_ftm, param_get_int,
12129 &con_mode_ftm, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
12130
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012131module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
12132 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
12133
12134module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
12135
12136module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
12137
12138module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);