xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_main.c (revision f65bd4cf8fca8a30dcc78601a42879626d6bc7ee)
1 /*
2  * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
3  *
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 /* denote that this file does not allow legacy hddLog */
36 #define HDD_DISALLOW_LEGACY_HDDLOG 1
37 
38 /* Include Files */
39 #include <wlan_hdd_includes.h>
40 #include <cds_api.h>
41 #include <cds_sched.h>
42 #include <linux/cpu.h>
43 #include <linux/etherdevice.h>
44 #include <linux/firmware.h>
45 #include <wlan_hdd_tx_rx.h>
46 #include <wni_api.h>
47 #include <wlan_hdd_cfg.h>
48 #include <wlan_ptt_sock_svc.h>
49 #include <dbglog_host.h>
50 #include <wlan_logging_sock_svc.h>
51 #include <wlan_hdd_wowl.h>
52 #include <wlan_hdd_misc.h>
53 #include <wlan_hdd_wext.h>
54 #include "wlan_hdd_trace.h"
55 #include "wlan_hdd_ioctl.h"
56 #include "wlan_hdd_ftm.h"
57 #include "wlan_hdd_power.h"
58 #include "wlan_hdd_stats.h"
59 #include "wlan_hdd_scan.h"
60 #include "qdf_types.h"
61 #include "qdf_trace.h"
62 #include <cdp_txrx_peer_ops.h>
63 
64 #include <net/addrconf.h>
65 #include <linux/wireless.h>
66 #include <net/cfg80211.h>
67 #include <linux/inetdevice.h>
68 #include <net/addrconf.h>
69 #include "wlan_hdd_cfg80211.h"
70 #include "wlan_hdd_ext_scan.h"
71 #include "wlan_hdd_p2p.h"
72 #include <linux/rtnetlink.h>
73 #include "sap_api.h"
74 #include <linux/semaphore.h>
75 #include <linux/ctype.h>
76 #include <linux/compat.h>
77 #ifdef MSM_PLATFORM
78 #include <soc/qcom/subsystem_restart.h>
79 #endif
80 #include <wlan_hdd_hostapd.h>
81 #include <wlan_hdd_softap_tx_rx.h>
82 #include "cfg_api.h"
83 #include "qwlan_version.h"
84 #include "wma_types.h"
85 #include "wlan_hdd_tdls.h"
86 #ifdef FEATURE_WLAN_CH_AVOID
87 #include "cds_regdomain.h"
88 #include "cdp_txrx_flow_ctrl_v2.h"
89 #endif /* FEATURE_WLAN_CH_AVOID */
90 #include "pld_common.h"
91 #include "wlan_hdd_ocb.h"
92 #include "wlan_hdd_nan.h"
93 #include "wlan_hdd_debugfs.h"
94 #include "wlan_hdd_driver_ops.h"
95 #include "epping_main.h"
96 #include "wlan_hdd_memdump.h"
97 
98 #include <wlan_hdd_ipa.h>
99 #include "hif.h"
100 #include "wma.h"
101 #include "cds_concurrency.h"
102 #include "wlan_hdd_tsf.h"
103 #include "wlan_hdd_green_ap.h"
104 #include "bmi.h"
105 #include <wlan_hdd_regulatory.h>
106 #include "ol_rx_fwd.h"
107 #include "wlan_hdd_lpass.h"
108 #include "nan_api.h"
109 #include <wlan_hdd_napi.h>
110 #include "wlan_hdd_disa.h"
111 #include <dispatcher_init_deinit.h>
112 
113 #ifdef MODULE
114 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
115 #else
116 #define WLAN_MODULE_NAME  "wlan"
117 #endif
118 
119 #ifdef TIMER_MANAGER
120 #define TIMER_MANAGER_STR " +TIMER_MANAGER"
121 #else
122 #define TIMER_MANAGER_STR ""
123 #endif
124 
125 #ifdef MEMORY_DEBUG
126 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
127 #else
128 #define MEMORY_DEBUG_STR ""
129 #endif
130 
131 #ifndef MODULE
132 static struct gwlan_loader *wlan_loader;
133 static ssize_t wlan_boot_cb(struct kobject *kobj,
134 			    struct kobj_attribute *attr,
135 			    const char *buf, size_t count);
136 struct gwlan_loader {
137 	bool loaded_state;
138 	struct kobject *boot_wlan_obj;
139 	struct attribute_group *attr_group;
140 };
141 
142 static struct kobj_attribute wlan_boot_attribute =
143 	__ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
144 
145 static struct attribute *attrs[] = {
146 	&wlan_boot_attribute.attr,
147 	NULL,
148 };
149 
150 #define MODULE_INITIALIZED 1
151 #endif
152 
153 /* the Android framework expects this param even though we don't use it */
154 #define BUF_LEN 20
155 static char fwpath_buffer[BUF_LEN];
156 static struct kparam_string fwpath = {
157 	.string = fwpath_buffer,
158 	.maxlen = BUF_LEN,
159 };
160 
161 static char *country_code;
162 static int enable_11d = -1;
163 static int enable_dfs_chan_scan = -1;
164 
165 /*
166  * spinlock for synchronizing asynchronous request/response
167  * (full description of use in wlan_hdd_main.h)
168  */
169 DEFINE_SPINLOCK(hdd_context_lock);
170 
171 #define WLAN_NLINK_CESIUM 30
172 
173 static qdf_wake_lock_t wlan_wake_lock;
174 
175 #define WOW_MAX_FILTER_LISTS 1
176 #define WOW_MAX_FILTERS_PER_LIST 4
177 #define WOW_MIN_PATTERN_SIZE 6
178 #define WOW_MAX_PATTERN_SIZE 64
179 
180 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
181 static const struct wiphy_wowlan_support wowlan_support_reg_init = {
182 	.flags = WIPHY_WOWLAN_ANY |
183 		 WIPHY_WOWLAN_MAGIC_PKT |
184 		 WIPHY_WOWLAN_DISCONNECT |
185 		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
186 		 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
187 		 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
188 		 WIPHY_WOWLAN_4WAY_HANDSHAKE |
189 		 WIPHY_WOWLAN_RFKILL_RELEASE,
190 	.n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
191 	.pattern_min_len = WOW_MIN_PATTERN_SIZE,
192 	.pattern_max_len = WOW_MAX_PATTERN_SIZE,
193 };
194 #endif
195 
196 /* internal function declaration */
197 
198 struct sock *cesium_nl_srv_sock;
199 
200 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
201 void wlan_hdd_auto_shutdown_cb(void);
202 #endif
203 
204 /**
205  * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
206  * @hdd_ctx: pointer to hdd_context_t
207  *
208  * Return: none
209  */
210 static void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx)
211 {
212 	hdd_adapter_t *adapter;
213 	hdd_adapter_list_node_t *adapter_node, *next;
214 	QDF_STATUS status = QDF_STATUS_SUCCESS;
215 
216 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
217 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
218 		adapter = adapter_node->pAdapter;
219 		if (NULL != adapter)
220 			hdd_send_rps_ind(adapter);
221 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
222 		adapter_node = next;
223 	}
224 }
225 
226 /**
227  * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
228  * @vdev_id: vdev_id
229  * @action: action type
230  * @reason: reason type
231  *
232  * Return: none
233  */
234 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
235 		enum netif_action_type action, enum netif_reason_type reason)
236 {
237 	hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
238 	hdd_adapter_t *adapter;
239 
240 	if (!hdd_ctx) {
241 		hdd_err("hdd ctx is NULL");
242 		return;
243 	}
244 	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
245 
246 	wlan_hdd_netif_queue_control(adapter, action, reason);
247 	return;
248 }
249 
250 /*
251  * Store WLAN driver version info in a global variable such that crash debugger
252  * can extract it from driver debug symbol and crashdump for post processing
253  */
254 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;
255 
256 /**
257  * hdd_device_mode_to_string() - return string conversion of device mode
258  * @device_mode: device mode
259  *
260  * This utility function helps log string conversion of device mode.
261  *
262  * Return: string conversion of device mode, if match found;
263  *	   "Unknown" otherwise.
264  */
265 const char *hdd_device_mode_to_string(uint8_t device_mode)
266 {
267 	switch (device_mode) {
268 	CASE_RETURN_STRING(QDF_STA_MODE);
269 	CASE_RETURN_STRING(QDF_SAP_MODE);
270 	CASE_RETURN_STRING(QDF_P2P_CLIENT_MODE);
271 	CASE_RETURN_STRING(QDF_P2P_GO_MODE);
272 	CASE_RETURN_STRING(QDF_FTM_MODE);
273 	CASE_RETURN_STRING(QDF_IBSS_MODE);
274 	CASE_RETURN_STRING(QDF_P2P_DEVICE_MODE);
275 	CASE_RETURN_STRING(QDF_OCB_MODE);
276 	CASE_RETURN_STRING(QDF_NDI_MODE);
277 	default:
278 		return "Unknown";
279 	}
280 }
281 
282 /**
283  * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
284  * @adapter: HDD adapter
285  * @chan_number: Channel number
286  * @chan_bw: Bandwidth
287  *
288  * Checks if the given bandwidth is valid for the given channel number.
289  *
290  * Return: 0 for success, non-zero for failure
291  */
292 int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
293 		uint32_t chan_number,
294 		enum phy_ch_width chan_bw)
295 {
296 	uint8_t chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
297 	uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN, i;
298 	bool found = false;
299 	tHalHandle hal;
300 
301 	hal = WLAN_HDD_GET_HAL_CTX(adapter);
302 	if (!hal) {
303 		hdd_err("Invalid HAL context");
304 		return -EINVAL;
305 	}
306 
307 	if (0 != sme_cfg_get_str(hal, WNI_CFG_VALID_CHANNEL_LIST, chan, &len)) {
308 		hdd_err("No valid channel list");
309 		return -EOPNOTSUPP;
310 	}
311 
312 	for (i = 0; i < len; i++) {
313 		if (chan[i] == chan_number) {
314 			found = true;
315 			break;
316 		}
317 	}
318 
319 	if (found == false) {
320 		hdd_err("Channel not in driver's valid channel list");
321 		return -EOPNOTSUPP;
322 	}
323 
324 	if ((!CDS_IS_CHANNEL_24GHZ(chan_number)) &&
325 			(!CDS_IS_CHANNEL_5GHZ(chan_number))) {
326 		hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
327 		return -EINVAL;
328 	}
329 
330 	if (CDS_IS_CHANNEL_24GHZ(chan_number)) {
331 		if (chan_bw == CH_WIDTH_80MHZ) {
332 			hdd_err("BW80 not possible in 2.4GHz band");
333 			return -EINVAL;
334 		}
335 		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
336 				(chan_bw != CH_WIDTH_MAX)) {
337 			hdd_err("Only BW20 possible on channel 14");
338 			return -EINVAL;
339 		}
340 	}
341 
342 	if (CDS_IS_CHANNEL_5GHZ(chan_number)) {
343 		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
344 				(chan_bw != CH_WIDTH_MAX)) {
345 			hdd_err("Only BW20 possible on channel 165");
346 			return -EINVAL;
347 		}
348 	}
349 
350 	return 0;
351 }
352 
353 static int __hdd_netdev_notifier_call(struct notifier_block *nb,
354 				    unsigned long state, void *data)
355 {
356 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
357 	struct netdev_notifier_info *dev_notif_info = data;
358 	struct net_device *dev = dev_notif_info->dev;
359 #else
360 	struct net_device *dev = data;
361 #endif
362 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
363 	hdd_context_t *hdd_ctx;
364 
365 	ENTER_DEV(dev);
366 
367 	/* Make sure that this callback corresponds to our device. */
368 	if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
369 		return NOTIFY_DONE;
370 
371 	if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) &&
372 	    (adapter->dev != dev)) {
373 		hdd_err("device adapter is not matching!!!");
374 		return NOTIFY_DONE;
375 	}
376 
377 	if (!dev->ieee80211_ptr) {
378 		hdd_err("ieee80211_ptr is NULL!!!");
379 		return NOTIFY_DONE;
380 	}
381 
382 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
383 	if (NULL == hdd_ctx) {
384 		hdd_alert("HDD Context Null Pointer");
385 		QDF_ASSERT(0);
386 		return NOTIFY_DONE;
387 	}
388 	if (cds_is_driver_recovering())
389 		return NOTIFY_DONE;
390 
391 	hdd_notice("%s New Net Device State = %lu",
392 	       dev->name, state);
393 
394 	switch (state) {
395 	case NETDEV_REGISTER:
396 		break;
397 
398 	case NETDEV_UNREGISTER:
399 		break;
400 
401 	case NETDEV_UP:
402 		sme_ch_avoid_update_req(hdd_ctx->hHal);
403 		break;
404 
405 	case NETDEV_DOWN:
406 		break;
407 
408 	case NETDEV_CHANGE:
409 		if (true == adapter->isLinkUpSvcNeeded)
410 			complete(&adapter->linkup_event_var);
411 		break;
412 
413 	case NETDEV_GOING_DOWN:
414 		if (adapter->scan_info.mScanPending != false) {
415 			unsigned long rc;
416 			INIT_COMPLETION(adapter->scan_info.
417 					abortscan_event_var);
418 			hdd_abort_mac_scan(adapter->pHddCtx,
419 					   adapter->sessionId,
420 					   eCSR_SCAN_ABORT_DEFAULT);
421 			rc = wait_for_completion_timeout(
422 				&adapter->scan_info.abortscan_event_var,
423 				msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
424 			if (!rc) {
425 				hdd_err("Timeout occurred while waiting for abortscan");
426 			}
427 		} else {
428 			hdd_notice("Scan is not Pending from user");
429 		}
430 		break;
431 
432 	default:
433 		break;
434 	}
435 
436 	return NOTIFY_DONE;
437 }
438 
439 /**
440  * hdd_netdev_notifier_call() - netdev notifier callback function
441  * @nb: pointer to notifier block
442  * @state: state
443  * @ndev: ndev pointer
444  *
445  * Return: 0 on success, error number otherwise.
446  */
447 static int hdd_netdev_notifier_call(struct notifier_block *nb,
448 					unsigned long state,
449 					void *ndev)
450 {
451 	int ret;
452 
453 	cds_ssr_protect(__func__);
454 	ret = __hdd_netdev_notifier_call(nb, state, ndev);
455 	cds_ssr_unprotect(__func__);
456 
457 	return ret;
458 }
459 
460 struct notifier_block hdd_netdev_notifier = {
461 	.notifier_call = hdd_netdev_notifier_call,
462 };
463 
464 /* variable to hold the insmod parameters */
465 static int con_mode;
466 
467 /* Variable to hold connection mode including module parameter con_mode */
468 static int curr_con_mode;
469 
470 /**
471  * hdd_map_nl_chan_width() - Map NL channel width to internal representation
472  * @ch_width: NL channel width
473  *
474  * Converts the NL channel width to the driver's internal representation
475  *
476  * Return: Converted channel width. In case of non matching NL channel width,
477  * CH_WIDTH_MAX will be returned.
478  */
479 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
480 {
481 	switch (ch_width) {
482 	case NL80211_CHAN_WIDTH_20_NOHT:
483 	case NL80211_CHAN_WIDTH_20:
484 		return CH_WIDTH_20MHZ;
485 	case NL80211_CHAN_WIDTH_40:
486 		return CH_WIDTH_40MHZ;
487 		break;
488 	case NL80211_CHAN_WIDTH_80:
489 		return CH_WIDTH_80MHZ;
490 	case NL80211_CHAN_WIDTH_80P80:
491 		return CH_WIDTH_80P80MHZ;
492 	case NL80211_CHAN_WIDTH_160:
493 		return CH_WIDTH_160MHZ;
494 	case NL80211_CHAN_WIDTH_5:
495 		return CH_WIDTH_5MHZ;
496 	case NL80211_CHAN_WIDTH_10:
497 		return CH_WIDTH_10MHZ;
498 	default:
499 		hdd_err("Invalid channel width %d, setting to default",
500 				ch_width);
501 		return CH_WIDTH_INVALID;
502 	}
503 }
504 
505 /* wlan_hdd_find_opclass() - Find operating class for a channel
506  * @hal: handler to HAL
507  * @channel: channel id
508  * @bw_offset: bandwidth offset
509  *
510  * Function invokes sme api to find the operating class
511  *
512  * Return: operating class
513  */
514 uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
515 				uint8_t bw_offset)
516 {
517 	uint8_t opclass = 0;
518 
519 	sme_get_opclass(hal, channel, bw_offset, &opclass);
520 	return opclass;
521 }
522 
523 /**
524  * hdd_qdf_trace_enable() - configure initial QDF Trace enable
525  * @moduleId:	Module whose trace level is being configured
526  * @bitmask:	Bitmask of log levels to be enabled
527  *
528  * Called immediately after the cfg.ini is read in order to configure
529  * the desired trace levels.
530  *
531  * Return: None
532  */
533 static void hdd_qdf_trace_enable(QDF_MODULE_ID moduleId, uint32_t bitmask)
534 {
535 	QDF_TRACE_LEVEL level;
536 
537 	/*
538 	 * if the bitmask is the default value, then a bitmask was not
539 	 * specified in cfg.ini, so leave the logging level alone (it
540 	 * will remain at the "compiled in" default value)
541 	 */
542 	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) {
543 		return;
544 	}
545 
546 	/* a mask was specified.  start by disabling all logging */
547 	qdf_trace_set_value(moduleId, QDF_TRACE_LEVEL_NONE, 0);
548 
549 	/* now cycle through the bitmask until all "set" bits are serviced */
550 	level = QDF_TRACE_LEVEL_FATAL;
551 	while (0 != bitmask) {
552 		if (bitmask & 1) {
553 			qdf_trace_set_value(moduleId, level, 1);
554 		}
555 		level++;
556 		bitmask >>= 1;
557 	}
558 }
559 
560 /**
561  * wlan_hdd_validate_context() - check the HDD context
562  * @hdd_ctx:	HDD context pointer
563  *
564  * Return: 0 if the context is valid. Error code otherwise
565  */
566 int wlan_hdd_validate_context(hdd_context_t *hdd_ctx)
567 {
568 	if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
569 		hdd_err("%pS HDD context is Null", (void *)_RET_IP_);
570 		return -ENODEV;
571 	}
572 
573 	if (cds_is_driver_recovering()) {
574 		hdd_err("%pS Recovery in Progress. State: 0x%x Ignore!!!",
575 			(void *)_RET_IP_, cds_get_driver_state());
576 		return -EAGAIN;
577 	}
578 
579 	if (cds_is_load_or_unload_in_progress()) {
580 		hdd_err("%pS Unloading/Loading in Progress. Ignore!!!: 0x%x",
581 			(void *)_RET_IP_, cds_get_driver_state());
582 		return -EAGAIN;
583 	}
584 
585 	if (hdd_ctx->start_modules_in_progress ||
586 	    hdd_ctx->stop_modules_in_progress) {
587 			hdd_err("%pS Start/Stop Modules in progress. Ignore!!!",
588 				(void *)_RET_IP_);
589 		return -EAGAIN;
590 	}
591 
592 	return 0;
593 }
594 
595 /**
596  * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
597  * @hdd_adapter_t Hdd adapter.
598  *
599  * This function sets the IBSS power save config parameters to WMA
600  * which will send it to firmware if FW supports IBSS power save
601  * before vdev start.
602  *
603  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
604  *         on failure.
605  */
606 QDF_STATUS hdd_set_ibss_power_save_params(hdd_adapter_t *adapter)
607 {
608 	int ret;
609 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
610 
611 	if (hdd_ctx == NULL) {
612 		hdd_err("HDD context is null");
613 		return QDF_STATUS_E_FAILURE;
614 	}
615 
616 	ret = wma_cli_set_command(adapter->sessionId,
617 				  WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
618 				  hdd_ctx->config->ibssATIMWinSize,
619 				  VDEV_CMD);
620 	if (0 != ret) {
621 		hdd_err("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d", ret);
622 		return QDF_STATUS_E_FAILURE;
623 	}
624 
625 	ret = wma_cli_set_command(adapter->sessionId,
626 				  WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
627 				  hdd_ctx->config->isIbssPowerSaveAllowed,
628 				  VDEV_CMD);
629 	if (0 != ret) {
630 		hdd_err("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d",
631 			ret);
632 		return QDF_STATUS_E_FAILURE;
633 	}
634 
635 	ret = wma_cli_set_command(adapter->sessionId,
636 				  WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
637 				  hdd_ctx->config->
638 				  isIbssPowerCollapseAllowed, VDEV_CMD);
639 	if (0 != ret) {
640 		hdd_err("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d",
641 			ret);
642 		return QDF_STATUS_E_FAILURE;
643 	}
644 
645 	ret = wma_cli_set_command(adapter->sessionId,
646 				  WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
647 				  hdd_ctx->config->isIbssAwakeOnTxRx,
648 				  VDEV_CMD);
649 	if (0 != ret) {
650 		hdd_err("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d", ret);
651 		return QDF_STATUS_E_FAILURE;
652 	}
653 
654 	ret = wma_cli_set_command(adapter->sessionId,
655 				  WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
656 				  hdd_ctx->config->ibssInactivityCount,
657 				  VDEV_CMD);
658 	if (0 != ret) {
659 		hdd_err("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d", ret);
660 		return QDF_STATUS_E_FAILURE;
661 	}
662 
663 	ret = wma_cli_set_command(adapter->sessionId,
664 				  WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
665 				  hdd_ctx->config->ibssTxSpEndInactivityTime,
666 				  VDEV_CMD);
667 	if (0 != ret) {
668 		hdd_err("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d",
669 			ret);
670 		return QDF_STATUS_E_FAILURE;
671 	}
672 
673 	ret = wma_cli_set_command(adapter->sessionId,
674 				  WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
675 				  hdd_ctx->config->ibssPsWarmupTime,
676 				  VDEV_CMD);
677 	if (0 != ret) {
678 		hdd_err("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d",
679 			ret);
680 		return QDF_STATUS_E_FAILURE;
681 	}
682 
683 	ret = wma_cli_set_command(adapter->sessionId,
684 				  WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
685 				  hdd_ctx->config->ibssPs1RxChainInAtimEnable,
686 				  VDEV_CMD);
687 	if (0 != ret) {
688 		hdd_err("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d",
689 			ret);
690 		return QDF_STATUS_E_FAILURE;
691 	}
692 
693 	return QDF_STATUS_SUCCESS;
694 }
695 
696 #define INTF_MACADDR_MASK       0x7
697 
698 /**
699  * hdd_update_macaddr() - update mac address
700  * @config:	hdd configuration
701  * @hw_macaddr:	mac address
702  *
703  * Mac address for multiple virtual interface is found as following
704  * i) The mac address of the first interface is just the actual hw mac address.
705  * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
706  *     define the mac address for the remaining interfaces and locally
707  *     admistered bit is set. INTF_MACADDR_MASK is based on the number of
708  *     supported virtual interfaces, right now this is 0x07 (meaning 8
709  *     interface).
710  *     Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
711  *     for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
712  *
713  * Return: None
714  */
715 void hdd_update_macaddr(struct hdd_config *config,
716 			struct qdf_mac_addr hw_macaddr)
717 {
718 	int8_t i;
719 	uint8_t macaddr_b3, tmp_br3;
720 
721 	qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
722 		     QDF_MAC_ADDR_SIZE);
723 	for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
724 		qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
725 			     QDF_MAC_ADDR_SIZE);
726 		macaddr_b3 = config->intfMacAddr[i].bytes[3];
727 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
728 			  INTF_MACADDR_MASK;
729 		macaddr_b3 += tmp_br3;
730 
731 		/* XOR-ing bit-24 of the mac address. This will give enough
732 		 * mac address range before collision
733 		 */
734 		macaddr_b3 ^= (1 << 7);
735 
736 		/* Set locally administered bit */
737 		config->intfMacAddr[i].bytes[0] |= 0x02;
738 		config->intfMacAddr[i].bytes[3] = macaddr_b3;
739 		hdd_notice("config->intfMacAddr[%d]: "
740 		       MAC_ADDRESS_STR, i,
741 		       MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
742 	}
743 }
744 
745 static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
746 				    struct wma_tgt_services *cfg)
747 {
748 	struct hdd_config *config = hdd_ctx->config;
749 
750 	/* Set up UAPSD */
751 	config->apUapsdEnabled &= cfg->uapsd;
752 
753 	/* 11AC mode support */
754 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
755 	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
756 		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
757 
758 	/* ARP offload: override user setting if invalid  */
759 	config->fhostArpOffload &= cfg->arp_offload;
760 
761 #ifdef FEATURE_WLAN_SCAN_PNO
762 	/* PNO offload */
763 	hdd_info("PNO Capability in f/w = %d", cfg->pno_offload);
764 	if (cfg->pno_offload)
765 		config->PnoOffload = true;
766 #endif
767 #ifdef FEATURE_WLAN_TDLS
768 	config->fEnableTDLSSupport &= cfg->en_tdls;
769 	config->fEnableTDLSOffChannel = config->fEnableTDLSOffChannel &&
770 						cfg->en_tdls_offchan;
771 	config->fEnableTDLSBufferSta = config->fEnableTDLSBufferSta &&
772 						cfg->en_tdls_uapsd_buf_sta;
773 	if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta) {
774 		config->fEnableTDLSSleepSta = true;
775 	} else {
776 		config->fEnableTDLSSleepSta = false;
777 	}
778 #endif
779 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
780 	config->isRoamOffloadEnabled &= cfg->en_roam_offload;
781 #endif
782 	sme_update_tgt_services(hdd_ctx->hHal, cfg);
783 
784 }
785 
786 /**
787  * hdd_update_vdev_nss() - sets the vdev nss
788  * @hdd_ctx: HDD context
789  *
790  * Sets the Nss per vdev type based on INI
791  *
792  * Return: None
793  */
794 static void hdd_update_vdev_nss(hdd_context_t *hdd_ctx)
795 {
796 	struct hdd_config *cfg_ini = hdd_ctx->config;
797 	uint8_t max_supp_nss = 1;
798 
799 	if (cfg_ini->enable2x2)
800 		max_supp_nss = 2;
801 
802 	sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
803 			cfg_ini->vdev_type_nss_2g, eCSR_BAND_24);
804 
805 	sme_update_vdev_type_nss(hdd_ctx->hHal, max_supp_nss,
806 			cfg_ini->vdev_type_nss_5g, eCSR_BAND_5G);
807 }
808 
809 static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
810 				  struct wma_tgt_ht_cap *cfg)
811 {
812 	QDF_STATUS status;
813 	uint32_t value, val32;
814 	uint16_t val16;
815 	struct hdd_config *pconfig = hdd_ctx->config;
816 	tSirMacHTCapabilityInfo *phtCapInfo;
817 	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
818 	uint8_t enable_tx_stbc;
819 
820 	/* check and update RX STBC */
821 	if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
822 		pconfig->enableRxSTBC = cfg->ht_rx_stbc;
823 
824 	/* get the MPDU density */
825 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);
826 
827 	if (status != QDF_STATUS_SUCCESS) {
828 		hdd_err("could not get MPDU DENSITY");
829 		value = 0;
830 	}
831 
832 	/*
833 	 * MPDU density:
834 	 * override user's setting if value is larger
835 	 * than the one supported by target
836 	 */
837 	if (value > cfg->mpdu_density) {
838 		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
839 					 cfg->mpdu_density);
840 
841 		if (status == QDF_STATUS_E_FAILURE)
842 			hdd_alert("could not set MPDU DENSITY to CCM");
843 	}
844 
845 	/* get the HT capability info */
846 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
847 	if (QDF_STATUS_SUCCESS != status) {
848 		hdd_err("could not get HT capability info");
849 		return;
850 	}
851 	val16 = (uint16_t) val32;
852 	phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;
853 
854 	/* Set the LDPC capability */
855 	phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;
856 
857 	if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
858 		pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;
859 
860 	if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
861 		pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;
862 
863 	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
864 	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
865 
866 	enable_tx_stbc = pconfig->enableTxSTBC;
867 
868 	if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
869 		pconfig->enable2x2 = 1;
870 	} else {
871 		pconfig->enable2x2 = 0;
872 		enable_tx_stbc = 0;
873 
874 		/* 1x1 */
875 		/* Update Rx Highest Long GI data Rate */
876 		if (sme_cfg_set_int(hdd_ctx->hHal,
877 				    WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
878 				    VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
879 				== QDF_STATUS_E_FAILURE) {
880 			hdd_err("Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM");
881 		}
882 
883 		/* Update Tx Highest Long GI data Rate */
884 		if (sme_cfg_set_int
885 			    (hdd_ctx->hHal,
886 			     WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
887 			     VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
888 			    QDF_STATUS_E_FAILURE) {
889 			hdd_err("VHT_TX_HIGHEST_SUPP_RATE_1_1 to CCM fail");
890 		}
891 	}
892 	if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
893 		enable_tx_stbc = 0;
894 	phtCapInfo->txSTBC = enable_tx_stbc;
895 
896 	val32 = val16;
897 	status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
898 	if (status != QDF_STATUS_SUCCESS)
899 		hdd_alert("could not set HT capability to CCM");
900 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
901 	value = SIZE_OF_SUPPORTED_MCS_SET;
902 	if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
903 			    &value) == QDF_STATUS_SUCCESS) {
904 		hdd_notice("Read MCS rate set");
905 
906 		if (pconfig->enable2x2) {
907 			for (value = 0; value < cfg->num_rf_chains; value++)
908 				mcs_set[value] =
909 					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
910 
911 			status =
912 				sme_cfg_set_str(hdd_ctx->hHal,
913 						WNI_CFG_SUPPORTED_MCS_SET,
914 						mcs_set,
915 						SIZE_OF_SUPPORTED_MCS_SET);
916 			if (status == QDF_STATUS_E_FAILURE)
917 				hdd_alert("could not set MCS SET to CCM");
918 		}
919 	}
920 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
921 }
922 
923 static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
924 				   struct wma_tgt_vht_cap *cfg)
925 {
926 	QDF_STATUS status;
927 	uint32_t value = 0;
928 	struct hdd_config *pconfig = hdd_ctx->config;
929 	struct wiphy *wiphy = hdd_ctx->wiphy;
930 	struct ieee80211_supported_band *band_5g =
931 		wiphy->bands[NL80211_BAND_5GHZ];
932 	uint32_t temp = 0;
933 
934 	if (!band_5g) {
935 		hdd_info("5GHz band disabled, skipping capability population");
936 		return;
937 	}
938 
939 	/* Get the current MPDU length */
940 	status =
941 		sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
942 				&value);
943 
944 	if (status != QDF_STATUS_SUCCESS) {
945 		hdd_err("could not get MPDU LENGTH");
946 		value = 0;
947 	}
948 
949 	/*
950 	 * VHT max MPDU length:
951 	 * override if user configured value is too high
952 	 * that the target cannot support
953 	 */
954 	if (value > cfg->vht_max_mpdu) {
955 		status = sme_cfg_set_int(hdd_ctx->hHal,
956 					 WNI_CFG_VHT_MAX_MPDU_LENGTH,
957 					 cfg->vht_max_mpdu);
958 
959 		if (status == QDF_STATUS_E_FAILURE) {
960 			hdd_alert("could not set VHT MAX MPDU LENGTH");
961 		}
962 	}
963 
964 	/* Get the current supported chan width */
965 	status = sme_cfg_get_int(hdd_ctx->hHal,
966 				WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
967 				&value);
968 
969 	if (status != QDF_STATUS_SUCCESS) {
970 		hdd_err("could not get MPDU LENGTH");
971 		value = 0;
972 	}
973 
974 	sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp);
975 	temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
976 
977 	if (pconfig->enable2x2)
978 		temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
979 
980 	if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, temp) ==
981 				QDF_STATUS_E_FAILURE) {
982 		hdd_err("Could not pass VHT_BASIC_MCS_SET to CCM");
983 	}
984 
985 	sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp);
986 	temp = (temp & VHT_MCS_1x1) | pconfig->vhtRxMCS;
987 	if (pconfig->enable2x2)
988 		temp = (temp & VHT_MCS_2x2) | (pconfig->vhtRxMCS2x2 << 2);
989 
990 	if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, temp) ==
991 			QDF_STATUS_E_FAILURE) {
992 		hdd_err("Could not pass WNI_CFG_VHT_RX_MCS_MAP to CCM");
993 	}
994 
995 	sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp);
996 	temp = (temp & VHT_MCS_1x1) | pconfig->vhtTxMCS;
997 	if (pconfig->enable2x2)
998 		temp = (temp & VHT_MCS_2x2) | (pconfig->vhtTxMCS2x2 << 2);
999 
1000 	hdd_info("vhtRxMCS2x2 - %x temp - %u enable2x2 %d",
1001 			pconfig->vhtRxMCS2x2, temp, pconfig->enable2x2);
1002 
1003 	if (sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, temp) ==
1004 			QDF_STATUS_E_FAILURE) {
1005 		hdd_err("Could not pass WNI_CFG_VHT_TX_MCS_MAP to CCM");
1006 	}
1007 	/* Get the current RX LDPC setting */
1008 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
1009 				&value);
1010 
1011 	if (status != QDF_STATUS_SUCCESS) {
1012 		hdd_err("could not get VHT LDPC CODING CAP");
1013 		value = 0;
1014 	}
1015 
1016 	/* Set the LDPC capability */
1017 	if (value && !cfg->vht_rx_ldpc) {
1018 		status = sme_cfg_set_int(hdd_ctx->hHal,
1019 					 WNI_CFG_VHT_LDPC_CODING_CAP,
1020 					 cfg->vht_rx_ldpc);
1021 
1022 		if (status == QDF_STATUS_E_FAILURE) {
1023 			hdd_alert("could not set VHT LDPC CODING CAP to CCM");
1024 		}
1025 	}
1026 
1027 	/* Get current GI 80 value */
1028 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
1029 				&value);
1030 
1031 	if (status != QDF_STATUS_SUCCESS) {
1032 		hdd_err("could not get SHORT GI 80MHZ");
1033 		value = 0;
1034 	}
1035 
1036 	/* set the Guard interval 80MHz */
1037 	if (value && !cfg->vht_short_gi_80) {
1038 		status = sme_cfg_set_int(hdd_ctx->hHal,
1039 					 WNI_CFG_VHT_SHORT_GI_80MHZ,
1040 					 cfg->vht_short_gi_80);
1041 
1042 		if (status == QDF_STATUS_E_FAILURE) {
1043 			hdd_alert("could not set SHORT GI 80MHZ to CCM");
1044 		}
1045 	}
1046 
1047 	/* Get current GI 160 value */
1048 	status = sme_cfg_get_int(hdd_ctx->hHal,
1049 				 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
1050 				 &value);
1051 
1052 	if (status != QDF_STATUS_SUCCESS) {
1053 		hdd_err("could not get SHORT GI 80 & 160");
1054 		value = 0;
1055 	}
1056 
1057 	/* Get VHT TX STBC cap */
1058 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);
1059 
1060 	if (status != QDF_STATUS_SUCCESS) {
1061 		hdd_err("could not get VHT TX STBC");
1062 		value = 0;
1063 	}
1064 
1065 	/* VHT TX STBC cap */
1066 	if (value && !cfg->vht_tx_stbc) {
1067 		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
1068 					 cfg->vht_tx_stbc);
1069 
1070 		if (status == QDF_STATUS_E_FAILURE) {
1071 			hdd_alert("could not set the VHT TX STBC to CCM");
1072 		}
1073 	}
1074 
1075 	/* Get VHT RX STBC cap */
1076 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);
1077 
1078 	if (status != QDF_STATUS_SUCCESS) {
1079 		hdd_err("could not get VHT RX STBC");
1080 		value = 0;
1081 	}
1082 
1083 	/* VHT RX STBC cap */
1084 	if (value && !cfg->vht_rx_stbc) {
1085 		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
1086 					 cfg->vht_rx_stbc);
1087 
1088 		if (status == QDF_STATUS_E_FAILURE) {
1089 			hdd_alert("could not set the VHT RX STBC to CCM");
1090 		}
1091 	}
1092 
1093 	/* Get VHT SU Beamformer cap */
1094 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1095 				 &value);
1096 
1097 	if (status != QDF_STATUS_SUCCESS) {
1098 		hdd_err("could not get VHT SU BEAMFORMER CAP");
1099 		value = 0;
1100 	}
1101 
1102 	/* set VHT SU Beamformer cap */
1103 	if (value && !cfg->vht_su_bformer) {
1104 		status = sme_cfg_set_int(hdd_ctx->hHal,
1105 					 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
1106 					 cfg->vht_su_bformer);
1107 
1108 		if (status == QDF_STATUS_E_FAILURE) {
1109 			hdd_alert("could not set VHT SU BEAMFORMER CAP");
1110 		}
1111 	}
1112 
1113 	/* check and update SU BEAMFORMEE capabality */
1114 	if (pconfig->enableTxBF && !cfg->vht_su_bformee)
1115 		pconfig->enableTxBF = cfg->vht_su_bformee;
1116 
1117 	status = sme_cfg_set_int(hdd_ctx->hHal,
1118 				 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1119 				 pconfig->enableTxBF);
1120 
1121 	if (status == QDF_STATUS_E_FAILURE) {
1122 		hdd_alert("could not set VHT SU BEAMFORMEE CAP");
1123 	}
1124 
1125 	/* Get VHT MU Beamformer cap */
1126 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1127 				 &value);
1128 
1129 	if (status != QDF_STATUS_SUCCESS) {
1130 		hdd_err("could not get VHT MU BEAMFORMER CAP");
1131 		value = 0;
1132 	}
1133 
1134 	/* set VHT MU Beamformer cap */
1135 	if (value && !cfg->vht_mu_bformer) {
1136 		status = sme_cfg_set_int(hdd_ctx->hHal,
1137 					 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
1138 					 cfg->vht_mu_bformer);
1139 
1140 		if (status == QDF_STATUS_E_FAILURE) {
1141 			hdd_alert("could not set the VHT MU BEAMFORMER CAP to CCM");
1142 		}
1143 	}
1144 
1145 	/* Get VHT MU Beamformee cap */
1146 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1147 				 &value);
1148 
1149 	if (status != QDF_STATUS_SUCCESS) {
1150 		hdd_err("could not get VHT MU BEAMFORMEE CAP");
1151 		value = 0;
1152 	}
1153 
1154 	/* set VHT MU Beamformee cap */
1155 	if (value && !cfg->vht_mu_bformee) {
1156 		status = sme_cfg_set_int(hdd_ctx->hHal,
1157 					 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
1158 					 cfg->vht_mu_bformee);
1159 
1160 		if (status == QDF_STATUS_E_FAILURE) {
1161 			hdd_alert("could not set VHT MU BEAMFORMER CAP");
1162 		}
1163 	}
1164 
1165 	/* Get VHT MAX AMPDU Len exp */
1166 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1167 				 &value);
1168 
1169 	if (status != QDF_STATUS_SUCCESS) {
1170 		hdd_err("could not get VHT AMPDU LEN");
1171 		value = 0;
1172 	}
1173 
1174 	/*
1175 	 * VHT max AMPDU len exp:
1176 	 * override if user configured value is too high
1177 	 * that the target cannot support.
1178 	 * Even though Rome publish ampdu_len=7, it can
1179 	 * only support 4 because of some h/w bug.
1180 	 */
1181 
1182 	if (value > cfg->vht_max_ampdu_len_exp) {
1183 		status = sme_cfg_set_int(hdd_ctx->hHal,
1184 					 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
1185 					 cfg->vht_max_ampdu_len_exp);
1186 
1187 		if (status == QDF_STATUS_E_FAILURE) {
1188 			hdd_alert("could not set the VHT AMPDU LEN EXP");
1189 		}
1190 	}
1191 
1192 	/* Get VHT TXOP PS CAP */
1193 	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);
1194 
1195 	if (status != QDF_STATUS_SUCCESS) {
1196 		hdd_err("could not get VHT TXOP PS");
1197 		value = 0;
1198 	}
1199 
1200 	/* set VHT TXOP PS cap */
1201 	if (value && !cfg->vht_txop_ps) {
1202 		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
1203 					 cfg->vht_txop_ps);
1204 
1205 		if (status == QDF_STATUS_E_FAILURE) {
1206 			hdd_alert("could not set the VHT TXOP PS");
1207 		}
1208 	}
1209 
1210 	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1211 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1212 	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1213 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1214 	else
1215 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1216 
1217 
1218 	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ))
1219 		band_5g->vht_cap.cap |=
1220 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1221 	else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ))
1222 		band_5g->vht_cap.cap |=
1223 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1224 
1225 	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC)
1226 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1227 
1228 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1229 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1230 	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1231 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1232 
1233 	if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1234 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1235 
1236 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1237 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1238 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1239 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1240 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1241 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1242 
1243 	band_5g->vht_cap.cap |=
1244 		(cfg->vht_max_ampdu_len_exp <<
1245 		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1246 
1247 	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1248 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1249 	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1250 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1251 	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1252 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1253 	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1254 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1255 
1256 	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1257 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1258 
1259 }
1260 
1261 /**
1262  * hdd_generate_macaddr_auto() - Auto-generate mac address
1263  * @hdd_ctx: Pointer to the HDD context
1264  *
1265  * Auto-generate mac address using device serial number.
1266  * Keep the first 3 bytes of OUI as before and replace
1267  * the last 3 bytes with the lower 3 bytes of serial number.
1268  *
1269  * Return: 0 for success
1270  *         Non zero failure code for errors
1271  */
1272 static int hdd_generate_macaddr_auto(hdd_context_t *hdd_ctx)
1273 {
1274 	unsigned int serialno = 0;
1275 	struct qdf_mac_addr mac_addr = {
1276 		{0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1277 	};
1278 
1279 	serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
1280 	if (serialno == 0)
1281 		return -EINVAL;
1282 
1283 	serialno &= 0x00ffffff;
1284 
1285 	mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1286 	mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1287 	mac_addr.bytes[5] = serialno & 0xff;
1288 
1289 	hdd_update_macaddr(hdd_ctx->config, mac_addr);
1290 	return 0;
1291 }
1292 
1293 /**
1294  * hdd_update_ra_rate_limit() - Update RA rate limit from target
1295  *  configuration to cfg_ini in HDD
1296  * @hdd_ctx: Pointer to hdd_ctx
1297  * @cfg: target configuration
1298  *
1299  * Return: None
1300  */
1301 #ifdef FEATURE_WLAN_RA_FILTERING
1302 static void hdd_update_ra_rate_limit(hdd_context_t *hdd_ctx,
1303 				     struct wma_tgt_cfg *cfg)
1304 {
1305 	hdd_ctx->config->IsRArateLimitEnabled = cfg->is_ra_rate_limit_enabled;
1306 }
1307 #else
1308 static void hdd_update_ra_rate_limit(hdd_context_t *hdd_ctx,
1309 				     struct wma_tgt_cfg *cfg)
1310 {
1311 }
1312 #endif
1313 
1314 void hdd_update_tgt_cfg(void *context, void *param)
1315 {
1316 	hdd_context_t *hdd_ctx = (hdd_context_t *) context;
1317 	struct wma_tgt_cfg *cfg = param;
1318 	uint8_t temp_band_cap;
1319 	struct cds_config_info *cds_cfg = cds_get_ini_config();
1320 
1321 	if (cds_cfg) {
1322 		if (hdd_ctx->config->enable_sub_20_channel_width !=
1323 			WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
1324 			hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1325 			cds_cfg->sub_20_channel_width =
1326 				WLAN_SUB_20_CH_WIDTH_NONE;
1327 		} else {
1328 			cds_cfg->sub_20_channel_width =
1329 				hdd_ctx->config->enable_sub_20_channel_width;
1330 		}
1331 	}
1332 
1333 	/* first store the INI band capability */
1334 	temp_band_cap = hdd_ctx->config->nBandCapability;
1335 
1336 	hdd_ctx->config->nBandCapability = cfg->band_cap;
1337 
1338 	/* now overwrite the target band capability with INI
1339 	   setting if INI setting is a subset */
1340 
1341 	if ((hdd_ctx->config->nBandCapability == eCSR_BAND_ALL) &&
1342 	    (temp_band_cap != eCSR_BAND_ALL))
1343 		hdd_ctx->config->nBandCapability = temp_band_cap;
1344 	else if ((hdd_ctx->config->nBandCapability != eCSR_BAND_ALL) &&
1345 		 (temp_band_cap != eCSR_BAND_ALL) &&
1346 		 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
1347 		hdd_warn("ini BandCapability not supported by the target");
1348 	}
1349 
1350 	if (!cds_is_driver_recovering()) {
1351 		hdd_ctx->reg.reg_domain = cfg->reg_domain;
1352 		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
1353 	}
1354 
1355 	/* This can be extended to other configurations like ht, vht cap... */
1356 
1357 	if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
1358 		hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
1359 		hdd_ctx->update_mac_addr_to_fw = false;
1360 	} else {
1361 		static struct qdf_mac_addr default_mac_addr = {
1362 			{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
1363 		};
1364 		if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
1365 					 &default_mac_addr)) {
1366 			if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
1367 				hdd_err("Fail to auto-generate MAC, using MAC from ini file "
1368 					MAC_ADDRESS_STR,
1369 					MAC_ADDR_ARRAY(hdd_ctx->config->
1370 						       intfMacAddr[0].bytes));
1371 		} else {
1372 			hdd_err("Invalid MAC passed from target, using MAC from ini file "
1373 				MAC_ADDRESS_STR,
1374 				MAC_ADDR_ARRAY(hdd_ctx->config->
1375 					       intfMacAddr[0].bytes));
1376 		}
1377 		hdd_ctx->update_mac_addr_to_fw = true;
1378 	}
1379 
1380 	hdd_ctx->target_fw_version = cfg->target_fw_version;
1381 	hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
1382 
1383 	hdd_ctx->max_intf_count = cfg->max_intf_count;
1384 
1385 	hdd_lpass_target_config(hdd_ctx, cfg);
1386 	hdd_green_ap_target_config(hdd_ctx, cfg);
1387 
1388 	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
1389 	hdd_update_tgt_services(hdd_ctx, &cfg->services);
1390 
1391 	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
1392 
1393 	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
1394 
1395 	hdd_update_vdev_nss(hdd_ctx);
1396 
1397 	hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
1398 	hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
1399 	hdd_info("fine_time_meas_cap: 0x%x",
1400 		hdd_ctx->config->fine_time_meas_cap);
1401 
1402 	hdd_ctx->current_antenna_mode =
1403 		(hdd_ctx->config->enable2x2 == 0x01) ?
1404 		HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
1405 	hdd_info("Init current antenna mode: %d",
1406 		 hdd_ctx->current_antenna_mode);
1407 
1408 	hdd_info("Target BPF %d Host BPF %d",
1409 		cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable);
1410 	hdd_ctx->bpf_enabled = (cfg->bpf_enabled &&
1411 				hdd_ctx->config->bpf_packet_filter_enable);
1412 	hdd_update_ra_rate_limit(hdd_ctx, cfg);
1413 
1414 	/*
1415 	 * If BPF is enabled, maxWowFilters set to WMA_STA_WOW_DEFAULT_PTRN_MAX
1416 	 * because we need atleast WMA_STA_WOW_DEFAULT_PTRN_MAX free slots to
1417 	 * configure the STA mode wow pattern.
1418 	 */
1419 	if (hdd_ctx->bpf_enabled)
1420 		hdd_ctx->config->maxWoWFilters = WMA_STA_WOW_DEFAULT_PTRN_MAX;
1421 
1422 	hdd_ctx->wmi_max_len = cfg->wmi_max_len;
1423 
1424 	/* Configure NAN datapath features */
1425 	hdd_nan_datapath_target_config(hdd_ctx, cfg);
1426 }
1427 
1428 /**
1429  * hdd_dfs_indicate_radar() - handle radar detection on current SAP channel
1430  * @context:	HDD context pointer
1431  * @param:	HDD radar indication pointer
1432  *
1433  * This function is invoked in atomic context when a radar
1434  * is found on the SAP current operating channel and Data Tx
1435  * from netif has to be stopped to honor the DFS regulations.
1436  * Actions: Stop the netif Tx queues,Indicate Radar present
1437  * in HDD context for future usage.
1438  *
1439  * Return: true to allow radar indication to host else false
1440  */
1441 bool hdd_dfs_indicate_radar(void *context, void *param)
1442 {
1443 	hdd_context_t *hdd_ctx = (hdd_context_t *) context;
1444 	struct wma_dfs_radar_ind *hdd_radar_event =
1445 		(struct wma_dfs_radar_ind *)param;
1446 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
1447 	hdd_adapter_t *adapter;
1448 	QDF_STATUS status;
1449 	hdd_ap_ctx_t *ap_ctx;
1450 
1451 	if (!hdd_ctx || !hdd_radar_event ||
1452 		 hdd_ctx->config->disableDFSChSwitch)
1453 		return true;
1454 
1455 	if (true == hdd_radar_event->dfs_radar_status) {
1456 		if (qdf_atomic_inc_return(&hdd_ctx->dfs_radar_found) > 1) {
1457 			/*
1458 			 * Application already triggered channel switch
1459 			 * on current channel, so return here.
1460 			 */
1461 			return false;
1462 		}
1463 
1464 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
1465 		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
1466 			adapter = adapterNode->pAdapter;
1467 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
1468 			if ((QDF_SAP_MODE == adapter->device_mode ||
1469 			     QDF_P2P_GO_MODE == adapter->device_mode) &&
1470 			     (CHANNEL_STATE_DFS ==
1471 			     cds_get_channel_state(ap_ctx->operatingChannel))) {
1472 				WLAN_HDD_GET_AP_CTX_PTR(adapter)->
1473 				dfs_cac_block_tx = true;
1474 				hdd_info("tx blocked for session:%d",
1475 					 adapter->sessionId);
1476 			}
1477 
1478 			status = hdd_get_next_adapter(hdd_ctx,
1479 						      adapterNode,
1480 						      &pNext);
1481 			adapterNode = pNext;
1482 		}
1483 	}
1484 
1485 	return true;
1486 }
1487 
1488 /**
1489  * hdd_is_valid_mac_address() - validate MAC address
1490  * @pMacAddr:	Pointer to the input MAC address
1491  *
1492  * This function validates whether the given MAC address is valid or not
1493  * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
1494  * where X is the hexa decimal digit character and separated by ':'
1495  * This algorithm works even if MAC address is not separated by ':'
1496  *
1497  * This code checks given input string mac contains exactly 12 hexadecimal
1498  * digits and a separator colon : appears in the input string only after
1499  * an even number of hex digits.
1500  *
1501  * Return: 1 for valid and 0 for invalid
1502  */
1503 bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
1504 {
1505 	int xdigit = 0;
1506 	int separator = 0;
1507 	while (*pMacAddr) {
1508 		if (isxdigit(*pMacAddr)) {
1509 			xdigit++;
1510 		} else if (':' == *pMacAddr) {
1511 			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
1512 				break;
1513 
1514 			++separator;
1515 		} else {
1516 			/* Invalid MAC found */
1517 			return 0;
1518 		}
1519 		++pMacAddr;
1520 	}
1521 	return xdigit == 12 && (separator == 5 || separator == 0);
1522 }
1523 
1524 /**
1525  * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
1526  * @dev: Handle to struct net_device to be updated.
1527  *
1528  * Return: None
1529  */
1530 static void hdd_mon_mode_ether_setup(struct net_device *dev)
1531 {
1532 	dev->header_ops         = NULL;
1533 	dev->type               = ARPHRD_IEEE80211_RADIOTAP;
1534 	dev->hard_header_len    = ETH_HLEN;
1535 	dev->mtu                = ETH_DATA_LEN;
1536 	dev->addr_len           = ETH_ALEN;
1537 	dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
1538 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
1539 	dev->priv_flags        |= IFF_TX_SKB_SHARING;
1540 
1541 	memset(dev->broadcast, 0xFF, ETH_ALEN);
1542 }
1543 
1544 /**
1545  * __hdd__mon_open() - HDD Open function
1546  * @dev: Pointer to net_device structure
1547  *
1548  * This is called in response to ifconfig up
1549  *
1550  * Return: 0 for success; non-zero for failure
1551  */
1552 static int __hdd_mon_open(struct net_device *dev)
1553 {
1554 	int ret;
1555 
1556 	ENTER_DEV(dev);
1557 	hdd_mon_mode_ether_setup(dev);
1558 	ret = hdd_set_mon_rx_cb(dev);
1559 	return ret;
1560 }
1561 
1562 /**
1563  * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
1564  * @dev:	Pointer to net_device structure
1565  *
1566  * This is called in response to ifconfig up
1567  *
1568  * Return: 0 for success; non-zero for failure
1569  */
1570 static int hdd_mon_open(struct net_device *dev)
1571 {
1572 	int ret;
1573 
1574 	cds_ssr_protect(__func__);
1575 	ret = __hdd_mon_open(dev);
1576 	cds_ssr_unprotect(__func__);
1577 
1578 	return ret;
1579 }
1580 
1581 /**
1582  * hdd_start_adapter() - Wrapper function for device specific adapter
1583  * @adapter: pointer to HDD adapter
1584  *
1585  * This function is called to start the device specific adapter for
1586  * the mode passed in the adapter's device_mode.
1587  *
1588  * Return: 0 for success; non-zero for failure
1589  */
1590 int hdd_start_adapter(hdd_adapter_t *adapter)
1591 {
1592 
1593 	int ret;
1594 	enum tQDF_ADAPTER_MODE device_mode = adapter->device_mode;
1595 
1596 	ENTER_DEV(adapter->dev);
1597 	hdd_info("Start_adapter for mode : %d", adapter->device_mode);
1598 
1599 	switch (device_mode) {
1600 	case QDF_P2P_CLIENT_MODE:
1601 	case QDF_P2P_DEVICE_MODE:
1602 	case QDF_OCB_MODE:
1603 	case QDF_STA_MODE:
1604 	case QDF_MONITOR_MODE:
1605 		ret = hdd_start_station_adapter(adapter);
1606 		if (ret)
1607 			goto err_start_adapter;
1608 		break;
1609 	case QDF_P2P_GO_MODE:
1610 	case QDF_SAP_MODE:
1611 		ret = hdd_start_ap_adapter(adapter);
1612 		if (ret)
1613 			goto err_start_adapter;
1614 		break;
1615 	case QDF_IBSS_MODE:
1616 		/*
1617 		 * For IBSS interface is initialized as part of
1618 		 * hdd_init_station_mode()
1619 		 */
1620 		return 0;
1621 	case QDF_FTM_MODE:
1622 		ret = hdd_start_ftm_adapter(adapter);
1623 		if (ret)
1624 			goto err_start_adapter;
1625 	break;
1626 	default:
1627 		hdd_err("Invalid session type %d", device_mode);
1628 		QDF_ASSERT(0);
1629 		goto err_start_adapter;
1630 	}
1631 	if (hdd_set_fw_params(adapter))
1632 		hdd_err("Failed to set the FW params for the adapter!");
1633 
1634 	/*
1635 	 * Action frame registered in one adapter which will
1636 	 * applicable to all interfaces
1637 	 */
1638 	wlan_hdd_cfg80211_register_frames(adapter);
1639 	EXIT();
1640 	return 0;
1641 err_start_adapter:
1642 	return -EINVAL;
1643 }
1644 
1645 /**
1646  * hdd_enable_power_management() - API to Enable Power Management
1647  *
1648  * API invokes Bus Interface Layer power management functionality
1649  *
1650  * Return: None
1651  */
1652 static void hdd_enable_power_management(void)
1653 {
1654 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1655 
1656 	if (!hif_ctx) {
1657 		hdd_err("Bus Interface Context is Invalid");
1658 		return;
1659 	}
1660 
1661 	hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
1662 }
1663 
1664 /**
1665  * hdd_disable_power_management() - API to disable Power Management
1666  *
1667  * API disable Bus Interface Layer Power management functionality
1668  *
1669  * Return: None
1670  */
1671 static void hdd_disable_power_management(void)
1672 {
1673 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1674 
1675 	if (!hif_ctx) {
1676 		hdd_err("Bus Interface Context is Invalid");
1677 		return;
1678 	}
1679 
1680 	hif_disable_power_management(hif_ctx);
1681 }
1682 
1683 /**
1684  * hdd_wlan_start_modules() - Single driver state machine for starting modules
1685  * @hdd_ctx: HDD context
1686  * @adapter: HDD adapter
1687  * @reinit: flag to indicate from SSR or normal path
1688  *
1689  * This function maintains the driver state machine it will be invoked from
1690  * startup, reinit and change interface. Depending on the driver state shall
1691  * perform the opening of the modules.
1692  *
1693  * Return: 0 for success; non-zero for failure
1694  */
1695 int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
1696 			   bool reinit)
1697 {
1698 	int ret;
1699 	qdf_device_t qdf_dev;
1700 	QDF_STATUS status;
1701 	p_cds_contextType p_cds_context;
1702 	bool unint = false;
1703 	void *hif_ctx;
1704 
1705 	ENTER();
1706 
1707 	p_cds_context = cds_get_global_context();
1708 	if (!p_cds_context) {
1709 		hdd_err("Global Context is NULL");
1710 		QDF_ASSERT(0);
1711 		return -EINVAL;
1712 	}
1713 
1714 	hdd_info("start modules called in  state! :%d reinit: %d",
1715 			 hdd_ctx->driver_status, reinit);
1716 
1717 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1718 	if (!qdf_dev) {
1719 		hdd_err("QDF Device Context is Invalid return");
1720 		return -EINVAL;
1721 	}
1722 
1723 	mutex_lock(&hdd_ctx->iface_change_lock);
1724 	hdd_ctx->start_modules_in_progress = true;
1725 
1726 	if (QDF_TIMER_STATE_RUNNING ==
1727 	    qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
1728 
1729 		hdd_set_idle_ps_config(hdd_ctx, false);
1730 		hdd_info("Interface change Timer running Stop timer");
1731 		qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
1732 	}
1733 
1734 	switch (hdd_ctx->driver_status) {
1735 	case DRIVER_MODULES_UNINITIALIZED:
1736 		unint = true;
1737 		/* Fall through dont add break here */
1738 	case DRIVER_MODULES_CLOSED:
1739 		if (!reinit && !unint) {
1740 			ret = pld_power_on(qdf_dev->dev);
1741 			if (ret) {
1742 				hdd_err("Failed to Powerup the device: %d", ret);
1743 				goto release_lock;
1744 			}
1745 		}
1746 		ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
1747 				   qdf_dev->bus_type,
1748 				   (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
1749 				   HIF_ENABLE_TYPE_PROBE);
1750 		if (ret) {
1751 			hdd_err("Failed to open hif: %d", ret);
1752 			goto power_down;
1753 		}
1754 
1755 		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1756 		if (!hif_ctx) {
1757 			hdd_err("hif context is null!!");
1758 			goto power_down;
1759 		}
1760 
1761 		status = ol_cds_init(qdf_dev, hif_ctx);
1762 		if (status != QDF_STATUS_SUCCESS) {
1763 			hdd_err("No Memory to Create BMI Context :%d", status);
1764 			goto hif_close;
1765 		}
1766 
1767 		ret = hdd_update_config(hdd_ctx);
1768 		if (ret) {
1769 			hdd_err("Failed to update configuration :%d", ret);
1770 			goto ol_cds_free;
1771 		}
1772 
1773 		status = cds_open();
1774 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1775 			hdd_err("Failed to Open CDS: %d", status);
1776 			goto ol_cds_free;
1777 		}
1778 
1779 		hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
1780 
1781 		hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
1782 
1783 		status = cds_pre_enable(hdd_ctx->pcds_context);
1784 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1785 			hdd_err("Failed to pre-enable CDS: %d", status);
1786 			goto close;
1787 		}
1788 
1789 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1790 			sme_register_ftm_msg_processor(hdd_ctx->hHal,
1791 						       hdd_ftm_mc_process_msg);
1792 			break;
1793 		}
1794 		if (unint) {
1795 			hdd_info("In phase-1 initialization  don't enable modules");
1796 			break;
1797 		}
1798 	/* Fall through dont add break here */
1799 	case DRIVER_MODULES_OPENED:
1800 		if (!adapter) {
1801 			hdd_alert("adapter is Null");
1802 			goto close;
1803 		}
1804 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
1805 			hdd_err("in ftm mode, no need to configure cds modules");
1806 			break;
1807 		}
1808 		if (hdd_configure_cds(hdd_ctx, adapter)) {
1809 			hdd_err("Failed to Enable cds modules");
1810 			goto close;
1811 		}
1812 		hdd_enable_power_management();
1813 		hdd_info("Driver Modules Successfully Enabled");
1814 		hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
1815 		break;
1816 	case DRIVER_MODULES_ENABLED:
1817 		hdd_info("Driver modules already Enabled");
1818 		break;
1819 	default:
1820 		hdd_err("WLAN start invoked in wrong state! :%d\n",
1821 				hdd_ctx->driver_status);
1822 		goto release_lock;
1823 	}
1824 	hdd_ctx->start_modules_in_progress = false;
1825 	mutex_unlock(&hdd_ctx->iface_change_lock);
1826 	EXIT();
1827 	return 0;
1828 
1829 close:
1830 	cds_close(p_cds_context);
1831 
1832 ol_cds_free:
1833 	ol_cds_free();
1834 
1835 hif_close:
1836 	hdd_hif_close(p_cds_context->pHIFContext);
1837 power_down:
1838 	if (!reinit && !unint)
1839 		pld_power_off(qdf_dev->dev);
1840 release_lock:
1841 	hdd_ctx->start_modules_in_progress = false;
1842 	mutex_unlock(&hdd_ctx->iface_change_lock);
1843 	EXIT();
1844 	return -EINVAL;
1845 }
1846 
1847 /**
1848  * __hdd_open() - HDD Open function
1849  * @dev:	Pointer to net_device structure
1850  *
1851  * This is called in response to ifconfig up
1852  *
1853  * Return: 0 for success; non-zero for failure
1854  */
1855 static int __hdd_open(struct net_device *dev)
1856 {
1857 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1858 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1859 	int ret;
1860 
1861 	ENTER_DEV(dev);
1862 	MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
1863 		adapter->sessionId, adapter->device_mode));
1864 
1865 	ret = wlan_hdd_validate_context(hdd_ctx);
1866 	if (ret)
1867 		return ret;
1868 
1869 
1870 	ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
1871 	if (ret) {
1872 		hdd_err("Failed to start WLAN modules return");
1873 		return -ret;
1874 	}
1875 
1876 
1877 	if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
1878 		ret = hdd_start_adapter(adapter);
1879 		if (ret) {
1880 			hdd_err("Failed to start adapter :%d",
1881 				adapter->device_mode);
1882 			return ret;
1883 		}
1884 	}
1885 
1886 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
1887 	if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
1888 		hdd_info("Enabling Tx Queues");
1889 		/* Enable TX queues only when we are connected */
1890 		wlan_hdd_netif_queue_control(adapter,
1891 					     WLAN_START_ALL_NETIF_QUEUE,
1892 					     WLAN_CONTROL_PATH);
1893 	}
1894 
1895 	/* Enable carrier and transmit queues for NDI */
1896 	if (WLAN_HDD_IS_NDI(adapter)) {
1897 		hdd_notice("Enabling Tx Queues");
1898 		wlan_hdd_netif_queue_control(adapter,
1899 			WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
1900 			WLAN_CONTROL_PATH);
1901 	}
1902 
1903 	return ret;
1904 }
1905 
1906 
1907 /**
1908  * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
1909  * @dev:	Pointer to net_device structure
1910  *
1911  * This is called in response to ifconfig up
1912  *
1913  * Return: 0 for success; non-zero for failure
1914  */
1915 static int hdd_open(struct net_device *dev)
1916 {
1917 	int ret;
1918 
1919 	cds_ssr_protect(__func__);
1920 	ret = __hdd_open(dev);
1921 	cds_ssr_unprotect(__func__);
1922 
1923 	return ret;
1924 }
1925 
1926 /**
1927  * __hdd_stop() - HDD stop function
1928  * @dev:	Pointer to net_device structure
1929  *
1930  * This is called in response to ifconfig down
1931  *
1932  * Return: 0 for success; non-zero for failure
1933  */
1934 static int __hdd_stop(struct net_device *dev)
1935 {
1936 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1937 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1938 	hdd_adapter_list_node_t *adapternode = NULL, *next = NULL;
1939 	int ret;
1940 	bool close_modules = true;
1941 	QDF_STATUS status;
1942 
1943 	ENTER_DEV(dev);
1944 
1945 	MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
1946 			 adapter->sessionId, adapter->device_mode));
1947 
1948 	ret = wlan_hdd_validate_context(hdd_ctx);
1949 	if (0 != ret)
1950 		return ret;
1951 
1952 	/* Nothing to be done if the interface is not opened */
1953 	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
1954 		hdd_err("NETDEV Interface is not OPENED");
1955 		return -ENODEV;
1956 	}
1957 
1958 	/* Make sure the interface is marked as closed */
1959 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
1960 	hdd_notice("Disabling OS Tx queues");
1961 
1962 	/*
1963 	 * Disable TX on the interface, after this hard_start_xmit() will not
1964 	 * be called on that interface
1965 	 */
1966 	hdd_notice("Disabling queues");
1967 	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1968 				   WLAN_CONTROL_PATH);
1969 
1970 	/*
1971 	 * NAN data interface is different in some sense. The traffic on NDI is
1972 	 * bursty in nature and depends on the need to transfer. The service
1973 	 * layer may down the interface after the usage and up again when
1974 	 * required. In some sense, the NDI is expected to be available
1975 	 * (like SAP) iface until NDI delete request is issued by the service
1976 	 * layer. Skip BSS termination and adapter deletion for NAN Data
1977 	 * interface (NDI).
1978 	 */
1979 	if (WLAN_HDD_IS_NDI(adapter))
1980 		return 0;
1981 
1982 	/*
1983 	 * The interface is marked as down for outside world (aka kernel)
1984 	 * But the driver is pretty much alive inside. The driver needs to
1985 	 * tear down the existing connection on the netdev (session)
1986 	 * cleanup the data pipes and wait until the control plane is stabilized
1987 	 * for this interface. The call also needs to wait until the above
1988 	 * mentioned actions are completed before returning to the caller.
1989 	 * Notice that the hdd_stop_adapter is requested not to close the session
1990 	 * That is intentional to be able to scan if it is a STA/P2P interface
1991 	 */
1992 	hdd_stop_adapter(hdd_ctx, adapter, true);
1993 
1994 	/* DeInit the adapter. This ensures datapath cleanup as well */
1995 	hdd_deinit_adapter(hdd_ctx, adapter, true);
1996 
1997 
1998 	/*
1999 	 * Find if any iface is up. If any iface is up then can't put device to
2000 	 * sleep/power save mode
2001 	 */
2002 	status = hdd_get_front_adapter(hdd_ctx, &adapternode);
2003 	while ((NULL != adapternode) && (QDF_STATUS_SUCCESS == status)) {
2004 		if (test_bit(DEVICE_IFACE_OPENED,
2005 			     &adapternode->pAdapter->event_flags)) {
2006 			hdd_info("Still other ifaces are up cannot close modules");
2007 			close_modules = false;
2008 			break;
2009 		}
2010 		status = hdd_get_next_adapter(hdd_ctx, adapternode, &next);
2011 		adapternode = next;
2012 
2013 	}
2014 
2015 	if (close_modules) {
2016 		hdd_info("Closing all modules from the hdd_stop");
2017 		qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
2018 				   hdd_ctx->config->iface_change_wait_time
2019 				   * 50000);
2020 	}
2021 
2022 	EXIT();
2023 	return 0;
2024 }
2025 
2026 /**
2027  * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
2028  * @dev: pointer to net_device structure
2029  *
2030  * This is called in response to ifconfig down
2031  *
2032  * Return: 0 for success and error number for failure
2033  */
2034 static int hdd_stop(struct net_device *dev)
2035 {
2036 	int ret;
2037 
2038 	cds_ssr_protect(__func__);
2039 	ret = __hdd_stop(dev);
2040 	cds_ssr_unprotect(__func__);
2041 
2042 	return ret;
2043 }
2044 
2045 /**
2046  * __hdd_uninit() - HDD uninit function
2047  * @dev:	Pointer to net_device structure
2048  *
2049  * This is called during the netdev unregister to uninitialize all data
2050  * associated with the device
2051  *
2052  * Return: None
2053  */
2054 static void __hdd_uninit(struct net_device *dev)
2055 {
2056 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2057 
2058 	ENTER_DEV(dev);
2059 
2060 	do {
2061 		if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
2062 			hdd_alert("Invalid magic");
2063 			break;
2064 		}
2065 
2066 		if (NULL == adapter->pHddCtx) {
2067 			hdd_alert("NULL hdd_ctx");
2068 			break;
2069 		}
2070 
2071 		if (dev != adapter->dev) {
2072 			hdd_alert("Invalid device reference");
2073 			/*
2074 			 * we haven't validated all cases so let this go for
2075 			 * now
2076 			 */
2077 		}
2078 
2079 		hdd_deinit_adapter(adapter->pHddCtx, adapter, true);
2080 
2081 		/* after uninit our adapter structure will no longer be valid */
2082 		adapter->dev = NULL;
2083 		adapter->magic = 0;
2084 	} while (0);
2085 
2086 	EXIT();
2087 }
2088 
2089 /**
2090  * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
2091  * @dev: pointer to net_device structure
2092  *
2093  * This is called during the netdev unregister to uninitialize all data
2094  * associated with the device
2095  *
2096  * Return: none
2097  */
2098 static void hdd_uninit(struct net_device *dev)
2099 {
2100 	cds_ssr_protect(__func__);
2101 	__hdd_uninit(dev);
2102 	cds_ssr_unprotect(__func__);
2103 }
2104 
2105 static int hdd_open_cesium_nl_sock(void)
2106 {
2107 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2108 	struct netlink_kernel_cfg cfg = {
2109 		.groups = WLAN_NLINK_MCAST_GRP_ID,
2110 		.input = NULL
2111 	};
2112 #endif
2113 	int ret = 0;
2114 
2115 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2116 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2117 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
2118 						   THIS_MODULE,
2119 #endif
2120 						   &cfg);
2121 #else
2122 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
2123 						   WLAN_NLINK_MCAST_GRP_ID,
2124 						   NULL, NULL, THIS_MODULE);
2125 #endif
2126 
2127 	if (cesium_nl_srv_sock == NULL) {
2128 		hdd_err("NLINK:  cesium netlink_kernel_create failed");
2129 		ret = -ECONNREFUSED;
2130 	}
2131 
2132 	return ret;
2133 }
2134 
2135 static void hdd_close_cesium_nl_sock(void)
2136 {
2137 	if (NULL != cesium_nl_srv_sock) {
2138 		netlink_kernel_release(cesium_nl_srv_sock);
2139 		cesium_nl_srv_sock = NULL;
2140 	}
2141 }
2142 
2143 /**
2144  * __hdd_set_mac_address() - set the user specified mac address
2145  * @dev:	Pointer to the net device.
2146  * @addr:	Pointer to the sockaddr.
2147  *
2148  * This function sets the user specified mac address using
2149  * the command ifconfig wlanX hw ether <mac adress>.
2150  *
2151  * Return: 0 for success, non zero for failure
2152  */
2153 static int __hdd_set_mac_address(struct net_device *dev, void *addr)
2154 {
2155 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2156 	hdd_context_t *hdd_ctx;
2157 	struct sockaddr *psta_mac_addr = addr;
2158 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
2159 	int ret;
2160 
2161 	ENTER_DEV(dev);
2162 
2163 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2164 	ret = wlan_hdd_validate_context(hdd_ctx);
2165 	if (0 != ret)
2166 		return ret;
2167 
2168 	memcpy(&adapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
2169 	memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
2170 
2171 	EXIT();
2172 	return qdf_ret_status;
2173 }
2174 
2175 /**
2176  * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
2177  *			function from SSR
2178  * @dev: pointer to net_device structure
2179  * @addr: Pointer to the sockaddr
2180  *
2181  * This function sets the user specified mac address using
2182  * the command ifconfig wlanX hw ether <mac adress>.
2183  *
2184  * Return: 0 for success.
2185  */
2186 static int hdd_set_mac_address(struct net_device *dev, void *addr)
2187 {
2188 	int ret;
2189 
2190 	cds_ssr_protect(__func__);
2191 	ret = __hdd_set_mac_address(dev, addr);
2192 	cds_ssr_unprotect(__func__);
2193 
2194 	return ret;
2195 }
2196 
2197 uint8_t *wlan_hdd_get_intf_addr(hdd_context_t *hdd_ctx)
2198 {
2199 	int i;
2200 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
2201 		if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
2202 			break;
2203 	}
2204 
2205 	if (QDF_MAX_CONCURRENCY_PERSONA == i)
2206 		return NULL;
2207 
2208 	hdd_ctx->config->intfAddrMask |= (1 << i);
2209 	return &hdd_ctx->config->intfMacAddr[i].bytes[0];
2210 }
2211 
2212 void wlan_hdd_release_intf_addr(hdd_context_t *hdd_ctx, uint8_t *releaseAddr)
2213 {
2214 	int i;
2215 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
2216 		if (!memcmp(releaseAddr,
2217 			    &hdd_ctx->config->intfMacAddr[i].bytes[0],
2218 			    6)) {
2219 			hdd_ctx->config->intfAddrMask &= ~(1 << i);
2220 			break;
2221 		}
2222 	}
2223 	return;
2224 }
2225 
2226 #ifdef WLAN_FEATURE_PACKET_FILTERING
2227 /**
2228  * __hdd_set_multicast_list() - set the multicast address list
2229  * @dev:	Pointer to the WLAN device.
2230  * @skb:	Pointer to OS packet (sk_buff).
2231  *
2232  * This funciton sets the multicast address list.
2233  *
2234  * Return: None
2235  */
2236 static void __hdd_set_multicast_list(struct net_device *dev)
2237 {
2238 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2239 	int mc_count;
2240 	int i = 0, status;
2241 	struct netdev_hw_addr *ha;
2242 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2243 	static const uint8_t ipv6_router_solicitation[]
2244 			= {0x33, 0x33, 0x00, 0x00, 0x00, 0x02};
2245 
2246 	ENTER_DEV(dev);
2247 
2248 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
2249 		return;
2250 
2251 	status = wlan_hdd_validate_context(hdd_ctx);
2252 	if (0 != status)
2253 		return;
2254 
2255 	if (dev->flags & IFF_ALLMULTI) {
2256 		hdd_notice("allow all multicast frames");
2257 		adapter->mc_addr_list.mc_cnt = 0;
2258 	} else {
2259 		mc_count = netdev_mc_count(dev);
2260 		hdd_notice("mc_count : %u", mc_count);
2261 
2262 		if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST) {
2263 			hdd_notice("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
2264 				   WLAN_HDD_MAX_MC_ADDR_LIST);
2265 			wlan_hdd_set_mc_addr_list(adapter, false);
2266 			adapter->mc_addr_list.mc_cnt = 0;
2267 			return;
2268 		}
2269 
2270 		adapter->mc_addr_list.mc_cnt = mc_count;
2271 
2272 		netdev_for_each_mc_addr(ha, dev) {
2273 			hdd_notice("ha_addr[%d] "MAC_ADDRESS_STR,
2274 				i, MAC_ADDR_ARRAY(ha->addr));
2275 
2276 			if (i == mc_count)
2277 				break;
2278 			/*
2279 			 * Skip following addresses:
2280 			 * 1)IPv6 router solicitation address
2281 			 * 2)Any other address pattern if its set during
2282 			 *  RXFILTER REMOVE driver command based on
2283 			 *  addr_filter_pattern
2284 			 */
2285 			if ((!memcmp(ha->addr, ipv6_router_solicitation,
2286 			   ETH_ALEN)) ||
2287 			   (adapter->addr_filter_pattern && (!memcmp(ha->addr,
2288 			    &adapter->addr_filter_pattern, 1)))) {
2289 				hdd_info("MC/BC filtering Skip addr ="MAC_ADDRESS_STR,
2290 					MAC_ADDR_ARRAY(ha->addr));
2291 				adapter->mc_addr_list.mc_cnt--;
2292 				continue;
2293 			}
2294 
2295 			memset(&(adapter->mc_addr_list.addr[i][0]), 0,
2296 			       ETH_ALEN);
2297 			memcpy(&(adapter->mc_addr_list.addr[i][0]), ha->addr,
2298 			       ETH_ALEN);
2299 			hdd_notice("mlist[%d] = " MAC_ADDRESS_STR, i,
2300 			       MAC_ADDR_ARRAY(adapter->mc_addr_list.addr[i]));
2301 			i++;
2302 		}
2303 	}
2304 	if (hdd_ctx->config->active_mode_offload) {
2305 		hdd_info("enable mc filtering");
2306 		wlan_hdd_set_mc_addr_list(adapter, true);
2307 	} else {
2308 		hdd_info("skip mc filtering enable it during cfg80211 suspend");
2309 	}
2310 	EXIT();
2311 	return;
2312 }
2313 
2314 /**
2315  * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
2316  * @dev: pointer to net_device
2317  *
2318  * Return: none
2319  */
2320 static void hdd_set_multicast_list(struct net_device *dev)
2321 {
2322 	cds_ssr_protect(__func__);
2323 	__hdd_set_multicast_list(dev);
2324 	cds_ssr_unprotect(__func__);
2325 }
2326 #endif
2327 
2328 /**
2329  * hdd_select_queue() - used by Linux OS to decide which queue to use first
2330  * @dev:	Pointer to the WLAN device.
2331  * @skb:	Pointer to OS packet (sk_buff).
2332  *
2333  * This function is registered with the Linux OS for network
2334  * core to decide which queue to use first.
2335  *
2336  * Return: ac, Queue Index/access category corresponding to UP in IP header
2337  */
2338 static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
2339 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
2340 			  , void *accel_priv
2341 #endif
2342 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
2343 			  , select_queue_fallback_t fallback
2344 #endif
2345 )
2346 {
2347 	return hdd_wmm_select_queue(dev, skb);
2348 }
2349 
2350 static struct net_device_ops wlan_drv_ops = {
2351 	.ndo_open = hdd_open,
2352 	.ndo_stop = hdd_stop,
2353 	.ndo_uninit = hdd_uninit,
2354 	.ndo_start_xmit = hdd_hard_start_xmit,
2355 	.ndo_tx_timeout = hdd_tx_timeout,
2356 	.ndo_get_stats = hdd_get_stats,
2357 	.ndo_do_ioctl = hdd_ioctl,
2358 	.ndo_set_mac_address = hdd_set_mac_address,
2359 	.ndo_select_queue = hdd_select_queue,
2360 #ifdef WLAN_FEATURE_PACKET_FILTERING
2361 	.ndo_set_rx_mode = hdd_set_multicast_list,
2362 #endif
2363 };
2364 
2365 /* Monitor mode net_device_ops, doesnot Tx and most of operations. */
2366 static struct net_device_ops wlan_mon_drv_ops = {
2367 	.ndo_open = hdd_mon_open,
2368 	.ndo_stop = hdd_stop,
2369 	.ndo_get_stats = hdd_get_stats,
2370 };
2371 
2372 /**
2373  * hdd_set_station_ops() - update net_device ops for monitor mode
2374  * @pWlanDev: Handle to struct net_device to be updated.
2375  * Return: None
2376  */
2377 void hdd_set_station_ops(struct net_device *pWlanDev)
2378 {
2379 	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
2380 		pWlanDev->netdev_ops = &wlan_mon_drv_ops;
2381 	else
2382 		pWlanDev->netdev_ops = &wlan_drv_ops;
2383 }
2384 
2385 #ifdef FEATURE_RUNTIME_PM
2386 /**
2387  * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
2388  * @hdd_ctx: HDD context
2389  *
2390  * Return: None
2391  */
2392 static void hdd_runtime_suspend_context_init(hdd_context_t *hdd_ctx)
2393 {
2394 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
2395 
2396 	ctx->scan = qdf_runtime_lock_init("scan");
2397 	ctx->roc = qdf_runtime_lock_init("roc");
2398 	ctx->dfs = qdf_runtime_lock_init("dfs");
2399 }
2400 
2401 /**
2402  * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
2403  * @hdd_ctx: HDD Context
2404  *
2405  * Return: None
2406  */
2407 static void hdd_runtime_suspend_context_deinit(hdd_context_t *hdd_ctx)
2408 {
2409 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
2410 
2411 	qdf_runtime_lock_deinit(ctx->scan);
2412 	ctx->scan = NULL;
2413 	qdf_runtime_lock_deinit(ctx->roc);
2414 	ctx->roc = NULL;
2415 	qdf_runtime_lock_deinit(ctx->dfs);
2416 	ctx->dfs = NULL;
2417 }
2418 
2419 static void hdd_adapter_runtime_suspend_init(hdd_adapter_t *adapter)
2420 {
2421 	struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
2422 
2423 	ctx->connect = qdf_runtime_lock_init("connect");
2424 }
2425 
2426 static void hdd_adapter_runtime_suspend_denit(hdd_adapter_t *adapter)
2427 {
2428 	struct hdd_connect_pm_context *ctx = &adapter->connect_rpm_ctx;
2429 
2430 	qdf_runtime_lock_deinit(ctx->connect);
2431 	ctx->connect = NULL;
2432 }
2433 #else /* FEATURE_RUNTIME_PM */
2434 static void hdd_runtime_suspend_context_init(hdd_context_t *hdd_ctx) {}
2435 static void hdd_runtime_suspend_context_deinit(hdd_context_t *hdd_ctx) {}
2436 static inline void hdd_adapter_runtime_suspend_init(hdd_adapter_t *adapter) {}
2437 static inline void hdd_adapter_runtime_suspend_denit(hdd_adapter_t *adapter) {}
2438 #endif /* FEATURE_RUNTIME_PM */
2439 /**
2440  * hdd_alloc_station_adapter() - allocate the station hdd adapter
2441  * @hdd_ctx: global hdd context
2442  * @macAddr: mac address to assign to the interface
2443  * @name: User-visible name of the interface
2444  *
2445  * hdd adapter pointer would point to the netdev->priv space, this function
2446  * would retrive the pointer, and setup the hdd adapter configuration.
2447  *
2448  * Return: the pointer to hdd adapter, otherwise NULL
2449  */
2450 static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
2451 						tSirMacAddr macAddr,
2452 						unsigned char name_assign_type,
2453 						const char *name)
2454 {
2455 	struct net_device *pWlanDev = NULL;
2456 	hdd_adapter_t *adapter = NULL;
2457 	/*
2458 	 * cfg80211 initialization and registration....
2459 	 */
2460 	pWlanDev = alloc_netdev_mq(sizeof(hdd_adapter_t), name,
2461 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
2462 				   name_assign_type,
2463 #endif
2464 				(QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
2465 				hdd_mon_mode_ether_setup : ether_setup),
2466 				NUM_TX_QUEUES);
2467 
2468 	if (pWlanDev != NULL) {
2469 
2470 		/* Save the pointer to the net_device in the HDD adapter */
2471 		adapter = (hdd_adapter_t *) netdev_priv(pWlanDev);
2472 
2473 		qdf_mem_zero(adapter, sizeof(hdd_adapter_t));
2474 
2475 		adapter->dev = pWlanDev;
2476 		adapter->pHddCtx = hdd_ctx;
2477 		adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
2478 		adapter->sessionId = HDD_SESSION_ID_INVALID;
2479 
2480 		init_completion(&adapter->session_open_comp_var);
2481 		init_completion(&adapter->session_close_comp_var);
2482 		init_completion(&adapter->disconnect_comp_var);
2483 		init_completion(&adapter->linkup_event_var);
2484 		init_completion(&adapter->cancel_rem_on_chan_var);
2485 		init_completion(&adapter->rem_on_chan_ready_event);
2486 		init_completion(&adapter->sta_authorized_event);
2487 		init_completion(&adapter->offchannel_tx_event);
2488 		init_completion(&adapter->tx_action_cnf_event);
2489 #ifdef FEATURE_WLAN_TDLS
2490 		init_completion(&adapter->tdls_add_station_comp);
2491 		init_completion(&adapter->tdls_del_station_comp);
2492 		init_completion(&adapter->tdls_mgmt_comp);
2493 		init_completion(&adapter->tdls_link_establish_req_comp);
2494 #endif
2495 		init_completion(&adapter->ibss_peer_info_comp);
2496 		init_completion(&adapter->change_country_code);
2497 
2498 
2499 		init_completion(&adapter->scan_info.abortscan_event_var);
2500 
2501 		adapter->offloads_configured = false;
2502 		adapter->isLinkUpSvcNeeded = false;
2503 		adapter->higherDtimTransition = true;
2504 		/* Init the net_device structure */
2505 		strlcpy(pWlanDev->name, name, IFNAMSIZ);
2506 
2507 		qdf_mem_copy(pWlanDev->dev_addr, (void *)macAddr,
2508 			     sizeof(tSirMacAddr));
2509 		qdf_mem_copy(adapter->macAddressCurrent.bytes, macAddr,
2510 			     sizeof(tSirMacAddr));
2511 		pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
2512 
2513 		if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
2514 			pWlanDev->features |=
2515 				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
2516 		pWlanDev->features |= NETIF_F_RXCSUM;
2517 
2518 		hdd_set_tso_flags(hdd_ctx, pWlanDev);
2519 
2520 		hdd_set_station_ops(adapter->dev);
2521 
2522 		pWlanDev->destructor = free_netdev;
2523 		pWlanDev->ieee80211_ptr = &adapter->wdev;
2524 		pWlanDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
2525 		adapter->wdev.wiphy = hdd_ctx->wiphy;
2526 		adapter->wdev.netdev = pWlanDev;
2527 		/* set pWlanDev's parent to underlying device */
2528 		SET_NETDEV_DEV(pWlanDev, hdd_ctx->parent_dev);
2529 		hdd_wmm_init(adapter);
2530 		hdd_adapter_runtime_suspend_init(adapter);
2531 		spin_lock_init(&adapter->pause_map_lock);
2532 		adapter->start_time = adapter->last_time = qdf_system_ticks();
2533 	}
2534 
2535 	return adapter;
2536 }
2537 
2538 static QDF_STATUS hdd_register_interface(hdd_adapter_t *adapter,
2539 					 bool rtnl_held)
2540 {
2541 	struct net_device *pWlanDev = adapter->dev;
2542 
2543 	if (rtnl_held) {
2544 		if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
2545 			if (dev_alloc_name(pWlanDev, pWlanDev->name) < 0) {
2546 				hdd_err("Failed:dev_alloc_name");
2547 				return QDF_STATUS_E_FAILURE;
2548 			}
2549 		}
2550 		if (register_netdevice(pWlanDev)) {
2551 			hdd_err("Failed:register_netdev");
2552 			return QDF_STATUS_E_FAILURE;
2553 		}
2554 	} else {
2555 		if (register_netdev(pWlanDev)) {
2556 			hdd_err("Failed:register_netdev");
2557 			return QDF_STATUS_E_FAILURE;
2558 		}
2559 	}
2560 	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
2561 
2562 	return QDF_STATUS_SUCCESS;
2563 }
2564 
2565 QDF_STATUS hdd_sme_close_session_callback(void *pContext)
2566 {
2567 	hdd_adapter_t *adapter = pContext;
2568 
2569 	if (NULL == adapter) {
2570 		hdd_alert("NULL adapter");
2571 		return QDF_STATUS_E_INVAL;
2572 	}
2573 
2574 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
2575 		hdd_alert("Invalid magic");
2576 		return QDF_STATUS_NOT_INITIALIZED;
2577 	}
2578 
2579 	/*
2580 	 * For NAN Data interface, the close session results in the final
2581 	 * indication to the userspace
2582 	 */
2583 	if (adapter->device_mode == QDF_NDI_MODE)
2584 		hdd_ndp_session_end_handler(adapter);
2585 
2586 	clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
2587 
2588 	/*
2589 	 * We can be blocked while waiting for scheduled work to be
2590 	 * flushed, and the adapter structure can potentially be freed, in
2591 	 * which case the magic will have been reset.  So make sure the
2592 	 * magic is still good, and hence the adapter structure is still
2593 	 * valid, before signaling completion
2594 	 */
2595 	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
2596 		complete(&adapter->session_close_comp_var);
2597 
2598 	return QDF_STATUS_SUCCESS;
2599 }
2600 
2601 /**
2602  * hdd_check_and_init_tdls() - check and init TDLS operation for desired mode
2603  * @adapter: pointer to device adapter
2604  * @type: type of interface
2605  *
2606  * This routine will check the mode of adapter and if it is required then it
2607  * will initialize the TDLS operations
2608  *
2609  * Return: QDF_STATUS
2610  */
2611 #ifdef FEATURE_WLAN_TDLS
2612 static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter, uint32_t type)
2613 {
2614 	if (QDF_IBSS_MODE != type) {
2615 		if (0 != wlan_hdd_tdls_init(adapter)) {
2616 			hdd_err("wlan_hdd_tdls_init failed");
2617 			return QDF_STATUS_E_FAILURE;
2618 		}
2619 		set_bit(TDLS_INIT_DONE, &adapter->event_flags);
2620 	}
2621 	return QDF_STATUS_SUCCESS;
2622 }
2623 #else
2624 static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter, uint32_t type)
2625 {
2626 	return QDF_STATUS_SUCCESS;
2627 }
2628 #endif
2629 
2630 QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
2631 {
2632 	struct net_device *pWlanDev = adapter->dev;
2633 	hdd_station_ctx_t *pHddStaCtx = &adapter->sessionCtx.station;
2634 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2635 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
2636 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2637 	uint32_t type, subType;
2638 	unsigned long rc;
2639 	int ret_val;
2640 
2641 	INIT_COMPLETION(adapter->session_open_comp_var);
2642 	sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
2643 	sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
2644 	status = cds_get_vdev_types(adapter->device_mode, &type, &subType);
2645 	if (QDF_STATUS_SUCCESS != status) {
2646 		hdd_err("failed to get vdev type");
2647 		goto error_sme_open;
2648 	}
2649 	/* Open a SME session for future operation */
2650 	qdf_ret_status =
2651 		sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback, adapter,
2652 				 (uint8_t *) &adapter->macAddressCurrent,
2653 				 &adapter->sessionId, type, subType);
2654 	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
2655 		hdd_alert("sme_open_session() failed, status code %08d [x%08x]",
2656 		       qdf_ret_status, qdf_ret_status);
2657 		status = QDF_STATUS_E_FAILURE;
2658 		goto error_sme_open;
2659 	}
2660 	/* Block on a completion variable. Can't wait forever though. */
2661 	rc = wait_for_completion_timeout(
2662 		&adapter->session_open_comp_var,
2663 		msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
2664 	if (!rc) {
2665 		hdd_alert("Session is not opened within timeout period code %ld",
2666 			rc);
2667 		status = QDF_STATUS_E_FAILURE;
2668 		goto error_sme_open;
2669 	}
2670 
2671 	sme_set_vdev_ies_per_band(hdd_ctx->hHal, adapter->sessionId);
2672 	/* Register wireless extensions */
2673 	qdf_ret_status = hdd_register_wext(pWlanDev);
2674 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2675 		hdd_alert("hdd_register_wext() failed, status code %08d [x%08x]",
2676 		       qdf_ret_status, qdf_ret_status);
2677 		status = QDF_STATUS_E_FAILURE;
2678 		goto error_register_wext;
2679 	}
2680 	/* Set the Connection State to Not Connected */
2681 	hdd_notice("Set HDD connState to eConnectionState_NotConnected");
2682 	pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
2683 
2684 	/* Set the default operation channel */
2685 	pHddStaCtx->conn_info.operationChannel =
2686 		hdd_ctx->config->OperatingChannel;
2687 
2688 	/* Make the default Auth Type as OPEN */
2689 	pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2690 
2691 	status = hdd_init_tx_rx(adapter);
2692 	if (QDF_STATUS_SUCCESS != status) {
2693 		hdd_alert("hdd_init_tx_rx() failed, status code %08d [x%08x]",
2694 		       status, status);
2695 		goto error_init_txrx;
2696 	}
2697 
2698 	set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2699 
2700 	status = hdd_wmm_adapter_init(adapter);
2701 	if (QDF_STATUS_SUCCESS != status) {
2702 		hdd_alert("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
2703 		       status, status);
2704 		goto error_wmm_init;
2705 	}
2706 
2707 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
2708 
2709 	ret_val = wma_cli_set_command(adapter->sessionId,
2710 				      WMI_PDEV_PARAM_BURST_ENABLE,
2711 				      hdd_ctx->config->enableSifsBurst,
2712 				      PDEV_CMD);
2713 
2714 	if (0 != ret_val) {
2715 		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d",
2716 		       ret_val);
2717 	}
2718 	status = hdd_check_and_init_tdls(adapter, type);
2719 	if (status != QDF_STATUS_SUCCESS)
2720 		goto error_tdls_init;
2721 
2722 	status = hdd_lro_enable(hdd_ctx, adapter);
2723 	if (status != QDF_STATUS_SUCCESS)
2724 		goto error_lro_enable;
2725 
2726 	return QDF_STATUS_SUCCESS;
2727 
2728 error_lro_enable:
2729 	wlan_hdd_tdls_exit(adapter);
2730 error_tdls_init:
2731 	clear_bit(WMM_INIT_DONE, &adapter->event_flags);
2732 	hdd_wmm_adapter_close(adapter);
2733 error_wmm_init:
2734 	clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2735 	hdd_deinit_tx_rx(adapter);
2736 error_init_txrx:
2737 	hdd_unregister_wext(pWlanDev);
2738 error_register_wext:
2739 	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2740 		INIT_COMPLETION(adapter->session_close_comp_var);
2741 		if (QDF_STATUS_SUCCESS == sme_close_session(hdd_ctx->hHal,
2742 							    adapter->sessionId,
2743 							    hdd_sme_close_session_callback,
2744 							    adapter)) {
2745 			unsigned long rc;
2746 
2747 			/*
2748 			 * Block on a completion variable.
2749 			 * Can't wait forever though.
2750 			 */
2751 			rc = wait_for_completion_timeout(
2752 				&adapter->session_close_comp_var,
2753 				msecs_to_jiffies
2754 					(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
2755 			if (rc <= 0)
2756 				hdd_err("Session is not opened within timeout period code %ld",
2757 				       rc);
2758 		}
2759 	}
2760 error_sme_open:
2761 	return status;
2762 }
2763 
2764 void hdd_cleanup_actionframe(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
2765 {
2766 	hdd_cfg80211_state_t *cfgState;
2767 
2768 	cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
2769 
2770 	if (NULL != cfgState->buf) {
2771 		unsigned long rc;
2772 		rc = wait_for_completion_timeout(
2773 			&adapter->tx_action_cnf_event,
2774 			msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
2775 		if (!rc) {
2776 			hdd_err("HDD Wait for Action Confirmation Failed!!");
2777 			/*
2778 			 * Inform tx status as FAILURE to upper layer and free
2779 			 * cfgState->buf
2780 			 */
2781 			 hdd_send_action_cnf(adapter, false);
2782 		}
2783 	}
2784 	return;
2785 }
2786 
2787 /**
2788  * hdd_station_adapter_deinit() - De-initialize the station adapter
2789  * @hdd_ctx: global hdd context
2790  * @adapter: HDD adapter
2791  * @rtnl_held: Used to indicate whether or not the caller is holding
2792  *             the kernel rtnl_mutex
2793  *
2794  * This function De-initializes the STA/P2P/OCB adapter.
2795  *
2796  * Return: None.
2797  */
2798 static void hdd_station_adapter_deinit(hdd_context_t *hdd_ctx,
2799 				       hdd_adapter_t *adapter,
2800 				       bool rtnl_held)
2801 {
2802 	ENTER_DEV(adapter->dev);
2803 
2804 	if (adapter->dev) {
2805 		if (rtnl_held)
2806 			adapter->dev->wireless_handlers = NULL;
2807 		else {
2808 			rtnl_lock();
2809 			adapter->dev->wireless_handlers = NULL;
2810 			rtnl_unlock();
2811 		}
2812 	}
2813 
2814 	if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
2815 		hdd_deinit_tx_rx(adapter);
2816 		clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
2817 	}
2818 
2819 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
2820 		hdd_wmm_adapter_close(adapter);
2821 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
2822 	}
2823 
2824 	hdd_cleanup_actionframe(hdd_ctx, adapter);
2825 	wlan_hdd_tdls_exit(adapter);
2826 
2827 	EXIT();
2828 }
2829 
2830 /**
2831  * hdd_ap_adapter_deinit() - De-initialize the ap adapter
2832  * @hdd_ctx: global hdd context
2833  * @adapter: HDD adapter
2834  * @rtnl_held: the rtnl lock hold flag
2835  * This function De-initializes the AP/P2PGo adapter.
2836  *
2837  * Return: None.
2838  */
2839 static void hdd_ap_adapter_deinit(hdd_context_t *hdd_ctx,
2840 				  hdd_adapter_t *adapter,
2841 				  bool rtnl_held)
2842 {
2843 	ENTER_DEV(adapter->dev);
2844 
2845 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
2846 		hdd_wmm_adapter_close(adapter);
2847 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
2848 	}
2849 	wlan_hdd_undo_acs(adapter);
2850 
2851 	hdd_cleanup_actionframe(hdd_ctx, adapter);
2852 
2853 	hdd_unregister_hostapd(adapter, rtnl_held);
2854 
2855 	EXIT();
2856 }
2857 
2858 void hdd_deinit_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
2859 			bool rtnl_held)
2860 {
2861 	ENTER();
2862 
2863 	switch (adapter->device_mode) {
2864 	case QDF_STA_MODE:
2865 	case QDF_P2P_CLIENT_MODE:
2866 	case QDF_P2P_DEVICE_MODE:
2867 	{
2868 		hdd_station_adapter_deinit(hdd_ctx, adapter, rtnl_held);
2869 		break;
2870 	}
2871 
2872 	case QDF_SAP_MODE:
2873 	case QDF_P2P_GO_MODE:
2874 	{
2875 
2876 		hdd_ap_adapter_deinit(hdd_ctx, adapter, rtnl_held);
2877 		break;
2878 	}
2879 
2880 	default:
2881 		break;
2882 	}
2883 
2884 	EXIT();
2885 }
2886 
2887 static void hdd_cleanup_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
2888 				bool rtnl_held)
2889 {
2890 	struct net_device *pWlanDev = NULL;
2891 
2892 	if (adapter)
2893 		pWlanDev = adapter->dev;
2894 	else {
2895 		hdd_err("adapter is Null");
2896 		return;
2897 	}
2898 
2899 	hdd_debugfs_exit(adapter);
2900 
2901 	if (adapter->scan_info.default_scan_ies) {
2902 		qdf_mem_free(adapter->scan_info.default_scan_ies);
2903 		adapter->scan_info.default_scan_ies = NULL;
2904 	}
2905 
2906 	hdd_adapter_runtime_suspend_denit(adapter);
2907 
2908 	/*
2909 	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
2910 	 * the driver is almost closed and cannot handle either control
2911 	 * messages or data. However, unregister_netdevice() call above will
2912 	 * eventually invoke hdd_stop (ndo_close) driver callback, which attempts
2913 	 * to close the active connections (basically excites control path) which
2914 	 * is not right. Setting this flag helps hdd_stop() to recognize that
2915 	 * the interface is closed and restricts any operations on that
2916 	 */
2917 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2918 
2919 	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
2920 		if (rtnl_held) {
2921 			unregister_netdevice(pWlanDev);
2922 		} else {
2923 			unregister_netdev(pWlanDev);
2924 		}
2925 		/*
2926 		 * Note that the adapter is no longer valid at this point
2927 		 * since the memory has been reclaimed
2928 		 */
2929 	}
2930 }
2931 
2932 static QDF_STATUS hdd_check_for_existing_macaddr(hdd_context_t *hdd_ctx,
2933 						 tSirMacAddr macAddr)
2934 {
2935 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
2936 	hdd_adapter_t *adapter;
2937 	QDF_STATUS status;
2938 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
2939 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
2940 		adapter = adapterNode->pAdapter;
2941 		if (adapter
2942 		    && !qdf_mem_cmp(adapter->macAddressCurrent.bytes,
2943 				       macAddr, sizeof(tSirMacAddr))) {
2944 			return QDF_STATUS_E_FAILURE;
2945 		}
2946 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
2947 		adapterNode = pNext;
2948 	}
2949 	return QDF_STATUS_SUCCESS;
2950 }
2951 
2952 #ifdef CONFIG_FW_LOGS_BASED_ON_INI
2953 /**
2954  * hdd_set_fw_log_params() - Set log parameters to FW
2955  * @hdd_ctx: HDD Context
2956  * @adapter: HDD Adapter
2957  *
2958  * This function set the FW Debug log level based on the INI.
2959  *
2960  * Return: None
2961  */
2962 static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
2963 				  hdd_adapter_t *adapter)
2964 {
2965 	uint8_t count = 0, numentries = 0,
2966 			moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
2967 	uint32_t value = 0;
2968 	int ret;
2969 
2970 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
2971 	    (!hdd_ctx->config->enable_fw_log)) {
2972 		hdd_info("enable_fw_log not enabled in INI or in FTM mode return");
2973 		return;
2974 	}
2975 
2976 	/* Enable FW logs based on INI configuration */
2977 	hdd_ctx->fw_log_settings.dl_type =
2978 			hdd_ctx->config->enableFwLogType;
2979 	ret = wma_cli_set_command(adapter->sessionId,
2980 			WMI_DBGLOG_TYPE,
2981 			hdd_ctx->config->enableFwLogType,
2982 			DBG_CMD);
2983 	if (ret != 0)
2984 		hdd_err("Failed to enable FW log type ret %d",
2985 			ret);
2986 
2987 	hdd_ctx->fw_log_settings.dl_loglevel =
2988 			hdd_ctx->config->enableFwLogLevel;
2989 	ret = wma_cli_set_command(adapter->sessionId,
2990 			WMI_DBGLOG_LOG_LEVEL,
2991 			hdd_ctx->config->enableFwLogLevel,
2992 			DBG_CMD);
2993 	if (ret != 0)
2994 		hdd_err("Failed to enable FW log level ret %d",
2995 			ret);
2996 
2997 	hdd_string_to_u8_array(
2998 		hdd_ctx->config->enableFwModuleLogLevel,
2999 		moduleloglevel,
3000 		&numentries,
3001 		FW_MODULE_LOG_LEVEL_STRING_LENGTH);
3002 
3003 	while (count < numentries) {
3004 		/*
3005 		 * FW module log level input string looks like
3006 		 * below:
3007 		 * gFwDebugModuleLoglevel=<FW Module ID>,
3008 		 * <Log Level>,...
3009 		 * For example:
3010 		 * gFwDebugModuleLoglevel=
3011 		 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
3012 		 * Above input string means :
3013 		 * For FW module ID 1 enable log level 0
3014 		 * For FW module ID 2 enable log level 1
3015 		 * For FW module ID 3 enable log level 2
3016 		 * For FW module ID 4 enable log level 3
3017 		 * For FW module ID 5 enable log level 4
3018 		 * For FW module ID 6 enable log level 5
3019 		 * For FW module ID 7 enable log level 6
3020 		 */
3021 
3022 		/* FW expects WMI command value =
3023 		 * Module ID * 10 + Module Log level
3024 		 */
3025 		value = ((moduleloglevel[count] * 10) +
3026 			 moduleloglevel[count + 1]);
3027 		ret = wma_cli_set_command(adapter->sessionId,
3028 				WMI_DBGLOG_MOD_LOG_LEVEL,
3029 				value, DBG_CMD);
3030 		if (ret != 0)
3031 			hdd_err("Failed to enable FW module log level %d ret %d",
3032 				value, ret);
3033 
3034 		count += 2;
3035 	}
3036 
3037 }
3038 #else
3039 static void hdd_set_fw_log_params(hdd_context_t *hdd_ctx,
3040 				  hdd_adapter_t *adapter)
3041 {
3042 }
3043 
3044 #endif
3045 
3046 /**
3047  * hdd_set_fw_params() - Set parameters to firmware
3048  * @adapter: HDD adapter
3049  *
3050  * This function Sets various parameters to fw once the
3051  * adapter is started.
3052  *
3053  * Return: 0 on success or errno on failure
3054  */
3055 int hdd_set_fw_params(hdd_adapter_t *adapter)
3056 {
3057 	int ret;
3058 	hdd_context_t *hdd_ctx;
3059 
3060 	ENTER_DEV(adapter->dev);
3061 
3062 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3063 	if (!hdd_ctx)
3064 		return -EINVAL;
3065 
3066 	if ((cds_get_conparam() != QDF_GLOBAL_FTM_MODE) &&
3067 	    (!hdd_ctx->config->enable2x2)) {
3068 #define HDD_DTIM_1CHAIN_RX_ID 0x5
3069 #define HDD_SMPS_PARAM_VALUE_S 29
3070 		/*
3071 		 * Disable DTIM 1 chain Rx when in 1x1,
3072 		 * we are passing two value
3073 		 * as param_id << 29 | param_value.
3074 		 * Below param_value = 0(disable)
3075 		 */
3076 		ret = wma_cli_set_command(adapter->sessionId,
3077 					  WMI_STA_SMPS_PARAM_CMDID,
3078 					  HDD_DTIM_1CHAIN_RX_ID <<
3079 					  HDD_SMPS_PARAM_VALUE_S,
3080 					  VDEV_CMD);
3081 		if (ret) {
3082 			hdd_err("DTIM 1 chain set failed %d", ret);
3083 			goto error;
3084 		}
3085 
3086 		ret = wma_cli_set_command(adapter->sessionId,
3087 					  WMI_PDEV_PARAM_TX_CHAIN_MASK,
3088 					  hdd_ctx->config->txchainmask1x1,
3089 					  PDEV_CMD);
3090 		if (ret) {
3091 			hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK set failed %d",
3092 				ret);
3093 			goto error;
3094 		}
3095 
3096 		ret = wma_cli_set_command(adapter->sessionId,
3097 					  WMI_PDEV_PARAM_RX_CHAIN_MASK,
3098 					  hdd_ctx->config->rxchainmask1x1,
3099 					  PDEV_CMD);
3100 		if (ret) {
3101 			hdd_err("WMI_PDEV_PARAM_RX_CHAIN_MASK set failed %d",
3102 				ret);
3103 			goto error;
3104 		}
3105 #undef HDD_DTIM_1CHAIN_RX_ID
3106 #undef HDD_SMPS_PARAM_VALUE_S
3107 	} else {
3108 		hdd_info("FTM Mode or 2x2 mode - Do not set 1x1 params");
3109 	}
3110 
3111 	if (QDF_GLOBAL_FTM_MODE != cds_get_conparam()) {
3112 		ret = wma_cli_set_command(adapter->sessionId,
3113 					  WMI_PDEV_PARAM_HYST_EN,
3114 					  hdd_ctx->config->enableMemDeepSleep,
3115 					  PDEV_CMD);
3116 
3117 		if (ret) {
3118 			hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d",
3119 				ret);
3120 			goto error;
3121 		}
3122 
3123 		ret = wma_cli_set_command(adapter->sessionId,
3124 					  WMI_VDEV_PARAM_ENABLE_RTSCTS,
3125 					  hdd_ctx->config->rts_profile,
3126 					  VDEV_CMD);
3127 		if (ret) {
3128 			hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
3129 			goto error;
3130 		}
3131 	}
3132 
3133 	hdd_set_fw_log_params(hdd_ctx, adapter);
3134 
3135 	EXIT();
3136 	return 0;
3137 
3138 error:
3139 	return -EINVAL;
3140 }
3141 
3142 /**
3143  * hdd_open_adapter() - open and setup the hdd adatper
3144  * @hdd_ctx: global hdd context
3145  * @session_type: type of the interface to be created
3146  * @iface_name: User-visible name of the interface
3147  * @macAddr: MAC address to assign to the interface
3148  * @name_assign_type: the name of assign type of the netdev
3149  * @rtnl_held: the rtnl lock hold flag
3150  *
3151  * This function open and setup the hdd adpater according to the device
3152  * type request, assign the name, the mac address assigned, and then prepared
3153  * the hdd related parameters, queue, lock and ready to start.
3154  *
3155  * Return: the pointer of hdd adapter, otherwise NULL.
3156  */
3157 hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
3158 				const char *iface_name, tSirMacAddr macAddr,
3159 				unsigned char name_assign_type,
3160 				bool rtnl_held)
3161 {
3162 	hdd_adapter_t *adapter = NULL;
3163 	hdd_adapter_list_node_t *pHddAdapterNode = NULL;
3164 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3165 	hdd_cfg80211_state_t *cfgState;
3166 
3167 	hdd_info("iface(%s) type(%d)", iface_name, session_type);
3168 
3169 	if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
3170 		/*
3171 		 * Max limit reached on the number of vdevs configured by the
3172 		 * host. Return error
3173 		 */
3174 		hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
3175 			hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
3176 		return NULL;
3177 	}
3178 
3179 	if (macAddr == NULL) {
3180 		/* Not received valid macAddr */
3181 		hdd_err("Unable to add virtual intf: Not able to get valid mac address");
3182 		return NULL;
3183 	}
3184 	status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
3185 	if (QDF_STATUS_E_FAILURE == status) {
3186 		hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
3187 				" already exists",
3188 				MAC_ADDR_ARRAY(macAddr));
3189 		return NULL;
3190 	}
3191 
3192 	switch (session_type) {
3193 	case QDF_STA_MODE:
3194 		/* Reset locally administered bit if the device mode is STA */
3195 		WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
3196 	/* fall through */
3197 	case QDF_P2P_CLIENT_MODE:
3198 	case QDF_P2P_DEVICE_MODE:
3199 	case QDF_OCB_MODE:
3200 	case QDF_NDI_MODE:
3201 	case QDF_MONITOR_MODE:
3202 		adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
3203 						    name_assign_type,
3204 						    iface_name);
3205 
3206 		if (NULL == adapter) {
3207 			hdd_err("failed to allocate adapter for session %d",
3208 					session_type);
3209 			return NULL;
3210 		}
3211 
3212 		if (QDF_P2P_CLIENT_MODE == session_type)
3213 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
3214 		else if (QDF_P2P_DEVICE_MODE == session_type)
3215 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
3216 		else if (QDF_MONITOR_MODE == session_type)
3217 			adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
3218 		else
3219 			adapter->wdev.iftype = NL80211_IFTYPE_STATION;
3220 
3221 		adapter->device_mode = session_type;
3222 
3223 		if (QDF_NDI_MODE == session_type) {
3224 			status = hdd_init_nan_data_mode(adapter);
3225 			if (QDF_STATUS_SUCCESS != status)
3226 				goto err_free_netdev;
3227 		}
3228 
3229 		/*
3230 		 * Workqueue which gets scheduled in IPv4 notification
3231 		 * callback
3232 		 */
3233 		INIT_WORK(&adapter->ipv4NotifierWorkQueue,
3234 			  hdd_ipv4_notifier_work_queue);
3235 
3236 #ifdef WLAN_NS_OFFLOAD
3237 		/*
3238 		 * Workqueue which gets scheduled in IPv6
3239 		 * notification callback.
3240 		 */
3241 		INIT_WORK(&adapter->ipv6NotifierWorkQueue,
3242 			  hdd_ipv6_notifier_work_queue);
3243 #endif
3244 		status = hdd_register_interface(adapter, rtnl_held);
3245 		if (QDF_STATUS_SUCCESS != status) {
3246 			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3247 			goto err_free_netdev;
3248 		}
3249 
3250 		/* Stop the Interface TX queue. */
3251 		hdd_info("Disabling queues");
3252 		wlan_hdd_netif_queue_control(adapter,
3253 					     WLAN_NETIF_TX_DISABLE_N_CARRIER,
3254 					     WLAN_CONTROL_PATH);
3255 		break;
3256 
3257 
3258 	case QDF_P2P_GO_MODE:
3259 	case QDF_SAP_MODE:
3260 		adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
3261 						 name_assign_type,
3262 						 (uint8_t *) iface_name);
3263 		if (NULL == adapter) {
3264 			hdd_alert("failed to allocate adapter for session %d",
3265 					  session_type);
3266 			return NULL;
3267 		}
3268 
3269 		adapter->wdev.iftype =
3270 			(session_type ==
3271 			 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
3272 			NL80211_IFTYPE_P2P_GO;
3273 		adapter->device_mode = session_type;
3274 
3275 		status = hdd_register_hostapd(adapter, rtnl_held);
3276 		if (QDF_STATUS_SUCCESS != status) {
3277 			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3278 			goto err_free_netdev;
3279 		}
3280 		hdd_info("Disabling queues");
3281 		wlan_hdd_netif_queue_control(adapter,
3282 					     WLAN_NETIF_TX_DISABLE_N_CARRIER,
3283 					     WLAN_CONTROL_PATH);
3284 		break;
3285 	case QDF_FTM_MODE:
3286 		adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
3287 						    name_assign_type,
3288 						    "wlan0");
3289 		if (NULL == adapter) {
3290 			hdd_err("Failed to allocate adapter for FTM mode");
3291 			return NULL;
3292 		}
3293 		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
3294 		adapter->device_mode = session_type;
3295 		status = hdd_register_interface(adapter, rtnl_held);
3296 		if (QDF_STATUS_SUCCESS != status) {
3297 			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3298 			goto err_free_netdev;
3299 		}
3300 		/* Stop the Interface TX queue. */
3301 		hdd_info("Disabling queues");
3302 		wlan_hdd_netif_queue_control(adapter,
3303 					     WLAN_NETIF_TX_DISABLE_N_CARRIER,
3304 					     WLAN_CONTROL_PATH);
3305 		break;
3306 	default:
3307 		hdd_alert("Invalid session type %d", session_type);
3308 		QDF_ASSERT(0);
3309 		return NULL;
3310 	}
3311 
3312 	cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
3313 	mutex_init(&cfgState->remain_on_chan_ctx_lock);
3314 
3315 	if (QDF_STATUS_SUCCESS == status) {
3316 		/* Add it to the hdd's session list. */
3317 		pHddAdapterNode =
3318 			qdf_mem_malloc(sizeof(hdd_adapter_list_node_t));
3319 		if (NULL == pHddAdapterNode) {
3320 			status = QDF_STATUS_E_NOMEM;
3321 		} else {
3322 			pHddAdapterNode->pAdapter = adapter;
3323 			status = hdd_add_adapter_back(hdd_ctx, pHddAdapterNode);
3324 		}
3325 	}
3326 
3327 	if (QDF_STATUS_SUCCESS != status) {
3328 		if (NULL != adapter) {
3329 			hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
3330 			adapter = NULL;
3331 		}
3332 		if (NULL != pHddAdapterNode) {
3333 			qdf_mem_free(pHddAdapterNode);
3334 		}
3335 		return NULL;
3336 	}
3337 
3338 	if (QDF_STATUS_SUCCESS == status) {
3339 		cds_set_concurrency_mode(session_type);
3340 
3341 		/* Initialize the WoWL service */
3342 		if (!hdd_init_wowl(adapter)) {
3343 			hdd_alert("hdd_init_wowl failed");
3344 			goto err_close_adapter;
3345 		}
3346 
3347 		/* Adapter successfully added. Increment the vdev count */
3348 		hdd_ctx->current_intf_count++;
3349 
3350 		hdd_debug("current_intf_count=%d",
3351 		       hdd_ctx->current_intf_count);
3352 
3353 		cds_check_and_restart_sap_with_non_dfs_acs();
3354 	}
3355 
3356 	if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
3357 		hdd_err("Interface %s wow debug_fs init failed", iface_name);
3358 
3359 	return adapter;
3360 
3361 err_close_adapter:
3362 	hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
3363 err_free_netdev:
3364 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->macAddressCurrent.bytes);
3365 	free_netdev(adapter->dev);
3366 
3367 	return NULL;
3368 }
3369 
3370 QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
3371 			     bool rtnl_held)
3372 {
3373 	hdd_adapter_list_node_t *adapterNode, *pCurrent, *pNext;
3374 	QDF_STATUS status;
3375 
3376 	status = hdd_get_front_adapter(hdd_ctx, &pCurrent);
3377 	if (QDF_STATUS_SUCCESS != status) {
3378 		hdd_warn("adapter list empty %d",
3379 		       status);
3380 		return status;
3381 	}
3382 
3383 	while (pCurrent->pAdapter != adapter) {
3384 		status = hdd_get_next_adapter(hdd_ctx, pCurrent, &pNext);
3385 		if (QDF_STATUS_SUCCESS != status)
3386 			break;
3387 
3388 		pCurrent = pNext;
3389 	}
3390 	adapterNode = pCurrent;
3391 	if (QDF_STATUS_SUCCESS == status) {
3392 		cds_clear_concurrency_mode(adapter->device_mode);
3393 		hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held);
3394 
3395 		hdd_remove_adapter(hdd_ctx, adapterNode);
3396 		qdf_mem_free(adapterNode);
3397 		adapterNode = NULL;
3398 
3399 		/* Adapter removed. Decrement vdev count */
3400 		if (hdd_ctx->current_intf_count != 0)
3401 			hdd_ctx->current_intf_count--;
3402 
3403 		/* Fw will take care incase of concurrency */
3404 		return QDF_STATUS_SUCCESS;
3405 	}
3406 
3407 	return QDF_STATUS_E_FAILURE;
3408 }
3409 
3410 /**
3411  * hdd_close_all_adapters - Close all open adapters
3412  * @hdd_ctx:	Hdd context
3413  * rtnl_held:	True if RTNL lock held
3414  *
3415  * Close all open adapters.
3416  *
3417  * Return: QDF status code
3418  */
3419 QDF_STATUS hdd_close_all_adapters(hdd_context_t *hdd_ctx, bool rtnl_held)
3420 {
3421 	hdd_adapter_list_node_t *pHddAdapterNode;
3422 	QDF_STATUS status;
3423 
3424 	ENTER();
3425 
3426 	do {
3427 		status = hdd_remove_front_adapter(hdd_ctx, &pHddAdapterNode);
3428 		if (pHddAdapterNode && QDF_STATUS_SUCCESS == status) {
3429 			wlan_hdd_release_intf_addr(hdd_ctx,
3430 			pHddAdapterNode->pAdapter->macAddressCurrent.bytes);
3431 			hdd_cleanup_adapter(hdd_ctx, pHddAdapterNode->pAdapter,
3432 					    rtnl_held);
3433 			qdf_mem_free(pHddAdapterNode);
3434 			/* Adapter removed. Decrement vdev count */
3435 			if (hdd_ctx->current_intf_count != 0)
3436 				hdd_ctx->current_intf_count--;
3437 		}
3438 	} while (NULL != pHddAdapterNode && QDF_STATUS_E_EMPTY != status);
3439 
3440 	EXIT();
3441 
3442 	return QDF_STATUS_SUCCESS;
3443 }
3444 
3445 void wlan_hdd_reset_prob_rspies(hdd_adapter_t *pHostapdAdapter)
3446 {
3447 	struct qdf_mac_addr *bssid = NULL;
3448 	tSirUpdateIE updateIE;
3449 	switch (pHostapdAdapter->device_mode) {
3450 	case QDF_STA_MODE:
3451 	case QDF_P2P_CLIENT_MODE:
3452 	{
3453 		hdd_station_ctx_t *pHddStaCtx =
3454 			WLAN_HDD_GET_STATION_CTX_PTR(pHostapdAdapter);
3455 		bssid = &pHddStaCtx->conn_info.bssId;
3456 		break;
3457 	}
3458 	case QDF_SAP_MODE:
3459 	case QDF_P2P_GO_MODE:
3460 	case QDF_IBSS_MODE:
3461 	{
3462 		bssid = &pHostapdAdapter->macAddressCurrent;
3463 		break;
3464 	}
3465 	case QDF_FTM_MODE:
3466 	case QDF_P2P_DEVICE_MODE:
3467 	default:
3468 		/*
3469 		 * wlan_hdd_reset_prob_rspies should not have been called
3470 		 * for these kind of devices
3471 		 */
3472 		hdd_err("Unexpected request for the current device type %d",
3473 		       pHostapdAdapter->device_mode);
3474 		return;
3475 	}
3476 
3477 	qdf_copy_macaddr(&updateIE.bssid, bssid);
3478 	updateIE.smeSessionId = pHostapdAdapter->sessionId;
3479 	updateIE.ieBufferlength = 0;
3480 	updateIE.pAdditionIEBuffer = NULL;
3481 	updateIE.append = true;
3482 	updateIE.notify = false;
3483 	if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
3484 			      &updateIE,
3485 			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
3486 		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
3487 	}
3488 }
3489 
3490 /**
3491  * hdd_wait_for_sme_close_sesion() - Close and wait for SME session close
3492  * @hdd_ctx: HDD context which is already NULL validated
3493  * @adapter: HDD adapter which is already NULL validated
3494  *
3495  * Close the SME session and wait for its completion, if needed.
3496  *
3497  * Return: None
3498  */
3499 static void hdd_wait_for_sme_close_sesion(hdd_context_t *hdd_ctx,
3500 					hdd_adapter_t *adapter)
3501 {
3502 	unsigned long rc;
3503 
3504 	if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3505 		hdd_err("session is not opened:%d", adapter->sessionId);
3506 		return;
3507 	}
3508 
3509 	INIT_COMPLETION(adapter->session_close_comp_var);
3510 	if (QDF_STATUS_SUCCESS ==
3511 			sme_close_session(hdd_ctx->hHal, adapter->sessionId,
3512 				hdd_sme_close_session_callback,
3513 				adapter)) {
3514 		/*
3515 		 * Block on a completion variable. Can't wait
3516 		 * forever though.
3517 		 */
3518 		rc = wait_for_completion_timeout(
3519 				&adapter->session_close_comp_var,
3520 				msecs_to_jiffies
3521 				(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
3522 		if (!rc) {
3523 			hdd_err("failure waiting for session_close_comp_var");
3524 			if (adapter->device_mode == QDF_NDI_MODE)
3525 				hdd_ndp_session_end_handler(adapter);
3526 			clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3527 			return;
3528 		}
3529 		adapter->sessionId = HDD_SESSION_ID_INVALID;
3530 	}
3531 }
3532 
3533 QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
3534 			    const bool bCloseSession)
3535 {
3536 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
3537 	hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
3538 	union iwreq_data wrqu;
3539 	tSirUpdateIE updateIE;
3540 	unsigned long rc;
3541 	hdd_scaninfo_t *scan_info = NULL;
3542 
3543 	ENTER();
3544 
3545 	scan_info = &adapter->scan_info;
3546 	hdd_notice("Disabling queues");
3547 	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
3548 				   WLAN_CONTROL_PATH);
3549 	switch (adapter->device_mode) {
3550 	case QDF_STA_MODE:
3551 	case QDF_P2P_CLIENT_MODE:
3552 	case QDF_IBSS_MODE:
3553 	case QDF_P2P_DEVICE_MODE:
3554 	case QDF_NDI_MODE:
3555 		if ((QDF_NDI_MODE == adapter->device_mode) ||
3556 			hdd_conn_is_connected(
3557 				WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
3558 			hdd_is_connecting(
3559 				WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
3560 			INIT_COMPLETION(adapter->disconnect_comp_var);
3561 			/*
3562 			 * For NDI do not use pWextState from sta_ctx, if needed
3563 			 * extract from ndi_ctx.
3564 			 */
3565 			if (QDF_NDI_MODE == adapter->device_mode)
3566 				qdf_ret_status = sme_roam_disconnect(
3567 					hdd_ctx->hHal,
3568 					adapter->sessionId,
3569 					eCSR_DISCONNECT_REASON_NDI_DELETE);
3570 			else if (pWextState->roamProfile.BSSType ==
3571 						eCSR_BSS_TYPE_START_IBSS)
3572 				qdf_ret_status = sme_roam_disconnect(
3573 					hdd_ctx->hHal,
3574 					adapter->sessionId,
3575 					eCSR_DISCONNECT_REASON_IBSS_LEAVE);
3576 			else
3577 				qdf_ret_status = sme_roam_disconnect(
3578 					hdd_ctx->hHal,
3579 					adapter->sessionId,
3580 					eCSR_DISCONNECT_REASON_UNSPECIFIED);
3581 			/* success implies disconnect command got queued up successfully */
3582 			if (qdf_ret_status == QDF_STATUS_SUCCESS) {
3583 				rc = wait_for_completion_timeout(
3584 					&adapter->disconnect_comp_var,
3585 					msecs_to_jiffies
3586 						(WLAN_WAIT_TIME_DISCONNECT));
3587 				if (!rc) {
3588 					hdd_err("wait on disconnect_comp_var failed");
3589 				}
3590 			} else {
3591 				hdd_err("failed to post disconnect event to SME");
3592 			}
3593 			memset(&wrqu, '\0', sizeof(wrqu));
3594 			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3595 			memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3596 			wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
3597 					    NULL);
3598 		}
3599 		if (scan_info != NULL && scan_info->mScanPending) {
3600 			wlan_hdd_scan_abort(adapter);
3601 		}
3602 		hdd_lro_disable(hdd_ctx, adapter);
3603 		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
3604 
3605 #ifdef WLAN_OPEN_SOURCE
3606 		cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
3607 #endif
3608 
3609 		hdd_deregister_tx_flow_control(adapter);
3610 
3611 #ifdef WLAN_NS_OFFLOAD
3612 #ifdef WLAN_OPEN_SOURCE
3613 		cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
3614 #endif
3615 #endif
3616 
3617 		/*
3618 		 * It is possible that the caller of this function does not
3619 		 * wish to close the session
3620 		 */
3621 		if (true == bCloseSession)
3622 			hdd_wait_for_sme_close_sesion(hdd_ctx, adapter);
3623 		break;
3624 
3625 	case QDF_SAP_MODE:
3626 	case QDF_P2P_GO_MODE:
3627 		if (hdd_ctx->config->conc_custom_rule1 &&
3628 			(QDF_SAP_MODE == adapter->device_mode)) {
3629 			/*
3630 			 * Before stopping the sap adapter, lets make sure there
3631 			 * is no sap restart work pending.
3632 			 */
3633 			cds_flush_work(&hdd_ctx->sap_start_work);
3634 			hdd_info("Canceled the pending SAP restart work");
3635 			cds_change_sap_restart_required_status(false);
3636 		}
3637 		/* Any softap specific cleanup here... */
3638 		if (adapter->device_mode == QDF_P2P_GO_MODE)
3639 			wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
3640 
3641 		hdd_deregister_tx_flow_control(adapter);
3642 
3643 		mutex_lock(&hdd_ctx->sap_lock);
3644 		if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
3645 			QDF_STATUS status;
3646 			QDF_STATUS qdf_status;
3647 
3648 			/* Stop Bss. */
3649 			status = wlansap_stop_bss(
3650 					WLAN_HDD_GET_SAP_CTX_PTR(adapter));
3651 
3652 			if (QDF_IS_STATUS_SUCCESS(status)) {
3653 				hdd_hostapd_state_t *hostapd_state =
3654 					WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
3655 				qdf_event_reset(&hostapd_state->
3656 						qdf_stop_bss_event);
3657 				qdf_status =
3658 					qdf_wait_single_event(&hostapd_state->
3659 							qdf_stop_bss_event,
3660 							BSS_WAIT_TIMEOUT);
3661 
3662 				if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3663 					hdd_err("failure waiting for wlansap_stop_bss %d",
3664 						qdf_status);
3665 				}
3666 			} else {
3667 				hdd_err("failure in wlansap_stop_bss");
3668 			}
3669 			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
3670 			cds_decr_session_set_pcl(
3671 						     adapter->device_mode,
3672 							adapter->sessionId);
3673 
3674 			qdf_copy_macaddr(&updateIE.bssid,
3675 					 &adapter->macAddressCurrent);
3676 			updateIE.smeSessionId = adapter->sessionId;
3677 			updateIE.ieBufferlength = 0;
3678 			updateIE.pAdditionIEBuffer = NULL;
3679 			updateIE.append = false;
3680 			updateIE.notify = false;
3681 			/* Probe bcn reset */
3682 			if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
3683 					      &updateIE, eUPDATE_IE_PROBE_BCN)
3684 			    == QDF_STATUS_E_FAILURE) {
3685 				hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
3686 			}
3687 			/* Assoc resp reset */
3688 			if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
3689 					      &updateIE,
3690 					      eUPDATE_IE_ASSOC_RESP) ==
3691 			    QDF_STATUS_E_FAILURE) {
3692 				hdd_err("Could not pass on ASSOC_RSP data to PE");
3693 			}
3694 			/* Reset WNI_CFG_PROBE_RSP Flags */
3695 			wlan_hdd_reset_prob_rspies(adapter);
3696 			qdf_mem_free(adapter->sessionCtx.ap.beacon);
3697 			adapter->sessionCtx.ap.beacon = NULL;
3698 		}
3699 		mutex_unlock(&hdd_ctx->sap_lock);
3700 		if (true == bCloseSession)
3701 			hdd_wait_for_sme_close_sesion(hdd_ctx, adapter);
3702 		break;
3703 	case QDF_OCB_MODE:
3704 		cdp_peer_clear(cds_get_context(QDF_MODULE_ID_SOC),
3705 			cds_get_context(QDF_MODULE_ID_TXRX),
3706 			WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.staId[0]);
3707 		break;
3708 	default:
3709 		break;
3710 	}
3711 
3712 	EXIT();
3713 	return QDF_STATUS_SUCCESS;
3714 }
3715 
3716 /**
3717  * hdd_deinit_all_adapters - deinit all adapters
3718  * @hdd_ctx:   HDD context
3719  * @rtnl_held: True if RTNL lock held
3720  *
3721  */
3722 void  hdd_deinit_all_adapters(hdd_context_t *hdd_ctx, bool rtnl_held)
3723 {
3724 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
3725 	QDF_STATUS status;
3726 	hdd_adapter_t *adapter;
3727 
3728 	ENTER();
3729 
3730 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
3731 
3732 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
3733 		adapter = adapter_node->pAdapter;
3734 		hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
3735 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
3736 		adapter_node = next;
3737 	}
3738 
3739 	EXIT();
3740 }
3741 
3742 QDF_STATUS hdd_stop_all_adapters(hdd_context_t *hdd_ctx)
3743 {
3744 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
3745 	QDF_STATUS status;
3746 	hdd_adapter_t *adapter;
3747 
3748 	ENTER();
3749 
3750 	cds_flush_work(&hdd_ctx->sap_pre_cac_work);
3751 
3752 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
3753 
3754 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
3755 		adapter = adapterNode->pAdapter;
3756 		hdd_stop_adapter(hdd_ctx, adapter, true);
3757 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
3758 		adapterNode = pNext;
3759 	}
3760 
3761 	EXIT();
3762 
3763 	return QDF_STATUS_SUCCESS;
3764 }
3765 
3766 QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
3767 {
3768 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
3769 	QDF_STATUS status;
3770 	hdd_adapter_t *adapter;
3771 
3772 	ENTER();
3773 
3774 	cds_flush_work(&hdd_ctx->sap_pre_cac_work);
3775 
3776 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
3777 
3778 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
3779 		adapter = adapterNode->pAdapter;
3780 		hdd_notice("Disabling queues");
3781 		wlan_hdd_netif_queue_control(adapter,
3782 					   WLAN_NETIF_TX_DISABLE_N_CARRIER,
3783 					   WLAN_CONTROL_PATH);
3784 
3785 		adapter->sessionCtx.station.hdd_ReassocScenario = false;
3786 
3787 		hdd_deinit_tx_rx(adapter);
3788 		cds_decr_session_set_pcl(adapter->device_mode,
3789 						adapter->sessionId);
3790 		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
3791 			hdd_wmm_adapter_close(adapter);
3792 			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3793 		}
3794 
3795 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
3796 		adapterNode = pNext;
3797 	}
3798 
3799 	EXIT();
3800 
3801 	return QDF_STATUS_SUCCESS;
3802 }
3803 
3804 /**
3805  * hdd_is_interface_up()- Checkfor interface up before ssr
3806  * @hdd_ctx: HDD context
3807  *
3808  * check  if there are any wlan interfaces before SSR accordingly start
3809  * the interface.
3810  *
3811  * Return: 0 if interface was opened else false
3812  */
3813 static bool hdd_is_interface_up(hdd_adapter_t *adapter)
3814 {
3815 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
3816 		return true;
3817 	else
3818 		return false;
3819 }
3820 
3821 #if defined CFG80211_CONNECT_BSS
3822 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
3823 	&& !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
3824 static
3825 struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
3826 					  struct ieee80211_channel *channel,
3827 					  const u8 *bssid, const u8 *ssid,
3828 					  size_t ssid_len)
3829 {
3830 	return cfg80211_get_bss(wiphy, channel, bssid,
3831 				ssid, ssid_len,
3832 				WLAN_CAPABILITY_ESS,
3833 				WLAN_CAPABILITY_ESS);
3834 }
3835 #else
3836 static
3837 struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
3838 					  struct ieee80211_channel *channel,
3839 					  const u8 *bssid, const u8 *ssid,
3840 					  size_t ssid_len)
3841 {
3842 	return cfg80211_get_bss(wiphy, channel, bssid,
3843 				ssid, ssid_len,
3844 				IEEE80211_BSS_TYPE_ESS,
3845 				IEEE80211_PRIVACY_ANY);
3846 }
3847 #endif
3848 #endif
3849 
3850 #if defined CFG80211_CONNECT_BSS
3851 /**
3852  * hdd_connect_bss() - API to send connection status to supplicant
3853  * @dev: network device
3854  * @bssid: bssid to which we want to associate
3855  * @req_ie: Request Information Element
3856  * @req_ie_len: len of the req IE
3857  * @resp_ie: Response IE
3858  * @resp_ie_len: len of ht response IE
3859  * @status: status
3860  * @gfp: Kernel Flag
3861  * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
3862  *
3863  * The API is a wrapper to send connection status to supplicant
3864  *
3865  * Return: Void
3866  */
3867 #if defined CFG80211_CONNECT_TIMEOUT
3868 static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
3869 			struct cfg80211_bss *bss, const u8 *req_ie,
3870 			size_t req_ie_len, const u8 *resp_ie,
3871 			size_t resp_ie_len, int status, gfp_t gfp,
3872 			bool connect_timeout)
3873 {
3874 	if (connect_timeout)
3875 		cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
3876 	else
3877 		cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
3878 			resp_ie, resp_ie_len, status, gfp);
3879 }
3880 #else
3881 static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
3882 			struct cfg80211_bss *bss, const u8 *req_ie,
3883 			size_t req_ie_len, const u8 *resp_ie,
3884 			size_t resp_ie_len, int status, gfp_t gfp,
3885 			bool connect_timeout)
3886 {
3887 	cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
3888 		resp_ie, resp_ie_len, status, gfp);
3889 }
3890 #endif
3891 
3892 /**
3893  * hdd_connect_result() - API to send connection status to supplicant
3894  * @dev: network device
3895  * @bssid: bssid to which we want to associate
3896  * @roam_info: information about connected bss
3897  * @req_ie: Request Information Element
3898  * @req_ie_len: len of the req IE
3899  * @resp_ie: Response IE
3900  * @resp_ie_len: len of ht response IE
3901  * @status: status
3902  * @gfp: Kernel Flag
3903  * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
3904  *
3905  * The API is a wrapper to send connection status to supplicant
3906  * and allow runtime suspend
3907  *
3908  * Return: Void
3909  */
3910 void hdd_connect_result(struct net_device *dev, const u8 *bssid,
3911 			tCsrRoamInfo *roam_info, const u8 *req_ie,
3912 			size_t req_ie_len, const u8 *resp_ie,
3913 			size_t resp_ie_len, u16 status, gfp_t gfp,
3914 			bool connect_timeout)
3915 {
3916 	hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
3917 	struct cfg80211_bss *bss = NULL;
3918 
3919 	if (WLAN_STATUS_SUCCESS == status) {
3920 		struct ieee80211_channel *chan;
3921 		int freq;
3922 		int chan_no = roam_info->pBssDesc->channelId;
3923 
3924 		if (chan_no <= 14)
3925 			freq = ieee80211_channel_to_frequency(chan_no,
3926 			NL80211_BAND_2GHZ);
3927 		else
3928 			freq = ieee80211_channel_to_frequency(chan_no,
3929 			NL80211_BAND_5GHZ);
3930 
3931 		chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
3932 		bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
3933 			roam_info->u.pConnectedProfile->SSID.ssId,
3934 			roam_info->u.pConnectedProfile->SSID.length);
3935 	}
3936 
3937 	hdd_connect_bss(dev, bssid, bss, req_ie,
3938 		req_ie_len, resp_ie, resp_ie_len,
3939 		status, gfp, connect_timeout);
3940 
3941 	qdf_runtime_pm_allow_suspend(padapter->connect_rpm_ctx.connect);
3942 }
3943 #else
3944 void hdd_connect_result(struct net_device *dev, const u8 *bssid,
3945 			tCsrRoamInfo *roam_info, const u8 *req_ie,
3946 			size_t req_ie_len, const u8 *resp_ie,
3947 			size_t resp_ie_len, u16 status, gfp_t gfp,
3948 			bool connect_timeout)
3949 {
3950 	hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
3951 
3952 	cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
3953 				resp_ie, resp_ie_len, status, gfp);
3954 	qdf_runtime_pm_allow_suspend(padapter->connect_rpm_ctx.connect);
3955 }
3956 #endif
3957 
3958 
3959 QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
3960 {
3961 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
3962 	QDF_STATUS status;
3963 	hdd_adapter_t *adapter;
3964 #ifndef MSM_PLATFORM
3965 	struct qdf_mac_addr bcastMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
3966 #endif
3967 	eConnectionState connState;
3968 
3969 	ENTER();
3970 
3971 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
3972 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
3973 		adapter = adapterNode->pAdapter;
3974 
3975 		if (!hdd_is_interface_up(adapter))
3976 			goto get_adapter;
3977 
3978 		hdd_wmm_init(adapter);
3979 
3980 		switch (adapter->device_mode) {
3981 		case QDF_STA_MODE:
3982 		case QDF_P2P_CLIENT_MODE:
3983 		case QDF_P2P_DEVICE_MODE:
3984 
3985 			connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
3986 					->conn_info.connState;
3987 
3988 			hdd_init_station_mode(adapter);
3989 			/* Open the gates for HDD to receive Wext commands */
3990 			adapter->isLinkUpSvcNeeded = false;
3991 			adapter->scan_info.mScanPending = false;
3992 
3993 			/* Indicate disconnect event to supplicant if associated previously */
3994 			if (eConnectionState_Associated == connState ||
3995 			    eConnectionState_IbssConnected == connState ||
3996 			    eConnectionState_NotConnected == connState ||
3997 			    eConnectionState_IbssDisconnected == connState ||
3998 			    eConnectionState_Disconnecting == connState) {
3999 				union iwreq_data wrqu;
4000 				memset(&wrqu, '\0', sizeof(wrqu));
4001 				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4002 				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
4003 				wireless_send_event(adapter->dev, SIOCGIWAP,
4004 						    &wrqu, NULL);
4005 				adapter->sessionCtx.station.
4006 				hdd_ReassocScenario = false;
4007 
4008 				/* indicate disconnected event to nl80211 */
4009 				wlan_hdd_cfg80211_indicate_disconnect(
4010 						adapter->dev, false,
4011 						WLAN_REASON_UNSPECIFIED);
4012 			} else if (eConnectionState_Connecting == connState) {
4013 				/*
4014 				 * Indicate connect failure to supplicant if we were in the
4015 				 * process of connecting
4016 				 */
4017 				hdd_connect_result(adapter->dev, NULL, NULL,
4018 							NULL, 0, NULL, 0,
4019 							WLAN_STATUS_ASSOC_DENIED_UNSPEC,
4020 							GFP_KERNEL, false);
4021 			}
4022 
4023 			hdd_register_tx_flow_control(adapter,
4024 					hdd_tx_resume_timer_expired_handler,
4025 					hdd_tx_resume_cb);
4026 
4027 			break;
4028 
4029 		case QDF_SAP_MODE:
4030 			/* softAP can handle SSR */
4031 			break;
4032 
4033 		case QDF_P2P_GO_MODE:
4034 #ifdef MSM_PLATFORM
4035 			hdd_err("[SSR] send stop ap to supplicant");
4036 			cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
4037 #else
4038 			hdd_err("[SSR] send restart supplicant");
4039 			/* event supplicant to restart */
4040 			cfg80211_del_sta(adapter->dev,
4041 					 (const u8 *)&bcastMac.bytes[0],
4042 					 GFP_KERNEL);
4043 #endif
4044 			break;
4045 
4046 		default:
4047 			break;
4048 		}
4049 get_adapter:
4050 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4051 		adapterNode = pNext;
4052 	}
4053 
4054 	EXIT();
4055 
4056 	return QDF_STATUS_SUCCESS;
4057 }
4058 
4059 QDF_STATUS hdd_get_front_adapter(hdd_context_t *hdd_ctx,
4060 				 hdd_adapter_list_node_t **padapterNode)
4061 {
4062 	QDF_STATUS status;
4063 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4064 	status = qdf_list_peek_front(&hdd_ctx->hddAdapters,
4065 				     (qdf_list_node_t **) padapterNode);
4066 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4067 	return status;
4068 }
4069 
4070 QDF_STATUS hdd_get_next_adapter(hdd_context_t *hdd_ctx,
4071 				hdd_adapter_list_node_t *adapterNode,
4072 				hdd_adapter_list_node_t **pNextAdapterNode)
4073 {
4074 	QDF_STATUS status;
4075 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4076 	status = qdf_list_peek_next(&hdd_ctx->hddAdapters,
4077 				    (qdf_list_node_t *) adapterNode,
4078 				    (qdf_list_node_t **) pNextAdapterNode);
4079 
4080 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4081 	return status;
4082 }
4083 
4084 QDF_STATUS hdd_remove_adapter(hdd_context_t *hdd_ctx,
4085 			      hdd_adapter_list_node_t *adapterNode)
4086 {
4087 	QDF_STATUS status;
4088 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4089 	status = qdf_list_remove_node(&hdd_ctx->hddAdapters,
4090 				      &adapterNode->node);
4091 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4092 	return status;
4093 }
4094 
4095 QDF_STATUS hdd_remove_front_adapter(hdd_context_t *hdd_ctx,
4096 				    hdd_adapter_list_node_t **padapterNode)
4097 {
4098 	QDF_STATUS status;
4099 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4100 	status = qdf_list_remove_front(&hdd_ctx->hddAdapters,
4101 				       (qdf_list_node_t **) padapterNode);
4102 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4103 	return status;
4104 }
4105 
4106 QDF_STATUS hdd_add_adapter_back(hdd_context_t *hdd_ctx,
4107 				hdd_adapter_list_node_t *adapterNode)
4108 {
4109 	QDF_STATUS status;
4110 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4111 	status = qdf_list_insert_back(&hdd_ctx->hddAdapters,
4112 				      (qdf_list_node_t *) adapterNode);
4113 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4114 	return status;
4115 }
4116 
4117 QDF_STATUS hdd_add_adapter_front(hdd_context_t *hdd_ctx,
4118 				 hdd_adapter_list_node_t *adapterNode)
4119 {
4120 	QDF_STATUS status;
4121 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
4122 	status = qdf_list_insert_front(&hdd_ctx->hddAdapters,
4123 				       (qdf_list_node_t *) adapterNode);
4124 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
4125 	return status;
4126 }
4127 
4128 hdd_adapter_t *hdd_get_adapter_by_macaddr(hdd_context_t *hdd_ctx,
4129 					  tSirMacAddr macAddr)
4130 {
4131 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4132 	hdd_adapter_t *adapter;
4133 	QDF_STATUS status;
4134 
4135 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4136 
4137 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
4138 		adapter = adapterNode->pAdapter;
4139 
4140 		if (adapter
4141 		    && !qdf_mem_cmp(adapter->macAddressCurrent.bytes,
4142 				       macAddr, sizeof(tSirMacAddr))) {
4143 			return adapter;
4144 		}
4145 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4146 		adapterNode = pNext;
4147 	}
4148 
4149 	return NULL;
4150 
4151 }
4152 
4153 hdd_adapter_t *hdd_get_adapter_by_vdev(hdd_context_t *hdd_ctx,
4154 				       uint32_t vdev_id)
4155 {
4156 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4157 	hdd_adapter_t *adapter;
4158 	QDF_STATUS qdf_status;
4159 
4160 	qdf_status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4161 
4162 	while ((NULL != adapterNode) && (QDF_STATUS_SUCCESS == qdf_status)) {
4163 		adapter = adapterNode->pAdapter;
4164 
4165 		if (adapter->sessionId == vdev_id)
4166 			return adapter;
4167 
4168 		qdf_status =
4169 			hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4170 		adapterNode = pNext;
4171 	}
4172 
4173 	hdd_err("vdev_id %d does not exist with host", vdev_id);
4174 
4175 	return NULL;
4176 }
4177 
4178 /**
4179  * hdd_get_adapter_by_sme_session_id() - Return adapter with
4180  * the sessionid
4181  * @hdd_ctx: hdd context.
4182  * @sme_session_id: sme session is for the adapter to get.
4183  *
4184  * This function is used to get the adapter with provided session id
4185  *
4186  * Return: adapter pointer if found
4187  *
4188  */
4189 hdd_adapter_t *hdd_get_adapter_by_sme_session_id(hdd_context_t *hdd_ctx,
4190 						uint32_t sme_session_id)
4191 {
4192 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
4193 	hdd_adapter_t *adapter;
4194 	QDF_STATUS qdf_status;
4195 
4196 
4197 	qdf_status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
4198 
4199 	while ((NULL != adapter_node) &&
4200 			(QDF_STATUS_SUCCESS == qdf_status)) {
4201 		adapter = adapter_node->pAdapter;
4202 
4203 		if (adapter &&
4204 			 adapter->sessionId == sme_session_id)
4205 			return adapter;
4206 
4207 		qdf_status =
4208 			hdd_get_next_adapter(hdd_ctx,
4209 				 adapter_node, &next);
4210 		adapter_node = next;
4211 	}
4212 	return NULL;
4213 }
4214 
4215 /**
4216  * hdd_get_adapter() - to get adapter matching the mode
4217  * @hdd_ctx: hdd context
4218  * @mode: adapter mode
4219  *
4220  * This routine will return the pointer to adapter matching
4221  * with the passed mode.
4222  *
4223  * Return: pointer to adapter or null
4224  */
4225 hdd_adapter_t *hdd_get_adapter(hdd_context_t *hdd_ctx,
4226 			enum tQDF_ADAPTER_MODE mode)
4227 {
4228 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4229 	hdd_adapter_t *adapter;
4230 	QDF_STATUS status;
4231 
4232 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4233 
4234 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
4235 		adapter = adapterNode->pAdapter;
4236 
4237 		if (adapter && (mode == adapter->device_mode))
4238 			return adapter;
4239 
4240 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4241 		adapterNode = pNext;
4242 	}
4243 
4244 	return NULL;
4245 
4246 }
4247 
4248 /**
4249  * hdd_get_operating_channel() - return operating channel of the device mode
4250  * @hdd_ctx:	Pointer to the HDD context.
4251  * @mode:	Device mode for which operating channel is required.
4252  *              Suported modes:
4253  *			QDF_STA_MODE,
4254  *			QDF_P2P_CLIENT_MODE,
4255  *			QDF_SAP_MODE,
4256  *			QDF_P2P_GO_MODE.
4257  *
4258  * This API returns the operating channel of the requested device mode
4259  *
4260  * Return: channel number. "0" id the requested device is not found OR it is
4261  *	   not connected.
4262  */
4263 uint8_t hdd_get_operating_channel(hdd_context_t *hdd_ctx,
4264 			enum tQDF_ADAPTER_MODE mode)
4265 {
4266 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4267 	QDF_STATUS status;
4268 	hdd_adapter_t *adapter;
4269 	uint8_t operatingChannel = 0;
4270 
4271 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4272 
4273 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
4274 		adapter = adapterNode->pAdapter;
4275 
4276 		if (mode == adapter->device_mode) {
4277 			switch (adapter->device_mode) {
4278 			case QDF_STA_MODE:
4279 			case QDF_P2P_CLIENT_MODE:
4280 				if (hdd_conn_is_connected
4281 					    (WLAN_HDD_GET_STATION_CTX_PTR
4282 						(adapter))) {
4283 					operatingChannel =
4284 						(WLAN_HDD_GET_STATION_CTX_PTR
4285 						(adapter))->conn_info.
4286 							operationChannel;
4287 				}
4288 				break;
4289 			case QDF_SAP_MODE:
4290 			case QDF_P2P_GO_MODE:
4291 				/* softap connection info */
4292 				if (test_bit
4293 					    (SOFTAP_BSS_STARTED,
4294 					    &adapter->event_flags))
4295 					operatingChannel =
4296 						(WLAN_HDD_GET_AP_CTX_PTR
4297 						(adapter))->operatingChannel;
4298 				break;
4299 			default:
4300 				break;
4301 			}
4302 
4303 			break;  /* Found the device of interest. break the loop */
4304 		}
4305 
4306 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4307 		adapterNode = pNext;
4308 	}
4309 	return operatingChannel;
4310 }
4311 
4312 static inline QDF_STATUS hdd_unregister_wext_all_adapters(hdd_context_t *
4313 							  hdd_ctx)
4314 {
4315 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4316 	QDF_STATUS status;
4317 	hdd_adapter_t *adapter;
4318 
4319 	ENTER();
4320 
4321 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4322 
4323 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
4324 		adapter = adapterNode->pAdapter;
4325 		if ((adapter->device_mode == QDF_STA_MODE) ||
4326 		    (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
4327 		    (adapter->device_mode == QDF_IBSS_MODE) ||
4328 		    (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
4329 		    (adapter->device_mode == QDF_SAP_MODE) ||
4330 		    (adapter->device_mode == QDF_P2P_GO_MODE)) {
4331 			wlan_hdd_cfg80211_deregister_frames(adapter);
4332 			hdd_unregister_wext(adapter->dev);
4333 		}
4334 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4335 		adapterNode = pNext;
4336 	}
4337 
4338 	EXIT();
4339 
4340 	return QDF_STATUS_SUCCESS;
4341 }
4342 
4343 QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx)
4344 {
4345 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
4346 	QDF_STATUS status;
4347 	hdd_adapter_t *adapter;
4348 
4349 	ENTER();
4350 
4351 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
4352 
4353 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
4354 		adapter = adapterNode->pAdapter;
4355 		if ((adapter->device_mode == QDF_STA_MODE) ||
4356 		    (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
4357 		    (adapter->device_mode == QDF_IBSS_MODE) ||
4358 		    (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
4359 		    (adapter->device_mode == QDF_SAP_MODE) ||
4360 		    (adapter->device_mode == QDF_P2P_GO_MODE)) {
4361 			hdd_abort_mac_scan(hdd_ctx, adapter->sessionId,
4362 					   eCSR_SCAN_ABORT_DEFAULT);
4363 		}
4364 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
4365 		adapterNode = pNext;
4366 	}
4367 
4368 	EXIT();
4369 
4370 	return QDF_STATUS_SUCCESS;
4371 }
4372 
4373 /**
4374  * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
4375  * adapters
4376  * @hdd_ctx: The HDD context containing the adapters to operate on
4377  *
4378  * return: QDF_STATUS_SUCCESS
4379  */
4380 static QDF_STATUS hdd_abort_sched_scan_all_adapters(hdd_context_t *hdd_ctx)
4381 {
4382 	hdd_adapter_list_node_t *adapter_node = NULL, *next_node = NULL;
4383 	QDF_STATUS status;
4384 	hdd_adapter_t *adapter;
4385 	int err;
4386 
4387 	ENTER();
4388 
4389 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
4390 
4391 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
4392 		adapter = adapter_node->pAdapter;
4393 		if ((adapter->device_mode == QDF_STA_MODE) ||
4394 		    (adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
4395 		    (adapter->device_mode == QDF_IBSS_MODE) ||
4396 		    (adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
4397 		    (adapter->device_mode == QDF_SAP_MODE) ||
4398 		    (adapter->device_mode == QDF_P2P_GO_MODE)) {
4399 			err = wlan_hdd_sched_scan_stop(adapter->dev);
4400 			if (err)
4401 				hdd_err("Unable to stop scheduled scan");
4402 		}
4403 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next_node);
4404 		adapter_node = next_node;
4405 	}
4406 
4407 	EXIT();
4408 
4409 	return QDF_STATUS_SUCCESS;
4410 }
4411 
4412 #ifdef WLAN_NS_OFFLOAD
4413 /**
4414  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4415  * @hdd_ctx: Pointer to hdd context
4416  *
4417  * Unregister for IPv6 address change notifications.
4418  *
4419  * Return: None
4420  */
4421 static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
4422 {
4423 	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4424 
4425 	return;
4426 }
4427 
4428 /**
4429  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4430  * @hdd_ctx: Pointer to hdd context
4431  *
4432  * Register for IPv6 address change notifications.
4433  *
4434  * Return: 0 on success and errno on failure.
4435  */
4436 static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
4437 {
4438 	int ret;
4439 
4440 	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
4441 	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4442 	if (ret) {
4443 		hdd_err("Failed to register IPv6 notifier: %d", ret);
4444 		goto out;
4445 	}
4446 
4447 	hdd_info("Registered IPv6 notifier");
4448 out:
4449 	return ret;
4450 }
4451 #else
4452 /**
4453  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4454  * @hdd_ctx: Pointer to hdd context
4455  *
4456  * Unregister for IPv6 address change notifications.
4457  *
4458  * Return: None
4459  */
4460 static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
4461 {
4462 }
4463 
4464 /**
4465  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4466  * @hdd_ctx: Pointer to hdd context
4467  *
4468  * Register for IPv6 address change notifications.
4469  *
4470  * Return: None
4471  */
4472 static int hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
4473 {
4474 	return 0;
4475 }
4476 #endif
4477 
4478 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
4479 /**
4480  * hdd_logging_sock_activate_svc() - Activate logging
4481  * @hdd_ctx: HDD context
4482  *
4483  * Activates the logging service
4484  *
4485  * Return: Zero in case of success, negative value otherwise
4486  */
4487 static int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
4488 {
4489 	int ret;
4490 	struct hdd_config *config = hdd_ctx->config;
4491 
4492 	if (!config->wlanLoggingEnable)
4493 		return 0;
4494 
4495 	ret = wlan_logging_sock_activate_svc(config->wlanLoggingFEToConsole,
4496 					     config->wlanLoggingNumBuf);
4497 	if (ret)
4498 		hdd_err("wlan_logging_sock_activate_svc failed: %d", ret);
4499 	return ret;
4500 }
4501 
4502 /**
4503  * wlan_hdd_logging_sock_deactivate_svc() - Deactivate logging
4504  * @hdd_ctx: HDD context
4505  *
4506  * Deactivates the logging service
4507  *
4508  * Return: 0 on deactivating the logging service
4509  */
4510 static int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
4511 {
4512 	if (hdd_ctx && hdd_ctx->config->wlanLoggingEnable)
4513 		return wlan_logging_sock_deactivate_svc();
4514 
4515 	return 0;
4516 }
4517 #else
4518 static inline int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
4519 {
4520 	return 0;
4521 }
4522 
4523 static inline int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
4524 {
4525 	return 0;
4526 }
4527 #endif
4528 
4529 /**
4530  * hdd_register_notifiers - Register netdev notifiers.
4531  * @hdd_ctx: HDD context
4532  *
4533  * Register netdev notifiers like IPv4 and IPv6.
4534  *
4535  * Return: 0 on success and errno on failure
4536  */
4537 static int hdd_register_notifiers(hdd_context_t *hdd_ctx)
4538 {
4539 	int ret;
4540 
4541 	ret = register_netdevice_notifier(&hdd_netdev_notifier);
4542 	if (ret) {
4543 		hdd_err("register_netdevice_notifier failed: %d", ret);
4544 		goto out;
4545 	}
4546 
4547 	ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
4548 	if (ret)
4549 		goto unregister_notifier;
4550 
4551 	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
4552 	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4553 	if (ret) {
4554 		hdd_err("Failed to register IPv4 notifier: %d", ret);
4555 		goto unregister_ip6_notifier;
4556 	}
4557 
4558 	return 0;
4559 
4560 unregister_ip6_notifier:
4561 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
4562 unregister_notifier:
4563 	unregister_netdevice_notifier(&hdd_netdev_notifier);
4564 out:
4565 	return ret;
4566 
4567 }
4568 
4569 /**
4570  * hdd_unregister_notifiers - Unregister netdev notifiers.
4571  * @hdd_ctx: HDD context
4572  *
4573  * Unregister netdev notifiers like IPv4 and IPv6.
4574  *
4575  * Return: None.
4576  */
4577 static void hdd_unregister_notifiers(hdd_context_t *hdd_ctx)
4578 {
4579 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
4580 
4581 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4582 
4583 	unregister_netdevice_notifier(&hdd_netdev_notifier);
4584 }
4585 
4586 /**
4587  * hdd_exit_netlink_services - Exit netlink services
4588  * @hdd_ctx: HDD context
4589  *
4590  * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
4591  * nl service.
4592  *
4593  * Return: None.
4594  */
4595 static void hdd_exit_netlink_services(hdd_context_t *hdd_ctx)
4596 {
4597 	hdd_close_cesium_nl_sock();
4598 
4599 	ptt_sock_deactivate_svc();
4600 
4601 	nl_srv_exit();
4602 }
4603 
4604 /**
4605  * hdd_init_netlink_services- Init netlink services
4606  * @hdd_ctx: HDD context
4607  *
4608  * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
4609  * nl service.
4610  *
4611  * Return: 0 on success and errno on failure.
4612  */
4613 static int hdd_init_netlink_services(hdd_context_t *hdd_ctx)
4614 {
4615 	int ret;
4616 
4617 	ret = wlan_hdd_nl_init(hdd_ctx);
4618 	if (ret) {
4619 		hdd_alert("nl_srv_init failed: %d", ret);
4620 		goto out;
4621 	}
4622 	cds_set_radio_index(hdd_ctx->radio_index);
4623 
4624 	ret = oem_activate_service(hdd_ctx);
4625 	if (ret) {
4626 		hdd_alert("oem_activate_service failed: %d", ret);
4627 		goto err_nl_srv;
4628 	}
4629 
4630 	ret = ptt_sock_activate_svc();
4631 	if (ret) {
4632 		hdd_alert("ptt_sock_activate_svc failed: %d", ret);
4633 		goto err_nl_srv;
4634 	}
4635 
4636 	ret = hdd_open_cesium_nl_sock();
4637 	if (ret)
4638 		hdd_warn("hdd_open_cesium_nl_sock failed");
4639 
4640 	ret = cnss_diag_activate_service();
4641 	if (ret) {
4642 		hdd_alert("cnss_diag_activate_service failed: %d", ret);
4643 		goto err_close_cesium;
4644 	}
4645 
4646 	return 0;
4647 
4648 err_close_cesium:
4649 	hdd_close_cesium_nl_sock();
4650 	ptt_sock_deactivate_svc();
4651 err_nl_srv:
4652 	nl_srv_exit();
4653 out:
4654 	return ret;
4655 }
4656 
4657 /**
4658  * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
4659  * @hdd_ctx:	HDD context.
4660  *
4661  * Destroy RX wakelock.
4662  *
4663  * Return: None.
4664  */
4665 static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx)
4666 {
4667 	qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
4668 }
4669 
4670 /**
4671  * hdd_rx_wake_lock_create() - Create RX wakelock
4672  * @hdd_ctx:	HDD context.
4673  *
4674  * Create RX wakelock.
4675  *
4676  * Return: None.
4677  */
4678 static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx)
4679 {
4680 	qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
4681 }
4682 
4683 /**
4684  * hdd_roc_context_init() - Init ROC context
4685  * @hdd_ctx:	HDD context.
4686  *
4687  * Initialize ROC context.
4688  *
4689  * Return: 0 on success and errno on failure.
4690  */
4691 static int hdd_roc_context_init(hdd_context_t *hdd_ctx)
4692 {
4693 	qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock);
4694 	qdf_list_create(&hdd_ctx->hdd_roc_req_q, MAX_ROC_REQ_QUEUE_ENTRY);
4695 
4696 	INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue);
4697 
4698 	return 0;
4699 }
4700 
4701 /**
4702  * hdd_roc_context_destroy() - Destroy ROC context
4703  * @hdd_ctx:	HDD context.
4704  *
4705  * Destroy roc list and flush the pending roc work.
4706  *
4707  * Return: None.
4708  */
4709 static void hdd_roc_context_destroy(hdd_context_t *hdd_ctx)
4710 {
4711 	flush_delayed_work(&hdd_ctx->roc_req_work);
4712 	qdf_list_destroy(&hdd_ctx->hdd_roc_req_q);
4713 }
4714 
4715 /**
4716  * hdd_context_deinit() - Deinitialize HDD context
4717  * @hdd_ctx:    HDD context.
4718  *
4719  * Deinitialize HDD context along with all the feature specific contexts but
4720  * do not free hdd context itself. Caller of this API is supposed to free
4721  * HDD context.
4722  *
4723  * return: 0 on success and errno on failure.
4724  */
4725 static int hdd_context_deinit(hdd_context_t *hdd_ctx)
4726 {
4727 	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
4728 
4729 	hdd_roc_context_destroy(hdd_ctx);
4730 
4731 	hdd_sap_context_destroy(hdd_ctx);
4732 
4733 	hdd_rx_wake_lock_destroy(hdd_ctx);
4734 
4735 	hdd_tdls_context_destroy(hdd_ctx);
4736 
4737 	hdd_scan_context_destroy(hdd_ctx);
4738 
4739 	qdf_list_destroy(&hdd_ctx->hddAdapters);
4740 
4741 	return 0;
4742 }
4743 
4744 /**
4745  * hdd_context_destroy() - Destroy HDD context
4746  * @hdd_ctx:	HDD context to be destroyed.
4747  *
4748  * Free config and HDD context as well as destroy all the resources.
4749  *
4750  * Return: None
4751  */
4752 static void hdd_context_destroy(hdd_context_t *hdd_ctx)
4753 {
4754 	if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
4755 		hdd_logging_sock_deactivate_svc(hdd_ctx);
4756 
4757 	hdd_context_deinit(hdd_ctx);
4758 
4759 	qdf_mem_free(hdd_ctx->config);
4760 	hdd_ctx->config = NULL;
4761 
4762 	wiphy_free(hdd_ctx->wiphy);
4763 }
4764 
4765 /**
4766  * hdd_wlan_exit() - HDD WLAN exit function
4767  * @hdd_ctx:	Pointer to the HDD Context
4768  *
4769  * This is the driver exit point (invoked during rmmod)
4770  *
4771  * Return: None
4772  */
4773 static void hdd_wlan_exit(hdd_context_t *hdd_ctx)
4774 {
4775 	v_CONTEXT_t p_cds_context = hdd_ctx->pcds_context;
4776 	QDF_STATUS qdf_status;
4777 	struct wiphy *wiphy = hdd_ctx->wiphy;
4778 	int driver_status;
4779 
4780 	ENTER();
4781 
4782 	if (QDF_TIMER_STATE_RUNNING ==
4783 		qdf_mc_timer_get_current_state(&hdd_ctx->iface_change_timer)) {
4784 		hdd_info("Stpp interface change timer");
4785 		qdf_mc_timer_stop(&hdd_ctx->iface_change_timer);
4786 	}
4787 
4788 	if (!QDF_IS_STATUS_SUCCESS
4789 	   (qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer)))
4790 		hdd_err("Cannot delete interface change timer");
4791 
4792 
4793 	hdd_unregister_notifiers(hdd_ctx);
4794 
4795 	hdd_bus_bandwidth_destroy(hdd_ctx);
4796 
4797 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4798 	if (QDF_TIMER_STATE_RUNNING ==
4799 	    qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
4800 		qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
4801 	}
4802 
4803 	if (!QDF_IS_STATUS_SUCCESS
4804 		    (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
4805 		hdd_err("Cannot deallocate ACS Skip timer");
4806 	}
4807 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4808 	qdf_mem_free(hdd_ctx->last_acs_channel_list);
4809 	hdd_ctx->last_acs_channel_list = NULL;
4810 	hdd_ctx->num_of_channels = 0;
4811 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4812 #endif
4813 
4814 	mutex_lock(&hdd_ctx->iface_change_lock);
4815 	driver_status = hdd_ctx->driver_status;
4816 	mutex_unlock(&hdd_ctx->iface_change_lock);
4817 
4818 	/*
4819 	 * Powersave Offload Case
4820 	 * Disable Idle Power Save Mode
4821 	 */
4822 	hdd_set_idle_ps_config(hdd_ctx, false);
4823 
4824 	if (driver_status != DRIVER_MODULES_CLOSED) {
4825 		hdd_unregister_wext_all_adapters(hdd_ctx);
4826 		/*
4827 		 * Cancel any outstanding scan requests.  We are about to close
4828 		 * all of our adapters, but an adapter structure is what SME
4829 		 * passes back to our callback function.  Hence if there
4830 		 * are any outstanding scan requests then there is a
4831 		 * race condition between when the adapter is closed and
4832 		 * when the callback is invoked.  We try to resolve that
4833 		 * race condition here by canceling any outstanding scans
4834 		 * before we close the adapters.
4835 		 * Note that the scans may be cancelled in an asynchronous
4836 		 * manner, so ideally there needs to be some kind of
4837 		 * synchronization.  Rather than introduce a new
4838 		 * synchronization here, we will utilize the fact that we are
4839 		 * about to Request Full Power, and since that is synchronized,
4840 		 * the expectation is that by the time Request Full Power has
4841 		 * completed, all scans will be cancelled
4842 		 */
4843 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
4844 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
4845 		hdd_stop_all_adapters(hdd_ctx);
4846 	}
4847 
4848 	/*
4849 	 * Close the scheduler before calling cds_close to make sure no thread
4850 	 * is scheduled after the each module close is called i.e after all the
4851 	 * data structures are freed.
4852 	 */
4853 	qdf_status = cds_sched_close(p_cds_context);
4854 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4855 		hdd_alert("Failed to close CDS Scheduler");
4856 		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
4857 	}
4858 
4859 	hdd_wlan_stop_modules(hdd_ctx);
4860 
4861 	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
4862 	qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
4863 	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
4864 
4865 	/*
4866 	 * Close CDS
4867 	 * This frees pMac(HAL) context. There should not be any call
4868 	 * that requires pMac access after this.
4869 	 */
4870 
4871 	hdd_green_ap_deinit(hdd_ctx);
4872 
4873 	hdd_runtime_suspend_context_deinit(hdd_ctx);
4874 	hdd_close_all_adapters(hdd_ctx, false);
4875 
4876 	hdd_ipa_cleanup(hdd_ctx);
4877 
4878 	/* Free up RoC request queue and flush workqueue */
4879 	cds_flush_work(&hdd_ctx->roc_req_work);
4880 
4881 	wlansap_global_deinit();
4882 	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
4883 	wiphy_unregister(wiphy);
4884 	wlan_hdd_cfg80211_deinit(wiphy);
4885 
4886 	hdd_lpass_notify_stop(hdd_ctx);
4887 
4888 	hdd_exit_netlink_services(hdd_ctx);
4889 	mutex_destroy(&hdd_ctx->iface_change_lock);
4890 	hdd_context_destroy(hdd_ctx);
4891 }
4892 
4893 void __hdd_wlan_exit(void)
4894 {
4895 	hdd_context_t *hdd_ctx;
4896 
4897 	ENTER();
4898 
4899 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4900 	if (!hdd_ctx) {
4901 		hdd_alert("Invalid HDD Context");
4902 		EXIT();
4903 		return;
4904 	}
4905 
4906 	/* Check IPA HW Pipe shutdown */
4907 	hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
4908 
4909 	memdump_deinit();
4910 	hdd_driver_memdump_deinit();
4911 
4912 	/* Do all the cleanup before deregistering the driver */
4913 	hdd_wlan_exit(hdd_ctx);
4914 
4915 	EXIT();
4916 }
4917 
4918 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4919 /**
4920  * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
4921  * @data: pointer to hdd_context_t
4922  *
4923  * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
4924  * Then new ACS request will do a fresh scan without reusing the cached
4925  * scan information.
4926  *
4927  * Return: void
4928  */
4929 void hdd_skip_acs_scan_timer_handler(void *data)
4930 {
4931 	hdd_context_t *hdd_ctx = (hdd_context_t *) data;
4932 
4933 	hdd_notice("ACS Scan result expired. Reset ACS scan skip");
4934 	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
4935 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4936 	qdf_mem_free(hdd_ctx->last_acs_channel_list);
4937 	hdd_ctx->last_acs_channel_list = NULL;
4938 	hdd_ctx->num_of_channels = 0;
4939 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4940 
4941 	if (!hdd_ctx->hHal)
4942 		return;
4943 	sme_scan_flush_result(hdd_ctx->hHal);
4944 }
4945 #endif
4946 
4947 #ifdef QCA_HT_2040_COEX
4948 /**
4949  * hdd_wlan_set_ht2040_mode() - notify FW with HT20/HT40 mode
4950  * @adapter: pointer to adapter
4951  * @staId: station id
4952  * @macAddrSTA: station MAC address
4953  * @channel_type: channel type
4954  *
4955  * This function notifies FW with HT20/HT40 mode
4956  *
4957  * Return: 0 if successful, error number otherwise
4958  */
4959 int hdd_wlan_set_ht2040_mode(hdd_adapter_t *adapter, uint16_t staId,
4960 			     struct qdf_mac_addr macAddrSTA, int channel_type)
4961 {
4962 	int status;
4963 	QDF_STATUS qdf_status;
4964 	hdd_context_t *hdd_ctx = NULL;
4965 
4966 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4967 
4968 	status = wlan_hdd_validate_context(hdd_ctx);
4969 	if (status)
4970 		return status;
4971 
4972 	if (!hdd_ctx->hHal)
4973 		return -EINVAL;
4974 
4975 	qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, staId, macAddrSTA,
4976 					    adapter->sessionId, channel_type);
4977 	if (QDF_STATUS_SUCCESS != qdf_status) {
4978 		hdd_err("Fail to send notification with ht2040 mode");
4979 		return -EINVAL;
4980 	}
4981 
4982 	return 0;
4983 }
4984 #endif
4985 
4986 /**
4987  * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
4988  * @state: state
4989  *
4990  * This function notifies FW with modem power status
4991  *
4992  * Return: 0 if successful, error number otherwise
4993  */
4994 int hdd_wlan_notify_modem_power_state(int state)
4995 {
4996 	int status;
4997 	QDF_STATUS qdf_status;
4998 	hdd_context_t *hdd_ctx;
4999 
5000 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5001 	status = wlan_hdd_validate_context(hdd_ctx);
5002 	if (status)
5003 		return status;
5004 
5005 	if (!hdd_ctx->hHal)
5006 		return -EINVAL;
5007 
5008 	qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
5009 	if (QDF_STATUS_SUCCESS != qdf_status) {
5010 		hdd_err("Fail to send notification with modem power state %d",
5011 		       state);
5012 		return -EINVAL;
5013 	}
5014 	return 0;
5015 }
5016 
5017 /**
5018  *
5019  * hdd_post_cds_enable_config() - HDD post cds start config helper
5020  * @adapter - Pointer to the HDD
5021  *
5022  * Return: None
5023  */
5024 QDF_STATUS hdd_post_cds_enable_config(hdd_context_t *hdd_ctx)
5025 {
5026 	QDF_STATUS qdf_ret_status;
5027 
5028 	/*
5029 	 * Send ready indication to the HDD.  This will kick off the MAC
5030 	 * into a 'running' state and should kick off an initial scan.
5031 	 */
5032 	qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
5033 	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
5034 		hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
5035 			qdf_ret_status, qdf_ret_status);
5036 		return QDF_STATUS_E_FAILURE;
5037 	}
5038 
5039 	return QDF_STATUS_SUCCESS;
5040 }
5041 
5042 /* wake lock APIs for HDD */
5043 void hdd_prevent_suspend(uint32_t reason)
5044 {
5045 	qdf_wake_lock_acquire(&wlan_wake_lock, reason);
5046 }
5047 
5048 void hdd_allow_suspend(uint32_t reason)
5049 {
5050 	qdf_wake_lock_release(&wlan_wake_lock, reason);
5051 }
5052 
5053 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
5054 {
5055 	cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
5056 	qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
5057 }
5058 
5059 /**
5060  * hdd_exchange_version_and_caps() - exchange version and capability with target
5061  * @hdd_ctx:	Pointer to HDD context
5062  *
5063  * This is the HDD function to exchange version and capability information
5064  * between Host and Target
5065  *
5066  * This function gets reported version of FW.
5067  * It also finds the version of target headers used to compile the host;
5068  * It compares the above two and prints a warning if they are different;
5069  * It gets the SW and HW version string;
5070  * Finally, it exchanges capabilities between host and target i.e. host
5071  * and target exchange a msg indicating the features they support through a
5072  * bitmap
5073  *
5074  * Return: None
5075  */
5076 void hdd_exchange_version_and_caps(hdd_context_t *hdd_ctx)
5077 {
5078 
5079 	tSirVersionType versionCompiled;
5080 	tSirVersionType versionReported;
5081 	tSirVersionString versionString;
5082 	uint8_t fwFeatCapsMsgSupported = 0;
5083 	QDF_STATUS vstatus;
5084 
5085 	memset(&versionCompiled, 0, sizeof(versionCompiled));
5086 	memset(&versionReported, 0, sizeof(versionReported));
5087 
5088 	/* retrieve and display WCNSS version information */
5089 	do {
5090 
5091 		vstatus = sme_get_wcnss_wlan_compiled_version(hdd_ctx->hHal,
5092 							      &versionCompiled);
5093 		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
5094 			hdd_alert("unable to retrieve WCNSS WLAN compiled version");
5095 			break;
5096 		}
5097 
5098 		vstatus = sme_get_wcnss_wlan_reported_version(hdd_ctx->hHal,
5099 							      &versionReported);
5100 		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
5101 			hdd_alert("unable to retrieve WCNSS WLAN reported version");
5102 			break;
5103 		}
5104 
5105 		if ((versionCompiled.major != versionReported.major) ||
5106 		    (versionCompiled.minor != versionReported.minor) ||
5107 		    (versionCompiled.version != versionReported.version) ||
5108 		    (versionCompiled.revision != versionReported.revision)) {
5109 			pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
5110 			       "Host expected %u.%u.%u.%u\n",
5111 			       WLAN_MODULE_NAME,
5112 			       (int)versionReported.major,
5113 			       (int)versionReported.minor,
5114 			       (int)versionReported.version,
5115 			       (int)versionReported.revision,
5116 			       (int)versionCompiled.major,
5117 			       (int)versionCompiled.minor,
5118 			       (int)versionCompiled.version,
5119 			       (int)versionCompiled.revision);
5120 		} else {
5121 			pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
5122 				WLAN_MODULE_NAME,
5123 				(int)versionReported.major,
5124 				(int)versionReported.minor,
5125 				(int)versionReported.version,
5126 				(int)versionReported.revision);
5127 		}
5128 
5129 		vstatus = sme_get_wcnss_software_version(hdd_ctx->hHal,
5130 							 versionString,
5131 							 sizeof(versionString));
5132 		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
5133 			hdd_alert("unable to retrieve WCNSS software version string");
5134 			break;
5135 		}
5136 
5137 		pr_info("%s: WCNSS software version %s\n",
5138 			WLAN_MODULE_NAME, versionString);
5139 
5140 		vstatus = sme_get_wcnss_hardware_version(hdd_ctx->hHal,
5141 							 versionString,
5142 							 sizeof(versionString));
5143 		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
5144 			hdd_alert("unable to retrieve WCNSS hardware version string");
5145 			break;
5146 		}
5147 
5148 		pr_info("%s: WCNSS hardware version %s\n",
5149 			WLAN_MODULE_NAME, versionString);
5150 
5151 		/*
5152 		 * 1.Check if FW version is greater than 0.1.1.0. Only then
5153 		 * send host-FW capability exchange message
5154 		 * 2.Host-FW capability exchange message  is only present on
5155 		 * target 1.1 so send the message only if it the target is 1.1
5156 		 * minor numbers for different target branches:
5157 		 * 0 -> (1.0)Mainline Build
5158 		 * 1 -> (1.1)Mainline Build
5159 		 * 2->(1.04) Stability Build
5160 		 */
5161 		if (((versionReported.major > 0) || (versionReported.minor > 1)
5162 		     || ((versionReported.minor >= 1)
5163 			 && (versionReported.version >= 1)))
5164 		    && ((versionReported.major == 1)
5165 			&& (versionReported.minor >= 1)))
5166 			fwFeatCapsMsgSupported = 1;
5167 
5168 		if (fwFeatCapsMsgSupported) {
5169 			/*
5170 			 * Indicate if IBSS heartbeat monitoring needs to be
5171 			 * offloaded
5172 			 */
5173 			if (!hdd_ctx->config->enableIbssHeartBeatOffload) {
5174 				sme_disable_feature_capablity
5175 					(IBSS_HEARTBEAT_OFFLOAD);
5176 			}
5177 
5178 			sme_feature_caps_exchange(hdd_ctx->hHal);
5179 		}
5180 
5181 	} while (0);
5182 
5183 }
5184 
5185 /* Initialize channel list in sme based on the country code */
5186 QDF_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx)
5187 {
5188 	return sme_init_chan_list(hdd_ctx->hHal, hdd_ctx->reg.alpha2,
5189 				  hdd_ctx->reg.cc_src);
5190 }
5191 
5192 /**
5193  * hdd_is_5g_supported() - check if hardware supports 5GHz
5194  * @hdd_ctx:	Pointer to the hdd context
5195  *
5196  * HDD function to know if hardware supports 5GHz
5197  *
5198  * Return:  true if hardware supports 5GHz
5199  */
5200 bool hdd_is_5g_supported(hdd_context_t *hdd_ctx)
5201 {
5202 	if (!hdd_ctx || !hdd_ctx->config)
5203 		return true;
5204 
5205 	if (hdd_ctx->config->nBandCapability != eCSR_BAND_24)
5206 		return true;
5207 	else
5208 		return false;
5209 }
5210 
5211 static int hdd_wiphy_init(hdd_context_t *hdd_ctx)
5212 {
5213 	struct wiphy *wiphy;
5214 	int ret_val;
5215 
5216 	wiphy = hdd_ctx->wiphy;
5217 
5218 	/*
5219 	 * The channel information in
5220 	 * wiphy needs to be initialized before wiphy registration
5221 	 */
5222 	ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
5223 	if (ret_val) {
5224 		hdd_alert("regulatory init failed");
5225 		return ret_val;
5226 	}
5227 
5228 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
5229 	wiphy->wowlan = &wowlan_support_reg_init;
5230 #else
5231 	wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
5232 			      WIPHY_WOWLAN_MAGIC_PKT |
5233 			      WIPHY_WOWLAN_DISCONNECT |
5234 			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
5235 			      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
5236 			      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
5237 			      WIPHY_WOWLAN_4WAY_HANDSHAKE |
5238 			      WIPHY_WOWLAN_RFKILL_RELEASE;
5239 
5240 	wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
5241 				    WOW_MAX_FILTERS_PER_LIST);
5242 	wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
5243 	wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
5244 #endif
5245 
5246 	/* registration of wiphy dev with cfg80211 */
5247 	ret_val = wlan_hdd_cfg80211_register(wiphy);
5248 	if (0 > ret_val)
5249 		hdd_err("wiphy registration failed");
5250 
5251 	return ret_val;
5252 }
5253 
5254 /**
5255  * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
5256  * @hdd_ctx - handle to hdd context
5257  * @tx_packets - transmit packet count
5258  * @rx_packets - receive packet count
5259  *
5260  * The function controls the bus bandwidth and dynamic control of
5261  * tcp delayed ack configuration
5262  *
5263  * Returns: None
5264  */
5265 #ifdef MSM_PLATFORM
5266 static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx,
5267 					  const uint64_t tx_packets,
5268 					  const uint64_t rx_packets)
5269 {
5270 	uint64_t total = tx_packets + rx_packets;
5271 	uint64_t temp_rx = 0;
5272 	uint64_t temp_tx = 0;
5273 	enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
5274 	enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
5275 	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
5276 	uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
5277 
5278 	if (total > hdd_ctx->config->busBandwidthHighThreshold)
5279 		next_vote_level = PLD_BUS_WIDTH_HIGH;
5280 	else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
5281 		next_vote_level = PLD_BUS_WIDTH_MEDIUM;
5282 	else if (total > hdd_ctx->config->busBandwidthLowThreshold)
5283 		next_vote_level = PLD_BUS_WIDTH_LOW;
5284 	else
5285 		next_vote_level = PLD_BUS_WIDTH_NONE;
5286 
5287 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level =
5288 							next_vote_level;
5289 
5290 	if (hdd_ctx->cur_vote_level != next_vote_level) {
5291 		hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
5292 			 next_vote_level, tx_packets, rx_packets);
5293 		hdd_ctx->cur_vote_level = next_vote_level;
5294 		pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
5295 		if (next_vote_level == PLD_BUS_WIDTH_LOW) {
5296 			if (hdd_ctx->hbw_requested) {
5297 				pld_remove_pm_qos(hdd_ctx->parent_dev);
5298 				hdd_ctx->hbw_requested = false;
5299 			}
5300 			if (cds_sched_handle_throughput_req(false))
5301 				hdd_err("low bandwidth set rx affinity fail");
5302 		 } else {
5303 			if (!hdd_ctx->hbw_requested) {
5304 				pld_request_pm_qos(hdd_ctx->parent_dev, 1);
5305 				hdd_ctx->hbw_requested = true;
5306 			}
5307 
5308 			if (cds_sched_handle_throughput_req(true))
5309 				hdd_err("high bandwidth set rx affinity fail");
5310 		 }
5311 		hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, rx_packets);
5312 	}
5313 
5314 	/* fine-tuning parameters for RX Flows */
5315 	temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
5316 
5317 	hdd_ctx->prev_rx = rx_packets;
5318 	if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh) {
5319 		if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
5320 		   (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
5321 			next_rx_level = WLAN_SVC_TP_HIGH;
5322 		}
5323 	} else {
5324 		next_rx_level = WLAN_SVC_TP_LOW;
5325 		hdd_ctx->rx_high_ind_cnt = 0;
5326 	}
5327 
5328 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level =
5329 								next_rx_level;
5330 
5331 	if (hdd_ctx->cur_rx_level != next_rx_level) {
5332 		hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
5333 		       next_rx_level, temp_rx);
5334 		hdd_ctx->cur_rx_level = next_rx_level;
5335 		/* Send throughput indication only if it is enabled.
5336 		 * Disabling tcp_del_ack will revert the tcp stack behavior
5337 		 * to default delayed ack. Note that this will disable the
5338 		 * dynamic delayed ack mechanism across the system
5339 		 */
5340 		if (hdd_ctx->config->enable_tcp_delack)
5341 			wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
5342 					WLAN_SVC_WLAN_TP_IND,
5343 					    &next_rx_level,
5344 					    sizeof(next_rx_level));
5345 	}
5346 
5347 	/* fine-tuning parameters for TX Flows */
5348 	temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
5349 	hdd_ctx->prev_tx = tx_packets;
5350 	if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
5351 		next_tx_level = WLAN_SVC_TP_HIGH;
5352 	else
5353 		next_tx_level = WLAN_SVC_TP_LOW;
5354 
5355 	 if (hdd_ctx->cur_tx_level != next_tx_level) {
5356 		hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
5357 				next_tx_level, temp_tx);
5358 		hdd_ctx->cur_tx_level = next_tx_level;
5359 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
5360 				WLAN_SVC_WLAN_TP_TX_IND,
5361 				&next_tx_level,
5362 				sizeof(next_tx_level));
5363 	}
5364 
5365 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_tx_level =
5366 								next_tx_level;
5367 	hdd_ctx->hdd_txrx_hist_idx++;
5368 	hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
5369 }
5370 
5371 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
5372 static void hdd_bus_bw_compute_cbk(void *priv)
5373 {
5374 	hdd_context_t *hdd_ctx = (hdd_context_t *) priv;
5375 	hdd_adapter_t *adapter = NULL;
5376 	uint64_t tx_packets = 0, rx_packets = 0;
5377 	uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
5378 	uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
5379 	uint64_t total_tx = 0, total_rx = 0;
5380 	hdd_adapter_list_node_t *adapterNode = NULL;
5381 	QDF_STATUS status = 0;
5382 	A_STATUS ret;
5383 	bool connected = false;
5384 	uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
5385 
5386 	if (wlan_hdd_validate_context(hdd_ctx))
5387 		return;
5388 
5389 	for (status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
5390 	     NULL != adapterNode && QDF_STATUS_SUCCESS == status;
5391 	     status =
5392 		     hdd_get_next_adapter(hdd_ctx, adapterNode, &adapterNode)) {
5393 
5394 		if (adapterNode->pAdapter == NULL)
5395 			continue;
5396 		adapter = adapterNode->pAdapter;
5397 		/*
5398 		 * Validate magic so we don't end up accessing
5399 		 * an invalid adapter.
5400 		 */
5401 		if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
5402 			continue;
5403 
5404 		if ((adapter->device_mode == QDF_STA_MODE ||
5405 		     adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
5406 		    WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
5407 		    != eConnectionState_Associated) {
5408 
5409 			continue;
5410 		}
5411 
5412 		if ((adapter->device_mode == QDF_SAP_MODE ||
5413 		     adapter->device_mode == QDF_P2P_GO_MODE) &&
5414 		    WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive == false) {
5415 
5416 			continue;
5417 		}
5418 
5419 		tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
5420 					      adapter->prev_tx_packets);
5421 		rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
5422 					      adapter->prev_rx_packets);
5423 
5424 		if (adapter->device_mode == QDF_SAP_MODE ||
5425 				adapter->device_mode == QDF_P2P_GO_MODE ||
5426 				adapter->device_mode == QDF_IBSS_MODE) {
5427 
5428 			ret = ol_get_intra_bss_fwd_pkts_count(
5429 				adapter->sessionId,
5430 				&fwd_tx_packets, &fwd_rx_packets);
5431 			if (ret == A_OK) {
5432 				fwd_tx_packets_diff += HDD_BW_GET_DIFF(
5433 					fwd_tx_packets,
5434 					adapter->prev_fwd_tx_packets);
5435 				fwd_rx_packets_diff += HDD_BW_GET_DIFF(
5436 					fwd_tx_packets,
5437 					adapter->prev_fwd_rx_packets);
5438 			}
5439 		}
5440 
5441 		total_rx += adapter->stats.rx_packets;
5442 		total_tx += adapter->stats.tx_packets;
5443 
5444 		spin_lock_bh(&hdd_ctx->bus_bw_lock);
5445 		adapter->prev_tx_packets = adapter->stats.tx_packets;
5446 		adapter->prev_rx_packets = adapter->stats.rx_packets;
5447 		adapter->prev_fwd_tx_packets = fwd_tx_packets;
5448 		adapter->prev_fwd_rx_packets = fwd_rx_packets;
5449 		spin_unlock_bh(&hdd_ctx->bus_bw_lock);
5450 		connected = true;
5451 	}
5452 
5453 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_rx = total_rx;
5454 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_tx = total_tx;
5455 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_rx =
5456 								rx_packets;
5457 	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_tx =
5458 								tx_packets;
5459 
5460 	/* add intra bss forwarded tx and rx packets */
5461 	tx_packets += fwd_tx_packets_diff;
5462 	rx_packets += fwd_rx_packets_diff;
5463 
5464 	hdd_ipa_uc_stat_query(hdd_ctx, &ipa_tx_packets, &ipa_rx_packets);
5465 	tx_packets += (uint64_t)ipa_tx_packets;
5466 	rx_packets += (uint64_t)ipa_rx_packets;
5467 
5468 	if (!connected) {
5469 		hdd_err("bus bandwidth timer running in disconnected state");
5470 		return;
5471 	}
5472 
5473 	hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
5474 
5475 	hdd_ipa_set_perf_level(hdd_ctx, tx_packets, rx_packets);
5476 	hdd_ipa_uc_stat_request(adapter, 2);
5477 
5478 	qdf_mc_timer_start(&hdd_ctx->bus_bw_timer,
5479 			   hdd_ctx->config->busBandwidthComputeInterval);
5480 }
5481 
5482 int hdd_bus_bandwidth_init(hdd_context_t *hdd_ctx)
5483 {
5484 	spin_lock_init(&hdd_ctx->bus_bw_lock);
5485 
5486 	qdf_mc_timer_init(&hdd_ctx->bus_bw_timer,
5487 			  QDF_TIMER_TYPE_SW,
5488 			  hdd_bus_bw_compute_cbk, (void *)hdd_ctx);
5489 
5490 	return 0;
5491 }
5492 
5493 void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx)
5494 {
5495 	if (qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer) ==
5496 	    QDF_TIMER_STATE_RUNNING)
5497 		hdd_reset_tcp_delack(hdd_ctx);
5498 
5499 	qdf_mc_timer_destroy(&hdd_ctx->bus_bw_timer);
5500 }
5501 #endif
5502 
5503 /**
5504  * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
5505  * @hdd_ctx: hdd context
5506  *
5507  * Return: 0 for success or error code
5508  */
5509 static int wlan_hdd_init_tx_rx_histogram(hdd_context_t *hdd_ctx)
5510 {
5511 	hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
5512 		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
5513 	if (hdd_ctx->hdd_txrx_hist == NULL) {
5514 		hdd_err("Failed malloc for hdd_txrx_hist");
5515 		return -ENOMEM;
5516 	}
5517 	return 0;
5518 }
5519 
5520 /**
5521  * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
5522  * @hdd_ctx: hdd context
5523  *
5524  * Return: none
5525  */
5526 void wlan_hdd_deinit_tx_rx_histogram(hdd_context_t *hdd_ctx)
5527 {
5528 	if (hdd_ctx->hdd_txrx_hist) {
5529 		qdf_mem_free(hdd_ctx->hdd_txrx_hist);
5530 		hdd_ctx->hdd_txrx_hist = NULL;
5531 	}
5532 }
5533 
5534 static uint8_t *convert_level_to_string(uint32_t level)
5535 {
5536 	switch (level) {
5537 	/* initialize the wlan sub system */
5538 	case WLAN_SVC_TP_NONE:
5539 		return "NONE";
5540 	case WLAN_SVC_TP_LOW:
5541 		return "LOW";
5542 	case WLAN_SVC_TP_MEDIUM:
5543 		return "MED";
5544 	case WLAN_SVC_TP_HIGH:
5545 		return "HIGH";
5546 	default:
5547 		return "INVAL";
5548 	}
5549 }
5550 
5551 
5552 /**
5553  * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
5554  * @hdd_ctx: hdd context
5555  *
5556  * Return: none
5557  */
5558 void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx)
5559 {
5560 	int i;
5561 
5562 #ifdef MSM_PLATFORM
5563 	hdd_err("BW compute Interval: %dms",
5564 		hdd_ctx->config->busBandwidthComputeInterval);
5565 	hdd_err("BW High TH: %d BW Med TH: %d BW Low TH: %d",
5566 		hdd_ctx->config->busBandwidthHighThreshold,
5567 		hdd_ctx->config->busBandwidthMediumThreshold,
5568 		hdd_ctx->config->busBandwidthLowThreshold);
5569 	hdd_err("Enable TCP DEL ACK: %d",
5570 		hdd_ctx->config->enable_tcp_delack);
5571 	hdd_err("TCP DEL High TH: %d TCP DEL Low TH: %d",
5572 		hdd_ctx->config->tcpDelackThresholdHigh,
5573 		hdd_ctx->config->tcpDelackThresholdLow);
5574 	hdd_err("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
5575 		hdd_ctx->config->tcp_tx_high_tput_thres);
5576 #endif
5577 
5578 	hdd_err("Total entries: %d Current index: %d",
5579 		NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
5580 
5581 	hdd_err("index, total_rx, interval_rx, total_tx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
5582 
5583 	for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
5584 		hdd_err("%d: %llu, %llu, %llu, %llu, %s, %s, %s",
5585 			i, hdd_ctx->hdd_txrx_hist[i].total_rx,
5586 			hdd_ctx->hdd_txrx_hist[i].interval_rx,
5587 			hdd_ctx->hdd_txrx_hist[i].total_tx,
5588 			hdd_ctx->hdd_txrx_hist[i].interval_tx,
5589 			convert_level_to_string(
5590 				hdd_ctx->hdd_txrx_hist[i].next_vote_level),
5591 			convert_level_to_string(
5592 				hdd_ctx->hdd_txrx_hist[i].next_rx_level),
5593 			convert_level_to_string(
5594 				hdd_ctx->hdd_txrx_hist[i].next_tx_level));
5595 	}
5596 	return;
5597 }
5598 
5599 /**
5600  * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
5601  * @hdd_ctx: hdd context
5602  *
5603  * Return: none
5604  */
5605 void wlan_hdd_clear_tx_rx_histogram(hdd_context_t *hdd_ctx)
5606 {
5607 	hdd_ctx->hdd_txrx_hist_idx = 0;
5608 	qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
5609 		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
5610 }
5611 
5612 /**
5613  * wlan_hdd_display_netif_queue_history() - display netif queue operation history
5614  * @pHddCtx: hdd context
5615  *
5616  * Return: none
5617  */
5618 void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx)
5619 {
5620 
5621 	hdd_adapter_t *adapter = NULL;
5622 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
5623 	QDF_STATUS status;
5624 	int i;
5625 	qdf_time_t total, pause, unpause, curr_time, delta;
5626 
5627 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
5628 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
5629 		adapter = adapter_node->pAdapter;
5630 
5631 		hdd_err("\nNetif queue operation statistics:");
5632 		hdd_err("Session_id %d device mode %d",
5633 			adapter->sessionId, adapter->device_mode);
5634 		hdd_err("Current pause_map value %x", adapter->pause_map);
5635 		curr_time = qdf_system_ticks();
5636 		total = curr_time - adapter->start_time;
5637 		delta = curr_time - adapter->last_time;
5638 		if (adapter->pause_map) {
5639 			pause = adapter->total_pause_time + delta;
5640 			unpause = adapter->total_unpause_time;
5641 		} else {
5642 			unpause = adapter->total_unpause_time + delta;
5643 			pause = adapter->total_pause_time;
5644 		}
5645 		hdd_err("Total: %ums Pause: %ums Unpause: %ums",
5646 			qdf_system_ticks_to_msecs(total),
5647 			qdf_system_ticks_to_msecs(pause),
5648 			qdf_system_ticks_to_msecs(unpause));
5649 		hdd_err("reason_type: pause_cnt: unpause_cnt: pause_time");
5650 
5651 		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
5652 			qdf_time_t pause_delta = 0;
5653 
5654 			if (adapter->pause_map & (1 << i))
5655 				pause_delta = delta;
5656 
5657 			hdd_err("%s: %d: %d: %ums",
5658 				hdd_reason_type_to_string(i),
5659 				adapter->queue_oper_stats[i].pause_count,
5660 				adapter->queue_oper_stats[i].unpause_count,
5661 				qdf_system_ticks_to_msecs(
5662 				adapter->queue_oper_stats[i].total_pause_time +
5663 				pause_delta));
5664 		}
5665 
5666 		hdd_err("\nNetif queue operation history:");
5667 		hdd_err("Total entries: %d current index %d",
5668 			WLAN_HDD_MAX_HISTORY_ENTRY, adapter->history_index);
5669 
5670 		hdd_err("index: time: action_type: reason_type: pause_map");
5671 
5672 		for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
5673 			hdd_err("%d: %u: %s: %s: %x",
5674 				i, qdf_system_ticks_to_msecs(
5675 					adapter->queue_oper_history[i].time),
5676 				hdd_action_type_to_string(
5677 				adapter->queue_oper_history[i].netif_action),
5678 				hdd_reason_type_to_string(
5679 				adapter->queue_oper_history[i].netif_reason),
5680 				adapter->queue_oper_history[i].pause_map);
5681 		}
5682 
5683 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
5684 		adapter_node = next;
5685 	}
5686 
5687 
5688 }
5689 
5690 /**
5691  * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
5692  * @hdd_ctx: hdd context
5693  *
5694  * Return: none
5695  */
5696 void wlan_hdd_clear_netif_queue_history(hdd_context_t *hdd_ctx)
5697 {
5698 	hdd_adapter_t *adapter = NULL;
5699 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
5700 	QDF_STATUS status;
5701 
5702 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
5703 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
5704 		adapter = adapter_node->pAdapter;
5705 
5706 		qdf_mem_zero(adapter->queue_oper_stats,
5707 					sizeof(adapter->queue_oper_stats));
5708 		qdf_mem_zero(adapter->queue_oper_history,
5709 					sizeof(adapter->queue_oper_history));
5710 		adapter->history_index = 0;
5711 		adapter->start_time = adapter->last_time = qdf_system_ticks();
5712 		adapter->total_pause_time = 0;
5713 		adapter->total_unpause_time = 0;
5714 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
5715 		adapter_node = next;
5716 	}
5717 }
5718 
5719 /**
5720  * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
5721  * @halHandle:	Hal handle
5722  * @pContext:	Pointer to the context
5723  * @sessionId:	Session ID
5724  * @scanId:	Scan ID
5725  * @status:	Status
5726  *
5727  * This is the callback to be executed when 11d scan is completed to flush out
5728  * the scan results
5729  *
5730  * 11d scan is done during driver load and is a passive scan on all
5731  * channels supported by the device, 11d scans may find some APs on
5732  * frequencies which are forbidden to be used in the regulatory domain
5733  * the device is operating in. If these APs are notified to the supplicant
5734  * it may try to connect to these APs, thus flush out all the scan results
5735  * which are present in SME after 11d scan is done.
5736  *
5737  * Return:  QDF_STATUS_SUCCESS
5738  */
5739 static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
5740 				    uint8_t sessionId, uint32_t scanId,
5741 				    eCsrScanStatus status)
5742 {
5743 	ENTER();
5744 
5745 	sme_scan_flush_result(halHandle);
5746 
5747 	EXIT();
5748 
5749 	return QDF_STATUS_SUCCESS;
5750 }
5751 
5752 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS
5753 /**
5754  * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
5755  * @hdd_ctx: hdd global context
5756  *
5757  * Return: none
5758  */
5759 static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
5760 {
5761 	uint8_t i;
5762 
5763 	mutex_init(&hdd_ctx->op_ctx.op_lock);
5764 	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
5765 		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
5766 		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
5767 	}
5768 }
5769 #else
5770 static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
5771 {
5772 }
5773 #endif
5774 
5775 #ifdef WLAN_FEATURE_FASTPATH
5776 /**
5777  * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
5778  * @hdd_cfg: hdd config
5779  * @context: lower layer context
5780  *
5781  * Return: none
5782  */
5783 void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
5784 				void *context)
5785 {
5786 	if (hdd_cfg->fastpath_enable)
5787 		hif_enable_fastpath(context);
5788 }
5789 #endif
5790 
5791 #if defined(FEATURE_WLAN_CH_AVOID)
5792 /**
5793  * hdd_set_thermal_level_cb() - set thermal level callback function
5794  * @context:	hdd context pointer
5795  * @level:	thermal level
5796  *
5797  * Change IPA data path to SW path when the thermal throttle level greater
5798  * than 0, and restore the original data path when throttle level is 0
5799  *
5800  * Return: none
5801  */
5802 static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
5803 {
5804 	hdd_context_t *hdd_ctx = context;
5805 
5806 	/* Change IPA to SW path when throttle level greater than 0 */
5807 	if (level > THROTTLE_LEVEL_0)
5808 		hdd_ipa_send_mcc_scc_msg(hdd_ctx, true);
5809 	else
5810 		/* restore original concurrency mode */
5811 		hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode);
5812 }
5813 
5814 /**
5815  * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
5816  * restart
5817  * @adapter: AP adapter, which should be checked for NULL
5818  *
5819  * Get a safe channel to restart SAP. PCL already takes into account the
5820  * unsafe channels. So, the PCL is validated with the ACS range to provide
5821  * a safe channel for the SAP to restart.
5822  *
5823  * Return: Channel number to restart SAP in case of success. In case of any
5824  * failure, the channel number returned is zero.
5825  */
5826 static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range(
5827 				hdd_adapter_t *adapter)
5828 {
5829 	struct sir_pcl_list pcl;
5830 	QDF_STATUS status;
5831 	uint32_t i, j;
5832 	tHalHandle *hal_handle;
5833 	hdd_context_t *hdd_ctx;
5834 	bool found = false;
5835 
5836 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5837 	if (!hdd_ctx) {
5838 		hdd_err("invalid HDD context");
5839 		return INVALID_CHANNEL_ID;
5840 	}
5841 
5842 	hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
5843 	if (!hal_handle) {
5844 		hdd_err("invalid HAL handle");
5845 		return INVALID_CHANNEL_ID;
5846 	}
5847 
5848 	status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE,
5849 			pcl.pcl_list, &pcl.pcl_len,
5850 			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
5851 	if (QDF_IS_STATUS_ERROR(status)) {
5852 		hdd_err("Get PCL failed");
5853 		return INVALID_CHANNEL_ID;
5854 	}
5855 
5856 	if (!pcl.pcl_len) {
5857 		hdd_alert("pcl length is zero. this is not expected");
5858 		return INVALID_CHANNEL_ID;
5859 	}
5860 
5861 	hdd_info("start:%d end:%d",
5862 		adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch,
5863 		adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch);
5864 
5865 	/* PCL already takes unsafe channel into account */
5866 	for (i = 0; i < pcl.pcl_len; i++) {
5867 		hdd_info("chan[%d]:%d", i, pcl.pcl_list[i]);
5868 		if ((pcl.pcl_list[i] >=
5869 		   adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch) &&
5870 		   (pcl.pcl_list[i] <=
5871 		   adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch)) {
5872 			hdd_info("found PCL safe chan:%d", pcl.pcl_list[i]);
5873 			return pcl.pcl_list[i];
5874 		}
5875 	}
5876 
5877 	hdd_info("no safe channel from PCL found in ACS range");
5878 
5879 	/* Try for safe channel from all valid channel */
5880 	pcl.pcl_len = MAX_NUM_CHAN;
5881 	status = sme_get_cfg_valid_channels(hal_handle, pcl.pcl_list,
5882 					&pcl.pcl_len);
5883 	if (QDF_IS_STATUS_ERROR(status)) {
5884 		hdd_err("error in getting valid channel list");
5885 		return INVALID_CHANNEL_ID;
5886 	}
5887 
5888 	for (i = 0; i < pcl.pcl_len; i++) {
5889 		hdd_info("chan[%d]:%d", i, pcl.pcl_list[i]);
5890 		found = false;
5891 		for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
5892 			if (pcl.pcl_list[i] ==
5893 					hdd_ctx->unsafe_channel_list[j]) {
5894 				hdd_info("unsafe chan:%d", pcl.pcl_list[i]);
5895 				found = true;
5896 				break;
5897 			}
5898 		}
5899 
5900 		if (found)
5901 			continue;
5902 
5903 		if ((pcl.pcl_list[i] >=
5904 		   adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch) &&
5905 		   (pcl.pcl_list[i] <=
5906 		   adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch)) {
5907 			hdd_info("found safe chan:%d", pcl.pcl_list[i]);
5908 			return pcl.pcl_list[i];
5909 		}
5910 	}
5911 
5912 	return INVALID_CHANNEL_ID;
5913 }
5914 
5915 /**
5916  * hdd_restart_sap() - Restarts SAP on the given channel
5917  * @adapter: AP adapter
5918  * @channel: Channel
5919  *
5920  * Restarts the SAP interface by invoking the function which executes the
5921  * callback to perform channel switch using (E)CSA.
5922  *
5923  * Return: None
5924  */
5925 static void hdd_restart_sap(hdd_adapter_t *adapter, uint8_t channel)
5926 {
5927 	hdd_ap_ctx_t *hdd_ap_ctx;
5928 	tHalHandle *hal_handle;
5929 
5930 	if (!adapter) {
5931 		hdd_err("invalid adapter");
5932 		return;
5933 	}
5934 
5935 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
5936 
5937 	hal_handle = WLAN_HDD_GET_HAL_CTX(adapter);
5938 	if (!hal_handle) {
5939 		hdd_err("invalid HAL handle");
5940 		return;
5941 	}
5942 
5943 	hdd_ap_ctx->sapConfig.channel = channel;
5944 	hdd_ap_ctx->sapConfig.ch_params.ch_width =
5945 		hdd_ap_ctx->sapConfig.ch_width_orig;
5946 
5947 	hdd_info("chan:%d width:%d",
5948 		channel, hdd_ap_ctx->sapConfig.ch_width_orig);
5949 
5950 	cds_set_channel_params(hdd_ap_ctx->sapConfig.channel,
5951 			hdd_ap_ctx->sapConfig.sec_ch,
5952 			&hdd_ap_ctx->sapConfig.ch_params);
5953 
5954 	cds_change_sap_channel_with_csa(adapter, hdd_ap_ctx);
5955 }
5956 /**
5957  * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
5958  * @hdd_ctx: hdd context pointer
5959  *
5960  * hdd_unsafe_channel_restart_sap check all unsafe channel list
5961  * and if ACS is enabled, driver will ask userspace to restart the
5962  * sap. User space on LTE coex indication restart driver.
5963  *
5964  * Return - none
5965  */
5966 void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctxt)
5967 {
5968 	QDF_STATUS status;
5969 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
5970 	hdd_adapter_t *adapter_temp;
5971 	uint32_t i;
5972 	bool found = false;
5973 	uint8_t restart_chan;
5974 
5975 	status = hdd_get_front_adapter(hdd_ctxt, &adapter_node);
5976 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
5977 		adapter_temp = adapter_node->pAdapter;
5978 
5979 		if (!adapter_temp) {
5980 			hdd_err("adapter is NULL, moving to next one");
5981 			goto next_adapater;
5982 		}
5983 
5984 		if (!((adapter_temp->device_mode == QDF_SAP_MODE) &&
5985 		   (adapter_temp->sessionCtx.ap.sapConfig.acs_cfg.acs_mode))) {
5986 			hdd_info("skip device mode:%d acs:%d",
5987 				adapter_temp->device_mode,
5988 				adapter_temp->sessionCtx.ap.sapConfig.
5989 				acs_cfg.acs_mode);
5990 			goto next_adapater;
5991 		}
5992 
5993 		found = false;
5994 		for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
5995 			if (adapter_temp->sessionCtx.ap.operatingChannel ==
5996 				hdd_ctxt->unsafe_channel_list[i]) {
5997 				found = true;
5998 				hdd_info("operating ch:%d is unsafe",
5999 				  adapter_temp->sessionCtx.ap.operatingChannel);
6000 				break;
6001 			}
6002 		}
6003 
6004 		if (!found) {
6005 			hdd_info("ch:%d is safe. no need to change channel",
6006 				adapter_temp->sessionCtx.ap.operatingChannel);
6007 			goto next_adapater;
6008 		}
6009 
6010 		restart_chan =
6011 			hdd_get_safe_channel_from_pcl_and_acs_range(
6012 					adapter_temp);
6013 		if (!restart_chan) {
6014 			hdd_alert("fail to restart SAP");
6015 		} else {
6016 			/* SAP restart due to unsafe channel. While restarting
6017 			 * the SAP, make sure to clear acs_channel, channel to
6018 			 * reset to 0. Otherwise these settings will override
6019 			 * the ACS while restart.
6020 			*/
6021 			hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
6022 			adapter_temp->sessionCtx.ap.sapConfig.channel =
6023 							AUTO_CHANNEL_SELECT;
6024 			hdd_info("sending coex indication");
6025 			wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
6026 					WLAN_SVC_LTE_COEX_IND, NULL, 0);
6027 			hdd_restart_sap(adapter_temp, restart_chan);
6028 		}
6029 
6030 next_adapater:
6031 		status = hdd_get_next_adapter(hdd_ctxt, adapter_node, &next);
6032 		adapter_node = next;
6033 	}
6034 }
6035 /**
6036  * hdd_ch_avoid_cb() - Avoid notified channels from FW handler
6037  * @adapter:	HDD adapter pointer
6038  * @indParam:	Channel avoid notification parameter
6039  *
6040  * Avoid channel notification from FW handler.
6041  * FW will send un-safe channel list to avoid over wrapping.
6042  * hostapd should not use notified channel
6043  *
6044  * Return: None
6045  */
6046 void hdd_ch_avoid_cb(void *hdd_context, void *indi_param)
6047 {
6048 	hdd_context_t *hdd_ctxt;
6049 	tSirChAvoidIndType *ch_avoid_indi;
6050 	uint8_t range_loop;
6051 	enum channel_enum channel_loop, start_channel_idx = INVALID_CHANNEL,
6052 					end_channel_idx = INVALID_CHANNEL;
6053 	uint16_t start_channel;
6054 	uint16_t end_channel;
6055 	v_CONTEXT_t cds_context;
6056 	tHddAvoidFreqList hdd_avoid_freq_list;
6057 	uint32_t i;
6058 
6059 	/* Basic sanity */
6060 	if (!hdd_context || !indi_param) {
6061 		hdd_err("Invalid arguments");
6062 		return;
6063 	}
6064 
6065 	hdd_ctxt = (hdd_context_t *) hdd_context;
6066 	ch_avoid_indi = (tSirChAvoidIndType *) indi_param;
6067 	cds_context = hdd_ctxt->pcds_context;
6068 
6069 	/* Make unsafe channel list */
6070 	hdd_notice("band count %d",
6071 	       ch_avoid_indi->avoid_range_count);
6072 
6073 	/* generate vendor specific event */
6074 	qdf_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList));
6075 	for (i = 0; i < ch_avoid_indi->avoid_range_count; i++) {
6076 		hdd_avoid_freq_list.avoidFreqRange[i].startFreq =
6077 			ch_avoid_indi->avoid_freq_range[i].start_freq;
6078 		hdd_avoid_freq_list.avoidFreqRange[i].endFreq =
6079 			ch_avoid_indi->avoid_freq_range[i].end_freq;
6080 	}
6081 	hdd_avoid_freq_list.avoidFreqRangeCount =
6082 		ch_avoid_indi->avoid_range_count;
6083 
6084 	/* clear existing unsafe channel cache */
6085 	hdd_ctxt->unsafe_channel_count = 0;
6086 	qdf_mem_zero(hdd_ctxt->unsafe_channel_list,
6087 					sizeof(hdd_ctxt->unsafe_channel_list));
6088 
6089 	for (range_loop = 0; range_loop < ch_avoid_indi->avoid_range_count;
6090 								range_loop++) {
6091 		if (hdd_ctxt->unsafe_channel_count >= NUM_CHANNELS) {
6092 			hdd_warn("LTE Coex unsafe channel list full");
6093 			break;
6094 		}
6095 
6096 		start_channel = ieee80211_frequency_to_channel(
6097 			ch_avoid_indi->avoid_freq_range[range_loop].start_freq);
6098 		end_channel   = ieee80211_frequency_to_channel(
6099 			ch_avoid_indi->avoid_freq_range[range_loop].end_freq);
6100 		hdd_notice("start %d : %d, end %d : %d",
6101 			ch_avoid_indi->avoid_freq_range[range_loop].start_freq,
6102 			start_channel,
6103 			ch_avoid_indi->avoid_freq_range[range_loop].end_freq,
6104 			end_channel);
6105 
6106 		/* do not process frequency bands that are not mapped to
6107 		 * predefined channels
6108 		 */
6109 		if (start_channel == 0 || end_channel == 0)
6110 			continue;
6111 
6112 		for (channel_loop = CHAN_ENUM_1; channel_loop <=
6113 					CHAN_ENUM_184; channel_loop++) {
6114 			if (CDS_CHANNEL_FREQ(channel_loop) >=
6115 						ch_avoid_indi->avoid_freq_range[
6116 						range_loop].start_freq) {
6117 				start_channel_idx = channel_loop;
6118 				break;
6119 			}
6120 		}
6121 		for (channel_loop = CHAN_ENUM_1; channel_loop <=
6122 					CHAN_ENUM_184; channel_loop++) {
6123 			if (CDS_CHANNEL_FREQ(channel_loop) >=
6124 						ch_avoid_indi->avoid_freq_range[
6125 						range_loop].end_freq) {
6126 				end_channel_idx = channel_loop;
6127 				if (CDS_CHANNEL_FREQ(channel_loop) >
6128 						ch_avoid_indi->avoid_freq_range[
6129 						range_loop].end_freq)
6130 					end_channel_idx--;
6131 				break;
6132 			}
6133 		}
6134 
6135 		if (start_channel_idx == INVALID_CHANNEL ||
6136 					end_channel_idx == INVALID_CHANNEL)
6137 			continue;
6138 
6139 		for (channel_loop = start_channel_idx; channel_loop <=
6140 					end_channel_idx; channel_loop++) {
6141 			hdd_ctxt->unsafe_channel_list[
6142 				hdd_ctxt->unsafe_channel_count++] =
6143 				CDS_CHANNEL_NUM(channel_loop);
6144 			if (hdd_ctxt->unsafe_channel_count >=
6145 							NUM_CHANNELS) {
6146 				hdd_warn("LTECoex unsafe ch list full");
6147 				break;
6148 			}
6149 		}
6150 	}
6151 
6152 	hdd_notice("number of unsafe channels is %d ",
6153 	       hdd_ctxt->unsafe_channel_count);
6154 
6155 	if (pld_set_wlan_unsafe_channel(hdd_ctxt->parent_dev,
6156 					hdd_ctxt->unsafe_channel_list,
6157 				hdd_ctxt->unsafe_channel_count)) {
6158 		hdd_err("Failed to set unsafe channel");
6159 
6160 		/* clear existing unsafe channel cache */
6161 		hdd_ctxt->unsafe_channel_count = 0;
6162 		qdf_mem_zero(hdd_ctxt->unsafe_channel_list,
6163 			sizeof(hdd_ctxt->unsafe_channel_list));
6164 
6165 		return;
6166 	}
6167 
6168 	for (channel_loop = 0;
6169 	     channel_loop < hdd_ctxt->unsafe_channel_count; channel_loop++) {
6170 		hdd_notice("channel %d is not safe ",
6171 		       hdd_ctxt->unsafe_channel_list[channel_loop]);
6172 	}
6173 
6174 	/*
6175 	 * first update the unsafe channel list to the platform driver and
6176 	 * send the avoid freq event to the application
6177 	 */
6178 	wlan_hdd_send_avoid_freq_event(hdd_ctxt, &hdd_avoid_freq_list);
6179 
6180 	if (!hdd_ctxt->unsafe_channel_count) {
6181 		hdd_info("no unsafe channels - not restarting SAP");
6182 		return;
6183 	}
6184 	hdd_unsafe_channel_restart_sap(hdd_ctxt);
6185 	return;
6186 }
6187 
6188 /**
6189  * hdd_init_channel_avoidance() - Initialize channel avoidance
6190  * @hdd_ctx:	HDD global context
6191  *
6192  * Initialize the channel avoidance logic by retrieving the unsafe
6193  * channel list from the platform driver and plumbing the data
6194  * down to the lower layers.  Then subscribe to subsequent channel
6195  * avoidance events.
6196  *
6197  * Return: None
6198  */
6199 static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
6200 {
6201 	uint16_t unsafe_channel_count;
6202 	int index;
6203 
6204 	pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
6205 				    hdd_ctx->unsafe_channel_list,
6206 				     &(hdd_ctx->unsafe_channel_count),
6207 				     sizeof(uint16_t) * NUM_CHANNELS);
6208 
6209 	hdd_notice("num of unsafe channels is %d",
6210 	       hdd_ctx->unsafe_channel_count);
6211 
6212 	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
6213 				       (uint16_t)NUM_CHANNELS);
6214 
6215 	for (index = 0; index < unsafe_channel_count; index++) {
6216 		hdd_notice("channel %d is not safe",
6217 		       hdd_ctx->unsafe_channel_list[index]);
6218 
6219 	}
6220 
6221 	/* Plug in avoid channel notification callback */
6222 	sme_add_ch_avoid_callback(hdd_ctx->hHal, hdd_ch_avoid_cb);
6223 }
6224 #else
6225 static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
6226 {
6227 }
6228 static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
6229 {
6230 }
6231 #endif /* defined(FEATURE_WLAN_CH_AVOID) */
6232 
6233 /**
6234  * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
6235  * user space
6236  * @frame_ind: Management frame data to be informed.
6237  *
6238  * This function is used to indicate management frame to
6239  * user space
6240  *
6241  * Return: None
6242  *
6243  */
6244 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
6245 {
6246 	hdd_context_t *hdd_ctx = NULL;
6247 	hdd_adapter_t *adapter = NULL;
6248 	void *cds_context = NULL;
6249 	int i;
6250 
6251 	/* Get the global VOSS context.*/
6252 	cds_context = cds_get_global_context();
6253 	if (!cds_context) {
6254 		hdd_err("Global CDS context is Null");
6255 		return;
6256 	}
6257 	/* Get the HDD context.*/
6258 	hdd_ctx = (hdd_context_t *)cds_get_context(QDF_MODULE_ID_HDD);
6259 
6260 	if (0 != wlan_hdd_validate_context(hdd_ctx))
6261 		return;
6262 
6263 	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
6264 		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
6265 			adapter =
6266 				hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
6267 			if (adapter)
6268 				break;
6269 		}
6270 	} else {
6271 		adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
6272 					frame_ind->sessionId);
6273 	}
6274 
6275 	if ((NULL != adapter) &&
6276 		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
6277 		__hdd_indicate_mgmt_frame(adapter,
6278 						frame_ind->frame_len,
6279 						frame_ind->frameBuf,
6280 						frame_ind->frameType,
6281 						frame_ind->rxChan,
6282 						frame_ind->rxRssi);
6283 	return;
6284 }
6285 
6286 /**
6287  * wlan_hdd_disable_all_dual_mac_features() - Disable dual mac features
6288  * @hdd_ctx: HDD context
6289  *
6290  * Disables all the dual mac features like DBS, Agile DFS etc.
6291  *
6292  * Return: QDF_STATUS_SUCCESS on success
6293  */
6294 static QDF_STATUS wlan_hdd_disable_all_dual_mac_features(hdd_context_t *hdd_ctx)
6295 {
6296 	struct sir_dual_mac_config cfg;
6297 	QDF_STATUS status;
6298 
6299 	if (!hdd_ctx) {
6300 		hdd_err("HDD context is NULL");
6301 		return QDF_STATUS_E_FAILURE;
6302 	}
6303 
6304 	cfg.scan_config = 0;
6305 	cfg.fw_mode_config = 0;
6306 	cfg.set_dual_mac_cb = cds_soc_set_dual_mac_cfg_cb;
6307 
6308 	hdd_debug("Disabling all dual mac features...");
6309 
6310 	status = sme_soc_set_dual_mac_config(hdd_ctx->hHal, cfg);
6311 	if (status != QDF_STATUS_SUCCESS) {
6312 		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
6313 		return status;
6314 	}
6315 
6316 	return QDF_STATUS_SUCCESS;
6317 }
6318 
6319 /**
6320  * hdd_override_ini_config - Override INI config
6321  * @hdd_ctx: HDD context
6322  *
6323  * Override INI config based on module parameter.
6324  *
6325  * Return: None
6326  */
6327 static void hdd_override_ini_config(hdd_context_t *hdd_ctx)
6328 {
6329 
6330 	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
6331 		hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
6332 		hdd_notice("Module enable_dfs_chan_scan set to %d",
6333 			   enable_dfs_chan_scan);
6334 	}
6335 	if (0 == enable_11d || 1 == enable_11d) {
6336 		hdd_ctx->config->Is11dSupportEnabled = enable_11d;
6337 		hdd_notice("Module enable_11d set to %d", enable_11d);
6338 	}
6339 
6340 	if (!hdd_ipa_is_present(hdd_ctx))
6341 		hdd_ctx->config->IpaConfig = 0;
6342 }
6343 
6344 /**
6345  * hdd_set_trace_level_for_each - Set trace level for each INI config
6346  * @hdd_ctx - HDD context
6347  *
6348  * Set trace level for each module based on INI config.
6349  *
6350  * Return: None
6351  */
6352 static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx)
6353 {
6354 	hdd_qdf_trace_enable(QDF_MODULE_ID_WMI,
6355 			     hdd_ctx->config->qdf_trace_enable_wdi);
6356 	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD,
6357 			     hdd_ctx->config->qdf_trace_enable_hdd);
6358 	hdd_qdf_trace_enable(QDF_MODULE_ID_SME,
6359 			     hdd_ctx->config->qdf_trace_enable_sme);
6360 	hdd_qdf_trace_enable(QDF_MODULE_ID_PE,
6361 			     hdd_ctx->config->qdf_trace_enable_pe);
6362 	hdd_qdf_trace_enable(QDF_MODULE_ID_WMA,
6363 			     hdd_ctx->config->qdf_trace_enable_wma);
6364 	hdd_qdf_trace_enable(QDF_MODULE_ID_SYS,
6365 			     hdd_ctx->config->qdf_trace_enable_sys);
6366 	hdd_qdf_trace_enable(QDF_MODULE_ID_QDF,
6367 			     hdd_ctx->config->qdf_trace_enable_qdf);
6368 	hdd_qdf_trace_enable(QDF_MODULE_ID_SAP,
6369 			     hdd_ctx->config->qdf_trace_enable_sap);
6370 	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
6371 			     hdd_ctx->config->qdf_trace_enable_hdd_sap);
6372 	hdd_qdf_trace_enable(QDF_MODULE_ID_BMI,
6373 				hdd_ctx->config->qdf_trace_enable_bmi);
6374 	hdd_qdf_trace_enable(QDF_MODULE_ID_CFG,
6375 				hdd_ctx->config->qdf_trace_enable_cfg);
6376 	hdd_qdf_trace_enable(QDF_MODULE_ID_EPPING,
6377 				hdd_ctx->config->qdf_trace_enable_epping);
6378 	hdd_qdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
6379 				hdd_ctx->config->qdf_trace_enable_qdf_devices);
6380 	hdd_qdf_trace_enable(QDF_MODULE_ID_TXRX,
6381 				hdd_ctx->config->cfd_trace_enable_txrx);
6382 	hdd_qdf_trace_enable(QDF_MODULE_ID_HTC,
6383 				hdd_ctx->config->qdf_trace_enable_htc);
6384 	hdd_qdf_trace_enable(QDF_MODULE_ID_HIF,
6385 				hdd_ctx->config->qdf_trace_enable_hif);
6386 	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
6387 				hdd_ctx->config->qdf_trace_enable_hdd_sap_data);
6388 	hdd_qdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
6389 				hdd_ctx->config->qdf_trace_enable_hdd_data);
6390 
6391 	hdd_cfg_print(hdd_ctx);
6392 }
6393 
6394 /**
6395  * hdd_context_init() - Initialize HDD context
6396  * @hdd_ctx:	HDD context.
6397  *
6398  * Initialize HDD context along with all the feature specific contexts.
6399  *
6400  * return: 0 on success and errno on failure.
6401  */
6402 static int hdd_context_init(hdd_context_t *hdd_ctx)
6403 {
6404 	int ret;
6405 
6406 	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
6407 	hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
6408 
6409 	hdd_init_ll_stats_ctx();
6410 
6411 	init_completion(&hdd_ctx->mc_sus_event_var);
6412 	init_completion(&hdd_ctx->ready_to_suspend);
6413 
6414 	hdd_init_bpf_completion();
6415 
6416 	qdf_spinlock_create(&hdd_ctx->connection_status_lock);
6417 	qdf_spinlock_create(&hdd_ctx->sta_update_info_lock);
6418 	qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
6419 
6420 	qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS);
6421 
6422 	init_completion(&hdd_ctx->set_antenna_mode_cmpl);
6423 
6424 	ret = hdd_scan_context_init(hdd_ctx);
6425 	if (ret)
6426 		goto list_destroy;
6427 
6428 	hdd_tdls_context_init(hdd_ctx);
6429 
6430 	hdd_rx_wake_lock_create(hdd_ctx);
6431 
6432 	ret = hdd_sap_context_init(hdd_ctx);
6433 	if (ret)
6434 		goto scan_destroy;
6435 
6436 	ret = hdd_roc_context_init(hdd_ctx);
6437 	if (ret)
6438 		goto sap_destroy;
6439 
6440 	wlan_hdd_cfg80211_extscan_init(hdd_ctx);
6441 
6442 	hdd_init_offloaded_packets_ctx(hdd_ctx);
6443 
6444 	ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
6445 				     hdd_ctx->config);
6446 	if (ret)
6447 		goto roc_destroy;
6448 
6449 	return 0;
6450 
6451 roc_destroy:
6452 	hdd_roc_context_destroy(hdd_ctx);
6453 
6454 sap_destroy:
6455 	hdd_sap_context_destroy(hdd_ctx);
6456 
6457 scan_destroy:
6458 	hdd_scan_context_destroy(hdd_ctx);
6459 	hdd_rx_wake_lock_destroy(hdd_ctx);
6460 	hdd_tdls_context_destroy(hdd_ctx);
6461 
6462 list_destroy:
6463 	qdf_list_destroy(&hdd_ctx->hddAdapters);
6464 	return ret;
6465 }
6466 
6467 /**
6468  * hdd_context_create() - Allocate and inialize HDD context.
6469  * @dev:	Device Pointer to the underlying device
6470  *
6471  * Allocate and initialize HDD context. HDD context is allocated as part of
6472  * wiphy allocation and then context is initialized.
6473  *
6474  * Return: HDD context on success and ERR_PTR on failure
6475  */
6476 static hdd_context_t *hdd_context_create(struct device *dev)
6477 {
6478 	QDF_STATUS status;
6479 	int ret = 0;
6480 	hdd_context_t *hdd_ctx;
6481 	v_CONTEXT_t p_cds_context;
6482 
6483 	ENTER();
6484 
6485 	p_cds_context = cds_get_global_context();
6486 	if (p_cds_context == NULL) {
6487 		hdd_alert("Failed to get CDS global context");
6488 		ret = -EINVAL;
6489 		goto err_out;
6490 	}
6491 
6492 	hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t));
6493 
6494 	if (hdd_ctx == NULL) {
6495 		ret = -ENOMEM;
6496 		goto err_out;
6497 	}
6498 
6499 	hdd_ctx->pcds_context = p_cds_context;
6500 	hdd_ctx->parent_dev = dev;
6501 
6502 	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
6503 	if (hdd_ctx->config == NULL) {
6504 		hdd_alert("Failed to alloc memory for HDD config!");
6505 		ret = -ENOMEM;
6506 		goto err_free_hdd_context;
6507 	}
6508 
6509 	/* Read and parse the qcom_cfg.ini file */
6510 	status = hdd_parse_config_ini(hdd_ctx);
6511 	if (QDF_STATUS_SUCCESS != status) {
6512 		hdd_err("Error (status: %d) parsing INI file: %s", status,
6513 			  WLAN_INI_FILE);
6514 		ret = -EINVAL;
6515 		goto err_free_config;
6516 	}
6517 
6518 	hdd_ctx->configuredMcastBcastFilter =
6519 		hdd_ctx->config->mcastBcastFilterSetting;
6520 
6521 	hdd_notice("Setting configuredMcastBcastFilter: %d",
6522 		   hdd_ctx->config->mcastBcastFilterSetting);
6523 
6524 	if (hdd_ctx->config->fhostNSOffload)
6525 		hdd_ctx->ns_offload_enable = true;
6526 
6527 	cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
6528 
6529 	hdd_override_ini_config(hdd_ctx);
6530 
6531 	((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx;
6532 
6533 	ret = hdd_context_init(hdd_ctx);
6534 
6535 	if (ret)
6536 		goto err_free_config;
6537 
6538 
6539 	pld_set_fw_debug_mode(hdd_ctx->parent_dev,
6540 			      hdd_ctx->config->enable_fw_log);
6541 
6542 
6543 	/* Uses to enabled logging after SSR */
6544 	hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;
6545 
6546 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
6547 		goto skip_multicast_logging;
6548 
6549 	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
6550 
6551 	ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
6552 	if (ret)
6553 		goto err_deinit_hdd_context;
6554 
6555 	ret = hdd_logging_sock_activate_svc(hdd_ctx);
6556 	if (ret)
6557 		goto err_free_histogram;
6558 
6559 
6560 	/*
6561 	 * Update QDF trace levels based upon the code. The multicast
6562 	 * levels of the code need not be set when the logger thread
6563 	 * is not enabled.
6564 	 */
6565 	if (cds_is_multicast_logging())
6566 		wlan_logging_set_log_level();
6567 
6568 skip_multicast_logging:
6569 	hdd_set_trace_level_for_each(hdd_ctx);
6570 
6571 	return hdd_ctx;
6572 
6573 err_free_histogram:
6574 	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
6575 
6576 err_deinit_hdd_context:
6577 	hdd_context_deinit(hdd_ctx);
6578 
6579 err_free_config:
6580 	qdf_mem_free(hdd_ctx->config);
6581 
6582 err_free_hdd_context:
6583 	wiphy_free(hdd_ctx->wiphy);
6584 
6585 err_out:
6586 	return ERR_PTR(ret);
6587 }
6588 
6589 #ifdef WLAN_OPEN_P2P_INTERFACE
6590 /**
6591  * hdd_open_p2p_interface - Open P2P interface
6592  * @hdd_ctx:	HDD context
6593  * @rtnl_held:	True if RTNL lock held
6594  *
6595  * Open P2P interface during probe. This function called to open the P2P
6596  * interface at probe along with STA interface.
6597  *
6598  * Return: 0 on success and errno on failure
6599  */
6600 static int hdd_open_p2p_interface(hdd_context_t *hdd_ctx, bool rtnl_held)
6601 {
6602 	hdd_adapter_t *adapter;
6603 	uint8_t *p2p_dev_addr;
6604 
6605 	if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
6606 	    !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
6607 		qdf_mem_copy(hdd_ctx->p2pDeviceAddress.bytes,
6608 			     hdd_ctx->config->intfMacAddr[0].bytes,
6609 			     sizeof(tSirMacAddr));
6610 
6611 		/*
6612 		 * Generate the P2P Device Address.  This consists of
6613 		 * the device's primary MAC address with the locally
6614 		 * administered bit set.
6615 		 */
6616 		hdd_ctx->p2pDeviceAddress.bytes[0] |= 0x02;
6617 	} else {
6618 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
6619 		if (p2p_dev_addr == NULL) {
6620 			hdd_alert("Failed to allocate mac_address for p2p_device");
6621 			return -ENOSPC;
6622 		}
6623 
6624 		qdf_mem_copy(&hdd_ctx->p2pDeviceAddress.bytes[0], p2p_dev_addr,
6625 			     QDF_MAC_ADDR_SIZE);
6626 	}
6627 
6628 	adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
6629 				   &hdd_ctx->p2pDeviceAddress.bytes[0],
6630 				   NET_NAME_UNKNOWN, rtnl_held);
6631 
6632 	if (NULL == adapter) {
6633 		hdd_alert("Failed to do hdd_open_adapter for P2P Device Interface");
6634 		return -ENOSPC;
6635 	}
6636 
6637 	return 0;
6638 }
6639 #else
6640 static inline int hdd_open_p2p_interface(hdd_context_t *hdd_ctx,
6641 					 bool rtnl_held)
6642 {
6643 	return 0;
6644 }
6645 #endif
6646 
6647 /**
6648  * hdd_start_station_adapter()- Start the Station Adapter
6649  * @adapter: HDD adapter
6650  *
6651  * This function initializes the adapter for the station mode.
6652  *
6653  * Return: 0 on success or errno on failure.
6654  */
6655 int hdd_start_station_adapter(hdd_adapter_t *adapter)
6656 {
6657 	QDF_STATUS status;
6658 
6659 	ENTER_DEV(adapter->dev);
6660 
6661 	status = hdd_init_station_mode(adapter);
6662 
6663 	if (QDF_STATUS_SUCCESS != status) {
6664 		hdd_err("Error Initializing station mode: %d", status);
6665 		return qdf_status_to_os_return(status);
6666 	}
6667 
6668 	hdd_register_tx_flow_control(adapter,
6669 		hdd_tx_resume_timer_expired_handler,
6670 		hdd_tx_resume_cb);
6671 
6672 	EXIT();
6673 	return 0;
6674 }
6675 
6676 /**
6677  * hdd_start_ap_adapter()- Start AP Adapter
6678  * @adapter: HDD adapter
6679  *
6680  * This function initializes the adapter for the AP mode.
6681  *
6682  * Return: 0 on success errno on failure.
6683  */
6684 int hdd_start_ap_adapter(hdd_adapter_t *adapter)
6685 {
6686 	QDF_STATUS status;
6687 
6688 	ENTER();
6689 
6690 	status = hdd_init_ap_mode(adapter);
6691 
6692 	if (QDF_STATUS_SUCCESS != status) {
6693 		hdd_err("Error Initializing the AP mode: %d", status);
6694 		return qdf_status_to_os_return(status);
6695 	}
6696 
6697 	hdd_register_tx_flow_control(adapter,
6698 		hdd_softap_tx_resume_timer_expired_handler,
6699 		hdd_softap_tx_resume_cb);
6700 
6701 	EXIT();
6702 	return 0;
6703 }
6704 
6705 /**
6706  * hdd_start_ftm_adapter()- Start FTM adapter
6707  * @adapter: HDD adapter
6708  *
6709  * This function initializes the adapter for the FTM mode.
6710  *
6711  * Return: 0 on success or errno on failure.
6712  */
6713 int hdd_start_ftm_adapter(hdd_adapter_t *adapter)
6714 {
6715 	QDF_STATUS qdf_status;
6716 
6717 	ENTER_DEV(adapter->dev);
6718 
6719 	qdf_status = hdd_init_tx_rx(adapter);
6720 
6721 	if (QDF_STATUS_SUCCESS != qdf_status) {
6722 		hdd_err("Failed to start FTM adapter: %d", qdf_status);
6723 		return qdf_status_to_os_return(qdf_status);
6724 	}
6725 
6726 	return 0;
6727 	EXIT();
6728 }
6729 
6730 /**
6731  * hdd_open_interfaces - Open all required interfaces
6732  * hdd_ctx:	HDD context
6733  * rtnl_held: True if RTNL lock is held
6734  *
6735  * Open all the interfaces like STA, P2P and OCB based on the configuration.
6736  *
6737  * Return: Primary adapter on success and PTR_ERR on failure
6738  */
6739 static hdd_adapter_t *hdd_open_interfaces(hdd_context_t *hdd_ctx,
6740 					  bool rtnl_held)
6741 {
6742 	hdd_adapter_t *adapter = NULL;
6743 	hdd_adapter_t *adapter_11p = NULL;
6744 	int ret;
6745 
6746 	if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE) {
6747 		/* Create only 802.11p interface */
6748 		adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
6749 					   wlan_hdd_get_intf_addr(hdd_ctx),
6750 					   NET_NAME_UNKNOWN, rtnl_held);
6751 
6752 		if (adapter == NULL)
6753 			return ERR_PTR(-ENOSPC);
6754 
6755 		return adapter;
6756 	}
6757 	adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
6758 				   wlan_hdd_get_intf_addr(hdd_ctx),
6759 				   NET_NAME_UNKNOWN, rtnl_held);
6760 
6761 	if (adapter == NULL)
6762 		return ERR_PTR(-ENOSPC);
6763 	ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
6764 	if (ret)
6765 		goto err_close_adapter;
6766 
6767 	/* Open 802.11p Interface */
6768 	if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
6769 		adapter_11p = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE,
6770 					       "wlanocb%d",
6771 					       wlan_hdd_get_intf_addr(hdd_ctx),
6772 					       NET_NAME_UNKNOWN, rtnl_held);
6773 		if (adapter_11p == NULL) {
6774 			hdd_err("Failed to open 802.11p interface");
6775 			goto err_close_adapter;
6776 		}
6777 	}
6778 
6779 	return adapter;
6780 
6781 err_close_adapter:
6782 	hdd_close_all_adapters(hdd_ctx, rtnl_held);
6783 	return ERR_PTR(ret);
6784 }
6785 
6786 /**
6787  * hdd_update_country_code - Update country code
6788  * @hdd_ctx: HDD context
6789  * @adapter: Primary adapter context
6790  *
6791  * Update country code based on module parameter country_code at SME and wait
6792  * for the settings to take effect.
6793  *
6794  * Return: 0 on success and errno on failure
6795  */
6796 static int hdd_update_country_code(hdd_context_t *hdd_ctx,
6797 				  hdd_adapter_t *adapter)
6798 {
6799 	QDF_STATUS status;
6800 	int ret = 0;
6801 	unsigned long rc;
6802 
6803 	if (country_code == NULL)
6804 		return 0;
6805 
6806 	INIT_COMPLETION(adapter->change_country_code);
6807 
6808 	status = sme_change_country_code(hdd_ctx->hHal,
6809 					 wlan_hdd_change_country_code_callback,
6810 					 country_code, adapter,
6811 					 hdd_ctx->pcds_context, eSIR_TRUE,
6812 					 eSIR_TRUE);
6813 
6814 
6815 	if (!QDF_IS_STATUS_SUCCESS(status)) {
6816 		hdd_err("SME Change Country code from module param fail ret=%d",
6817 			ret);
6818 		return -EINVAL;
6819 	}
6820 
6821 	rc = wait_for_completion_timeout(&adapter->change_country_code,
6822 			 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
6823 	if (!rc) {
6824 		hdd_err("SME while setting country code timed out");
6825 		ret = -ETIMEDOUT;
6826 	}
6827 
6828 	return ret;
6829 }
6830 
6831 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
6832 /**
6833  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
6834  * @cds_cfg: CDS Configuration
6835  * @hdd_ctx: Pointer to hdd context
6836  *
6837  * Return: none
6838  */
6839 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
6840 						*cds_cfg,
6841 						hdd_context_t *hdd_ctx)
6842 {
6843 	cds_cfg->tx_flow_stop_queue_th =
6844 		hdd_ctx->config->TxFlowStopQueueThreshold;
6845 	cds_cfg->tx_flow_start_queue_offset =
6846 		hdd_ctx->config->TxFlowStartQueueOffset;
6847 }
6848 #else
6849 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
6850 						*cds_cfg,
6851 						hdd_context_t *hdd_ctx)
6852 {
6853 }
6854 #endif
6855 
6856 #ifdef FEATURE_WLAN_RA_FILTERING
6857 /**
6858  * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
6859  * @cds_cfg: CDS Configuration
6860  * @hdd_ctx: Pointer to hdd context
6861  *
6862  * Return: none
6863  */
6864 inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
6865 			      hdd_context_t *hdd_ctx)
6866 {
6867 	cds_cfg->ra_ratelimit_interval =
6868 		hdd_ctx->config->RArateLimitInterval;
6869 	cds_cfg->is_ra_ratelimit_enabled =
6870 		hdd_ctx->config->IsRArateLimitEnabled;
6871 }
6872 #else
6873 inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
6874 			     hdd_context_t *hdd_ctx)
6875 {
6876 }
6877 #endif
6878 
6879 /**
6880  * hdd_update_cds_config() - API to update cds configuration parameters
6881  * @hdd_ctx: HDD Context
6882  *
6883  * Return: 0 for Success, errno on failure
6884  */
6885 static int hdd_update_cds_config(hdd_context_t *hdd_ctx)
6886 {
6887 	struct cds_config_info *cds_cfg;
6888 
6889 	cds_cfg = (struct cds_config_info *)qdf_mem_malloc(sizeof(*cds_cfg));
6890 	if (!cds_cfg) {
6891 		hdd_err("failed to allocate cds config");
6892 		return -ENOMEM;
6893 	}
6894 
6895 	/* UMA is supported in hardware for performing the
6896 	 * frame translation 802.11 <-> 802.3
6897 	 */
6898 	cds_cfg->frame_xln_reqd = 1;
6899 	cds_cfg->driver_type = DRIVER_TYPE_PRODUCTION;
6900 	cds_cfg->powersave_offload_enabled =
6901 		hdd_ctx->config->enablePowersaveOffload;
6902 	cds_cfg->sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
6903 	cds_cfg->sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
6904 	cds_cfg->sta_maxlimod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
6905 	cds_cfg->wow_enable = hdd_ctx->config->wowEnable;
6906 	cds_cfg->max_wow_filters = hdd_ctx->config->maxWoWFilters;
6907 
6908 	/* Here ol_ini_info is used to store ini status of arp offload
6909 	 * ns offload and others. Currently 1st bit is used for arp
6910 	 * off load and 2nd bit for ns offload currently, rest bits are unused
6911 	 */
6912 	if (hdd_ctx->config->fhostArpOffload)
6913 		cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x1;
6914 	if (hdd_ctx->config->fhostNSOffload)
6915 		cds_cfg->ol_ini_info = cds_cfg->ol_ini_info | 0x2;
6916 
6917 	/*
6918 	 * Copy the DFS Phyerr Filtering Offload status.
6919 	 * This parameter reflects the value of the
6920 	 * dfs_phyerr_filter_offload flag as set in the ini.
6921 	 */
6922 	cds_cfg->dfs_phyerr_filter_offload =
6923 		hdd_ctx->config->fDfsPhyerrFilterOffload;
6924 	if (hdd_ctx->config->ssdp)
6925 		cds_cfg->ssdp = hdd_ctx->config->ssdp;
6926 
6927 	cds_cfg->enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
6928 	cds_cfg->ap_maxoffload_peers = hdd_ctx->config->apMaxOffloadPeers;
6929 
6930 	cds_cfg->ap_maxoffload_reorderbuffs =
6931 		hdd_ctx->config->apMaxOffloadReorderBuffs;
6932 
6933 	cds_cfg->ap_disable_intrabss_fwd =
6934 		hdd_ctx->config->apDisableIntraBssFwd;
6935 
6936 	cds_cfg->dfs_pri_multiplier =
6937 		hdd_ctx->config->dfsRadarPriMultiplier;
6938 	cds_cfg->reorder_offload =
6939 			hdd_ctx->config->reorderOffloadSupport;
6940 
6941 	/* IPA micro controller data path offload resource config item */
6942 	cds_cfg->uc_offload_enabled = hdd_ipa_uc_is_enabled(hdd_ctx);
6943 	cds_cfg->uc_txbuf_count = hdd_ctx->config->IpaUcTxBufCount;
6944 	cds_cfg->uc_txbuf_size = hdd_ctx->config->IpaUcTxBufSize;
6945 	cds_cfg->uc_rxind_ringcount =
6946 			hdd_ctx->config->IpaUcRxIndRingCount;
6947 	cds_cfg->uc_tx_partition_base =
6948 				hdd_ctx->config->IpaUcTxPartitionBase;
6949 	cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
6950 
6951 	cds_cfg->ip_tcp_udp_checksum_offload =
6952 		hdd_ctx->config->enable_ip_tcp_udp_checksum_offload;
6953 	cds_cfg->enable_rxthread = hdd_ctx->enableRxThread;
6954 	cds_cfg->ce_classify_enabled =
6955 		hdd_ctx->config->ce_classify_enabled;
6956 	cds_cfg->bpf_packet_filter_enable =
6957 		hdd_ctx->config->bpf_packet_filter_enable;
6958 	cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
6959 	cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
6960 	cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
6961 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
6962 	cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
6963 	cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
6964 	cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
6965 
6966 	hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
6967 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
6968 	hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
6969 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
6970 	cds_init_ini_config(cds_cfg);
6971 	return 0;
6972 }
6973 
6974 /**
6975  * hdd_init_thermal_info - Initialize thermal level
6976  * @hdd_ctx:	HDD context
6977  *
6978  * Initialize thermal level at SME layer and set the thermal level callback
6979  * which would be called when a configured thermal threshold is hit.
6980  *
6981  * Return: 0 on success and errno on failure
6982  */
6983 static int hdd_init_thermal_info(hdd_context_t *hdd_ctx)
6984 {
6985 	tSmeThermalParams thermal_param;
6986 	QDF_STATUS status;
6987 
6988 	thermal_param.smeThermalMgmtEnabled =
6989 		hdd_ctx->config->thermalMitigationEnable;
6990 	thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
6991 
6992 	thermal_param.sme_throttle_duty_cycle_tbl[0] =
6993 		hdd_ctx->config->throttle_dutycycle_level0;
6994 	thermal_param.sme_throttle_duty_cycle_tbl[1] =
6995 		hdd_ctx->config->throttle_dutycycle_level1;
6996 	thermal_param.sme_throttle_duty_cycle_tbl[2] =
6997 		hdd_ctx->config->throttle_dutycycle_level2;
6998 	thermal_param.sme_throttle_duty_cycle_tbl[3] =
6999 		hdd_ctx->config->throttle_dutycycle_level3;
7000 
7001 	thermal_param.smeThermalLevels[0].smeMinTempThreshold =
7002 		hdd_ctx->config->thermalTempMinLevel0;
7003 	thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
7004 		hdd_ctx->config->thermalTempMaxLevel0;
7005 	thermal_param.smeThermalLevels[1].smeMinTempThreshold =
7006 		hdd_ctx->config->thermalTempMinLevel1;
7007 	thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
7008 		hdd_ctx->config->thermalTempMaxLevel1;
7009 	thermal_param.smeThermalLevels[2].smeMinTempThreshold =
7010 		hdd_ctx->config->thermalTempMinLevel2;
7011 	thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
7012 		hdd_ctx->config->thermalTempMaxLevel2;
7013 	thermal_param.smeThermalLevels[3].smeMinTempThreshold =
7014 		hdd_ctx->config->thermalTempMinLevel3;
7015 	thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
7016 		hdd_ctx->config->thermalTempMaxLevel3;
7017 
7018 	status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);
7019 
7020 	if (!QDF_IS_STATUS_SUCCESS(status))
7021 		return qdf_status_to_os_return(status);
7022 
7023 	sme_add_set_thermal_level_callback(hdd_ctx->hHal,
7024 					   hdd_set_thermal_level_cb);
7025 
7026 	return 0;
7027 
7028 }
7029 
7030 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
7031 /**
7032  * hdd_hold_rtnl_lock - Hold RTNL lock
7033  *
7034  * Hold RTNL lock
7035  *
7036  * Return: True if held and false otherwise
7037  */
7038 static inline bool hdd_hold_rtnl_lock(void)
7039 {
7040 	rtnl_lock();
7041 	return true;
7042 }
7043 
7044 /**
7045  * hdd_release_rtnl_lock - Release RTNL lock
7046  *
7047  * Release RTNL lock
7048  *
7049  * Return: None
7050  */
7051 static inline void hdd_release_rtnl_lock(void)
7052 {
7053 	rtnl_unlock();
7054 }
7055 #else
7056 static inline bool hdd_hold_rtnl_lock(void) { return false; }
7057 static inline void hdd_release_rtnl_lock(void) { }
7058 #endif
7059 
7060 #if !defined(REMOVE_PKT_LOG)
7061 
7062 /* MAX iwpriv command support */
7063 #define PKTLOG_SET_BUFF_SIZE	3
7064 #define MAX_PKTLOG_SIZE		16
7065 
7066 /**
7067  * hdd_pktlog_set_buff_size() - set pktlog buffer size
7068  * @hdd_ctx: hdd context
7069  * @set_value2: pktlog buffer size value
7070  *
7071  *
7072  * Return: 0 for success or error.
7073  */
7074 static int hdd_pktlog_set_buff_size(hdd_context_t *hdd_ctx, int set_value2)
7075 {
7076 	struct sir_wifi_start_log start_log = { 0 };
7077 	QDF_STATUS status;
7078 
7079 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
7080 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
7081 	start_log.ini_triggered = cds_is_packet_log_enabled();
7082 	start_log.user_triggered = 1;
7083 	start_log.size = set_value2;
7084 
7085 	status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
7086 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7087 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
7088 		EXIT();
7089 		return -EINVAL;
7090 	}
7091 
7092 	return 0;
7093 }
7094 
7095 /**
7096  * hdd_process_pktlog_command() - process pktlog command
7097  * @hdd_ctx: hdd context
7098  * @set_value: value set by user
7099  * @set_value2: pktlog buffer size value
7100  *
7101  * This function process pktlog command.
7102  * set_value2 only matters when set_value is 3 (set buff size)
7103  * otherwise we ignore it.
7104  *
7105  * Return: 0 for success or error.
7106  */
7107 int hdd_process_pktlog_command(hdd_context_t *hdd_ctx, uint32_t set_value,
7108 			       int set_value2)
7109 {
7110 	int ret;
7111 	bool enable;
7112 	uint8_t user_triggered = 0;
7113 
7114 	ret = wlan_hdd_validate_context(hdd_ctx);
7115 	if (0 != ret)
7116 		return ret;
7117 
7118 	hdd_info("set pktlog %d, set size %d", set_value, set_value2);
7119 
7120 	if (set_value > PKTLOG_SET_BUFF_SIZE) {
7121 		hdd_err("invalid pktlog value %d", set_value);
7122 		return -EINVAL;
7123 	}
7124 
7125 	if (set_value == PKTLOG_SET_BUFF_SIZE) {
7126 		if (set_value2 <= 0) {
7127 			hdd_err("invalid pktlog size %d", set_value2);
7128 			return -EINVAL;
7129 		} else if (set_value2 > MAX_PKTLOG_SIZE) {
7130 			hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
7131 			return -EINVAL;
7132 		}
7133 		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
7134 	}
7135 
7136 	/*
7137 	 * set_value = 0 then disable packetlog
7138 	 * set_value = 1 enable packetlog forcefully
7139 	 * set_vlaue = 2 then disable packetlog if disabled through ini or
7140 	 *                     enable packetlog with AUTO type.
7141 	 */
7142 	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
7143 			 true : false;
7144 
7145 	if (1 == set_value) {
7146 		enable = true;
7147 		user_triggered = 1;
7148 	}
7149 
7150 	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
7151 }
7152 /**
7153  * hdd_pktlog_enable_disable() - Enable/Disable packet logging
7154  * @hdd_ctx: HDD context
7155  * @enable: Flag to enable/disable
7156  * @user_triggered: triggered through iwpriv
7157  * @size: buffer size to be used for packetlog
7158  *
7159  * Return: 0 on success; error number otherwise
7160  */
7161 int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable,
7162 				uint8_t user_triggered, int size)
7163 {
7164 	struct sir_wifi_start_log start_log;
7165 	QDF_STATUS status;
7166 
7167 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
7168 	start_log.verbose_level =
7169 			enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
7170 	start_log.ini_triggered = cds_is_packet_log_enabled();
7171 	start_log.user_triggered = user_triggered;
7172 	start_log.size = size;
7173 	/*
7174 	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
7175 	 * commands. Host uses this flag to decide whether to send pktlog
7176 	 * disable command to fw without sending pktlog enable command
7177 	 * previously. For eg, If vendor sends pktlog disable command without
7178 	 * sending pktlog enable command, then host discards the packet
7179 	 * but for iwpriv command, host will send it to fw.
7180 	 */
7181 	start_log.is_iwpriv_command = 1;
7182 	status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
7183 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7184 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
7185 		EXIT();
7186 		return -EINVAL;
7187 	}
7188 
7189 	return 0;
7190 }
7191 #endif /* REMOVE_PKT_LOG */
7192 
7193 
7194 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7195 /**
7196  * hdd_register_for_sap_restart_with_channel_switch() - Register for SAP channel
7197  * switch without restart
7198  *
7199  * Registers callback function to change the operating channel of SAP by using
7200  * channel switch announcements instead of restarting SAP.
7201  *
7202  * Return: QDF_STATUS
7203  */
7204 QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void)
7205 {
7206 	QDF_STATUS status;
7207 
7208 	status = cds_register_sap_restart_channel_switch_cb(
7209 			(void *)hdd_sap_restart_with_channel_switch);
7210 	if (!QDF_IS_STATUS_SUCCESS(status))
7211 		hdd_err("restart cb registration failed");
7212 
7213 	return status;
7214 }
7215 #endif
7216 
7217 /**
7218  * hdd_get_platform_wlan_mac_buff() - API to query platform driver
7219  *                                    for MAC address
7220  * @dev: Device Pointer
7221  * @num: Number of Valid Mac address
7222  *
7223  * Return: Pointer to MAC address buffer
7224  */
7225 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
7226 					       uint32_t *num)
7227 {
7228 	return pld_get_wlan_mac_address(dev, num);
7229 }
7230 
7231 /**
7232  * hdd_populate_random_mac_addr() - API to populate random mac addresses
7233  * @hdd_ctx: HDD Context
7234  * @num: Number of random mac addresses needed
7235  *
7236  * Generate random addresses using bit manipulation on the base mac address
7237  *
7238  * Return: None
7239  */
7240 static void hdd_populate_random_mac_addr(hdd_context_t *hdd_ctx, uint32_t num)
7241 {
7242 	uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
7243 	uint32_t iter;
7244 	struct hdd_config *ini = hdd_ctx->config;
7245 	uint8_t *buf = NULL;
7246 	uint8_t macaddr_b3, tmp_br3;
7247 	uint8_t *src = ini->intfMacAddr[0].bytes;
7248 
7249 	for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
7250 		buf = ini->intfMacAddr[iter].bytes;
7251 		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
7252 		macaddr_b3 = buf[3];
7253 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
7254 			INTF_MACADDR_MASK;
7255 		macaddr_b3 += tmp_br3;
7256 		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
7257 		buf[0] |= 0x02;
7258 		buf[3] = macaddr_b3;
7259 		hdd_info(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
7260 	}
7261 }
7262 
7263 /**
7264  * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
7265  * @hdd_ctx: HDD Context
7266  *
7267  * API to get mac addresses from platform driver and update the driver
7268  * structures and configure FW with the base mac address.
7269  * Return: int
7270  */
7271 static int hdd_platform_wlan_mac(hdd_context_t *hdd_ctx)
7272 {
7273 	uint32_t no_of_mac_addr, iter;
7274 	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
7275 	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
7276 	uint8_t *addr, *buf;
7277 	struct device *dev = hdd_ctx->parent_dev;
7278 	struct hdd_config *ini = hdd_ctx->config;
7279 	tSirMacAddr mac_addr;
7280 	QDF_STATUS status;
7281 
7282 	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
7283 
7284 	if (no_of_mac_addr == 0 || !addr) {
7285 		hdd_warn("Platform Driver Doesn't have wlan mac addresses");
7286 		return -EINVAL;
7287 	}
7288 
7289 	if (no_of_mac_addr > max_mac_addr)
7290 		no_of_mac_addr = max_mac_addr;
7291 
7292 	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
7293 
7294 	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
7295 		buf = ini->intfMacAddr[iter].bytes;
7296 		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
7297 		hdd_info(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
7298 	}
7299 
7300 	status = sme_set_custom_mac_addr(mac_addr);
7301 
7302 	if (!QDF_IS_STATUS_SUCCESS(status))
7303 		return -EAGAIN;
7304 	if (no_of_mac_addr < max_mac_addr)
7305 		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
7306 					     no_of_mac_addr);
7307 	return 0;
7308 }
7309 
7310 /**
7311  * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
7312  * @hdd_ctx: HDD Context
7313  *
7314  * Update MAC address to FW. If MAC address passed by FW is invalid, host
7315  * will generate its own MAC and update it to FW.
7316  *
7317  * Return: 0 for success
7318  *         Non-zero error code for failure
7319  */
7320 static int hdd_update_mac_addr_to_fw(hdd_context_t *hdd_ctx)
7321 {
7322 	tSirMacAddr customMacAddr;
7323 	QDF_STATUS status;
7324 
7325 	qdf_mem_copy(&customMacAddr,
7326 		     &hdd_ctx->config->intfMacAddr[0].bytes[0],
7327 		     sizeof(tSirMacAddr));
7328 	status = sme_set_custom_mac_addr(customMacAddr);
7329 	if (!QDF_IS_STATUS_SUCCESS(status))
7330 		return -EAGAIN;
7331 	return 0;
7332 }
7333 
7334 /**
7335  * hdd_initialize_mac_address() - API to get wlan mac addresses
7336  * @hdd_ctx: HDD Context
7337  *
7338  * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
7339  * is provisioned with mac addresses, driver uses it, else it will use
7340  * wlan_mac.bin to update HW MAC addresses.
7341  *
7342  * Return: None
7343  */
7344 static void hdd_initialize_mac_address(hdd_context_t *hdd_ctx)
7345 {
7346 	QDF_STATUS status;
7347 	int ret;
7348 
7349 	ret = hdd_platform_wlan_mac(hdd_ctx);
7350 	if (ret == 0)
7351 		return;
7352 
7353 	hdd_warn("Can't update mac config via platform driver ret:%d", ret);
7354 
7355 	status = hdd_update_mac_config(hdd_ctx);
7356 
7357 	if (QDF_IS_STATUS_SUCCESS(status))
7358 		return;
7359 
7360 	hdd_warn("can't update mac config via wlan_mac.bin, using MAC from ini file or auto-gen");
7361 
7362 	if (hdd_ctx->update_mac_addr_to_fw) {
7363 		ret = hdd_update_mac_addr_to_fw(hdd_ctx);
7364 		if (ret != 0) {
7365 			hdd_err("MAC address out-of-sync, ret:%d", ret);
7366 			QDF_ASSERT(ret);
7367 		}
7368 	}
7369 }
7370 
7371 /**
7372  * hdd_tsf_init() - Initialize the TSF synchronization interface
7373  * @hdd_ctx: HDD global context
7374  *
7375  * When TSF synchronization via GPIO is supported by the driver and
7376  * has been enabled in the configuration file, this function plumbs
7377  * the GPIO value down to firmware via SME.
7378  *
7379  * Return: None
7380  */
7381 #ifdef WLAN_FEATURE_TSF
7382 static void hdd_tsf_init(hdd_context_t *hdd_ctx)
7383 {
7384 	QDF_STATUS status;
7385 
7386 	if (hdd_ctx->config->tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
7387 		return;
7388 
7389 	status = sme_set_tsf_gpio(hdd_ctx->hHal,
7390 				      hdd_ctx->config->tsf_gpio_pin);
7391 	if (!QDF_IS_STATUS_SUCCESS(status))
7392 		hdd_err("Set tsf GPIO failed, status: %d", status);
7393 }
7394 #else
7395 static void hdd_tsf_init(hdd_context_t *hdd_ctx)
7396 {
7397 }
7398 #endif
7399 
7400 /**
7401  * hdd_pre_enable_configure() - Configurations prior to cds_enable
7402  * @hdd_ctx:	HDD context
7403  *
7404  * Pre configurations to be done at lower layer before calling cds enable.
7405  *
7406  * Return: 0 on success and errno on failure.
7407  */
7408 static int hdd_pre_enable_configure(hdd_context_t *hdd_ctx)
7409 {
7410 	int ret;
7411 	QDF_STATUS status;
7412 	tSirRetStatus hal_status;
7413 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
7414 
7415 	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
7416 	/*
7417 	 * Set 802.11p config
7418 	 * TODO-OCB: This has been temporarily added here to ensure this
7419 	 * parameter is set in CSR when we init the channel list. This should
7420 	 * be removed once the 5.9 GHz channels are added to the regulatory
7421 	 * domain.
7422 	 */
7423 	hdd_set_dot11p_config(hdd_ctx);
7424 
7425 	/*
7426 	 * Note that the cds_pre_enable() sequence triggers the cfg download.
7427 	 * The cfg download must occur before we update the SME config
7428 	 * since the SME config operation must access the cfg database
7429 	 */
7430 	status = hdd_set_sme_config(hdd_ctx);
7431 
7432 	if (QDF_STATUS_SUCCESS != status) {
7433 		hdd_alert("Failed hdd_set_sme_config: %d", status);
7434 		ret = qdf_status_to_os_return(status);
7435 		goto out;
7436 	}
7437 
7438 	ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
7439 				  hdd_ctx->config->tx_chain_mask_1ss,
7440 				  PDEV_CMD);
7441 	if (0 != ret) {
7442 		hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
7443 		goto out;
7444 	}
7445 
7446 	hdd_program_country_code(hdd_ctx);
7447 
7448 	status = hdd_set_sme_chan_list(hdd_ctx);
7449 	if (status != QDF_STATUS_SUCCESS) {
7450 		hdd_alert("Failed to init channel list: %d", status);
7451 		ret = qdf_status_to_os_return(status);
7452 		goto out;
7453 	}
7454 
7455 	/* Apply the cfg.ini to cfg.dat */
7456 	if (!hdd_update_config_cfg(hdd_ctx)) {
7457 		hdd_alert("config update failed");
7458 		ret = -EINVAL;
7459 		goto out;
7460 	}
7461 
7462 	/*
7463 	 * Set the MAC Address Currently this is used by HAL to add self sta.
7464 	 * Remove this once self sta is added as part of session open.
7465 	 */
7466 	hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
7467 				     hdd_ctx->config->intfMacAddr[0].bytes,
7468 				     sizeof(hdd_ctx->config->intfMacAddr[0]));
7469 
7470 	if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
7471 		hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
7472 			hal_status, hal_status);
7473 		ret = -EINVAL;
7474 		goto out;
7475 	}
7476 
7477 	hdd_init_channel_avoidance(hdd_ctx);
7478 
7479 out:
7480 	return ret;
7481 }
7482 
7483 /**
7484  * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
7485  * @context_ptr - hdd context pointer
7486  * @event_ptr - event structure pointer
7487  *
7488  * This is the p2p listen offload stop event handler, it sends vendor
7489  * event back to supplicant to notify the stop reason.
7490  *
7491  * Return: None
7492  */
7493 static void wlan_hdd_p2p_lo_event_callback(void *context_ptr,
7494 				void *event_ptr)
7495 {
7496 	hdd_context_t *hdd_ctx = (hdd_context_t *)context_ptr;
7497 	struct sir_p2p_lo_event *evt = event_ptr;
7498 	struct sk_buff *vendor_event;
7499 
7500 	ENTER();
7501 
7502 	if (hdd_ctx == NULL) {
7503 		hdd_err("Invalid HDD context pointer");
7504 		return;
7505 	}
7506 
7507 	vendor_event =
7508 		cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
7509 			NULL, sizeof(uint32_t) + NLMSG_HDRLEN,
7510 			QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
7511 			GFP_KERNEL);
7512 
7513 	if (!vendor_event) {
7514 		hdd_err("cfg80211_vendor_event_alloc failed");
7515 		return;
7516 	}
7517 
7518 	if (nla_put_u32(vendor_event,
7519 			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
7520 			evt->reason_code)) {
7521 		hdd_err("nla put failed");
7522 		kfree_skb(vendor_event);
7523 		return;
7524 	}
7525 
7526 	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
7527 }
7528 
7529 /**
7530  * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
7531  * @hdd_ctx: HDD context
7532  *
7533  * This function sends the adaptive dwell time config configuration to the
7534  * firmware via WMA
7535  *
7536  * Return: 0 - success, < 0 - failure
7537  */
7538 static int hdd_adaptive_dwelltime_init(hdd_context_t *hdd_ctx)
7539 {
7540 	QDF_STATUS status;
7541 	struct adaptive_dwelltime_params dwelltime_params;
7542 
7543 	dwelltime_params.is_enabled =
7544 			hdd_ctx->config->adaptive_dwell_mode_enabled;
7545 	dwelltime_params.dwelltime_mode =
7546 			hdd_ctx->config->global_adapt_dwelltime_mode;
7547 	dwelltime_params.lpf_weight =
7548 			hdd_ctx->config->adapt_dwell_lpf_weight;
7549 	dwelltime_params.passive_mon_intval =
7550 			hdd_ctx->config->adapt_dwell_passive_mon_intval;
7551 	dwelltime_params.wifi_act_threshold =
7552 			hdd_ctx->config->adapt_dwell_wifi_act_threshold;
7553 
7554 	status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
7555 						   &dwelltime_params);
7556 
7557 	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
7558 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7559 		hdd_err("Failed to send Adaptive Dwelltime configuration!");
7560 		return -EAGAIN;
7561 	}
7562 	return 0;
7563 }
7564 
7565 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
7566 /**
7567  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
7568  * @hdd_ctx:	HDD context
7569  *
7570  * Set auto shutdown callback to get indications from firmware to indicate
7571  * userspace to shutdown WLAN after a configured amount of inactivity.
7572  *
7573  * Return: 0 on success and errno on failure.
7574  */
7575 static int hdd_set_auto_shutdown_cb(hdd_context_t *hdd_ctx)
7576 {
7577 	QDF_STATUS status;
7578 
7579 	if (!hdd_ctx->config->WlanAutoShutdown)
7580 		return 0;
7581 
7582 	status = sme_set_auto_shutdown_cb(hdd_ctx->hHal,
7583 					  wlan_hdd_auto_shutdown_cb);
7584 	if (status != QDF_STATUS_SUCCESS)
7585 		hdd_err("Auto shutdown feature could not be enabled: %d",
7586 			status);
7587 
7588 	return qdf_status_to_os_return(status);
7589 }
7590 #else
7591 static int hdd_set_auto_shutdown_cb(hdd_context_t *hdd_ctx)
7592 {
7593 	return 0;
7594 }
7595 #endif
7596 
7597 /**
7598  * hdd_features_init() - Init features
7599  * @hdd_ctx:	HDD context
7600  * @adapter:	Primary adapter context
7601  *
7602  * Initialize features and their feature context after WLAN firmware is up.
7603  *
7604  * Return: 0 on success and errno on failure.
7605  */
7606 static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
7607 {
7608 	tSirTxPowerLimit hddtxlimit;
7609 	QDF_STATUS status;
7610 	int ret;
7611 
7612 	ENTER();
7613 
7614 	ret = hdd_update_country_code(hdd_ctx, adapter);
7615 	if (ret) {
7616 		hdd_err("Failed to update country code: %d", ret);
7617 		goto out;
7618 	}
7619 
7620 	/* FW capabilities received, Set the Dot11 mode */
7621 	sme_setdef_dot11mode(hdd_ctx->hHal);
7622 	sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal,
7623 			hdd_ctx->config->sta_prefer_80MHz_over_160MHz);
7624 
7625 
7626 	if (hdd_ctx->config->fIsImpsEnabled)
7627 		hdd_set_idle_ps_config(hdd_ctx, true);
7628 	else
7629 		hdd_set_idle_ps_config(hdd_ctx, false);
7630 
7631 	if (hdd_lro_init(hdd_ctx))
7632 		hdd_err("Unable to initialize LRO in fw");
7633 
7634 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
7635 		hdd_err("Unable to send adaptive dwelltime setting to FW");
7636 
7637 	ret = hdd_init_thermal_info(hdd_ctx);
7638 	if (ret) {
7639 		hdd_err("Error while initializing thermal information");
7640 		goto deregister_frames;
7641 	}
7642 
7643 	hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
7644 	hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
7645 	status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
7646 	if (!QDF_IS_STATUS_SUCCESS(status))
7647 		hdd_err("Error setting txlimit in sme: %d", status);
7648 
7649 	hdd_tsf_init(hdd_ctx);
7650 	hdd_encrypt_decrypt_init(hdd_ctx);
7651 
7652 	ret = hdd_register_cb(hdd_ctx);
7653 	if (ret) {
7654 		hdd_err("Failed to register HDD callbacks!");
7655 		goto deregister_frames;
7656 	}
7657 
7658 	if (hdd_ctx->config->dual_mac_feature_disable) {
7659 		status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx);
7660 		if (status != QDF_STATUS_SUCCESS) {
7661 			hdd_err("Failed to disable dual mac features");
7662 			goto deregister_cb;
7663 		}
7664 	}
7665 
7666 	/* register P2P Listen Offload event callback */
7667 	if (wma_is_p2p_lo_capable())
7668 		sme_register_p2p_lo_event(hdd_ctx->hHal, hdd_ctx,
7669 				wlan_hdd_p2p_lo_event_callback);
7670 
7671 	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
7672 
7673 	if (ret)
7674 		goto deregister_cb;
7675 
7676 	EXIT();
7677 	return 0;
7678 
7679 deregister_cb:
7680 	hdd_deregister_cb(hdd_ctx);
7681 deregister_frames:
7682 	wlan_hdd_cfg80211_deregister_frames(adapter);
7683 out:
7684 	return -EINVAL;
7685 
7686 }
7687 
7688 
7689 /**
7690  * hdd_configure_cds() - Configure cds modules
7691  * @hdd_ctx:	HDD context
7692  * @adapter:	Primary adapter context
7693  *
7694  * Enable Cds modules after WLAN firmware is up.
7695  *
7696  * Return: 0 on success and errno on failure.
7697  */
7698 int hdd_configure_cds(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
7699 {
7700 	int ret;
7701 	QDF_STATUS status;
7702 	/* structure of function pointers to be used by CDS */
7703 	struct cds_sme_cbacks sme_cbacks;
7704 
7705 	ret = hdd_pre_enable_configure(hdd_ctx);
7706 	if (ret) {
7707 		hdd_err("Failed to pre-configure cds");
7708 		goto out;
7709 	}
7710 
7711 	/*
7712 	 * Start CDS which starts up the SME/MAC/HAL modules and everything
7713 	 * else
7714 	 */
7715 	status = cds_enable(hdd_ctx->pcds_context);
7716 
7717 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7718 		hdd_alert("cds_enable failed");
7719 		goto out;
7720 	}
7721 
7722 	status = hdd_post_cds_enable_config(hdd_ctx);
7723 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7724 		hdd_alert("hdd_post_cds_enable_config failed");
7725 		goto cds_disable;
7726 	}
7727 
7728 	ret = hdd_features_init(hdd_ctx, adapter);
7729 	if (ret)
7730 		goto cds_disable;
7731 
7732 	sme_cbacks.sme_get_valid_channels = sme_get_cfg_valid_channels;
7733 	sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
7734 	status = cds_init_policy_mgr(&sme_cbacks);
7735 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7736 		hdd_err("Policy manager initialization failed");
7737 		goto hdd_features_deinit;
7738 	}
7739 
7740 	return 0;
7741 
7742 hdd_features_deinit:
7743 	hdd_deregister_cb(hdd_ctx);
7744 	wlan_hdd_cfg80211_deregister_frames(adapter);
7745 cds_disable:
7746 	cds_disable(hdd_ctx->pcds_context);
7747 
7748 out:
7749 	return -EINVAL;
7750 }
7751 
7752 /**
7753  * hdd_deconfigure_cds() -De-Configure cds
7754  * @hdd_ctx:	HDD context
7755  *
7756  * Deconfigure Cds modules before WLAN firmware is down.
7757  *
7758  * Return: 0 on success and errno on failure.
7759  */
7760 static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
7761 {
7762 	QDF_STATUS qdf_status;
7763 	int ret = 0;
7764 
7765 	ENTER();
7766 	/* De-register the SME callbacks */
7767 	hdd_deregister_cb(hdd_ctx);
7768 	hdd_encrypt_decrypt_deinit(hdd_ctx);
7769 
7770 	/* De-init Policy Manager */
7771 	if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
7772 		hdd_err("Failed to deinit policy manager");
7773 		/* Proceed and complete the clean up */
7774 		ret = -EINVAL;
7775 	}
7776 
7777 	qdf_status = cds_disable(hdd_ctx->pcds_context);
7778 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
7779 		hdd_err("Failed to Disable the CDS Modules! :%d",
7780 			qdf_status);
7781 		ret = -EINVAL;
7782 	}
7783 
7784 	EXIT();
7785 	return ret;
7786 }
7787 
7788 
7789 /**
7790  * hdd_wlan_stop_modules - Single driver state machine for stoping modules
7791  * @hdd_ctx: HDD context
7792  *
7793  * This function maintains the driver state machine it will be invoked from
7794  * exit, shutdown and con_mode change handler. Depending on the driver state
7795  * shall perform the stopping/closing of the modules.
7796  *
7797  * Return: 0 for success; non-zero for failure
7798  */
7799 int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
7800 {
7801 	void *hif_ctx;
7802 	qdf_device_t qdf_ctx;
7803 	QDF_STATUS qdf_status;
7804 	int ret = 0;
7805 	p_cds_sched_context cds_sched_context = NULL;
7806 
7807 	ENTER();
7808 
7809 
7810 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
7811 	if (!qdf_ctx) {
7812 		hdd_err("QDF device context NULL");
7813 		return -EINVAL;
7814 	}
7815 
7816 	cds_sched_context = get_cds_sched_ctxt();
7817 	if (!cds_sched_context) {
7818 		hdd_err("cds scheduler context NULL");
7819 		return -EINVAL;
7820 	}
7821 	mutex_lock(&hdd_ctx->iface_change_lock);
7822 	hdd_ctx->stop_modules_in_progress = true;
7823 
7824 	hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
7825 
7826 	switch (hdd_ctx->driver_status) {
7827 	case DRIVER_MODULES_UNINITIALIZED:
7828 		hdd_info("Modules not initialized just return");
7829 		goto done;
7830 	case DRIVER_MODULES_CLOSED:
7831 		hdd_info("Modules already closed");
7832 		goto done;
7833 	case DRIVER_MODULES_ENABLED:
7834 		hdd_disable_power_management();
7835 		if (hdd_deconfigure_cds(hdd_ctx)) {
7836 			hdd_alert("Failed to de-configure CDS");
7837 			QDF_ASSERT(0);
7838 			ret = -EINVAL;
7839 		}
7840 		hdd_info("successfully Disabled the CDS modules!");
7841 		hdd_ctx->driver_status = DRIVER_MODULES_OPENED;
7842 		break;
7843 	case DRIVER_MODULES_OPENED:
7844 		hdd_info("Closing CDS modules!");
7845 		break;
7846 	default:
7847 		hdd_err("Trying to stop wlan in a wrong state: %d",
7848 				hdd_ctx->driver_status);
7849 		QDF_ASSERT(0);
7850 		ret = -EINVAL;
7851 		goto done;
7852 	}
7853 
7854 	qdf_status = cds_post_disable(hdd_ctx->pcds_context);
7855 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
7856 		hdd_err("Failed to process post CDS disable Modules! :%d",
7857 			qdf_status);
7858 		ret = -EINVAL;
7859 		QDF_ASSERT(0);
7860 	}
7861 	qdf_status = cds_close(hdd_ctx->pcds_context);
7862 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
7863 		hdd_warn("Failed to stop CDS:%d", qdf_status);
7864 		ret = -EINVAL;
7865 		QDF_ASSERT(0);
7866 	}
7867 	/* Clean up message queues of TX, RX and MC thread */
7868 	if (!cds_is_driver_recovering())
7869 		cds_sched_flush_mc_mqs(cds_sched_context);
7870 
7871 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
7872 	if (!hif_ctx) {
7873 		hdd_err("Hif context is Null");
7874 		ret = -EINVAL;
7875 	}
7876 
7877 	hdd_hif_close(hif_ctx);
7878 
7879 	ol_cds_free();
7880 
7881 	if (!cds_is_driver_recovering()) {
7882 		ret = pld_power_off(qdf_ctx->dev);
7883 		if (ret)
7884 			hdd_err("CNSS power down failed put device into Low power mode:%d",
7885 				ret);
7886 	}
7887 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
7888 
7889 done:
7890 	hdd_ctx->stop_modules_in_progress = false;
7891 	mutex_unlock(&hdd_ctx->iface_change_lock);
7892 	EXIT();
7893 
7894 	return ret;
7895 
7896 }
7897 
7898 /**
7899  * hdd_iface_change_callback() - Function invoked when stop modules expires
7900  * @priv: pointer to hdd context
7901  *
7902  * This function is invoked when the timer waiting for the interface change
7903  * expires, it shall cut-down the power to wlan and stop all the modules.
7904  *
7905  * Return: void
7906  */
7907 static void hdd_iface_change_callback(void *priv)
7908 {
7909 	hdd_context_t *hdd_ctx = (hdd_context_t *) priv;
7910 	int ret;
7911 	int status = wlan_hdd_validate_context(hdd_ctx);
7912 
7913 	if (status)
7914 		return;
7915 
7916 	ENTER();
7917 	hdd_info("Interface change timer expired close the modules!");
7918 	ret = hdd_wlan_stop_modules(hdd_ctx);
7919 	if (ret)
7920 		hdd_alert("Failed to stop modules");
7921 	EXIT();
7922 }
7923 
7924 /**
7925  * hdd_state_info_dump() - prints state information of hdd layer
7926  * @buf: buffer pointer
7927  * @size: size of buffer to be filled
7928  *
7929  * This function is used to dump state information of hdd layer
7930  *
7931  * Return: None
7932  */
7933 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
7934 {
7935 	hdd_context_t *hdd_ctx;
7936 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
7937 	QDF_STATUS status;
7938 	hdd_station_ctx_t *hdd_sta_ctx;
7939 	hdd_adapter_t *adapter;
7940 	uint16_t len = 0;
7941 	char *buf = *buf_ptr;
7942 
7943 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7944 	if (!hdd_ctx) {
7945 		hdd_err("Failed to get hdd context ");
7946 		return;
7947 	}
7948 
7949 	hdd_notice("size of buffer: %d", *size);
7950 
7951 	len += scnprintf(buf + len, *size - len,
7952 		"\n isWiphySuspended %d", hdd_ctx->isWiphySuspended);
7953 	len += scnprintf(buf + len, *size - len,
7954 		"\n isMcThreadSuspended %d",
7955 		hdd_ctx->isMcThreadSuspended);
7956 
7957 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
7958 
7959 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
7960 		adapter = adapter_node->pAdapter;
7961 		if (adapter->dev)
7962 			len += scnprintf(buf + len, *size - len,
7963 				"\n device name: %s", adapter->dev->name);
7964 			len += scnprintf(buf + len, *size - len,
7965 				"\n device_mode: %d", adapter->device_mode);
7966 		switch (adapter->device_mode) {
7967 		case QDF_STA_MODE:
7968 		case QDF_P2P_CLIENT_MODE:
7969 			hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7970 			len += scnprintf(buf + len, *size - len,
7971 				"\n connState: %d",
7972 				hdd_sta_ctx->conn_info.connState);
7973 			break;
7974 
7975 		default:
7976 			break;
7977 		}
7978 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
7979 		adapter_node = next;
7980 	}
7981 
7982 	*size -= len;
7983 	*buf_ptr += len;
7984 }
7985 
7986 /**
7987  * hdd_register_debug_callback() - registration function for hdd layer
7988  * to print hdd state information
7989  *
7990  * Return: None
7991  */
7992 static void hdd_register_debug_callback(void)
7993 {
7994 	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
7995 }
7996 
7997 /**
7998  * hdd_wlan_startup() - HDD init function
7999  * @dev:	Pointer to the underlying device
8000  *
8001  * This is the driver startup code executed once a WLAN device has been detected
8002  *
8003  * Return:  0 for success, < 0 for failure
8004  */
8005 int hdd_wlan_startup(struct device *dev)
8006 {
8007 	QDF_STATUS status;
8008 	hdd_adapter_t *adapter = NULL;
8009 	hdd_context_t *hdd_ctx = NULL;
8010 	int ret;
8011 	void *hif_sc;
8012 	bool rtnl_held;
8013 	int set_value;
8014 
8015 	ENTER();
8016 
8017 	hdd_ctx = hdd_context_create(dev);
8018 
8019 	if (IS_ERR(hdd_ctx))
8020 		return PTR_ERR(hdd_ctx);
8021 
8022 	qdf_mc_timer_init(&hdd_ctx->iface_change_timer, QDF_TIMER_TYPE_SW,
8023 			  hdd_iface_change_callback, (void *)hdd_ctx);
8024 
8025 	mutex_init(&hdd_ctx->iface_change_lock);
8026 
8027 	ret = hdd_init_netlink_services(hdd_ctx);
8028 	if (ret)
8029 		goto err_hdd_free_context;
8030 
8031 	hdd_green_ap_init(hdd_ctx);
8032 
8033 	ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
8034 	if (ret) {
8035 		hdd_alert("Failed to start modules: %d", ret);
8036 		goto err_exit_nl_srv;
8037 	}
8038 
8039 	wlan_hdd_update_wiphy(hdd_ctx->wiphy, hdd_ctx->config);
8040 
8041 	hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);
8042 
8043 	if (NULL == hdd_ctx->hHal) {
8044 		hdd_alert("HAL context is null");
8045 		goto err_stop_modules;
8046 	}
8047 
8048 	ret = hdd_wiphy_init(hdd_ctx);
8049 	if (ret) {
8050 		hdd_alert("Failed to initialize wiphy: %d", ret);
8051 		goto err_stop_modules;
8052 	}
8053 
8054 	if (hdd_ctx->config->enable_dp_trace)
8055 		qdf_dp_trace_init();
8056 
8057 	if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
8058 		goto err_wiphy_unregister;
8059 
8060 	hdd_initialize_mac_address(hdd_ctx);
8061 
8062 	rtnl_held = hdd_hold_rtnl_lock();
8063 
8064 	adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
8065 
8066 	if (IS_ERR(adapter)) {
8067 		hdd_alert("Failed to open interface, adapter is NULL");
8068 		ret = PTR_ERR(adapter);
8069 		goto err_ipa_cleanup;
8070 	}
8071 
8072 	hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
8073 	if (!hif_sc) {
8074 		hdd_err("HIF context is NULL");
8075 		goto err_close_adapter;
8076 	}
8077 	/*
8078 	 * target hw version/revision would only be retrieved after firmware
8079 	 * donwload
8080 	 */
8081 	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
8082 			&hdd_ctx->target_hw_revision,
8083 			&hdd_ctx->target_hw_name);
8084 
8085 	/* Get the wlan hw/fw version */
8086 	hdd_wlan_get_version(hdd_ctx, NULL, NULL);
8087 
8088 	hdd_release_rtnl_lock();
8089 	rtnl_held = false;
8090 
8091 	if (hdd_ctx->config->enable_go_cts2self_for_sta)
8092 		sme_set_cts2self_for_p2p_go(hdd_ctx->hHal);
8093 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
8094 	status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
8095 				   QDF_TIMER_TYPE_SW,
8096 				   hdd_skip_acs_scan_timer_handler,
8097 				   (void *)hdd_ctx);
8098 	if (!QDF_IS_STATUS_SUCCESS(status))
8099 		hdd_err("Failed to init ACS Skip timer");
8100 	qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
8101 #endif
8102 
8103 	hdd_bus_bandwidth_init(hdd_ctx);
8104 
8105 	hdd_lpass_notify_start(hdd_ctx);
8106 
8107 	if (hdd_ctx->rps)
8108 		hdd_set_rps_cpu_mask(hdd_ctx);
8109 
8110 
8111 	if (cds_is_packet_log_enabled())
8112 		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
8113 
8114 	ret = hdd_register_notifiers(hdd_ctx);
8115 	if (ret)
8116 		goto err_debugfs_exit;
8117 
8118 	status = wlansap_global_init();
8119 	if (QDF_IS_STATUS_ERROR(status))
8120 		goto err_debugfs_exit;
8121 
8122 	hdd_runtime_suspend_context_init(hdd_ctx);
8123 	memdump_init();
8124 	hdd_driver_memdump_init();
8125 
8126 	if (hdd_ctx->config->fIsImpsEnabled)
8127 		hdd_set_idle_ps_config(hdd_ctx, true);
8128 
8129 	if (hdd_ctx->config->sifs_burst_duration) {
8130 		set_value = (SIFS_BURST_DUR_MULTIPLIER) *
8131 			hdd_ctx->config->sifs_burst_duration;
8132 
8133 		if ((set_value > 0) && (set_value <= SIFS_BURST_DUR_MAX))
8134 			wma_cli_set_command(0, (int)WMI_PDEV_PARAM_BURST_DUR,
8135 					    set_value, PDEV_CMD);
8136 	}
8137 
8138 	qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
8139 			   hdd_ctx->config->iface_change_wait_time * 5000);
8140 
8141 	if (hdd_ctx->config->goptimize_chan_avoid_event) {
8142 		status = sme_enable_disable_chanavoidind_event(
8143 							hdd_ctx->hHal, 0);
8144 		if (!QDF_IS_STATUS_SUCCESS(status))
8145 			hdd_err("Failed to disable Chan Avoidance Indication");
8146 	}
8147 	goto success;
8148 
8149 err_debugfs_exit:
8150 	hdd_debugfs_exit(adapter);
8151 
8152 err_close_adapter:
8153 	hdd_close_all_adapters(hdd_ctx, false);
8154 
8155 	if (rtnl_held)
8156 		hdd_release_rtnl_lock();
8157 
8158 err_ipa_cleanup:
8159 	hdd_ipa_cleanup(hdd_ctx);
8160 
8161 err_wiphy_unregister:
8162 	wiphy_unregister(hdd_ctx->wiphy);
8163 
8164 err_stop_modules:
8165 	hdd_wlan_stop_modules(hdd_ctx);
8166 
8167 
8168 	status = cds_sched_close(hdd_ctx->pcds_context);
8169 	if (!QDF_IS_STATUS_SUCCESS(status)) {
8170 		hdd_alert("Failed to close CDS Scheduler");
8171 		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
8172 	}
8173 
8174 err_exit_nl_srv:
8175 	hdd_green_ap_deinit(hdd_ctx);
8176 	hdd_exit_netlink_services(hdd_ctx);
8177 
8178 	cds_deinit_ini_config();
8179 err_hdd_free_context:
8180 	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
8181 	qdf_mc_timer_destroy(&hdd_ctx->iface_change_timer);
8182 	mutex_destroy(&hdd_ctx->iface_change_lock);
8183 	hdd_context_destroy(hdd_ctx);
8184 	QDF_BUG(1);
8185 
8186 	return -EIO;
8187 
8188 success:
8189 	EXIT();
8190 	return 0;
8191 }
8192 
8193 /**
8194  * hdd_wlan_update_target_info() - update target type info
8195  * @hdd_ctx: HDD context
8196  * @context: hif context
8197  *
8198  * Update target info received from firmware in hdd context
8199  * Return:None
8200  */
8201 
8202 void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context)
8203 {
8204 	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
8205 
8206 	if (!tgt_info) {
8207 		hdd_err("Target info is Null");
8208 		return;
8209 	}
8210 
8211 	hdd_ctx->target_type = tgt_info->target_type;
8212 }
8213 
8214 /**
8215  * hdd_register_cb - Register HDD callbacks.
8216  * @hdd_ctx: HDD context
8217  *
8218  * Register the HDD callbacks to CDS/SME.
8219  *
8220  * Return: 0 for success or Error code for failure
8221  */
8222 int hdd_register_cb(hdd_context_t *hdd_ctx)
8223 {
8224 	QDF_STATUS status;
8225 	int ret = 0;
8226 
8227 	ENTER();
8228 
8229 	sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);
8230 
8231 	sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
8232 					hdd_send_oem_data_rsp_msg);
8233 
8234 	status = sme_fw_mem_dump_register_cb(hdd_ctx->hHal,
8235 					     wlan_hdd_cfg80211_fw_mem_dump_cb);
8236 	if (!QDF_IS_STATUS_SUCCESS(status)) {
8237 		hdd_err("Failed to register memdump callback");
8238 		ret = -EINVAL;
8239 		return ret;
8240 	}
8241 	sme_register_mgmt_frame_ind_callback(hdd_ctx->hHal,
8242 					     hdd_indicate_mgmt_frame);
8243 	sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
8244 	sme_nan_register_callback(hdd_ctx->hHal,
8245 				  wlan_hdd_cfg80211_nan_callback);
8246 	sme_stats_ext_register_callback(hdd_ctx->hHal,
8247 					wlan_hdd_cfg80211_stats_ext_callback);
8248 
8249 	sme_ext_scan_register_callback(hdd_ctx->hHal,
8250 				       wlan_hdd_cfg80211_extscan_callback);
8251 
8252 	status = cds_register_sap_restart_channel_switch_cb(
8253 			(void *)hdd_sap_restart_with_channel_switch);
8254 	if (!QDF_IS_STATUS_SUCCESS(status)) {
8255 		hdd_err("restart cb registration failed");
8256 		ret = -EINVAL;
8257 		return ret;
8258 	}
8259 
8260 	sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
8261 				hdd_rssi_threshold_breached);
8262 
8263 	status = sme_bpf_offload_register_callback(hdd_ctx->hHal,
8264 						   hdd_get_bpf_offload_cb);
8265 	if (!QDF_IS_STATUS_SUCCESS(status)) {
8266 		hdd_err("set bpf offload callback failed");
8267 		ret = -EINVAL;
8268 		return ret;
8269 	}
8270 
8271 	sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
8272 				wlan_hdd_cfg80211_link_layer_stats_callback);
8273 
8274 	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
8275 
8276 	EXIT();
8277 
8278 	return ret;
8279 }
8280 
8281 /**
8282  * hdd_deregister_cb() - De-Register HDD callbacks.
8283  * @hdd_ctx: HDD context
8284  *
8285  * De-Register the HDD callbacks to CDS/SME.
8286  *
8287  * Return: void
8288  */
8289 void hdd_deregister_cb(hdd_context_t *hdd_ctx)
8290 {
8291 	QDF_STATUS status;
8292 
8293 	ENTER();
8294 
8295 	status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
8296 	if (!QDF_IS_STATUS_SUCCESS(status))
8297 		hdd_err("De-register of dcc stats callback failed: %d",
8298 			status);
8299 
8300 	sme_reset_link_layer_stats_ind_cb(hdd_ctx->hHal);
8301 	status = sme_bpf_offload_deregister_callback(hdd_ctx->hHal);
8302 	if (!QDF_IS_STATUS_SUCCESS(status))
8303 		hdd_err("De-register bpf offload callback failed: %d",
8304 			status);
8305 	sme_reset_rssi_threshold_breached_cb(hdd_ctx->hHal);
8306 
8307 	status = cds_deregister_sap_restart_channel_switch_cb();
8308 	if (!QDF_IS_STATUS_SUCCESS(status))
8309 		hdd_err("De-register restart cb registration failed: %d",
8310 			status);
8311 
8312 	sme_stats_ext_register_callback(hdd_ctx->hHal,
8313 					wlan_hdd_cfg80211_stats_ext_callback);
8314 
8315 	sme_nan_deregister_callback(hdd_ctx->hHal);
8316 	status = sme_reset_tsfcb(hdd_ctx->hHal);
8317 	if (!QDF_IS_STATUS_SUCCESS(status))
8318 		hdd_err("Failed to de-register tsfcb the callback:%d",
8319 			status);
8320 	status = sme_fw_mem_dump_unregister_cb(hdd_ctx->hHal);
8321 	if (!QDF_IS_STATUS_SUCCESS(status))
8322 		hdd_err("Failed to de-register the fw mem dump callback: %d",
8323 			status);
8324 
8325 	sme_deregister_oem_data_rsp_callback(hdd_ctx->hHal);
8326 	sme_deregister11d_scan_done_callback(hdd_ctx->hHal);
8327 
8328 	EXIT();
8329 }
8330 
8331 /**
8332  * hdd_softap_sta_deauth() - handle deauth req from HDD
8333  * @adapter:	Pointer to the HDD
8334  * @enable:	bool value
8335  *
8336  * This to take counter measure to handle deauth req from HDD
8337  *
8338  * Return: None
8339  */
8340 QDF_STATUS hdd_softap_sta_deauth(hdd_adapter_t *adapter,
8341 				 struct tagCsrDelStaParams *pDelStaParams)
8342 {
8343 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
8344 
8345 	ENTER();
8346 
8347 	hdd_notice("hdd_softap_sta_deauth:(%p, false)",
8348 	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
8349 
8350 	/* Ignore request to deauth bcmc station */
8351 	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
8352 		return qdf_status;
8353 
8354 	qdf_status =
8355 		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
8356 				   pDelStaParams);
8357 
8358 	EXIT();
8359 	return qdf_status;
8360 }
8361 
8362 /**
8363  * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
8364  * @adapter:	Pointer to the HDD
8365  * @p_del_sta_params: pointer to station deletion parameters
8366  *
8367  * This to take counter measure to handle deauth req from HDD
8368  *
8369  * Return: None
8370  */
8371 void hdd_softap_sta_disassoc(hdd_adapter_t *adapter,
8372 			     struct tagCsrDelStaParams *pDelStaParams)
8373 {
8374 	ENTER();
8375 
8376 	hdd_err("hdd_softap_sta_disassoc:(%p, false)",
8377 	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
8378 
8379 	/* Ignore request to disassoc bcmc station */
8380 	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
8381 		return;
8382 
8383 	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
8384 			     pDelStaParams);
8385 }
8386 
8387 void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *adapter,
8388 					      bool enable)
8389 {
8390 	ENTER();
8391 
8392 	hdd_err("hdd_softap_tkip_mic_fail_counter_measure:(%p, false)",
8393 	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
8394 
8395 	wlansap_set_counter_measure(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
8396 				    (bool) enable);
8397 }
8398 
8399 /**
8400  * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
8401  * @hdd_ctx:	HDD Context
8402  *
8403  * API to find if there is any STA or P2P-Client is connected
8404  *
8405  * Return: true if connected; false otherwise
8406  */
8407 QDF_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *hdd_ctx)
8408 {
8409 	return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
8410 }
8411 
8412 /**
8413  * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
8414  * @adapter:	HDD adapter pointer
8415  *
8416  * This function loop through each adapter and disable roaming on each STA
8417  * device mode except the input adapter.
8418  *
8419  * Note: On the input adapter roaming is not enabled yet hence no need to
8420  *       disable.
8421  *
8422  * Return: None
8423  */
8424 void wlan_hdd_disable_roaming(hdd_adapter_t *adapter)
8425 {
8426 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8427 	hdd_adapter_t *adapterIdx = NULL;
8428 	hdd_adapter_list_node_t *adapterNode = NULL;
8429 	hdd_adapter_list_node_t *pNext = NULL;
8430 	QDF_STATUS status;
8431 
8432 	if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
8433 	    hdd_ctx->config->isRoamOffloadScanEnabled &&
8434 	    QDF_STA_MODE == adapter->device_mode &&
8435 	    cds_is_sta_active_connection_exists()) {
8436 		hdd_notice("Connect received on STA sessionId(%d)",
8437 		       adapter->sessionId);
8438 		/*
8439 		 * Loop through adapter and disable roaming for each STA device
8440 		 * mode except the input adapter.
8441 		 */
8442 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
8443 
8444 		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
8445 			adapterIdx = adapterNode->pAdapter;
8446 
8447 			if (QDF_STA_MODE == adapterIdx->device_mode
8448 			    && adapter->sessionId != adapterIdx->sessionId) {
8449 				hdd_notice("Disable Roaming on sessionId(%d)",
8450 				       adapterIdx->sessionId);
8451 				sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
8452 							 (adapterIdx),
8453 						 adapterIdx->sessionId, 0);
8454 			}
8455 
8456 			status = hdd_get_next_adapter(hdd_ctx,
8457 						      adapterNode,
8458 						      &pNext);
8459 			adapterNode = pNext;
8460 		}
8461 	}
8462 }
8463 
8464 /**
8465  * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
8466  * @adapter:	HDD adapter pointer
8467  *
8468  * This function loop through each adapter and enable roaming on each STA
8469  * device mode except the input adapter.
8470  * Note: On the input adapter no need to enable roaming because link got
8471  *       disconnected on this.
8472  *
8473  * Return: None
8474  */
8475 void wlan_hdd_enable_roaming(hdd_adapter_t *adapter)
8476 {
8477 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8478 	hdd_adapter_t *adapterIdx = NULL;
8479 	hdd_adapter_list_node_t *adapterNode = NULL;
8480 	hdd_adapter_list_node_t *pNext = NULL;
8481 	QDF_STATUS status;
8482 
8483 	if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
8484 	    hdd_ctx->config->isRoamOffloadScanEnabled &&
8485 	    QDF_STA_MODE == adapter->device_mode &&
8486 	    cds_is_sta_active_connection_exists()) {
8487 		hdd_notice("Disconnect received on STA sessionId(%d)",
8488 		       adapter->sessionId);
8489 		/*
8490 		 * Loop through adapter and enable roaming for each STA device
8491 		 * mode except the input adapter.
8492 		 */
8493 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
8494 
8495 		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
8496 			adapterIdx = adapterNode->pAdapter;
8497 
8498 			if (QDF_STA_MODE == adapterIdx->device_mode
8499 			    && adapter->sessionId != adapterIdx->sessionId) {
8500 				hdd_notice("Enabling Roaming on sessionId(%d)",
8501 				       adapterIdx->sessionId);
8502 				sme_start_roaming(WLAN_HDD_GET_HAL_CTX
8503 							  (adapterIdx),
8504 						  adapterIdx->sessionId,
8505 						  REASON_CONNECT);
8506 			}
8507 
8508 			status = hdd_get_next_adapter(hdd_ctx,
8509 						      adapterNode,
8510 						      &pNext);
8511 			adapterNode = pNext;
8512 		}
8513 	}
8514 }
8515 
8516 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
8517 {
8518 	struct sk_buff *skb;
8519 	struct nlmsghdr *nlh;
8520 	tAniMsgHdr *ani_hdr;
8521 	void *nl_data = NULL;
8522 	int flags = GFP_KERNEL;
8523 	struct radio_index_tlv *radio_info;
8524 	int tlv_len;
8525 
8526 	if (in_interrupt() || irqs_disabled() || in_atomic())
8527 		flags = GFP_ATOMIC;
8528 
8529 	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
8530 
8531 	if (skb == NULL) {
8532 		hdd_err("alloc_skb failed");
8533 		return;
8534 	}
8535 
8536 	nlh = (struct nlmsghdr *)skb->data;
8537 	nlh->nlmsg_pid = 0;     /* from kernel */
8538 	nlh->nlmsg_flags = 0;
8539 	nlh->nlmsg_seq = 0;
8540 	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8541 
8542 	ani_hdr = NLMSG_DATA(nlh);
8543 	ani_hdr->type = type;
8544 
8545 	switch (type) {
8546 	case WLAN_SVC_FW_CRASHED_IND:
8547 	case WLAN_SVC_FW_SHUTDOWN_IND:
8548 	case WLAN_SVC_LTE_COEX_IND:
8549 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
8550 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
8551 		ani_hdr->length = 0;
8552 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8553 		skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8554 		break;
8555 	case WLAN_SVC_WLAN_STATUS_IND:
8556 	case WLAN_SVC_WLAN_VERSION_IND:
8557 	case WLAN_SVC_DFS_CAC_START_IND:
8558 	case WLAN_SVC_DFS_CAC_END_IND:
8559 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
8560 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
8561 	case WLAN_SVC_WLAN_TP_IND:
8562 	case WLAN_SVC_WLAN_TP_TX_IND:
8563 	case WLAN_SVC_RPS_ENABLE_IND:
8564 		ani_hdr->length = len;
8565 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
8566 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
8567 		memcpy(nl_data, data, len);
8568 		skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
8569 		break;
8570 
8571 	default:
8572 		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
8573 		       type);
8574 		kfree_skb(skb);
8575 		return;
8576 	}
8577 
8578 	/*
8579 	 * Add radio index at the end of the svc event in TLV format to maintain
8580 	 * the backward compatibility with userspace applications.
8581 	*/
8582 
8583 	tlv_len = 0;
8584 
8585 	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
8586 		< WLAN_NL_MAX_PAYLOAD) {
8587 		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
8588 		sizeof(*ani_hdr) + len);
8589 		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
8590 		radio_info->length = (unsigned short) sizeof(radio_info->radio);
8591 		radio_info->radio = radio;
8592 		tlv_len = sizeof(*radio_info);
8593 		QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
8594 			"Added radio index tlv - radio index %d",
8595 			radio_info->radio);
8596 	}
8597 
8598 	nlh->nlmsg_len += tlv_len;
8599 	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
8600 
8601 	nl_srv_bcast(skb);
8602 
8603 	return;
8604 }
8605 
8606 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
8607 void wlan_hdd_auto_shutdown_cb(void)
8608 {
8609 	hdd_context_t *hdd_ctx = cds_get_global_context();
8610 
8611 	if (!hdd_ctx)
8612 		return;
8613 
8614 	hdd_err("Wlan Idle. Sending Shutdown event..");
8615 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8616 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
8617 }
8618 
8619 void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, bool enable)
8620 {
8621 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
8622 	QDF_STATUS status;
8623 	hdd_adapter_t *adapter;
8624 	bool ap_connected = false, sta_connected = false;
8625 	tHalHandle hal_handle;
8626 
8627 	hal_handle = hdd_ctx->hHal;
8628 	if (hal_handle == NULL)
8629 		return;
8630 
8631 	if (hdd_ctx->config->WlanAutoShutdown == 0)
8632 		return;
8633 
8634 	if (enable == false) {
8635 		if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
8636 							QDF_STATUS_SUCCESS) {
8637 			hdd_err("Failed to stop wlan auto shutdown timer");
8638 		}
8639 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8640 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
8641 		return;
8642 	}
8643 
8644 	/* To enable shutdown timer check conncurrency */
8645 	if (cds_concurrent_open_sessions_running()) {
8646 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
8647 
8648 		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
8649 			adapter = adapterNode->pAdapter;
8650 			if (adapter
8651 			    && adapter->device_mode ==
8652 			    QDF_STA_MODE) {
8653 				if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
8654 				    conn_info.connState ==
8655 				    eConnectionState_Associated) {
8656 					sta_connected = true;
8657 					break;
8658 				}
8659 			}
8660 			if (adapter
8661 			    && adapter->device_mode == QDF_SAP_MODE) {
8662 				if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
8663 				    bApActive == true) {
8664 					ap_connected = true;
8665 					break;
8666 				}
8667 			}
8668 			status = hdd_get_next_adapter(hdd_ctx,
8669 						      adapterNode,
8670 						      &pNext);
8671 			adapterNode = pNext;
8672 		}
8673 	}
8674 
8675 	if (ap_connected == true || sta_connected == true) {
8676 		hdd_notice("CC Session active. Shutdown timer not enabled");
8677 		return;
8678 	} else {
8679 		if (sme_set_auto_shutdown_timer(hal_handle,
8680 						hdd_ctx->config->
8681 						WlanAutoShutdown)
8682 		    != QDF_STATUS_SUCCESS)
8683 			hdd_err("Failed to start wlan auto shutdown timer");
8684 		else
8685 			hdd_notice("Auto Shutdown timer for %d seconds enabled",
8686 			       hdd_ctx->config->WlanAutoShutdown);
8687 
8688 	}
8689 }
8690 #endif
8691 
8692 hdd_adapter_t *hdd_get_con_sap_adapter(hdd_adapter_t *this_sap_adapter,
8693 							bool check_start_bss)
8694 {
8695 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
8696 	hdd_adapter_t *adapter, *con_sap_adapter;
8697 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8698 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
8699 
8700 	con_sap_adapter = NULL;
8701 
8702 	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
8703 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
8704 		adapter = adapterNode->pAdapter;
8705 		if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
8706 				(adapter->device_mode == QDF_P2P_GO_MODE)) &&
8707 						adapter != this_sap_adapter) {
8708 			if (check_start_bss) {
8709 				if (test_bit(SOFTAP_BSS_STARTED,
8710 						&adapter->event_flags)) {
8711 					con_sap_adapter = adapter;
8712 					break;
8713 				}
8714 			} else {
8715 				con_sap_adapter = adapter;
8716 				break;
8717 			}
8718 		}
8719 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
8720 		adapterNode = pNext;
8721 	}
8722 
8723 	return con_sap_adapter;
8724 }
8725 
8726 #ifdef MSM_PLATFORM
8727 void hdd_start_bus_bw_compute_timer(hdd_adapter_t *adapter)
8728 {
8729 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8730 
8731 	if (QDF_TIMER_STATE_RUNNING ==
8732 	    qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer))
8733 		return;
8734 
8735 	qdf_mc_timer_start(&hdd_ctx->bus_bw_timer,
8736 			   hdd_ctx->config->busBandwidthComputeInterval);
8737 }
8738 
8739 void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *adapter)
8740 {
8741 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
8742 	QDF_STATUS status;
8743 	bool can_stop = true;
8744 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8745 
8746 	if (QDF_TIMER_STATE_RUNNING !=
8747 	    qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) {
8748 		/* trying to stop timer, when not running is not good */
8749 		hdd_info("bus band width compute timer is not running");
8750 		return;
8751 	}
8752 
8753 	if (cds_concurrent_open_sessions_running()) {
8754 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
8755 
8756 		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
8757 			adapter = adapterNode->pAdapter;
8758 			if (adapter
8759 			    && (adapter->device_mode == QDF_STA_MODE
8760 				|| adapter->device_mode == QDF_P2P_CLIENT_MODE)
8761 			    && WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
8762 			    conn_info.connState ==
8763 			    eConnectionState_Associated) {
8764 				can_stop = false;
8765 				break;
8766 			}
8767 			if (adapter
8768 			    && (adapter->device_mode == QDF_SAP_MODE
8769 				|| adapter->device_mode == QDF_P2P_GO_MODE)
8770 			    && WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive ==
8771 			    true) {
8772 				can_stop = false;
8773 				break;
8774 			}
8775 			status = hdd_get_next_adapter(hdd_ctx,
8776 						      adapterNode,
8777 						      &pNext);
8778 			adapterNode = pNext;
8779 		}
8780 	}
8781 
8782 	if (can_stop == true) {
8783 		qdf_mc_timer_stop(&hdd_ctx->bus_bw_timer);
8784 		hdd_reset_tcp_delack(hdd_ctx);
8785 	}
8786 }
8787 #endif
8788 
8789 /**
8790  * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
8791  *                                            and sta's operating channel.
8792  * @sta_adapter:  Describe the first argument to foobar.
8793  * @ap_adapter:   Describe the second argument to foobar.
8794  * @roam_profile: Roam profile of AP to which STA wants to connect.
8795  * @concurrent_chnl_same: If both SAP and STA channels are same then
8796  *                        set this flag to true else false.
8797  *
8798  * This function checks the sap's operating channel and sta's operating channel.
8799  * if both are same then it will return false else it will restart the sap in
8800  * sta's channel and return true.
8801  *
8802  * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
8803  */
8804 QDF_STATUS wlan_hdd_check_custom_con_channel_rules(hdd_adapter_t *sta_adapter,
8805 						  hdd_adapter_t *ap_adapter,
8806 						  tCsrRoamProfile *roam_profile,
8807 						  tScanResultHandle *scan_cache,
8808 						  bool *concurrent_chnl_same)
8809 {
8810 	hdd_ap_ctx_t *hdd_ap_ctx;
8811 	uint8_t channel_id;
8812 	QDF_STATUS status;
8813 	enum tQDF_ADAPTER_MODE device_mode = ap_adapter->device_mode;
8814 	*concurrent_chnl_same = true;
8815 
8816 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
8817 	status =
8818 	 sme_get_ap_channel_from_scan_cache(WLAN_HDD_GET_HAL_CTX(sta_adapter),
8819 					    roam_profile,
8820 					    scan_cache,
8821 					    &channel_id);
8822 	if ((QDF_STATUS_SUCCESS == status)) {
8823 		if ((QDF_SAP_MODE == device_mode) &&
8824 			(channel_id < SIR_11A_CHANNEL_BEGIN)) {
8825 			if (hdd_ap_ctx->operatingChannel != channel_id) {
8826 				*concurrent_chnl_same = false;
8827 				hdd_info("channels are different");
8828 			}
8829 		} else if ((QDF_P2P_GO_MODE == device_mode) &&
8830 				(channel_id >= SIR_11A_CHANNEL_BEGIN)) {
8831 			if (hdd_ap_ctx->operatingChannel != channel_id) {
8832 				*concurrent_chnl_same = false;
8833 				hdd_info("channels are different");
8834 			}
8835 		}
8836 	} else {
8837 		/*
8838 		 * Lets handle worst case scenario here, Scan cache lookup is
8839 		 * failed so we have to stop the SAP to avoid any channel
8840 		 * discrepancy  between SAP's channel and STA's channel.
8841 		 * Return the status as failure so caller function could know
8842 		 * that scan look up is failed.
8843 		 */
8844 		hdd_err("Finding AP from scan cache failed");
8845 		return QDF_STATUS_E_FAILURE;
8846 	}
8847 	return QDF_STATUS_SUCCESS;
8848 }
8849 
8850 /**
8851  * wlan_hdd_stop_sap() - This function stops bss of SAP.
8852  * @ap_adapter: SAP adapter
8853  *
8854  * This function will process the stopping of sap adapter.
8855  *
8856  * Return: None
8857  */
8858 void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter)
8859 {
8860 	hdd_ap_ctx_t *hdd_ap_ctx;
8861 	hdd_hostapd_state_t *hostapd_state;
8862 	QDF_STATUS qdf_status;
8863 	hdd_context_t *hdd_ctx;
8864 
8865 	if (NULL == ap_adapter) {
8866 		hdd_err("ap_adapter is NULL here");
8867 		return;
8868 	}
8869 
8870 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
8871 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
8872 	if (wlan_hdd_validate_context(hdd_ctx))
8873 		return;
8874 
8875 	mutex_lock(&hdd_ctx->sap_lock);
8876 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
8877 		wlan_hdd_del_station(ap_adapter);
8878 		hdd_cleanup_actionframe(hdd_ctx, ap_adapter);
8879 		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
8880 		hdd_info("Now doing SAP STOPBSS");
8881 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
8882 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
8883 							sapContext)) {
8884 			qdf_status = qdf_wait_single_event(&hostapd_state->
8885 							   qdf_stop_bss_event,
8886 							   BSS_WAIT_TIMEOUT);
8887 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
8888 				mutex_unlock(&hdd_ctx->sap_lock);
8889 				hdd_err("SAP Stop Failed");
8890 				return;
8891 			}
8892 		}
8893 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
8894 		cds_decr_session_set_pcl(ap_adapter->device_mode,
8895 						ap_adapter->sessionId);
8896 		hdd_info("SAP Stop Success");
8897 	} else {
8898 		hdd_err("Can't stop ap because its not started");
8899 	}
8900 	mutex_unlock(&hdd_ctx->sap_lock);
8901 	return;
8902 }
8903 
8904 /**
8905  * wlan_hdd_start_sap() - this function starts bss of SAP.
8906  * @ap_adapter: SAP adapter
8907  *
8908  * This function will process the starting of sap adapter.
8909  *
8910  * Return: None
8911  */
8912 void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
8913 {
8914 	hdd_ap_ctx_t *hdd_ap_ctx;
8915 	hdd_hostapd_state_t *hostapd_state;
8916 	QDF_STATUS qdf_status;
8917 	hdd_context_t *hdd_ctx;
8918 	tsap_Config_t *sap_config;
8919 
8920 	if (NULL == ap_adapter) {
8921 		hdd_err("ap_adapter is NULL here");
8922 		return;
8923 	}
8924 
8925 	if (QDF_SAP_MODE != ap_adapter->device_mode) {
8926 		hdd_err("SoftAp role has not been enabled");
8927 		return;
8928 	}
8929 
8930 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
8931 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
8932 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
8933 	sap_config = &ap_adapter->sessionCtx.ap.sapConfig;
8934 
8935 	if (wlan_hdd_validate_context(hdd_ctx))
8936 		return;
8937 
8938 	mutex_lock(&hdd_ctx->sap_lock);
8939 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
8940 		goto end;
8941 
8942 	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
8943 		hdd_err("SAP Not able to set AP IEs");
8944 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
8945 		goto end;
8946 	}
8947 
8948 	if (wlansap_start_bss(hdd_ap_ctx->sapContext, hdd_hostapd_sap_event_cb,
8949 			      &hdd_ap_ctx->sapConfig,
8950 			      ap_adapter->dev)
8951 			      != QDF_STATUS_SUCCESS)
8952 		goto end;
8953 
8954 	hdd_info("Waiting for SAP to start");
8955 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
8956 					BSS_WAIT_TIMEOUT);
8957 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
8958 		hdd_err("SAP Start failed");
8959 		goto end;
8960 	}
8961 	hdd_info("SAP Start Success");
8962 	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
8963 	cds_incr_active_session(ap_adapter->device_mode,
8964 					ap_adapter->sessionId);
8965 	hostapd_state->bCommit = true;
8966 
8967 end:
8968 	mutex_unlock(&hdd_ctx->sap_lock);
8969 	return;
8970 }
8971 
8972 /**
8973  * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual
8974  * mac scan config
8975  * @status: Status of set antenna mode
8976  *
8977  * Callback on setting the dual mac configuration
8978  *
8979  * Return: None
8980  */
8981 void wlan_hdd_soc_set_antenna_mode_cb(
8982 	enum set_antenna_mode_status status)
8983 {
8984 	hdd_context_t *hdd_ctx;
8985 
8986 	hdd_info("Status: %d", status);
8987 
8988 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8989 	if (0 != wlan_hdd_validate_context(hdd_ctx))
8990 		return;
8991 
8992 	/* Signal the completion of set dual mac config */
8993 	complete(&hdd_ctx->set_antenna_mode_cmpl);
8994 }
8995 
8996 /**
8997  * hdd_get_fw_version() - Get FW version
8998  * @hdd_ctx:     pointer to HDD context.
8999  * @major_spid:  FW version - major spid.
9000  * @minor_spid:  FW version - minor spid
9001  * @ssid:        FW version - ssid
9002  * @crmid:       FW version - crmid
9003  *
9004  * This function is called to get the firmware build version stored
9005  * as part of the HDD context
9006  *
9007  * Return:   None
9008  */
9009 void hdd_get_fw_version(hdd_context_t *hdd_ctx,
9010 			uint32_t *major_spid, uint32_t *minor_spid,
9011 			uint32_t *siid, uint32_t *crmid)
9012 {
9013 	*major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
9014 	*minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
9015 	*siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
9016 	*crmid = hdd_ctx->target_fw_version & 0x7fff;
9017 }
9018 
9019 #ifdef QCA_CONFIG_SMP
9020 /**
9021  * wlan_hdd_get_cpu() - get cpu_index
9022  *
9023  * Return: cpu_index
9024  */
9025 int wlan_hdd_get_cpu(void)
9026 {
9027 	int cpu_index = get_cpu();
9028 	put_cpu();
9029 	return cpu_index;
9030 }
9031 #endif
9032 
9033 /**
9034  * hdd_get_fwpath() - get framework path
9035  *
9036  * This function is used to get the string written by
9037  * userspace to start the wlan driver
9038  *
9039  * Return: string
9040  */
9041 const char *hdd_get_fwpath(void)
9042 {
9043 	return fwpath.string;
9044 }
9045 
9046 /**
9047  * hdd_init() - Initialize Driver
9048  *
9049  * This function initilizes CDS global context with the help of cds_init. This
9050  * has to be the first function called after probe to get a valid global
9051  * context.
9052  *
9053  * Return: 0 for success, errno on failure
9054  */
9055 int hdd_init(void)
9056 {
9057 	v_CONTEXT_t p_cds_context = NULL;
9058 	int ret = 0;
9059 
9060 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9061 	wlan_logging_sock_init_svc();
9062 #endif
9063 	p_cds_context = cds_init();
9064 
9065 	if (p_cds_context == NULL) {
9066 		hdd_alert("Failed to allocate CDS context");
9067 		ret = -ENOMEM;
9068 		goto err_out;
9069 	}
9070 
9071 	hdd_trace_init();
9072 	hdd_register_debug_callback();
9073 
9074 err_out:
9075 	return ret;
9076 }
9077 
9078 /**
9079  * hdd_deinit() - Deinitialize Driver
9080  *
9081  * This function frees CDS global context with the help of cds_deinit. This
9082  * has to be the last function call in remove callback to free the global
9083  * context.
9084  */
9085 void hdd_deinit(void)
9086 {
9087 	cds_deinit();
9088 
9089 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9090 	wlan_logging_sock_deinit_svc();
9091 #endif
9092 }
9093 
9094 #ifdef QCA_WIFI_3_0_ADRASTEA
9095 #define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
9096 #else
9097 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
9098 #endif
9099 
9100 /**
9101  * __hdd_module_init - Module init helper
9102  *
9103  * Module init helper function used by both module and static driver.
9104  *
9105  * Return: 0 for success, errno on failure
9106  */
9107 static int __hdd_module_init(void)
9108 {
9109 	int ret = 0;
9110 
9111 	pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
9112 		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9113 
9114 	pld_init();
9115 
9116 	ret = hdd_init();
9117 	if (ret) {
9118 		pr_err("hdd_init failed %x\n", ret);
9119 		goto err_hdd_init;
9120 	}
9121 
9122 	dispatcher_init();
9123 
9124 	qdf_wake_lock_create(&wlan_wake_lock, "wlan");
9125 
9126 	hdd_set_conparam((uint32_t) con_mode);
9127 
9128 	ret = wlan_hdd_register_driver();
9129 	if (ret) {
9130 		pr_err("%s: driver load failure, err %d\n", WLAN_MODULE_NAME,
9131 			ret);
9132 		goto out;
9133 	}
9134 
9135 	pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
9136 
9137 	return 0;
9138 out:
9139 	qdf_wake_lock_destroy(&wlan_wake_lock);
9140 	dispatcher_deinit();
9141 	hdd_deinit();
9142 
9143 err_hdd_init:
9144 	pld_deinit();
9145 
9146 	return ret;
9147 }
9148 
9149 /**
9150  * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
9151  *
9152  * Block the unloading of the driver until the cds recovery is completed
9153  *
9154  * Return: None
9155  */
9156 static void hdd_wait_for_recovery_completion(void)
9157 {
9158 	int retry = 0;
9159 
9160 	/* Wait for recovery to complete */
9161 	while (cds_is_driver_recovering()) {
9162 		hdd_alert("Recovery in progress; wait here!!!");
9163 		msleep(1000);
9164 		if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
9165 			hdd_alert("SSR never completed, fatal error");
9166 			QDF_BUG(0);
9167 		}
9168 	}
9169 }
9170 
9171 /**
9172  * __hdd_module_exit - Module exit helper
9173  *
9174  * Module exit helper function used by both module and static driver.
9175  */
9176 static void __hdd_module_exit(void)
9177 {
9178 	pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
9179 		QWLAN_VERSIONSTR);
9180 
9181 	hdd_wait_for_recovery_completion();
9182 
9183 	wlan_hdd_unregister_driver();
9184 
9185 	qdf_wake_lock_destroy(&wlan_wake_lock);
9186 
9187 	dispatcher_deinit();
9188 	hdd_deinit();
9189 	pld_deinit();
9190 
9191 	return;
9192 }
9193 
9194 #ifndef MODULE
9195 /**
9196  * wlan_boot_cb() - Wlan boot callback
9197  * @kobj:      object whose directory we're creating the link in.
9198  * @attr:      attribute the user is interacting with
9199  * @buff:      the buffer containing the user data
9200  * @count:     number of bytes in the buffer
9201  *
9202  * This callback is invoked when the fs is ready to start the
9203  * wlan driver initialization.
9204  *
9205  * Return: 'count' on success or a negative error code in case of failure
9206  */
9207 static ssize_t wlan_boot_cb(struct kobject *kobj,
9208 				struct kobj_attribute *attr,
9209 				const char *buf,
9210 				size_t count)
9211 {
9212 
9213 	int ret = 0;
9214 
9215 	if (wlan_loader->loaded_state) {
9216 		pr_info("Wlan driver already initialized");
9217 		return 0;
9218 	}
9219 
9220 
9221 	pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
9222 		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9223 
9224 	if (__hdd_module_init()) {
9225 		pr_err("%s: Failed to register handler\n", __func__);
9226 		ret = -EINVAL;
9227 	} else
9228 		wlan_loader->loaded_state = MODULE_INITIALIZED;
9229 
9230 	return count;
9231 
9232 }
9233 
9234 /**
9235  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
9236  * ready
9237  *
9238  * This is creates the syfs entry boot_wlan. Which shall be invoked
9239  * when the filesystem is ready.
9240  *
9241  * Return: 0 for success, errno on failure
9242  */
9243 static int wlan_init_sysfs(void)
9244 {
9245 	int ret = -EINVAL;
9246 
9247 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
9248 	if (!wlan_loader) {
9249 		pr_err("%s: memory alloc failed\n", __func__);
9250 		ret = -ENOMEM;
9251 		return ret;
9252 	}
9253 
9254 	wlan_loader->boot_wlan_obj = NULL;
9255 	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
9256 					  GFP_KERNEL);
9257 	if (!wlan_loader->attr_group) {
9258 		pr_err("%s: malloc attr_group failed\n", __func__);
9259 		ret = -ENOMEM;
9260 		goto error_return;
9261 	}
9262 
9263 	wlan_loader->loaded_state = 0;
9264 	wlan_loader->attr_group->attrs = attrs;
9265 
9266 	wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
9267 							    kernel_kobj);
9268 	if (!wlan_loader->boot_wlan_obj) {
9269 		pr_err("%s: sysfs create and add failed\n", __func__);
9270 		ret = -ENOMEM;
9271 		goto error_return;
9272 	}
9273 
9274 	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
9275 				 wlan_loader->attr_group);
9276 	if (ret) {
9277 		pr_err("%s: sysfs create group failed %d\n", __func__, ret);
9278 		goto error_return;
9279 	}
9280 
9281 	return 0;
9282 
9283 error_return:
9284 
9285 	if (wlan_loader->boot_wlan_obj) {
9286 		kobject_del(wlan_loader->boot_wlan_obj);
9287 		wlan_loader->boot_wlan_obj = NULL;
9288 	}
9289 
9290 	return ret;
9291 }
9292 
9293 /**
9294  * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
9295  *
9296  * Return: 0 on success or errno on failure
9297  */
9298 static int wlan_deinit_sysfs(void)
9299 {
9300 
9301 	if (!wlan_loader) {
9302 		hdd_alert("wlan loader context is Null!");
9303 		return -EINVAL;
9304 	}
9305 
9306 	if (wlan_loader->boot_wlan_obj) {
9307 		sysfs_remove_group(wlan_loader->boot_wlan_obj,
9308 				   wlan_loader->attr_group);
9309 		kobject_del(wlan_loader->boot_wlan_obj);
9310 		wlan_loader->boot_wlan_obj = NULL;
9311 	}
9312 
9313 	return 0;
9314 }
9315 
9316 #endif
9317 
9318 #ifdef MODULE
9319 /**
9320  * __hdd_module_init - Module init helper
9321  *
9322  * Module init helper function used by both module and static driver.
9323  *
9324  * Return: 0 for success, errno on failure
9325  */
9326 static int hdd_module_init(void)
9327 {
9328 	int ret = 0;
9329 
9330 	pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
9331 		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9332 
9333 	if (__hdd_module_init()) {
9334 		pr_err("%s: Failed to register handler\n", __func__);
9335 		ret = -EINVAL;
9336 	}
9337 
9338 	return ret;
9339 }
9340 #else
9341 static int __init hdd_module_init(void)
9342 {
9343 	int ret = -EINVAL;
9344 
9345 	ret = wlan_init_sysfs();
9346 	if (ret)
9347 		pr_err("Failed to create sysfs entry for loading wlan");
9348 
9349 	return ret;
9350 }
9351 #endif
9352 
9353 
9354 #ifdef MODULE
9355 /**
9356  * hdd_module_exit() - Exit function
9357  *
9358  * This is the driver exit point (invoked when module is unloaded using rmmod)
9359  *
9360  * Return: None
9361  */
9362 static void __exit hdd_module_exit(void)
9363 {
9364 	__hdd_module_exit();
9365 }
9366 #else
9367 static void __exit hdd_module_exit(void)
9368 {
9369 	__hdd_module_exit();
9370 	wlan_deinit_sysfs();
9371 }
9372 #endif
9373 
9374 static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
9375 {
9376 	return param_set_copystring(kmessage, kp);
9377 }
9378 
9379 /**
9380  * is_con_mode_valid() check con mode is valid or not
9381  * @mode: global con mode
9382  *
9383  * Return: TRUE on success FALSE on failure
9384  */
9385 static bool is_con_mode_valid(enum tQDF_GLOBAL_CON_MODE mode)
9386 {
9387 	switch (mode) {
9388 	case QDF_GLOBAL_MONITOR_MODE:
9389 	case QDF_GLOBAL_FTM_MODE:
9390 	case QDF_GLOBAL_EPPING_MODE:
9391 	case QDF_GLOBAL_MISSION_MODE:
9392 		return true;
9393 	default:
9394 		return false;
9395 	}
9396 }
9397 
9398 /**
9399  * hdd_get_adpter_mode() - returns adapter mode based on global con mode
9400  * @mode: global con mode
9401  *
9402  * Return: adapter mode
9403  */
9404 static enum tQDF_ADAPTER_MODE hdd_get_adpter_mode(
9405 					enum tQDF_GLOBAL_CON_MODE mode)
9406 {
9407 
9408 	switch (mode) {
9409 	case QDF_GLOBAL_MISSION_MODE:
9410 		return QDF_STA_MODE;
9411 	case QDF_GLOBAL_MONITOR_MODE:
9412 		return QDF_MONITOR_MODE;
9413 	case QDF_GLOBAL_EPPING_MODE:
9414 		return QDF_EPPING_MODE;
9415 	case QDF_GLOBAL_FTM_MODE:
9416 		return QDF_FTM_MODE;
9417 	case QDF_GLOBAL_QVIT_MODE:
9418 		return QDF_QVIT_MODE;
9419 	default:
9420 		return QDF_MAX_NO_OF_MODE;
9421 	}
9422 }
9423 
9424 static void hdd_cleanup_present_mode(hdd_context_t *hdd_ctx,
9425 				    enum tQDF_GLOBAL_CON_MODE curr_mode)
9426 {
9427 	switch (curr_mode) {
9428 	case QDF_GLOBAL_MISSION_MODE:
9429 	case QDF_GLOBAL_MONITOR_MODE:
9430 	case QDF_GLOBAL_FTM_MODE:
9431 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
9432 		hdd_stop_all_adapters(hdd_ctx);
9433 		hdd_deinit_all_adapters(hdd_ctx, false);
9434 		hdd_close_all_adapters(hdd_ctx, false);
9435 		break;
9436 	case QDF_GLOBAL_EPPING_MODE:
9437 		epping_disable();
9438 		epping_close();
9439 		break;
9440 	default:
9441 		return;
9442 	}
9443 }
9444 
9445 static int hdd_register_req_mode(hdd_context_t *hdd_ctx,
9446 				 enum tQDF_GLOBAL_CON_MODE mode)
9447 {
9448 	hdd_adapter_t *adapter;
9449 	int ret = 0;
9450 	bool rtnl_held;
9451 	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
9452 	QDF_STATUS status;
9453 
9454 	if (!qdf_dev) {
9455 		hdd_err("qdf device context is Null return!");
9456 		return -EINVAL;
9457 	}
9458 
9459 	rtnl_held = hdd_hold_rtnl_lock();
9460 	switch (mode) {
9461 	case QDF_GLOBAL_MISSION_MODE:
9462 		adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
9463 		if (IS_ERR(adapter)) {
9464 			hdd_alert("Failed to open interface, adapter is NULL");
9465 			ret = -EINVAL;
9466 		}
9467 		break;
9468 	case QDF_GLOBAL_FTM_MODE:
9469 		adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
9470 					   wlan_hdd_get_intf_addr(hdd_ctx),
9471 					   NET_NAME_UNKNOWN, rtnl_held);
9472 		if (adapter == NULL)
9473 			ret = -EINVAL;
9474 		break;
9475 	case QDF_GLOBAL_MONITOR_MODE:
9476 		adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
9477 					   wlan_hdd_get_intf_addr(hdd_ctx),
9478 					   NET_NAME_UNKNOWN, rtnl_held);
9479 		if (adapter == NULL)
9480 			ret = -EINVAL;
9481 		break;
9482 	case QDF_GLOBAL_EPPING_MODE:
9483 		status = epping_open();
9484 		 if (status != QDF_STATUS_SUCCESS) {
9485 			hdd_err("Failed to open in eeping mode: %d", status);
9486 			ret = -EINVAL;
9487 			break;
9488 		}
9489 		ret = epping_enable(qdf_dev->dev);
9490 		if (ret) {
9491 			hdd_err("Failed to enable in epping mode : %d", ret);
9492 			epping_close();
9493 		}
9494 		break;
9495 	default:
9496 		hdd_info("Mode not supported");
9497 		ret = -ENOTSUPP;
9498 		break;
9499 	}
9500 	hdd_release_rtnl_lock();
9501 	rtnl_held = false;
9502 	return ret;
9503 }
9504 
9505 /**
9506  * __con_mode_handler() - Handles module param con_mode change
9507  * @kmessage: con mode name on which driver to be bring up
9508  * @kp: The associated kernel parameter
9509  * @hdd_ctx: Pointer to the global HDD context
9510  *
9511  * This function is invoked when user updates con mode using sys entry,
9512  * to initialize and bring-up driver in that specific mode.
9513  *
9514  * Return - 0 on success and failure code on failure
9515  */
9516 static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
9517 			      hdd_context_t *hdd_ctx)
9518 {
9519 	int ret;
9520 	hdd_adapter_t *adapter;
9521 	enum tQDF_GLOBAL_CON_MODE curr_mode;
9522 	enum tQDF_ADAPTER_MODE adapter_mode;
9523 
9524 	ret = wlan_hdd_validate_context(hdd_ctx);
9525 	if (ret)
9526 		return ret;
9527 
9528 	cds_set_load_in_progress(true);
9529 
9530 	hdd_info("con_mode handler: %s", kmessage);
9531 	ret = param_set_int(kmessage, kp);
9532 
9533 
9534 
9535 	if (!(is_con_mode_valid(con_mode))) {
9536 		hdd_err("invlaid con_mode %d", con_mode);
9537 		ret = -EINVAL;
9538 		goto reset_flags;
9539 	}
9540 
9541 	curr_mode = hdd_get_conparam();
9542 	if (curr_mode == con_mode) {
9543 		hdd_err("curr mode: %d is same as user triggered mode %d",
9544 		       curr_mode, con_mode);
9545 		ret = 0;
9546 		goto reset_flags;
9547 	}
9548 
9549 	/* Cleanup present mode before switching to new mode */
9550 	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
9551 
9552 	ret = hdd_wlan_stop_modules(hdd_ctx);
9553 	if (ret) {
9554 		hdd_err("Stop wlan modules failed");
9555 		goto reset_flags;
9556 	}
9557 
9558 	hdd_set_conparam(con_mode);
9559 
9560 	/* Register for new con_mode & then kick_start modules again */
9561 	ret = hdd_register_req_mode(hdd_ctx, con_mode);
9562 	if (ret) {
9563 		hdd_err("Failed to register for new mode");
9564 		goto reset_flags;
9565 	}
9566 
9567 	adapter_mode = hdd_get_adpter_mode(con_mode);
9568 	if (adapter_mode == QDF_MAX_NO_OF_MODE) {
9569 		hdd_err("invalid adapter");
9570 		ret = -EINVAL;
9571 		goto reset_flags;
9572 	}
9573 
9574 	adapter = hdd_get_adapter(hdd_ctx, adapter_mode);
9575 	if (!adapter) {
9576 		hdd_err("Failed to get adapter:%d", adapter_mode);
9577 		goto reset_flags;
9578 	}
9579 
9580 	ret = hdd_wlan_start_modules(hdd_ctx, adapter, false);
9581 	if (ret) {
9582 		hdd_err("Start wlan modules failed: %d", ret);
9583 		goto reset_flags;
9584 	}
9585 
9586 	if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
9587 		con_mode == QDF_GLOBAL_FTM_MODE) {
9588 		if (hdd_start_adapter(adapter)) {
9589 			hdd_err("Failed to start %s adapter", kmessage);
9590 			ret = -EINVAL;
9591 			goto reset_flags;
9592 		}
9593 	}
9594 
9595 	hdd_info("Mode successfully changed to %s", kmessage);
9596 	ret = 0;
9597 
9598 reset_flags:
9599 	cds_set_load_in_progress(false);
9600 	return ret;
9601 }
9602 
9603 
9604 static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
9605 {
9606 	int ret;
9607 	hdd_context_t *hdd_ctx;
9608 
9609 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9610 	ret = wlan_hdd_validate_context(hdd_ctx);
9611 	if (ret)
9612 		return ret;
9613 
9614 	cds_ssr_protect(__func__);
9615 	ret = __con_mode_handler(kmessage, kp, hdd_ctx);
9616 	cds_ssr_unprotect(__func__);
9617 
9618 	return ret;
9619 }
9620 
9621 /**
9622  * hdd_get_conparam() - driver exit point
9623  *
9624  * This is the driver exit point (invoked when module is unloaded using rmmod)
9625  *
9626  * Return: enum tQDF_GLOBAL_CON_MODE
9627  */
9628 enum tQDF_GLOBAL_CON_MODE hdd_get_conparam(void)
9629 {
9630 	return (enum tQDF_GLOBAL_CON_MODE) curr_con_mode;
9631 }
9632 
9633 void hdd_set_conparam(uint32_t con_param)
9634 {
9635 	curr_con_mode = con_param;
9636 }
9637 
9638 /**
9639  * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
9640  * @hdd_ctx: HDD context
9641  *
9642  * Cleans up the pre cac interface, if it exists
9643  *
9644  * Return: None
9645  */
9646 void hdd_clean_up_pre_cac_interface(hdd_context_t *hdd_ctx)
9647 {
9648 	uint8_t session_id;
9649 	QDF_STATUS status;
9650 	struct hdd_adapter_s *precac_adapter;
9651 
9652 	status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->hHal, &session_id);
9653 	if (QDF_IS_STATUS_ERROR(status)) {
9654 		hdd_err("failed to get pre cac vdev id");
9655 		return;
9656 	}
9657 
9658 	precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
9659 	if (!precac_adapter) {
9660 		hdd_err("invalid pre cac adapater");
9661 		return;
9662 	}
9663 
9664 	qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
9665 			wlan_hdd_sap_pre_cac_failure,
9666 			(void *)precac_adapter);
9667 	qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
9668 
9669 }
9670 
9671 /**
9672  * hdd_update_ol_config - API to update ol configuration parameters
9673  * @hdd_ctx: HDD context
9674  *
9675  * Return: void
9676  */
9677 static void hdd_update_ol_config(hdd_context_t *hdd_ctx)
9678 {
9679 	struct ol_config_info cfg;
9680 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
9681 
9682 	if (!ol_ctx)
9683 		return;
9684 
9685 	cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
9686 	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
9687 	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
9688 	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
9689 	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
9690 
9691 	ol_init_ini_config(ol_ctx, &cfg);
9692 }
9693 
9694 #ifdef FEATURE_RUNTIME_PM
9695 /**
9696  * hdd_populate_runtime_cfg() - populate runtime configuration
9697  * @hdd_ctx: hdd context
9698  * @cfg: pointer to the configuration memory being populated
9699  *
9700  * Return: void
9701  */
9702 static void hdd_populate_runtime_cfg(hdd_context_t *hdd_ctx,
9703 				     struct hif_config_info *cfg)
9704 {
9705 	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
9706 	cfg->runtime_pm_delay = hdd_ctx->config->runtime_pm_delay;
9707 }
9708 #else
9709 static void hdd_populate_runtime_cfg(hdd_context_t *hdd_ctx,
9710 				     struct hif_config_info *cfg)
9711 {
9712 }
9713 #endif
9714 
9715 /**
9716  * hdd_update_hif_config - API to update HIF configuration parameters
9717  * @hdd_ctx: HDD Context
9718  *
9719  * Return: void
9720  */
9721 static void hdd_update_hif_config(hdd_context_t *hdd_ctx)
9722 {
9723 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
9724 	struct hif_config_info cfg;
9725 
9726 	if (!scn)
9727 		return;
9728 
9729 	cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
9730 	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
9731 	hif_init_ini_config(scn, &cfg);
9732 }
9733 
9734 /**
9735  * hdd_update_config() - Initialize driver per module ini parameters
9736  * @hdd_ctx: HDD Context
9737  *
9738  * API is used to initialize all driver per module configuration parameters
9739  * Return: 0 for success, errno for failure
9740  */
9741 int hdd_update_config(hdd_context_t *hdd_ctx)
9742 {
9743 	int ret;
9744 
9745 	hdd_update_ol_config(hdd_ctx);
9746 	hdd_update_hif_config(hdd_ctx);
9747 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
9748 		ret = hdd_update_cds_config_ftm(hdd_ctx);
9749 	else
9750 		ret = hdd_update_cds_config(hdd_ctx);
9751 
9752 	return ret;
9753 }
9754 
9755 /**
9756  * wlan_hdd_get_dfs_mode() - get ACS DFS mode
9757  * @mode : cfg80211 DFS mode
9758  *
9759  * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
9760  */
9761 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
9762 {
9763 	switch (mode) {
9764 	case DFS_MODE_ENABLE:
9765 		return ACS_DFS_MODE_ENABLE;
9766 		break;
9767 	case DFS_MODE_DISABLE:
9768 		return ACS_DFS_MODE_DISABLE;
9769 		break;
9770 	case DFS_MODE_DEPRIORITIZE:
9771 		return ACS_DFS_MODE_DEPRIORITIZE;
9772 		break;
9773 	default:
9774 		hdd_err("ACS dfs mode is NONE");
9775 		return  ACS_DFS_MODE_NONE;
9776 	}
9777 }
9778 
9779 /**
9780  * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
9781  * @hddctx: pointer to hdd context
9782  * @set_value: enable/disable
9783  *
9784  * When Host sends vendor command enable, FW will send *ONE* CA ind to
9785  * Host(even though it is duplicate). When Host send vendor command
9786  * disable,FW doesn't perform any action. Whenever any change in
9787  * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
9788  *
9789  * return - 0 on success, appropriate error values on failure.
9790  */
9791 int hdd_enable_disable_ca_event(hdd_context_t *hddctx, uint8_t set_value)
9792 {
9793 	QDF_STATUS status;
9794 
9795 	if (0 != wlan_hdd_validate_context(hddctx)) {
9796 		return -EAGAIN;
9797 	}
9798 
9799 	if (!hddctx->config->goptimize_chan_avoid_event) {
9800 		hdd_warn("goptimize_chan_avoid_event ini param disabled");
9801 		return -EINVAL;
9802 	}
9803 
9804 	status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
9805 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9806 		hdd_err("Failed to send chan avoid command to SME");
9807 		return -EINVAL;
9808 	}
9809 	return 0;
9810 }
9811 
9812 /* Register the module init/exit functions */
9813 module_init(hdd_module_init);
9814 module_exit(hdd_module_exit);
9815 
9816 MODULE_LICENSE("Dual BSD/GPL");
9817 MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9818 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9819 
9820 module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9821 		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
9822 
9823 module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
9824 		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
9825 
9826 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
9827 
9828 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
9829 
9830 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
9831