/*
 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**
 *  DOC: wlan_hdd_main.c
 *
 *  WLAN Host Device Driver implementation
 *
 */

/* Include Files */
#include <wlan_hdd_includes.h>
#include <cds_api.h>
#include <cds_sched.h>
#ifdef WLAN_FEATURE_LPSS
#include <cds_utils.h>
#endif
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wlan_hdd_tx_rx.h>
#include <wni_api.h>
#include <wlan_hdd_cfg.h>
#include <wlan_ptt_sock_svc.h>
#include <dbglog_host.h>
#include <wlan_logging_sock_svc.h>
#include <wlan_hdd_wowl.h>
#include <wlan_hdd_misc.h>
#include <wlan_hdd_wext.h>
#include "wlan_hdd_trace.h"
#include "wlan_hdd_ioctl.h"
#include "wlan_hdd_ftm.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_stats.h"
#include "qdf_types.h"
#include "cdf_trace.h"

#include <net/addrconf.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#include "wlan_hdd_cfg80211.h"
#include "wlan_hdd_ext_scan.h"
#include "wlan_hdd_p2p.h"
#include <linux/rtnetlink.h>
#include "sap_api.h"
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include <linux/compat.h>
#ifdef MSM_PLATFORM
#ifdef CONFIG_CNSS
#include <soc/qcom/subsystem_restart.h>
#endif
#endif
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include "cfg_api.h"
#include "qwlan_version.h"
#include "wma_types.h"
#include "wlan_hdd_tdls.h"
#ifdef FEATURE_WLAN_CH_AVOID
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif
#include "cds_regdomain.h"

#include "wlan_hdd_ocb.h"

extern int hdd_hostapd_stop(struct net_device *dev);
#endif /* FEATURE_WLAN_CH_AVOID */

#include "wlan_hdd_nan.h"
#include "wlan_hdd_debugfs.h"
#include "wlan_hdd_driver_ops.h"
#include "epping_main.h"
#include "wlan_hdd_memdump.h"

#include <wlan_hdd_ipa.h>
#include "hif.h"
#include "wma.h"
#include "cds_concurrency.h"
#include "wlan_hdd_green_ap.h"
#include "platform_icnss.h"
#include "bmi.h"

#ifdef MODULE
#define WLAN_MODULE_NAME  module_name(THIS_MODULE)
#else
#define WLAN_MODULE_NAME  "wlan"
#endif

#ifdef TIMER_MANAGER
#define TIMER_MANAGER_STR " +TIMER_MANAGER"
#else
#define TIMER_MANAGER_STR ""
#endif

#ifdef MEMORY_DEBUG
#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
#else
#define MEMORY_DEBUG_STR ""
#endif

/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath_buffer[BUF_LEN];
static struct kparam_string fwpath = {
	.string = fwpath_buffer,
	.maxlen = BUF_LEN,
};

static char *country_code;
static int enable_11d = -1;
static int enable_dfs_chan_scan = -1;

#ifndef MODULE
static int wlan_hdd_inited;
#endif

/*
 * spinlock for synchronizing asynchronous request/response
 * (full description of use in wlan_hdd_main.h)
 */
DEFINE_SPINLOCK(hdd_context_lock);

static cdf_wake_lock_t wlan_wake_lock;

#define WOW_MAX_FILTER_LISTS 1
#define WOW_MAX_FILTERS_PER_LIST 4
#define WOW_MIN_PATTERN_SIZE 6
#define WOW_MAX_PATTERN_SIZE 64

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
static const struct wiphy_wowlan_support wowlan_support_reg_init = {
	.flags = WIPHY_WOWLAN_ANY |
		 WIPHY_WOWLAN_MAGIC_PKT |
		 WIPHY_WOWLAN_DISCONNECT |
		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
		 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
		 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
		 WIPHY_WOWLAN_4WAY_HANDSHAKE |
		 WIPHY_WOWLAN_RFKILL_RELEASE,
	.n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
	.pattern_min_len = WOW_MIN_PATTERN_SIZE,
	.pattern_max_len = WOW_MAX_PATTERN_SIZE,
};
#endif

/* internal function declaration */

struct sock *cesium_nl_srv_sock;

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
void wlan_hdd_auto_shutdown_cb(void);
#endif

/**
 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
 * @vdev_id: vdev_id
 * @action: action type
 * @reason: reason type
 *
 * Return: none
 */
void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
		enum netif_action_type action, enum netif_reason_type reason)
{
	hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	hdd_adapter_t *adapter;

	if (!hdd_ctx) {
		hdd_err("hdd ctx is NULL");
		return;
	}
	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);

	wlan_hdd_netif_queue_control(adapter, action, reason);
	return;
}

/*
 * Store WLAN driver version info in a global variable such that crash debugger
 * can extract it from driver debug symbol and crashdump for post processing
 */
uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR;

/**
 * hdd_device_mode_to_string() - return string conversion of device mode
 * @device_mode: device mode
 *
 * This utility function helps log string conversion of device mode.
 *
 * Return: string conversion of device mode, if match found;
 *	   "Unknown" otherwise.
 */
const char *hdd_device_mode_to_string(uint8_t device_mode)
{
	switch (device_mode) {
	CASE_RETURN_STRING(WLAN_HDD_INFRA_STATION);
	CASE_RETURN_STRING(WLAN_HDD_SOFTAP);
	CASE_RETURN_STRING(WLAN_HDD_P2P_CLIENT);
	CASE_RETURN_STRING(WLAN_HDD_P2P_GO);
	CASE_RETURN_STRING(WLAN_HDD_FTM);
	CASE_RETURN_STRING(WLAN_HDD_IBSS);
	CASE_RETURN_STRING(WLAN_HDD_P2P_DEVICE);
	CASE_RETURN_STRING(WLAN_HDD_OCB);
	default:
		return "Unknown";
	}
}

/**
 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
 * @adapter: HDD adapter
 * @chan_number: Channel number
 * @chan_bw: Bandwidth
 *
 * Checks if the given bandwidth is valid for the given channel number.
 *
 * Return: 0 for success, non-zero for failure
 */
int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
		uint32_t chan_number,
		phy_ch_width chan_bw)
{
	uint8_t chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
	uint32_t len = WNI_CFG_VALID_CHANNEL_LIST_LEN, i;
	bool found = false;
	tHalHandle hal;

	hal = WLAN_HDD_GET_HAL_CTX(adapter);
	if (!hal) {
		hdd_err("Invalid HAL context");
		return -EINVAL;
	}

	if (0 != sme_cfg_get_str(hal, WNI_CFG_VALID_CHANNEL_LIST, chan, &len)) {
		hdd_err("No valid channel list");
		return -EOPNOTSUPP;
	}

	for (i = 0; i < len; i++) {
		if (chan[i] == chan_number) {
			found = true;
			break;
		}
	}

	if (found == false) {
		hdd_err("Channel not in driver's valid channel list");
		return -EOPNOTSUPP;
	}

	if ((!CDS_IS_CHANNEL_24GHZ(chan_number)) &&
			(!CDS_IS_CHANNEL_5GHZ(chan_number))) {
		hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
		return -EINVAL;
	}

	if (CDS_IS_CHANNEL_24GHZ(chan_number)) {
		if (chan_bw == CH_WIDTH_80MHZ) {
			hdd_err("BW80 not possible in 2.4GHz band");
			return -EINVAL;
		}
		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
				(chan_bw != CH_WIDTH_MAX)) {
			hdd_err("Only BW20 possible on channel 14");
			return -EINVAL;
		}
	}

	if (CDS_IS_CHANNEL_5GHZ(chan_number)) {
		if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
				(chan_bw != CH_WIDTH_MAX)) {
			hdd_err("Only BW20 possible on channel 165");
			return -EINVAL;
		}
	}

	return 0;
}

static int __hdd_netdev_notifier_call(struct notifier_block *nb,
				    unsigned long state, void *data)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
	struct netdev_notifier_info *dev_notif_info = data;
	struct net_device *dev = dev_notif_info->dev;
#else
	struct net_device *dev = data;
#endif
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx;

	/* Make sure that this callback corresponds to our device. */
	if ((strncmp(dev->name, "wlan", 4)) && (strncmp(dev->name, "p2p", 3)))
		return NOTIFY_DONE;

	if ((adapter->magic != WLAN_HDD_ADAPTER_MAGIC) &&
	    (adapter->dev != dev)) {
		hddLog(LOGE, FL("device adapter is not matching!!!"));
		return NOTIFY_DONE;
	}

	if (!dev->ieee80211_ptr) {
		hddLog(LOGE, FL("ieee80211_ptr is NULL!!!"));
		return NOTIFY_DONE;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (NULL == hdd_ctx) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("HDD Context Null Pointer"));
		CDF_ASSERT(0);
		return NOTIFY_DONE;
	}
	if (cds_is_driver_recovering())
		return NOTIFY_DONE;

	hddLog(CDF_TRACE_LEVEL_INFO, FL("%s New Net Device State = %lu"),
	       dev->name, state);

	switch (state) {
	case NETDEV_REGISTER:
		break;

	case NETDEV_UNREGISTER:
		break;

	case NETDEV_UP:
		sme_ch_avoid_update_req(hdd_ctx->hHal);
		break;

	case NETDEV_DOWN:
		break;

	case NETDEV_CHANGE:
		if (true == adapter->isLinkUpSvcNeeded)
			complete(&adapter->linkup_event_var);
		break;

	case NETDEV_GOING_DOWN:
		if (adapter->scan_info.mScanPending != false) {
			unsigned long rc;
			INIT_COMPLETION(adapter->scan_info.
					abortscan_event_var);
			hdd_abort_mac_scan(adapter->pHddCtx,
					   adapter->sessionId,
					   eCSR_SCAN_ABORT_DEFAULT);
			rc = wait_for_completion_timeout(
				&adapter->scan_info.abortscan_event_var,
				msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
			if (!rc) {
				hddLog(LOGE,
				       FL("Timeout occurred while waiting for abortscan"));
			}
		} else {
			hddLog(CDF_TRACE_LEVEL_INFO,
			       FL("Scan is not Pending from user"));
		}
		break;

	default:
		break;
	}

	return NOTIFY_DONE;
}

/**
 * hdd_netdev_notifier_call() - netdev notifier callback function
 * @nb: pointer to notifier block
 * @state: state
 * @ndev: ndev pointer
 *
 * Return: 0 on success, error number otherwise.
 */
static int hdd_netdev_notifier_call(struct notifier_block *nb,
					unsigned long state,
					void *ndev)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __hdd_netdev_notifier_call(nb, state, ndev);
	cds_ssr_unprotect(__func__);

	return ret;
}

struct notifier_block hdd_netdev_notifier = {
	.notifier_call = hdd_netdev_notifier_call,
};

/* variable to hold the insmod parameters */
static int con_mode;

/* Variable to hold connection mode including module parameter con_mode */
static int curr_con_mode;

/**
 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
 * @ch_width: NL channel width
 *
 * Converts the NL channel width to the driver's internal representation
 *
 * Return: Converted channel width. In case of non matching NL channel width,
 * CH_WIDTH_MAX will be returned.
 */
phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
{
	switch (ch_width) {
	case NL80211_CHAN_WIDTH_20_NOHT:
	case NL80211_CHAN_WIDTH_20:
		return CH_WIDTH_20MHZ;
	case NL80211_CHAN_WIDTH_40:
		return CH_WIDTH_40MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		return CH_WIDTH_80MHZ;
	case NL80211_CHAN_WIDTH_80P80:
		return CH_WIDTH_80P80MHZ;
	case NL80211_CHAN_WIDTH_160:
		return CH_WIDTH_160MHZ;
	case NL80211_CHAN_WIDTH_5:
	case NL80211_CHAN_WIDTH_10:
	default:
		hdd_err("Invalid channel width %d, setting to default",
				ch_width);
		return CH_WIDTH_MAX;
	}
}

/* wlan_hdd_find_opclass() - Find operating class for a channel
 * @hal: handler to HAL
 * @channel: channel id
 * @bw_offset: bandwidth offset
 *
 * Function invokes sme api to find the operating class
 *
 * Return: operating class
 */
uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
				uint8_t bw_offset)
{
	uint8_t opclass = 0;

	sme_get_opclass(hal, channel, bw_offset, &opclass);
	return opclass;
}

/**
 * hdd_cdf_trace_enable() - configure initial CDF Trace enable
 * @moduleId:	Module whose trace level is being configured
 * @bitmask:	Bitmask of log levels to be enabled
 *
 * Called immediately after the cfg.ini is read in order to configure
 * the desired trace levels.
 *
 * Return: None
 */
static void hdd_cdf_trace_enable(QDF_MODULE_ID moduleId, uint32_t bitmask)
{
	CDF_TRACE_LEVEL level;

	/*
	 * if the bitmask is the default value, then a bitmask was not
	 * specified in cfg.ini, so leave the logging level alone (it
	 * will remain at the "compiled in" default value)
	 */
	if (CFG_CDF_TRACE_ENABLE_DEFAULT == bitmask) {
		return;
	}

	/* a mask was specified.  start by disabling all logging */
	cdf_trace_set_value(moduleId, CDF_TRACE_LEVEL_NONE, 0);

	/* now cycle through the bitmask until all "set" bits are serviced */
	level = CDF_TRACE_LEVEL_FATAL;
	while (0 != bitmask) {
		if (bitmask & 1) {
			cdf_trace_set_value(moduleId, level, 1);
		}
		level++;
		bitmask >>= 1;
	}
}

/**
 * wlan_hdd_validate_context() - check the HDD context
 * @hdd_ctx:	HDD context pointer
 *
 * Return: 0 if the context is valid. Error code otherwise
 */
int wlan_hdd_validate_context(hdd_context_t *hdd_ctx)
{
	if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
		hddLog(LOGE, FL("HDD context is Null"));
		return -ENODEV;
	}

	if (cds_is_driver_recovering()) {
		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
			 cds_get_driver_state());
		return -EAGAIN;
	}

	if (cds_is_load_or_unload_in_progress()) {
		hdd_err("Unloading/Loading in Progress. Ignore!!!: 0x%x",
			cds_get_driver_state());
		return -EAGAIN;
	}
	return 0;
}

void hdd_checkandupdate_phymode(hdd_context_t *hdd_ctx)
{
	hdd_adapter_t *adapter = NULL;
	hdd_station_ctx_t *pHddStaCtx = NULL;
	eCsrPhyMode phyMode;
	struct hdd_config *cfg_param = NULL;

	if (NULL == hdd_ctx) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("HDD Context is null !!"));
		return;
	}

	adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
	if (NULL == adapter) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("adapter is null !!"));
		return;
	}

	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	cfg_param = hdd_ctx->config;
	if (NULL == cfg_param) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("cfg_params not available !!"));
		return;
	}

	phyMode = sme_get_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter));

	if (!hdd_ctx->isVHT80Allowed) {
		if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
		    (eCSR_DOT11_MODE_11ac == phyMode) ||
		    (eCSR_DOT11_MODE_11ac_ONLY == phyMode)) {
			hddLog(CDF_TRACE_LEVEL_INFO,
			       FL("Setting phymode to 11n!!"));
			sme_set_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter),
					 eCSR_DOT11_MODE_11n);
		}
	} else {
		/*
		 * New country Supports 11ac as well resetting value back from
		 * .ini
		 */
		sme_set_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter),
				 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->
							       dot11Mode));
		return;
	}

	if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
	    ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode)
	     || (eCSR_CFG_DOT11_MODE_11AC ==
		 pHddStaCtx->conn_info.dot11Mode))) {
		QDF_STATUS qdf_status;

		/* need to issue a disconnect to CSR. */
		INIT_COMPLETION(adapter->disconnect_comp_var);
		qdf_status = sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(adapter),
						 adapter->sessionId,
						 eCSR_DISCONNECT_REASON_UNSPECIFIED);

		if (QDF_STATUS_SUCCESS == qdf_status) {
			unsigned long rc;

			rc = wait_for_completion_timeout(
				&adapter->disconnect_comp_var,
				msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
			if (!rc)
				hddLog(LOGE,
				       FL("failure waiting for disconnect_comp_var"));
		}
	}
}

/**
 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
 * @hdd_adapter_t Hdd adapter.
 *
 * This function sets the IBSS power save config parameters to WMA
 * which will send it to firmware if FW supports IBSS power save
 * before vdev start.
 *
 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
 *         on failure.
 */
QDF_STATUS hdd_set_ibss_power_save_params(hdd_adapter_t *adapter)
{
	int ret;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	if (hdd_ctx == NULL) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("HDD context is null"));
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
				  hdd_ctx->config->ibssATIMWinSize,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d"), ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
				  hdd_ctx->config->isIbssPowerSaveAllowed,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d"),
		       ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
				  hdd_ctx->config->
				  isIbssPowerCollapseAllowed, VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d"),
		       ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
				  hdd_ctx->config->isIbssAwakeOnTxRx,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d"), ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
				  hdd_ctx->config->ibssInactivityCount,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d"), ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
				  hdd_ctx->config->ibssTxSpEndInactivityTime,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d"
			 ),
		       ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
				  hdd_ctx->config->ibssPsWarmupTime,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d"),
		       ret);
		return QDF_STATUS_E_FAILURE;
	}

	ret = wma_cli_set_command(adapter->sessionId,
				  WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
				  hdd_ctx->config->ibssPs1RxChainInAtimEnable,
				  VDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d"
			 ),
		       ret);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

#define INTF_MACADDR_MASK       0x7

/**
 * hdd_update_macaddr() - update mac address
 * @config:	hdd configuration
 * @hw_macaddr:	mac address
 *
 * Mac address for multiple virtual interface is found as following
 * i) The mac address of the first interface is just the actual hw mac address.
 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
 *     define the mac address for the remaining interfaces and locally
 *     admistered bit is set. INTF_MACADDR_MASK is based on the number of
 *     supported virtual interfaces, right now this is 0x07 (meaning 8
 *     interface).
 *     Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
 *     for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
 *
 * Return: None
 */
void hdd_update_macaddr(struct hdd_config *config,
			struct qdf_mac_addr hw_macaddr)
{
	int8_t i;
	uint8_t macaddr_b3, tmp_br3;

	cdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
		     QDF_MAC_ADDR_SIZE);
	for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
		cdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
			     QDF_MAC_ADDR_SIZE);
		macaddr_b3 = config->intfMacAddr[i].bytes[3];
		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
			  INTF_MACADDR_MASK;
		macaddr_b3 += tmp_br3;

		/* XOR-ing bit-24 of the mac address. This will give enough
		 * mac address range before collision
		 */
		macaddr_b3 ^= (1 << 7);

		/* Set locally administered bit */
		config->intfMacAddr[i].bytes[0] |= 0x02;
		config->intfMacAddr[i].bytes[3] = macaddr_b3;
		hddLog(CDF_TRACE_LEVEL_INFO, "config->intfMacAddr[%d]: "
		       MAC_ADDRESS_STR, i,
		       MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
	}
}

static void hdd_update_tgt_services(hdd_context_t *hdd_ctx,
				    struct wma_tgt_services *cfg)
{
	struct hdd_config *config = hdd_ctx->config;

	/* Set up UAPSD */
	config->apUapsdEnabled &= cfg->uapsd;

#ifdef WLAN_FEATURE_11AC
	/* 11AC mode support */
	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
#endif /* #ifdef WLAN_FEATURE_11AC */

	/* ARP offload: override user setting if invalid  */
	config->fhostArpOffload &= cfg->arp_offload;

#ifdef FEATURE_WLAN_SCAN_PNO
	/* PNO offload */
	hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
	       FL("PNO Capability in f/w = %d"), cfg->pno_offload);
	if (cfg->pno_offload)
		config->PnoOffload = true;
#endif
#ifdef FEATURE_WLAN_TDLS
	config->fEnableTDLSSupport &= cfg->en_tdls;
	config->fEnableTDLSOffChannel &= cfg->en_tdls_offchan;
	config->fEnableTDLSBufferSta &= cfg->en_tdls_uapsd_buf_sta;
	if (config->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta) {
		config->fEnableTDLSSleepSta = true;
	} else {
		config->fEnableTDLSSleepSta = false;
	}
#endif
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	config->isRoamOffloadEnabled &= cfg->en_roam_offload;
#endif
	sme_update_tgt_services(hdd_ctx->hHal, cfg);

}

static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx,
				  struct wma_tgt_ht_cap *cfg)
{
	QDF_STATUS status;
	uint32_t value, val32;
	uint16_t val16;
	struct hdd_config *pconfig = hdd_ctx->config;
	tSirMacHTCapabilityInfo *phtCapInfo;
	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
	uint8_t enable_tx_stbc;

	/* check and update RX STBC */
	if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc)
		pconfig->enableRxSTBC = cfg->ht_rx_stbc;

	/* get the MPDU density */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get MPDU DENSITY"));
		value = 0;
	}

	/*
	 * MPDU density:
	 * override user's setting if value is larger
	 * than the one supported by target
	 */
	if (value > cfg->mpdu_density) {
		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY,
					 cfg->mpdu_density);

		if (status == QDF_STATUS_E_FAILURE)
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set MPDU DENSITY to CCM"));
	}

	/* get the HT capability info */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32);
	if (QDF_STATUS_SUCCESS != status) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get HT capability info"));
		return;
	}
	val16 = (uint16_t) val32;
	phtCapInfo = (tSirMacHTCapabilityInfo *) &val16;

	/* Set the LDPC capability */
	phtCapInfo->advCodingCap = cfg->ht_rx_ldpc;

	if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20)
		pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20;

	if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40)
		pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40;

	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;

	enable_tx_stbc = pconfig->enableTxSTBC;

	if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) {
		pconfig->enable2x2 = 1;
	} else {
		pconfig->enable2x2 = 0;
		enable_tx_stbc = 0;

		/* 1x1 */
		/* Update Rx Highest Long GI data Rate */
		if (sme_cfg_set_int(hdd_ctx->hHal,
				    WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
				    HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1)
				== QDF_STATUS_E_FAILURE) {
			hddLog(LOGE,
			       FL(
				  "Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM"
				 ));
		}

		/* Update Tx Highest Long GI data Rate */
		if (sme_cfg_set_int
			    (hdd_ctx->hHal,
			     WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
			     HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1) ==
			    QDF_STATUS_E_FAILURE) {
			hddLog(LOGE,
			       FL(
				  "Could not pass on HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 to CCM"
				 ));
		}
	}
	if (!(cfg->ht_tx_stbc && pconfig->enable2x2))
		enable_tx_stbc = 0;
	phtCapInfo->txSTBC = enable_tx_stbc;

	val32 = val16;
	status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, val32);
	if (status != QDF_STATUS_SUCCESS)
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("could not set HT capability to CCM"));
#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
	value = SIZE_OF_SUPPORTED_MCS_SET;
	if (sme_cfg_get_str(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set,
			    &value) == QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_INFO, FL("Read MCS rate set"));

		if (pconfig->enable2x2) {
			for (value = 0; value < cfg->num_rf_chains; value++)
				mcs_set[value] =
					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;

			status =
				sme_cfg_set_str(hdd_ctx->hHal,
						WNI_CFG_SUPPORTED_MCS_SET,
						mcs_set,
						SIZE_OF_SUPPORTED_MCS_SET);
			if (status == QDF_STATUS_E_FAILURE)
				hddLog(CDF_TRACE_LEVEL_FATAL,
				       FL("could not set MCS SET to CCM"));
		}
	}
#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
}

#ifdef WLAN_FEATURE_11AC
static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
				   struct wma_tgt_vht_cap *cfg)
{
	QDF_STATUS status;
	uint32_t value = 0;
	struct hdd_config *pconfig = hdd_ctx->config;
	struct wiphy *wiphy = hdd_ctx->wiphy;
	struct ieee80211_supported_band *band_5g =
		wiphy->bands[IEEE80211_BAND_5GHZ];

	/* Get the current MPDU length */
	status =
		sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH,
				&value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR, FL("could not get MPDU LENGTH"));
		value = 0;
	}

	/*
	 * VHT max MPDU length:
	 * override if user configured value is too high
	 * that the target cannot support
	 */
	if (value > cfg->vht_max_mpdu) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_MAX_MPDU_LENGTH,
					 cfg->vht_max_mpdu);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set VHT MAX MPDU LENGTH"));
		}
	}

	/* Get the current supported chan width */
	status = sme_cfg_get_int(hdd_ctx->hHal,
				WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
				&value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get MPDU LENGTH"));
		value = 0;
	}

	/* Get the current RX LDPC setting */
	status =
		sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP,
				&value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT LDPC CODING CAP"));
		value = 0;
	}

	/* Set the LDPC capability */
	if (value && !cfg->vht_rx_ldpc) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_LDPC_CODING_CAP,
					 cfg->vht_rx_ldpc);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set VHT LDPC CODING CAP to CCM"));
		}
	}

	/* Get current GI 80 value */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ,
				&value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get SHORT GI 80MHZ"));
		value = 0;
	}

	/* set the Guard interval 80MHz */
	if (value && !cfg->vht_short_gi_80) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_SHORT_GI_80MHZ,
					 cfg->vht_short_gi_80);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set SHORT GI 80MHZ to CCM"));
		}
	}

	/* Get current GI 160 value */
	status = sme_cfg_get_int(hdd_ctx->hHal,
				 WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
				 &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get SHORT GI 80 & 160"));
		value = 0;
	}

	/* Get VHT TX STBC cap */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT TX STBC"));
		value = 0;
	}

	/* VHT TX STBC cap */
	if (value && !cfg->vht_tx_stbc) {
		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC,
					 cfg->vht_tx_stbc);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set the VHT TX STBC to CCM"));
		}
	}

	/* Get VHT RX STBC cap */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT RX STBC"));
		value = 0;
	}

	/* VHT RX STBC cap */
	if (value && !cfg->vht_rx_stbc) {
		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC,
					 cfg->vht_rx_stbc);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set the VHT RX STBC to CCM"));
		}
	}

	/* Get VHT SU Beamformer cap */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
				 &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT SU BEAMFORMER CAP"));
		value = 0;
	}

	/* set VHT SU Beamformer cap */
	if (value && !cfg->vht_su_bformer) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_SU_BEAMFORMER_CAP,
					 cfg->vht_su_bformer);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set VHT SU BEAMFORMER CAP"));
		}
	}

	/* check and update SU BEAMFORMEE capabality */
	if (pconfig->enableTxBF && !cfg->vht_su_bformee)
		pconfig->enableTxBF = cfg->vht_su_bformee;

	status = sme_cfg_set_int(hdd_ctx->hHal,
				 WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
				 pconfig->enableTxBF);

	if (status == QDF_STATUS_E_FAILURE) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("could not set VHT SU BEAMFORMEE CAP"));
	}

	/* Get VHT MU Beamformer cap */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP,
				 &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT MU BEAMFORMER CAP"));
		value = 0;
	}

	/* set VHT MU Beamformer cap */
	if (value && !cfg->vht_mu_bformer) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_MU_BEAMFORMER_CAP,
					 cfg->vht_mu_bformer);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL(
				  "could not set the VHT MU BEAMFORMER CAP to CCM"
				 ));
		}
	}

	/* Get VHT MU Beamformee cap */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
				 &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT MU BEAMFORMEE CAP"));
		value = 0;
	}

	/* set VHT MU Beamformee cap */
	if (value && !cfg->vht_mu_bformee) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
					 cfg->vht_mu_bformee);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set VHT MU BEAMFORMER CAP"));
		}
	}

	/* Get VHT MAX AMPDU Len exp */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
				 &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT AMPDU LEN"));
		value = 0;
	}

	/*
	 * VHT max AMPDU len exp:
	 * override if user configured value is too high
	 * that the target cannot support.
	 * Even though Rome publish ampdu_len=7, it can
	 * only support 4 because of some h/w bug.
	 */

	if (value > cfg->vht_max_ampdu_len_exp) {
		status = sme_cfg_set_int(hdd_ctx->hHal,
					 WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
					 cfg->vht_max_ampdu_len_exp);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set the VHT AMPDU LEN EXP"));
		}
	}

	/* Get VHT TXOP PS CAP */
	status = sme_cfg_get_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("could not get VHT TXOP PS"));
		value = 0;
	}

	/* set VHT TXOP PS cap */
	if (value && !cfg->vht_txop_ps) {
		status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS,
					 cfg->vht_txop_ps);

		if (status == QDF_STATUS_E_FAILURE) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("could not set the VHT TXOP PS"));
		}
	}

	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
	else
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;


	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
		band_5g->vht_cap.cap |=
			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
	}
	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
		band_5g->vht_cap.cap |=
			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
	}

	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;

	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;

	if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;

	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;

	band_5g->vht_cap.cap |=
		(cfg->vht_max_ampdu_len_exp <<
		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);

	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;

	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;

}
#endif /* #ifdef WLAN_FEATURE_11AC */

void hdd_update_tgt_cfg(void *context, void *param)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *) context;
	struct wma_tgt_cfg *cfg = param;
	uint8_t temp_band_cap;

	/* first store the INI band capability */
	temp_band_cap = hdd_ctx->config->nBandCapability;

	hdd_ctx->config->nBandCapability = cfg->band_cap;

	/* now overwrite the target band capability with INI
	   setting if INI setting is a subset */

	if ((hdd_ctx->config->nBandCapability == eCSR_BAND_ALL) &&
	    (temp_band_cap != eCSR_BAND_ALL))
		hdd_ctx->config->nBandCapability = temp_band_cap;
	else if ((hdd_ctx->config->nBandCapability != eCSR_BAND_ALL) &&
		 (temp_band_cap != eCSR_BAND_ALL) &&
		 (hdd_ctx->config->nBandCapability != temp_band_cap)) {
		hddLog(CDF_TRACE_LEVEL_WARN,
		       FL("ini BandCapability not supported by the target"));
	}

	if (!cds_is_driver_recovering()) {
		hdd_ctx->reg.reg_domain = cfg->reg_domain;
		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
	}

	/* This can be extended to other configurations like ht, vht cap... */

	if (!cdf_is_macaddr_zero(&cfg->hw_macaddr)) {
		hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
	} else {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "Invalid MAC passed from target, using MAC from ini file"
			  MAC_ADDRESS_STR),
		       MAC_ADDR_ARRAY(hdd_ctx->config->intfMacAddr[0].bytes));
	}

	hdd_ctx->target_fw_version = cfg->target_fw_version;

	hdd_ctx->max_intf_count = cfg->max_intf_count;

#ifdef WLAN_FEATURE_LPSS
	hdd_ctx->lpss_support = cfg->lpss_support;
#endif

	hdd_wlan_set_egap_support(hdd_ctx, cfg);

	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
	hdd_update_tgt_services(hdd_ctx, &cfg->services);

	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);

#ifdef WLAN_FEATURE_11AC
	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
#endif /* #ifdef WLAN_FEATURE_11AC */
	hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap;
	hdd_info(FL("fine_time_meas_cap: 0x%x"),
		hdd_ctx->config->fine_time_meas_cap);
}

/**
 * hdd_dfs_indicate_radar() - handle radar detection on current SAP channel
 * @context:	HDD context pointer
 * @param:	HDD radar indication pointer
 *
 * This function is invoked when a radar in found on the
 * SAP current operating channel and Data Tx from netif
 * has to be stopped to honor the DFS regulations.
 * Actions: Stop the netif Tx queues,Indicate Radar present
 * in HDD context for future usage.
 *
 * Return: true to allow radar indication to host else false
 */
bool hdd_dfs_indicate_radar(void *context, void *param)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *) context;
	struct wma_dfs_radar_ind *hdd_radar_event =
		(struct wma_dfs_radar_ind *)param;
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS status;

	if (!hdd_ctx || !hdd_radar_event ||
		 hdd_ctx->config->disableDFSChSwitch)
		return true;

	if (true == hdd_radar_event->dfs_radar_status) {
		mutex_lock(&hdd_ctx->dfs_lock);
		if (hdd_ctx->dfs_radar_found) {
			/*
			 * Application already triggered channel switch
			 * on current channel, so return here.
			 */
			mutex_unlock(&hdd_ctx->dfs_lock);
			return false;
		}

		hdd_ctx->dfs_radar_found = true;
		mutex_unlock(&hdd_ctx->dfs_lock);

		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
			adapter = adapterNode->pAdapter;
			if (WLAN_HDD_SOFTAP == adapter->device_mode ||
			    WLAN_HDD_P2P_GO == adapter->device_mode) {
				WLAN_HDD_GET_AP_CTX_PTR(adapter)->
				dfs_cac_block_tx = true;
			}

			status = hdd_get_next_adapter(hdd_ctx,
						      adapterNode,
						      &pNext);
			adapterNode = pNext;
		}
	}

	return true;
}

/**
 * hdd_is_valid_mac_address() - validate MAC address
 * @pMacAddr:	Pointer to the input MAC address
 *
 * This function validates whether the given MAC address is valid or not
 * Expected MAC address is of the format XX:XX:XX:XX:XX:XX
 * where X is the hexa decimal digit character and separated by ':'
 * This algorithm works even if MAC address is not separated by ':'
 *
 * This code checks given input string mac contains exactly 12 hexadecimal
 * digits and a separator colon : appears in the input string only after
 * an even number of hex digits.
 *
 * Return: 1 for valid and 0 for invalid
 */
bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
{
	int xdigit = 0;
	int separator = 0;
	while (*pMacAddr) {
		if (isxdigit(*pMacAddr)) {
			xdigit++;
		} else if (':' == *pMacAddr) {
			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
				break;

			++separator;
		} else {
			/* Invalid MAC found */
			return 0;
		}
		++pMacAddr;
	}
	return xdigit == 12 && (separator == 5 || separator == 0);
}

/**
 * __hdd_open() - HDD Open function
 * @dev:	Pointer to net_device structure
 *
 * This is called in response to ifconfig up
 *
 * Return: 0 for success; non-zero for failure
 */
static int __hdd_open(struct net_device *dev)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int ret;

	MTRACE(cdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
			 adapter->sessionId, adapter->device_mode));

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return ret;
	}

	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
	if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
		hddLog(LOG1, FL("Enabling Tx Queues"));
		/* Enable TX queues only when we are connected */
		wlan_hdd_netif_queue_control(adapter,
					WLAN_START_ALL_NETIF_QUEUE,
					WLAN_CONTROL_PATH);
	}

	return ret;
}

/**
 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
 * @dev:	Pointer to net_device structure
 *
 * This is called in response to ifconfig up
 *
 * Return: 0 for success; non-zero for failure
 */
int hdd_open(struct net_device *dev)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __hdd_open(dev);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __hdd_stop() - HDD stop function
 * @dev:	Pointer to net_device structure
 *
 * This is called in response to ifconfig down
 *
 * Return: 0 for success; non-zero for failure
 */
static int __hdd_stop(struct net_device *dev)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int ret;

	ENTER();

	MTRACE(cdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
			 adapter->sessionId, adapter->device_mode));

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	/* Nothing to be done if the interface is not opened */
	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("NETDEV Interface is not OPENED"));
		return -ENODEV;
	}

	/* Make sure the interface is marked as closed */
	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
	hddLog(CDF_TRACE_LEVEL_INFO, FL("Disabling OS Tx queues"));

	/*
	 * Disable TX on the interface, after this hard_start_xmit() will not
	 * be called on that interface
	 */
	hddLog(LOG1, FL("Disabling queues"));
	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
				   WLAN_CONTROL_PATH);

	/*
	 * The interface is marked as down for outside world (aka kernel)
	 * But the driver is pretty much alive inside. The driver needs to
	 * tear down the existing connection on the netdev (session)
	 * cleanup the data pipes and wait until the control plane is stabilized
	 * for this interface. The call also needs to wait until the above
	 * mentioned actions are completed before returning to the caller.
	 * Notice that the hdd_stop_adapter is requested not to close the session
	 * That is intentional to be able to scan if it is a STA/P2P interface
	 */
	hdd_stop_adapter(hdd_ctx, adapter, false);

	/* DeInit the adapter. This ensures datapath cleanup as well */
	hdd_deinit_adapter(hdd_ctx, adapter, true);

	EXIT();
	return 0;
}

/**
 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
 * @dev: pointer to net_device structure
 *
 * This is called in response to ifconfig down
 *
 * Return: 0 for success and error number for failure
 */
int hdd_stop(struct net_device *dev)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __hdd_stop(dev);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __hdd_uninit() - HDD uninit function
 * @dev:	Pointer to net_device structure
 *
 * This is called during the netdev unregister to uninitialize all data
 * associated with the device
 *
 * Return: None
 */
static void __hdd_uninit(struct net_device *dev)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);

	ENTER();

	do {
		if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
			hddLog(LOGP, FL("Invalid magic"));
			break;
		}

		if (NULL == adapter->pHddCtx) {
			hddLog(LOGP, FL("NULL hdd_ctx"));
			break;
		}

		if (dev != adapter->dev) {
			hddLog(LOGP, FL("Invalid device reference"));
			/*
			 * we haven't validated all cases so let this go for
			 * now
			 */
		}

		hdd_deinit_adapter(adapter->pHddCtx, adapter, true);

		/* after uninit our adapter structure will no longer be valid */
		adapter->dev = NULL;
		adapter->magic = 0;
	} while (0);

	EXIT();
}

/**
 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
 * @dev: pointer to net_device structure
 *
 * This is called during the netdev unregister to uninitialize all data
 * associated with the device
 *
 * Return: none
 */
static void hdd_uninit(struct net_device *dev)
{
	cds_ssr_protect(__func__);
	__hdd_uninit(dev);
	cds_ssr_unprotect(__func__);
}

/**
 * __hdd_set_mac_address() - set the user specified mac address
 * @dev:	Pointer to the net device.
 * @addr:	Pointer to the sockaddr.
 *
 * This function sets the user specified mac address using
 * the command ifconfig wlanX hw ether <mac adress>.
 *
 * Return: 0 for success, non zero for failure
 */
static int __hdd_set_mac_address(struct net_device *dev, void *addr)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	hdd_context_t *hdd_ctx;
	struct sockaddr *psta_mac_addr = addr;
	QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
	int ret;

	ENTER();

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	memcpy(&adapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
	memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);

	EXIT();
	return cdf_ret_status;
}

/**
 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
 *			function from SSR
 * @dev: pointer to net_device structure
 * @addr: Pointer to the sockaddr
 *
 * This function sets the user specified mac address using
 * the command ifconfig wlanX hw ether <mac adress>.
 *
 * Return: 0 for success.
 */
static int hdd_set_mac_address(struct net_device *dev, void *addr)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __hdd_set_mac_address(dev, addr);
	cds_ssr_unprotect(__func__);

	return ret;
}

uint8_t *wlan_hdd_get_intf_addr(hdd_context_t *hdd_ctx)
{
	int i;
	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
		if (0 == ((hdd_ctx->config->intfAddrMask) & (1 << i)))
			break;
	}

	if (QDF_MAX_CONCURRENCY_PERSONA == i)
		return NULL;

	hdd_ctx->config->intfAddrMask |= (1 << i);
	return &hdd_ctx->config->intfMacAddr[i].bytes[0];
}

void wlan_hdd_release_intf_addr(hdd_context_t *hdd_ctx, uint8_t *releaseAddr)
{
	int i;
	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
		if (!memcmp(releaseAddr,
			    &hdd_ctx->config->intfMacAddr[i].bytes[0],
			    6)) {
			hdd_ctx->config->intfAddrMask &= ~(1 << i);
			break;
		}
	}
	return;
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
/**
 * __hdd_set_multicast_list() - set the multicast address list
 * @dev:	Pointer to the WLAN device.
 * @skb:	Pointer to OS packet (sk_buff).
 *
 * This funciton sets the multicast address list.
 *
 * Return: None
 */
static void __hdd_set_multicast_list(struct net_device *dev)
{
	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	int mc_count;
	int i = 0, status;
	struct netdev_hw_addr *ha;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	static const uint8_t ipv6_router_solicitation[]
			= {0x33, 0x33, 0x00, 0x00, 0x00, 0x02};

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		return;

	ENTER();

	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status)
		return;

	if (dev->flags & IFF_ALLMULTI) {
		hddLog(CDF_TRACE_LEVEL_INFO,
		       FL("allow all multicast frames"));
		adapter->mc_addr_list.mc_cnt = 0;
	} else {
		mc_count = netdev_mc_count(dev);
		hddLog(CDF_TRACE_LEVEL_INFO,
		       FL("mc_count = %u"), mc_count);
		if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST) {
			hddLog(CDF_TRACE_LEVEL_INFO,
			       FL(
				  "No free filter available; allow all multicast frames"
				 ));
			adapter->mc_addr_list.mc_cnt = 0;
			return;
		}

		adapter->mc_addr_list.mc_cnt = mc_count;

		netdev_for_each_mc_addr(ha, dev) {
			if (i == mc_count)
				break;
			/*
			 * Skip following addresses:
			 * 1)IPv6 router solicitation address
			 * 2)Any other address pattern if its set during
			 *  RXFILTER REMOVE driver command based on
			 *  addr_filter_pattern
			 */
			if ((!memcmp(ha->addr, ipv6_router_solicitation,
			   ETH_ALEN)) ||
			   (adapter->addr_filter_pattern && (!memcmp(ha->addr,
			    &adapter->addr_filter_pattern, 1)))) {
				hdd_info("MC/BC filtering Skip addr ="MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(ha->addr));
				adapter->mc_addr_list.mc_cnt--;
				continue;
			}

			memset(&(adapter->mc_addr_list.addr[i][0]), 0,
			       ETH_ALEN);
			memcpy(&(adapter->mc_addr_list.addr[i][0]), ha->addr,
			       ETH_ALEN);
			hddLog(CDF_TRACE_LEVEL_INFO,
			       FL("mlist[%d] = " MAC_ADDRESS_STR), i,
			       MAC_ADDR_ARRAY(adapter->mc_addr_list.addr[i]));
			i++;
		}
	}
	if (hdd_ctx->config->active_mode_offload) {
		hdd_info("enable mc filtering");
		wlan_hdd_set_mc_addr_list(adapter, true);
	} else {
		hdd_info("skip mc filtering enable it during cfg80211 suspend");
	}
	EXIT();
	return;
}

/**
 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
 * @dev: pointer to net_device
 *
 * Return: none
 */
static void hdd_set_multicast_list(struct net_device *dev)
{
	cds_ssr_protect(__func__);
	__hdd_set_multicast_list(dev);
	cds_ssr_unprotect(__func__);
}
#endif

/**
 * hdd_select_queue() - used by Linux OS to decide which queue to use first
 * @dev:	Pointer to the WLAN device.
 * @skb:	Pointer to OS packet (sk_buff).
 *
 * This function is registered with the Linux OS for network
 * core to decide which queue to use first.
 *
 * Return: ac, Queue Index/access category corresponding to UP in IP header
 */
static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
			  , void *accel_priv
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
			  , select_queue_fallback_t fallback
#endif
)
{
	return hdd_wmm_select_queue(dev, skb);
}

static struct net_device_ops wlan_drv_ops = {
	.ndo_open = hdd_open,
	.ndo_stop = hdd_stop,
	.ndo_uninit = hdd_uninit,
	.ndo_start_xmit = hdd_hard_start_xmit,
	.ndo_tx_timeout = hdd_tx_timeout,
	.ndo_get_stats = hdd_get_stats,
	.ndo_do_ioctl = hdd_ioctl,
	.ndo_set_mac_address = hdd_set_mac_address,
	.ndo_select_queue = hdd_select_queue,
#ifdef WLAN_FEATURE_PACKET_FILTERING
	.ndo_set_rx_mode = hdd_set_multicast_list,
#endif
};

void hdd_set_station_ops(struct net_device *pWlanDev)
{
	pWlanDev->netdev_ops = &wlan_drv_ops;
}

static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
						tSirMacAddr macAddr,
						const char *name)
{
	struct net_device *pWlanDev = NULL;
	hdd_adapter_t *adapter = NULL;
	/*
	 * cfg80211 initialization and registration....
	 */
	pWlanDev =
		alloc_netdev_mq(sizeof(hdd_adapter_t), name,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
				NET_NAME_UNKNOWN,
#endif
				ether_setup,
				NUM_TX_QUEUES);

	if (pWlanDev != NULL) {

		/* Save the pointer to the net_device in the HDD adapter */
		adapter = (hdd_adapter_t *) netdev_priv(pWlanDev);

		cdf_mem_zero(adapter, sizeof(hdd_adapter_t));

		adapter->dev = pWlanDev;
		adapter->pHddCtx = hdd_ctx;
		adapter->magic = WLAN_HDD_ADAPTER_MAGIC;

		init_completion(&adapter->session_open_comp_var);
		init_completion(&adapter->session_close_comp_var);
		init_completion(&adapter->disconnect_comp_var);
		init_completion(&adapter->linkup_event_var);
		init_completion(&adapter->cancel_rem_on_chan_var);
		init_completion(&adapter->rem_on_chan_ready_event);
		init_completion(&adapter->sta_authorized_event);
		init_completion(&adapter->offchannel_tx_event);
		init_completion(&adapter->tx_action_cnf_event);
#ifdef FEATURE_WLAN_TDLS
		init_completion(&adapter->tdls_add_station_comp);
		init_completion(&adapter->tdls_del_station_comp);
		init_completion(&adapter->tdls_mgmt_comp);
		init_completion(&adapter->tdls_link_establish_req_comp);
#endif
		init_completion(&adapter->change_country_code);


		init_completion(&adapter->scan_info.abortscan_event_var);

		adapter->offloads_configured = false;
		adapter->isLinkUpSvcNeeded = false;
		adapter->higherDtimTransition = true;
		/* Init the net_device structure */
		strlcpy(pWlanDev->name, name, IFNAMSIZ);

		cdf_mem_copy(pWlanDev->dev_addr, (void *)macAddr,
			     sizeof(tSirMacAddr));
		cdf_mem_copy(adapter->macAddressCurrent.bytes, macAddr,
			     sizeof(tSirMacAddr));
		pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;

		if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
			pWlanDev->features |=
				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
		pWlanDev->features |= NETIF_F_RXCSUM;

		hdd_set_tso_flags(hdd_ctx, pWlanDev);

		hdd_set_station_ops(adapter->dev);

		pWlanDev->destructor = free_netdev;
		pWlanDev->ieee80211_ptr = &adapter->wdev;
		pWlanDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
		adapter->wdev.wiphy = hdd_ctx->wiphy;
		adapter->wdev.netdev = pWlanDev;
		/* set pWlanDev's parent to underlying device */
		SET_NETDEV_DEV(pWlanDev, hdd_ctx->parent_dev);
		hdd_wmm_init(adapter);
		spin_lock_init(&adapter->pause_map_lock);
	}

	return adapter;
}

QDF_STATUS hdd_register_interface(hdd_adapter_t *adapter,
				  bool rtnl_held)
{
	struct net_device *pWlanDev = adapter->dev;
	/* hdd_station_ctx_t *pHddStaCtx = &adapter->sessionCtx.station; */
	/* hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX( adapter ); */
	/* QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS; */

	if (rtnl_held) {
		if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
			if (dev_alloc_name(pWlanDev, pWlanDev->name) < 0) {
				hddLog(CDF_TRACE_LEVEL_ERROR,
				       FL("Failed:dev_alloc_name"));
				return QDF_STATUS_E_FAILURE;
			}
		}
		if (register_netdevice(pWlanDev)) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("Failed:register_netdev"));
			return QDF_STATUS_E_FAILURE;
		}
	} else {
		if (register_netdev(pWlanDev)) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("Failed:register_netdev"));
			return QDF_STATUS_E_FAILURE;
		}
	}
	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);

	return QDF_STATUS_SUCCESS;
}

static QDF_STATUS hdd_sme_close_session_callback(void *pContext)
{
	hdd_adapter_t *adapter = pContext;

	if (NULL == adapter) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("NULL adapter"));
		return QDF_STATUS_E_INVAL;
	}

	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("Invalid magic"));
		return QDF_STATUS_NOT_INITIALIZED;
	}

	clear_bit(SME_SESSION_OPENED, &adapter->event_flags);

#if !defined (CONFIG_CNSS) && \
	!defined (WLAN_OPEN_SOURCE)
	/*
	 * need to make sure all of our scheduled work has completed.
	 * This callback is called from MC thread context, so it is safe to
	 * to call below flush workqueue API from here.
	 *
	 * Even though this is called from MC thread context, if there is a faulty
	 * work item in the system, that can hang this call forever.  So flushing
	 * this global work queue is not safe; and now we make sure that
	 * individual work queues are stopped correctly. But the cancel work queue
	 * is a GPL only API, so the proprietary  version of the driver would still
	 * rely on the global work queue flush.
	 */
	flush_scheduled_work();
#endif

	/*
	 * We can be blocked while waiting for scheduled work to be
	 * flushed, and the adapter structure can potentially be freed, in
	 * which case the magic will have been reset.  So make sure the
	 * magic is still good, and hence the adapter structure is still
	 * valid, before signaling completion
	 */
	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
		complete(&adapter->session_close_comp_var);

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
{
	struct net_device *pWlanDev = adapter->dev;
	hdd_station_ctx_t *pHddStaCtx = &adapter->sessionCtx.station;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	uint32_t type, subType;
	unsigned long rc;
	int ret_val;

	INIT_COMPLETION(adapter->session_open_comp_var);
	sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
	status = cds_get_vdev_types(adapter->device_mode, &type, &subType);
	if (QDF_STATUS_SUCCESS != status) {
		hddLog(LOGE, FL("failed to get vdev type"));
		goto error_sme_open;
	}
	/* Open a SME session for future operation */
	cdf_ret_status =
		sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback, adapter,
				 (uint8_t *) &adapter->macAddressCurrent,
				 &adapter->sessionId, type, subType);
	if (!QDF_IS_STATUS_SUCCESS(cdf_ret_status)) {
		hddLog(LOGP,
		       FL("sme_open_session() failed, status code %08d [x%08x]"),
		       cdf_ret_status, cdf_ret_status);
		status = QDF_STATUS_E_FAILURE;
		goto error_sme_open;
	}
	/* Block on a completion variable. Can't wait forever though. */
	rc = wait_for_completion_timeout(
		&adapter->session_open_comp_var,
		msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
	if (!rc) {
		hddLog(LOGP,
			FL("Session is not opened within timeout period code %ld"),
			rc);
		status = QDF_STATUS_E_FAILURE;
		goto error_sme_open;
	}

	/* Register wireless extensions */
	cdf_ret_status = hdd_register_wext(pWlanDev);
	if (QDF_STATUS_SUCCESS != cdf_ret_status) {
		hddLog(LOGP,
		       FL("hdd_register_wext() failed, status code %08d [x%08x]"),
		       cdf_ret_status, cdf_ret_status);
		status = QDF_STATUS_E_FAILURE;
		goto error_register_wext;
	}
	/* Set the Connection State to Not Connected */
	hddLog(LOG1,
	       FL("Set HDD connState to eConnectionState_NotConnected"));
	pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;

	/* Set the default operation channel */
	pHddStaCtx->conn_info.operationChannel =
		hdd_ctx->config->OperatingChannel;

	/* Make the default Auth Type as OPEN */
	pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;

	status = hdd_init_tx_rx(adapter);
	if (QDF_STATUS_SUCCESS != status) {
		hddLog(LOGP,
		       FL("hdd_init_tx_rx() failed, status code %08d [x%08x]"),
		       status, status);
		goto error_init_txrx;
	}

	set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);

	status = hdd_wmm_adapter_init(adapter);
	if (QDF_STATUS_SUCCESS != status) {
		hddLog(LOGP,
		       FL("hdd_wmm_adapter_init() failed, status code %08d [x%08x]"),
		       status, status);
		goto error_wmm_init;
	}

	set_bit(WMM_INIT_DONE, &adapter->event_flags);

	ret_val = wma_cli_set_command(adapter->sessionId,
				      WMI_PDEV_PARAM_BURST_ENABLE,
				      hdd_ctx->config->enableSifsBurst,
				      PDEV_CMD);

	if (0 != ret_val) {
		hddLog(LOGE,
		       FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
		       ret_val);
	}
#ifdef FEATURE_WLAN_TDLS
	if (0 != wlan_hdd_tdls_init(adapter)) {
		status = QDF_STATUS_E_FAILURE;
		hddLog(LOGE, FL("wlan_hdd_tdls_init failed"));
		goto error_tdls_init;
	}
	set_bit(TDLS_INIT_DONE, &adapter->event_flags);
#endif

	return QDF_STATUS_SUCCESS;

#ifdef FEATURE_WLAN_TDLS
error_tdls_init:
	clear_bit(WMM_INIT_DONE, &adapter->event_flags);
	hdd_wmm_adapter_close(adapter);
#endif
error_wmm_init:
	clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
	hdd_deinit_tx_rx(adapter);
error_init_txrx:
	hdd_unregister_wext(pWlanDev);
error_register_wext:
	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
		INIT_COMPLETION(adapter->session_close_comp_var);
		if (QDF_STATUS_SUCCESS == sme_close_session(hdd_ctx->hHal,
							    adapter->sessionId,
							    hdd_sme_close_session_callback,
							    adapter)) {
			unsigned long rc;

			/*
			 * Block on a completion variable.
			 * Can't wait forever though.
			 */
			rc = wait_for_completion_timeout(
				&adapter->session_close_comp_var,
				msecs_to_jiffies
					(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
			if (rc <= 0)
				hddLog(LOGE,
				       FL("Session is not opened within timeout period code %ld"),
				       rc);
		}
	}
error_sme_open:
	return status;
}

void hdd_cleanup_actionframe(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
{
	hdd_cfg80211_state_t *cfgState;

	cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);

	if (NULL != cfgState->buf) {
		unsigned long rc;
		rc = wait_for_completion_timeout(
			&adapter->tx_action_cnf_event,
			msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
		if (!rc) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("HDD Wait for Action Confirmation Failed!!"));
			/*
			 * Inform tx status as FAILURE to upper layer and free
			 * cfgState->buf
			 */
			 hdd_send_action_cnf(adapter, false);
		}
	}
	return;
}

void hdd_deinit_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
			bool rtnl_held)
{
	ENTER();
	switch (adapter->device_mode) {
	case WLAN_HDD_INFRA_STATION:
	case WLAN_HDD_P2P_CLIENT:
	case WLAN_HDD_P2P_DEVICE:
	{
		if (test_bit
			    (INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
			hdd_deinit_tx_rx(adapter);
			clear_bit(INIT_TX_RX_SUCCESS,
				  &adapter->event_flags);
		}

		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
			hdd_wmm_adapter_close(adapter);
			clear_bit(WMM_INIT_DONE,
				  &adapter->event_flags);
		}

		hdd_cleanup_actionframe(hdd_ctx, adapter);
		wlan_hdd_tdls_exit(adapter);
		break;
	}

	case WLAN_HDD_SOFTAP:
	case WLAN_HDD_P2P_GO:
	{

		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
			hdd_wmm_adapter_close(adapter);
			clear_bit(WMM_INIT_DONE,
				  &adapter->event_flags);
		}

		hdd_cleanup_actionframe(hdd_ctx, adapter);

		hdd_unregister_hostapd(adapter, rtnl_held);

		break;
	}

	default:
		break;
	}

	EXIT();
}

void hdd_cleanup_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
			 bool rtnl_held)
{
	struct net_device *pWlanDev = NULL;

	if (adapter)
		pWlanDev = adapter->dev;
	else {
		hddLog(LOGE, FL("adapter is Null"));
		return;
	}

	hdd_lro_disable(hdd_ctx, adapter);
	/*
	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
	 * the driver is almost closed and cannot handle either control
	 * messages or data. However, unregister_netdevice() call above will
	 * eventually invoke hdd_stop (ndo_close) driver callback, which attempts
	 * to close the active connections (basically excites control path) which
	 * is not right. Setting this flag helps hdd_stop() to recognize that
	 * the interface is closed and restricts any operations on that
	 */
	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);

	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
		if (rtnl_held) {
			unregister_netdevice(pWlanDev);
		} else {
			unregister_netdev(pWlanDev);
		}
		/*
		 * Note that the adapter is no longer valid at this point
		 * since the memory has been reclaimed
		 */
	}
}

QDF_STATUS hdd_check_for_existing_macaddr(hdd_context_t *hdd_ctx,
					  tSirMacAddr macAddr)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS status;
	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		if (adapter
		    && cdf_mem_compare(adapter->macAddressCurrent.bytes,
				       macAddr, sizeof(tSirMacAddr))) {
			return QDF_STATUS_E_FAILURE;
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}
	return QDF_STATUS_SUCCESS;
}
hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
				const char *iface_name, tSirMacAddr macAddr,
				bool rtnl_held)
{
	hdd_adapter_t *adapter = NULL;
	hdd_adapter_list_node_t *pHddAdapterNode = NULL;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	hdd_cfg80211_state_t *cfgState;
	int ret;

	hddLog(LOG2, FL("iface(%s) type(%d)"), iface_name, session_type);

	if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
		/*
		 * Max limit reached on the number of vdevs configured by the
		 * host. Return error
		 */
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d"
			 ),
		       hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
		return NULL;
	}

	if (macAddr == NULL) {
		/* Not received valid macAddr */
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "Unable to add virtual intf: Not able to get valid mac address"
			 ));
		return NULL;
	}
	status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
	if (QDF_STATUS_E_FAILURE == status) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       "Duplicate MAC addr: " MAC_ADDRESS_STR
		       " already exists",
		       MAC_ADDR_ARRAY(macAddr));
		return NULL;
	}

	switch (session_type) {
	case WLAN_HDD_INFRA_STATION:
		/* Reset locally administered bit if the device mode is STA */
		WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
	/* fall through */
	case WLAN_HDD_P2P_CLIENT:
	case WLAN_HDD_P2P_DEVICE:
	case WLAN_HDD_OCB:
	{
		adapter =
			hdd_alloc_station_adapter(hdd_ctx, macAddr, iface_name);

		if (NULL == adapter) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("failed to allocate adapter for session %d"),
			       session_type);
			return NULL;
		}

		if (WLAN_HDD_P2P_CLIENT == session_type)
			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
		else if (WLAN_HDD_P2P_DEVICE == session_type)
			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
		else
			adapter->wdev.iftype = NL80211_IFTYPE_STATION;

		adapter->device_mode = session_type;

		status = hdd_init_station_mode(adapter);
		if (QDF_STATUS_SUCCESS != status)
			goto err_free_netdev;

		hdd_lro_enable(hdd_ctx, adapter);

		/*
		 * Workqueue which gets scheduled in IPv4 notification
		 * callback
		 */
#ifdef CONFIG_CNSS
		cnss_init_work(&adapter->ipv4NotifierWorkQueue,
			       hdd_ipv4_notifier_work_queue);
#else
		INIT_WORK(&adapter->ipv4NotifierWorkQueue,
			  hdd_ipv4_notifier_work_queue);
#endif

#ifdef WLAN_NS_OFFLOAD
		/*
		 * Workqueue which gets scheduled in IPv6
		 * notification callback.
		 */
#ifdef CONFIG_CNSS
		cnss_init_work(&adapter->ipv6NotifierWorkQueue,
			       hdd_ipv6_notifier_work_queue);
#else
		INIT_WORK(&adapter->ipv6NotifierWorkQueue,
			  hdd_ipv6_notifier_work_queue);
#endif
#endif
		status = hdd_register_interface(adapter, rtnl_held);
		if (QDF_STATUS_SUCCESS != status) {
			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
			goto err_lro_cleanup;
		}

		/* Stop the Interface TX queue. */
		hddLog(LOG1, FL("Disabling queues"));
		wlan_hdd_netif_queue_control(adapter,
					   WLAN_NETIF_TX_DISABLE_N_CARRIER,
					   WLAN_CONTROL_PATH);

		hdd_register_tx_flow_control(adapter,
				hdd_tx_resume_timer_expired_handler,
				hdd_tx_resume_cb);

		break;
	}

	case WLAN_HDD_P2P_GO:
	case WLAN_HDD_SOFTAP:
	{
		adapter =
			hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
					       (uint8_t *) iface_name);
		if (NULL == adapter) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("failed to allocate adapter for session %d"),
			       session_type);
			return NULL;
		}

		adapter->wdev.iftype =
			(session_type ==
			 WLAN_HDD_SOFTAP) ? NL80211_IFTYPE_AP :
			NL80211_IFTYPE_P2P_GO;
		adapter->device_mode = session_type;

		status = hdd_init_ap_mode(adapter);
		if (QDF_STATUS_SUCCESS != status)
			goto err_free_netdev;

		status = hdd_register_hostapd(adapter, rtnl_held);
		if (QDF_STATUS_SUCCESS != status) {
			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
			goto err_free_netdev;
		}

		hddLog(LOG1, FL("Disabling queues"));
		wlan_hdd_netif_queue_control(adapter,
					   WLAN_NETIF_TX_DISABLE_N_CARRIER,
					   WLAN_CONTROL_PATH);

		break;
	}
	case WLAN_HDD_FTM:
	{
		adapter =
			hdd_alloc_station_adapter(hdd_ctx, macAddr, iface_name);

		if (NULL == adapter) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("failed to allocate adapter for session %d"),
			       session_type);
			return NULL;
		}

		/*
		 * Assign NL80211_IFTYPE_STATION as interface type to resolve
		 * Kernel Warning message while loading driver in FTM mode.
		 */
		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
		adapter->device_mode = session_type;
		status = hdd_register_interface(adapter, rtnl_held);

		hdd_init_tx_rx(adapter);

		/* Stop the Interface TX queue. */
		hddLog(LOG1, FL("Disabling queues"));
		wlan_hdd_netif_queue_control(adapter,
					   WLAN_NETIF_TX_DISABLE_N_CARRIER,
					   WLAN_CONTROL_PATH);
	}
	break;
	default:
	{
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Invalid session type %d"),
		       session_type);
		CDF_ASSERT(0);
		return NULL;
	}
	}

	cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter);
	mutex_init(&cfgState->remain_on_chan_ctx_lock);

	if (QDF_STATUS_SUCCESS == status) {
		/* Add it to the hdd's session list. */
		pHddAdapterNode =
			cdf_mem_malloc(sizeof(hdd_adapter_list_node_t));
		if (NULL == pHddAdapterNode) {
			status = QDF_STATUS_E_NOMEM;
		} else {
			pHddAdapterNode->pAdapter = adapter;
			status = hdd_add_adapter_back(hdd_ctx, pHddAdapterNode);
		}
	}

	if (QDF_STATUS_SUCCESS != status) {
		if (NULL != adapter) {
			hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
			adapter = NULL;
		}
		if (NULL != pHddAdapterNode) {
			cdf_mem_free(pHddAdapterNode);
		}
		return NULL;
	}

	if (QDF_STATUS_SUCCESS == status) {
		cds_set_concurrency_mode(session_type);

		/* Initialize the WoWL service */
		if (!hdd_init_wowl(adapter)) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL("hdd_init_wowl failed"));
			goto err_lro_cleanup;
		}

		/* Adapter successfully added. Increment the vdev count */
		hdd_ctx->current_intf_count++;

		hddLog(CDF_TRACE_LEVEL_DEBUG, FL("current_intf_count=%d"),
		       hdd_ctx->current_intf_count);

		cds_check_and_restart_sap_with_non_dfs_acs();
	}

	if ((cds_get_conparam() != QDF_GLOBAL_FTM_MODE)
	    && (!hdd_ctx->config->enable2x2)) {
#define HDD_DTIM_1CHAIN_RX_ID 0x5
#define HDD_SMPS_PARAM_VALUE_S 29

		/*
		 * Disable DTIM 1 chain Rx when in 1x1, we are passing two value
		 * as param_id << 29 | param_value.
		 * Below param_value = 0(disable)
		 */
		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_STA_SMPS_PARAM_CMDID,
					  HDD_DTIM_1CHAIN_RX_ID <<
						HDD_SMPS_PARAM_VALUE_S,
					  VDEV_CMD);

		if (ret != 0) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("DTIM 1 chain set failed %d"), ret);
			goto err_lro_cleanup;
		}

		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_PDEV_PARAM_TX_CHAIN_MASK,
					  hdd_ctx->config->txchainmask1x1,
					  PDEV_CMD);
		if (ret != 0) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("WMI_PDEV_PARAM_TX_CHAIN_MASK set failed %d"),
			       ret);
			goto err_lro_cleanup;
		}
		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_PDEV_PARAM_RX_CHAIN_MASK,
					  hdd_ctx->config->rxchainmask1x1,
					  PDEV_CMD);
		if (ret != 0) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("WMI_PDEV_PARAM_RX_CHAIN_MASK set failed %d"),
			       ret);
			goto err_lro_cleanup;
		}
#undef HDD_DTIM_1CHAIN_RX_ID
#undef HDD_SMPS_PARAM_VALUE_S
	}

	if (QDF_GLOBAL_FTM_MODE != cds_get_conparam()) {
		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_PDEV_PARAM_HYST_EN,
					  hdd_ctx->config->enableMemDeepSleep,
					  PDEV_CMD);

		if (ret != 0) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("WMI_PDEV_PARAM_HYST_EN set failed %d"),
			       ret);
			goto err_lro_cleanup;
		}
	}

#ifdef CONFIG_FW_LOGS_BASED_ON_INI

	/* Enable FW logs based on INI configuration */
	if ((QDF_GLOBAL_FTM_MODE != cds_get_conparam()) &&
	    (hdd_ctx->config->enable_fw_log)) {
		uint8_t count = 0;
		uint32_t value = 0;
		uint8_t numEntries = 0;
		uint8_t moduleLoglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];

		hdd_ctx->fw_log_settings.dl_type =
					hdd_ctx->config->enableFwLogType;
		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_DBGLOG_TYPE,
					  hdd_ctx->config->enableFwLogType,
					  DBG_CMD);
		if (ret != 0) {
			hddLog(LOGE, FL("Failed to enable FW log type ret %d"),
			       ret);
		}

		hdd_ctx->fw_log_settings.dl_loglevel =
					hdd_ctx->config->enableFwLogLevel;
		ret = wma_cli_set_command(adapter->sessionId,
					  WMI_DBGLOG_LOG_LEVEL,
					  hdd_ctx->config->enableFwLogLevel,
					  DBG_CMD);
		if (ret != 0) {
			hddLog(LOGE, FL("Failed to enable FW log level ret %d"),
			       ret);
		}

		hdd_string_to_u8_array(hdd_ctx->config->enableFwModuleLogLevel,
				       moduleLoglevel,
				       &numEntries,
				       FW_MODULE_LOG_LEVEL_STRING_LENGTH);
		while (count < numEntries) {
			/*
			 * FW module log level input string looks like below:
			 * gFwDebugModuleLoglevel=<FW Module ID>,<Log Level>,...
			 * For example:
			 * gFwDebugModuleLoglevel=1,0,2,1,3,2,4,3,5,4,6,5,7,6
			 * Above input string means :
			 * For FW module ID 1 enable log level 0
			 * For FW module ID 2 enable log level 1
			 * For FW module ID 3 enable log level 2
			 * For FW module ID 4 enable log level 3
			 * For FW module ID 5 enable log level 4
			 * For FW module ID 6 enable log level 5
			 * For FW module ID 7 enable log level 6
			 */

			/* FW expects WMI command value =
			 *               Module ID * 10 + Module Log level
			 */
			value =	((moduleLoglevel[count] * 10) +
				 moduleLoglevel[count + 1]);
			ret = wma_cli_set_command(adapter->sessionId,
						  WMI_DBGLOG_MOD_LOG_LEVEL,
						  value, DBG_CMD);
			if (ret != 0) {
				hddLog(LOGE,
				       FL
					       ("Failed to enable FW module log level %d ret %d"),
				       value, ret);
			}

			count += 2;
		}
	}
#endif

	return adapter;

err_lro_cleanup:
	hdd_lro_disable(hdd_ctx, adapter);
err_free_netdev:
	free_netdev(adapter->dev);
	wlan_hdd_release_intf_addr(hdd_ctx, adapter->macAddressCurrent.bytes);

	return NULL;
}

QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
			     bool rtnl_held)
{
	hdd_adapter_list_node_t *adapterNode, *pCurrent, *pNext;
	QDF_STATUS status;

	status = hdd_get_front_adapter(hdd_ctx, &pCurrent);
	if (QDF_STATUS_SUCCESS != status) {
		hddLog(CDF_TRACE_LEVEL_WARN, FL("adapter list empty %d"),
		       status);
		return status;
	}

	while (pCurrent->pAdapter != adapter) {
		status = hdd_get_next_adapter(hdd_ctx, pCurrent, &pNext);
		if (QDF_STATUS_SUCCESS != status)
			break;

		pCurrent = pNext;
	}
	adapterNode = pCurrent;
	if (QDF_STATUS_SUCCESS == status) {
		cds_clear_concurrency_mode(adapter->device_mode);
		hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held);

		hdd_remove_adapter(hdd_ctx, adapterNode);
		cdf_mem_free(adapterNode);
		adapterNode = NULL;

		/* Adapter removed. Decrement vdev count */
		if (hdd_ctx->current_intf_count != 0)
			hdd_ctx->current_intf_count--;

		/* Fw will take care incase of concurrency */
		return QDF_STATUS_SUCCESS;
	}
	return QDF_STATUS_E_FAILURE;
}

/**
 * hdd_close_all_adapters - Close all open adapters
 * @hdd_ctx:	Hdd context
 * rtnl_held:	True if RTNL lock held
 *
 * Close all open adapters.
 *
 * Return: CDF status code
 */
QDF_STATUS hdd_close_all_adapters(hdd_context_t *hdd_ctx, bool rtnl_held)
{
	hdd_adapter_list_node_t *pHddAdapterNode;
	QDF_STATUS status;

	ENTER();

	do {
		status = hdd_remove_front_adapter(hdd_ctx, &pHddAdapterNode);
		if (pHddAdapterNode && QDF_STATUS_SUCCESS == status) {
			hdd_cleanup_adapter(hdd_ctx, pHddAdapterNode->pAdapter,
					    rtnl_held);
			cdf_mem_free(pHddAdapterNode);
		}
	} while (NULL != pHddAdapterNode && QDF_STATUS_E_EMPTY != status);

	EXIT();

	return QDF_STATUS_SUCCESS;
}

void wlan_hdd_reset_prob_rspies(hdd_adapter_t *pHostapdAdapter)
{
	struct qdf_mac_addr *bssid = NULL;
	tSirUpdateIE updateIE;
	switch (pHostapdAdapter->device_mode) {
	case WLAN_HDD_INFRA_STATION:
	case WLAN_HDD_P2P_CLIENT:
	{
		hdd_station_ctx_t *pHddStaCtx =
			WLAN_HDD_GET_STATION_CTX_PTR(pHostapdAdapter);
		bssid = &pHddStaCtx->conn_info.bssId;
		break;
	}
	case WLAN_HDD_SOFTAP:
	case WLAN_HDD_P2P_GO:
	case WLAN_HDD_IBSS:
	{
		bssid = &pHostapdAdapter->macAddressCurrent;
		break;
	}
	case WLAN_HDD_FTM:
	case WLAN_HDD_P2P_DEVICE:
	default:
		/*
		 * wlan_hdd_reset_prob_rspies should not have been called
		 * for these kind of devices
		 */
		hddLog(LOGE,
		       FL("Unexpected request for the current device type %d"),
		       pHostapdAdapter->device_mode);
		return;
	}

	cdf_copy_macaddr(&updateIE.bssid, bssid);
	updateIE.smeSessionId = pHostapdAdapter->sessionId;
	updateIE.ieBufferlength = 0;
	updateIE.pAdditionIEBuffer = NULL;
	updateIE.append = true;
	updateIE.notify = false;
	if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
			      &updateIE,
			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
		hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
	}
}

QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
			    const bool bCloseSession)
{
	QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
	hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
	union iwreq_data wrqu;
	tSirUpdateIE updateIE;
	unsigned long rc;

	ENTER();

	hddLog(LOG1, FL("Disabling queues"));
	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
				   WLAN_CONTROL_PATH);
	switch (adapter->device_mode) {
	case WLAN_HDD_INFRA_STATION:
	case WLAN_HDD_P2P_CLIENT:
	case WLAN_HDD_IBSS:
	case WLAN_HDD_P2P_DEVICE:
		if (hdd_conn_is_connected(
				WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
			hdd_is_connecting(
				WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
			if (pWextState->roamProfile.BSSType ==
			    eCSR_BSS_TYPE_START_IBSS)
				cdf_ret_status =
					sme_roam_disconnect(hdd_ctx->hHal,
							    adapter->sessionId,
							    eCSR_DISCONNECT_REASON_IBSS_LEAVE);
			else
				cdf_ret_status =
					sme_roam_disconnect(hdd_ctx->hHal,
							    adapter->sessionId,
							    eCSR_DISCONNECT_REASON_UNSPECIFIED);
			/* success implies disconnect command got queued up successfully */
			if (cdf_ret_status == QDF_STATUS_SUCCESS) {
				rc = wait_for_completion_timeout(
					&adapter->disconnect_comp_var,
					msecs_to_jiffies
						(WLAN_WAIT_TIME_DISCONNECT));
				if (!rc) {
					hddLog(CDF_TRACE_LEVEL_ERROR,
					       FL(
						  "wait on disconnect_comp_var failed"
						 ));
				}
			} else {
				hddLog(LOGE,
				       FL(
					  "failed to post disconnect event to SME"
					 ));
			}
			memset(&wrqu, '\0', sizeof(wrqu));
			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
			memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
			wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
					    NULL);
		} else {
			hdd_abort_mac_scan(hdd_ctx, adapter->sessionId,
					   eCSR_SCAN_ABORT_DEFAULT);
		}
		wlan_hdd_cleanup_remain_on_channel_ctx(adapter);

#ifdef WLAN_OPEN_SOURCE
		cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
#endif

		hdd_deregister_tx_flow_control(adapter);

#ifdef WLAN_NS_OFFLOAD
#ifdef WLAN_OPEN_SOURCE
		cancel_work_sync(&adapter->ipv6NotifierWorkQueue);
#endif
#endif

		/*
		 * It is possible that the caller of this function does not
		 * wish to close the session
		 */
		if (true == bCloseSession &&
		    test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
			INIT_COMPLETION(adapter->session_close_comp_var);
			if (QDF_STATUS_SUCCESS ==
			    sme_close_session(hdd_ctx->hHal, adapter->sessionId,
					      hdd_sme_close_session_callback,
					      adapter)) {
				/*
				 * Block on a completion variable. Can't wait
				 * forever though.
				 */
				rc = wait_for_completion_timeout(
					&adapter->session_close_comp_var,
					msecs_to_jiffies
						(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
				if (!rc) {
					hddLog(LOGE,
					       FL(
						  "failure waiting for session_close_comp_var"
						 ));
				}
			}
		}
		break;

	case WLAN_HDD_SOFTAP:
	case WLAN_HDD_P2P_GO:
		if (hdd_ctx->config->conc_custom_rule1 &&
			(WLAN_HDD_SOFTAP == adapter->device_mode)) {
			/*
			 * Before stopping the sap adapter, lets make sure there
			 * is no sap restart work pending.
			 */
			cds_flush_work(&hdd_ctx->sap_start_work);
			hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
			       FL("Canceled the pending SAP restart work"));
			cds_change_sap_restart_required_status(false);
		}
		/* Any softap specific cleanup here... */
		if (adapter->device_mode == WLAN_HDD_P2P_GO)
			wlan_hdd_cleanup_remain_on_channel_ctx(adapter);

		hdd_deregister_tx_flow_control(adapter);

		mutex_lock(&hdd_ctx->sap_lock);
		if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
			QDF_STATUS status;
			QDF_STATUS qdf_status;

			/* Stop Bss. */
#ifdef WLAN_FEATURE_MBSSID
			status = wlansap_stop_bss(
					WLAN_HDD_GET_SAP_CTX_PTR(adapter));
#else
			status = wlansap_stop_bss(
				(WLAN_HDD_GET_CTX(adapter))->pcds_context);
#endif

			if (QDF_IS_STATUS_SUCCESS(status)) {
				hdd_hostapd_state_t *hostapd_state =
					WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
				qdf_event_reset(&hostapd_state->
						cdf_stop_bss_event);
				qdf_status =
					qdf_wait_single_event(&hostapd_state->
							cdf_stop_bss_event,
							BSS_WAIT_TIMEOUT);

				if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
					hddLog(LOGE,
					       FL(
						  "failure waiting for wlansap_stop_bss %d"
						 ),
					       qdf_status);
				}
			} else {
				hddLog(LOGE, FL("failure in wlansap_stop_bss"));
			}
			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
			cds_decr_session_set_pcl(
						     adapter->device_mode,
							adapter->sessionId);

			cdf_copy_macaddr(&updateIE.bssid,
					 &adapter->macAddressCurrent);
			updateIE.smeSessionId = adapter->sessionId;
			updateIE.ieBufferlength = 0;
			updateIE.pAdditionIEBuffer = NULL;
			updateIE.append = false;
			updateIE.notify = false;
			/* Probe bcn reset */
			if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
					      &updateIE, eUPDATE_IE_PROBE_BCN)
			    == QDF_STATUS_E_FAILURE) {
				hddLog(LOGE,
				       FL(
					  "Could not pass on PROBE_RSP_BCN data to PE"
					 ));
			}
			/* Assoc resp reset */
			if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
					      &updateIE,
					      eUPDATE_IE_ASSOC_RESP) ==
			    QDF_STATUS_E_FAILURE) {
				hddLog(LOGE,
				       FL(
					  "Could not pass on ASSOC_RSP data to PE"
					 ));
			}
			/* Reset WNI_CFG_PROBE_RSP Flags */
			wlan_hdd_reset_prob_rspies(adapter);
			kfree(adapter->sessionCtx.ap.beacon);
			adapter->sessionCtx.ap.beacon = NULL;
		}
		mutex_unlock(&hdd_ctx->sap_lock);
		break;
	case WLAN_HDD_OCB:
		ol_txrx_clear_peer(WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
			conn_info.staId[0]);
		break;
	default:
		break;
	}

	EXIT();
	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_stop_all_adapters(hdd_context_t *hdd_ctx)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;

	ENTER();

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		hdd_stop_adapter(hdd_ctx, adapter, true);
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;

	ENTER();

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		hddLog(LOG1, FL("Disabling queues"));
		wlan_hdd_netif_queue_control(adapter,
					   WLAN_NETIF_TX_DISABLE_N_CARRIER,
					   WLAN_CONTROL_PATH);

		adapter->sessionCtx.station.hdd_ReassocScenario = false;

		hdd_deinit_tx_rx(adapter);
		cds_decr_session_set_pcl(adapter->device_mode,
						adapter->sessionId);
		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
			hdd_wmm_adapter_close(adapter);
			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
		}

		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;
#ifndef MSM_PLATFORM
	struct qdf_mac_addr bcastMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
#endif
	eConnectionState connState;

	ENTER();

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;

		hdd_wmm_init(adapter);

		switch (adapter->device_mode) {
		case WLAN_HDD_INFRA_STATION:
		case WLAN_HDD_P2P_CLIENT:
		case WLAN_HDD_P2P_DEVICE:

			connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
					->conn_info.connState;

			hdd_init_station_mode(adapter);
			/* Open the gates for HDD to receive Wext commands */
			adapter->isLinkUpSvcNeeded = false;
			adapter->scan_info.mScanPending = false;

			/* Indicate disconnect event to supplicant if associated previously */
			if (eConnectionState_Associated == connState ||
			    eConnectionState_IbssConnected == connState ||
			    eConnectionState_NotConnected == connState ||
			    eConnectionState_IbssDisconnected == connState ||
			    eConnectionState_Disconnecting == connState) {
				union iwreq_data wrqu;
				memset(&wrqu, '\0', sizeof(wrqu));
				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
				wireless_send_event(adapter->dev, SIOCGIWAP,
						    &wrqu, NULL);
				adapter->sessionCtx.station.
				hdd_ReassocScenario = false;

				/* indicate disconnected event to nl80211 */
				cfg80211_disconnected(adapter->dev,
						      WLAN_REASON_UNSPECIFIED,
						      NULL, 0, GFP_KERNEL);
			} else if (eConnectionState_Connecting == connState) {
				/*
				 * Indicate connect failure to supplicant if we were in the
				 * process of connecting
				 */
				cfg80211_connect_result(adapter->dev, NULL,
							NULL, 0, NULL, 0,
							WLAN_STATUS_ASSOC_DENIED_UNSPEC,
							GFP_KERNEL);
			}

			hdd_register_tx_flow_control(adapter,
					hdd_tx_resume_timer_expired_handler,
					hdd_tx_resume_cb);

			break;

		case WLAN_HDD_SOFTAP:
			/* softAP can handle SSR */
			break;

		case WLAN_HDD_P2P_GO:
#ifdef MSM_PLATFORM
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("[SSR] send stop ap to supplicant"));
			cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
#else
			hddLog(CDF_TRACE_LEVEL_ERROR,
			       FL("[SSR] send restart supplicant"));
			/* event supplicant to restart */
			cfg80211_del_sta(adapter->dev,
					 (const u8 *)&bcastMac.bytes[0],
					 GFP_KERNEL);
#endif
			break;

		default:
			break;
		}

		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_get_front_adapter(hdd_context_t *hdd_ctx,
				 hdd_adapter_list_node_t **padapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_peek_front(&hdd_ctx->hddAdapters,
				     (qdf_list_node_t **) padapterNode);
	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

QDF_STATUS hdd_get_next_adapter(hdd_context_t *hdd_ctx,
				hdd_adapter_list_node_t *adapterNode,
				hdd_adapter_list_node_t **pNextAdapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_peek_next(&hdd_ctx->hddAdapters,
				    (qdf_list_node_t *) adapterNode,
				    (qdf_list_node_t **) pNextAdapterNode);

	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

QDF_STATUS hdd_remove_adapter(hdd_context_t *hdd_ctx,
			      hdd_adapter_list_node_t *adapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_remove_node(&hdd_ctx->hddAdapters,
				      &adapterNode->node);
	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

QDF_STATUS hdd_remove_front_adapter(hdd_context_t *hdd_ctx,
				    hdd_adapter_list_node_t **padapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_remove_front(&hdd_ctx->hddAdapters,
				       (qdf_list_node_t **) padapterNode);
	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

QDF_STATUS hdd_add_adapter_back(hdd_context_t *hdd_ctx,
				hdd_adapter_list_node_t *adapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_insert_back(&hdd_ctx->hddAdapters,
				      (qdf_list_node_t *) adapterNode);
	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

QDF_STATUS hdd_add_adapter_front(hdd_context_t *hdd_ctx,
				 hdd_adapter_list_node_t *adapterNode)
{
	QDF_STATUS status;
	cdf_spin_lock(&hdd_ctx->hdd_adapter_lock);
	status = qdf_list_insert_front(&hdd_ctx->hddAdapters,
				       (qdf_list_node_t *) adapterNode);
	cdf_spin_unlock(&hdd_ctx->hdd_adapter_lock);
	return status;
}

hdd_adapter_t *hdd_get_adapter_by_macaddr(hdd_context_t *hdd_ctx,
					  tSirMacAddr macAddr)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS status;

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;

		if (adapter
		    && cdf_mem_compare(adapter->macAddressCurrent.bytes,
				       macAddr, sizeof(tSirMacAddr))) {
			return adapter;
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	return NULL;

}

hdd_adapter_t *hdd_get_adapter_by_vdev(hdd_context_t *hdd_ctx,
				       uint32_t vdev_id)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS qdf_status;

	qdf_status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while ((NULL != adapterNode) && (QDF_STATUS_SUCCESS == qdf_status)) {
		adapter = adapterNode->pAdapter;

		if (adapter->sessionId == vdev_id)
			return adapter;

		qdf_status =
			hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	hddLog(CDF_TRACE_LEVEL_ERROR,
	       FL("vdev_id %d does not exist with host"), vdev_id);

	return NULL;
}

/**
 * hdd_get_adapter_by_sme_session_id() - Return adapter with
 * the sessionid
 * @hdd_ctx: hdd context.
 * @sme_session_id: sme session is for the adapter to get.
 *
 * This function is used to get the adapter with provided session id
 *
 * Return: adapter pointer if found
 *
 */
hdd_adapter_t *hdd_get_adapter_by_sme_session_id(hdd_context_t *hdd_ctx,
						uint32_t sme_session_id)
{
	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS qdf_status;


	qdf_status = hdd_get_front_adapter(hdd_ctx, &adapter_node);

	while ((NULL != adapter_node) &&
			(QDF_STATUS_SUCCESS == qdf_status)) {
		adapter = adapter_node->pAdapter;

		if (adapter &&
			 adapter->sessionId == sme_session_id)
			return adapter;

		qdf_status =
			hdd_get_next_adapter(hdd_ctx,
				 adapter_node, &next);
		adapter_node = next;
	}
	return NULL;
}

hdd_adapter_t *hdd_get_adapter(hdd_context_t *hdd_ctx, device_mode_t mode)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	hdd_adapter_t *adapter;
	QDF_STATUS status;

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;

		if (adapter && (mode == adapter->device_mode))
			return adapter;

		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	return NULL;

}

/**
 * hdd_get_operating_channel() - return operating channel of the device mode
 * @hdd_ctx:	Pointer to the HDD context.
 * @mode:	Device mode for which operating channel is required.
 *              Suported modes:
 *			WLAN_HDD_INFRA_STATION,
 *			WLAN_HDD_P2P_CLIENT,
 *			WLAN_HDD_SOFTAP,
 *			WLAN_HDD_P2P_GO.
 *
 * This API returns the operating channel of the requested device mode
 *
 * Return: channel number. "0" id the requested device is not found OR it is
 *	   not connected.
 */
uint8_t hdd_get_operating_channel(hdd_context_t *hdd_ctx, device_mode_t mode)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;
	uint8_t operatingChannel = 0;

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;

		if (mode == adapter->device_mode) {
			switch (adapter->device_mode) {
			case WLAN_HDD_INFRA_STATION:
			case WLAN_HDD_P2P_CLIENT:
				if (hdd_conn_is_connected
					    (WLAN_HDD_GET_STATION_CTX_PTR
						(adapter))) {
					operatingChannel =
						(WLAN_HDD_GET_STATION_CTX_PTR
						(adapter))->conn_info.
							operationChannel;
				}
				break;
			case WLAN_HDD_SOFTAP:
			case WLAN_HDD_P2P_GO:
				/* softap connection info */
				if (test_bit
					    (SOFTAP_BSS_STARTED,
					    &adapter->event_flags))
					operatingChannel =
						(WLAN_HDD_GET_AP_CTX_PTR
						(adapter))->operatingChannel;
				break;
			default:
				break;
			}

			break;  /* Found the device of interest. break the loop */
		}

		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}
	return operatingChannel;
}

static inline QDF_STATUS hdd_unregister_wext_all_adapters(hdd_context_t *
							  hdd_ctx)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;

	ENTER();

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		if ((adapter->device_mode == WLAN_HDD_INFRA_STATION) ||
		    (adapter->device_mode == WLAN_HDD_P2P_CLIENT) ||
		    (adapter->device_mode == WLAN_HDD_IBSS) ||
		    (adapter->device_mode == WLAN_HDD_P2P_DEVICE) ||
		    (adapter->device_mode == WLAN_HDD_SOFTAP) ||
		    (adapter->device_mode == WLAN_HDD_P2P_GO)) {
			wlan_hdd_cfg80211_deregister_frames(adapter);
			hdd_unregister_wext(adapter->dev);
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;

	ENTER();

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		if ((adapter->device_mode == WLAN_HDD_INFRA_STATION) ||
		    (adapter->device_mode == WLAN_HDD_P2P_CLIENT) ||
		    (adapter->device_mode == WLAN_HDD_IBSS) ||
		    (adapter->device_mode == WLAN_HDD_P2P_DEVICE) ||
		    (adapter->device_mode == WLAN_HDD_SOFTAP) ||
		    (adapter->device_mode == WLAN_HDD_P2P_GO)) {
			hdd_abort_mac_scan(hdd_ctx, adapter->sessionId,
					   eCSR_SCAN_ABORT_DEFAULT);
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

#ifdef WLAN_NS_OFFLOAD
/**
 * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: None
 */
static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
{
	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);

	return;
}

/**
 * hdd_wlan_register_ip6_notifier() - register IP6 change notifier
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: None
 */
static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
{
	int ret;

	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
	if (ret)
		hddLog(LOGE, FL("Failed to register IPv6 notifier"));
	else
		hdd_info("Registered IPv6 notifier");

	return;
}
#else
/**
 * hdd_wlan_unregister_ip6_notifier() - unregister IP6 change notifier
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: None
 */
static void hdd_wlan_unregister_ip6_notifier(hdd_context_t *hdd_ctx)
{
}
/**
 * hdd_wlan_register_ip6_notifier() - register IP6 change notifier
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: None
 */
static void hdd_wlan_register_ip6_notifier(hdd_context_t *hdd_ctx)
{
}
#endif

#ifdef QCA_WIFI_FTM
/**
 * hdd_disable_ftm() - Disable FTM mode
 * @hdd_ctx:	HDD context
 *
 * Helper function to disable FTM mode.
 *
 * Return: None.
 */
static void hdd_disable_ftm(hdd_context_t *hdd_ctx)
{
	hdd_notice("Disabling FTM mode");

	if (hdd_ftm_stop(hdd_ctx)) {
		hdd_alert("hdd_ftm_stop Failed!");
		CDF_ASSERT(0);
	}

	hdd_ctx->ftm.ftm_state = WLAN_FTM_STOPPED;

	wlan_hdd_ftm_close(hdd_ctx);

	return;
}

/**
 * hdd_enable_ftm() - Enable FTM mode
 * @hdd_ctx:	HDD context
 *
 * Helper function to enable FTM mode.
 *
 * Return: 0 on success and errno on failure.
 */
int hdd_enable_ftm(hdd_context_t *hdd_ctx)
{
	int ret;

	ret = wlan_hdd_ftm_open(hdd_ctx);
	if (ret) {
		hdd_alert("wlan_hdd_ftm_open Failed: %d", ret);
		goto err_out;
	}

	ret = hdd_ftm_start(hdd_ctx);

	if (ret) {
		hdd_alert("hdd_ftm_start Failed: %d", ret);
		goto err_ftm_close;
	}

	ret = wiphy_register(hdd_ctx->wiphy);
	if (ret) {
		hdd_alert("wiphy register failed: %d", ret);
		goto err_ftm_stop;
	}

	hdd_err("FTM driver loaded");

	return 0;

err_ftm_stop:
	hdd_ftm_stop(hdd_ctx);
err_ftm_close:
	wlan_hdd_ftm_close(hdd_ctx);
err_out:
	return ret;

}
#else
int hdd_enable_ftm(hdd_context_t *hdd_ctx)
{
	hdd_err("Driver built without FTM feature enabled!");

	return -ENOTSUPP;
}

static inline void hdd_disable_ftm(hdd_context_t *hdd_ctx) { }
#endif

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
/**
 * hdd_logging_sock_activate_svc() - Activate logging
 * @hdd_ctx: HDD context
 *
 * Activates the logging service
 *
 * Return: Zero in case of success, negative value otherwise
 */
static int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
{
	int ret;
	struct hdd_config *config = hdd_ctx->config;

	if (!config->wlanLoggingEnable)
		return 0;

	ret = wlan_logging_sock_activate_svc(config->wlanLoggingFEToConsole,
					     config->wlanLoggingNumBuf);
	if (ret)
		hdd_err("wlan_logging_sock_activate_svc failed: %d", ret);
	return ret;
}

/**
 * wlan_hdd_logging_sock_deactivate_svc() - Deactivate logging
 * @hdd_ctx: HDD context
 *
 * Deactivates the logging service
 *
 * Return: 0 on deactivating the logging service
 */
static int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
{
	if (hdd_ctx && hdd_ctx->config->wlanLoggingEnable)
		return wlan_logging_sock_deactivate_svc();

	return 0;
}
#else
static inline int hdd_logging_sock_activate_svc(hdd_context_t *hdd_ctx)
{
	return 0;
}

static inline int hdd_logging_sock_deactivate_svc(hdd_context_t *hdd_ctx)
{
	return 0;
}
#endif

/**
 * hdd_free_context - Free HDD context
 * @hdd_ctx:	HDD context to be freed.
 *
 * Free config and HDD context.
 *
 * Return: None
 */
static void hdd_free_context(hdd_context_t *hdd_ctx)
{
	if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
		hdd_logging_sock_deactivate_svc(hdd_ctx);

	cdf_mem_free(hdd_ctx->config);
	hdd_ctx->config = NULL;

	wiphy_free(hdd_ctx->wiphy);
}

/**
 * hdd_wlan_exit() - HDD WLAN exit function
 * @hdd_ctx:	Pointer to the HDD Context
 *
 * This is the driver exit point (invoked during rmmod)
 *
 * Return: None
 */
void hdd_wlan_exit(hdd_context_t *hdd_ctx)
{
	v_CONTEXT_t p_cds_context = hdd_ctx->pcds_context;
	QDF_STATUS qdf_status;
	struct wiphy *wiphy = hdd_ctx->wiphy;

	ENTER();

	hddLog(LOGE, FL("Unregister IPv6 notifier"));
	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
	hddLog(LOGE, FL("Unregister IPv4 notifier"));
	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);

	hdd_unregister_wext_all_adapters(hdd_ctx);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_disable_ftm(hdd_ctx);

		hdd_alert("FTM driver unloaded");
		goto free_hdd_ctx;
	}

	/*
	 * Cancel any outstanding scan requests.  We are about to close all
	 * of our adapters, but an adapter structure is what SME passes back
	 * to our callback function.  Hence if there are any outstanding scan
	 * requests then there is a race condition between when the adapter
	 * is closed and when the callback is invoked.  We try to resolve that
	 * race condition here by canceling any outstanding scans before we
	 * close the adapters.
	 * Note that the scans may be cancelled in an asynchronous manner, so
	 * ideally there needs to be some kind of synchronization.  Rather than
	 * introduce a new synchronization here, we will utilize the fact that
	 * we are about to Request Full Power, and since that is synchronized,
	 * the expectation is that by the time Request Full Power has completed,
	 * all scans will be cancelled
	 */
	hdd_abort_mac_scan_all_adapters(hdd_ctx);

#ifdef MSM_PLATFORM
	if (CDF_TIMER_STATE_RUNNING ==
	    cdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) {
		cdf_mc_timer_stop(&hdd_ctx->bus_bw_timer);
	}

	if (!QDF_IS_STATUS_SUCCESS
		    (cdf_mc_timer_destroy(&hdd_ctx->bus_bw_timer))) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("Cannot deallocate Bus bandwidth timer"));
	}
#endif

#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
	if (CDF_TIMER_STATE_RUNNING ==
	    cdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
		cdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
	}

	if (!QDF_IS_STATUS_SUCCESS
		    (cdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("Cannot deallocate ACS Skip timer"));
	}
#endif
	if (CDF_TIMER_STATE_RUNNING ==
		cdf_mc_timer_get_current_state(
			&hdd_ctx->dbs_opportunistic_timer)) {
		cdf_mc_timer_stop(&hdd_ctx->dbs_opportunistic_timer);
	}

	if (!QDF_IS_STATUS_SUCCESS
			(cdf_mc_timer_destroy(
				&hdd_ctx->dbs_opportunistic_timer))) {
		hdd_err("Cannot deallocate dbs opportunistic timer");
	}

	/*
	 * Powersave Offload Case
	 * Disable Idle Power Save Mode
	 */
	hdd_set_idle_ps_config(hdd_ctx, false);

	hdd_debugfs_exit(hdd_ctx);

	/* Unregister the Net Device Notifier */
	unregister_netdevice_notifier(&hdd_netdev_notifier);

	/*
	 * Stop all adapters, this will ensure the termination of active
	 * connections on the interface. Make sure the cds_scheduler is
	 * still available to handle those control messages
	 */
	hdd_stop_all_adapters(hdd_ctx);

	/* Stop all the modules */
	qdf_status = cds_disable(p_cds_context);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Failed to stop CDS"));
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}

	/*
	 * Close the scheduler before calling cds_close to make sure no thread
	 * is scheduled after the each module close is called i.e after all the
	 * data structures are freed.
	 */
	qdf_status = cds_sched_close(p_cds_context);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Failed to close CDS Scheduler"));
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
	}
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
	/* Destroy the wake lock */
	cdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
#endif
	/* Destroy the wake lock */
	cdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);

	hdd_hostapd_channel_wakelock_deinit(hdd_ctx);

	/*
	 * Close CDS
	 * This frees pMac(HAL) context. There should not be any call
	 * that requires pMac access after this.
	 */
	cds_close(p_cds_context);

	hdd_wlan_green_ap_deinit(hdd_ctx);

#ifdef WLAN_KD_READY_NOTIFIER
	cnss_diag_notify_wlan_close();
	ptt_sock_deactivate_svc();
#endif /* WLAN_KD_READY_NOTIFIER */
	nl_srv_exit();

	hdd_close_all_adapters(hdd_ctx, false);

	hdd_ipa_cleanup(hdd_ctx);

	/* Free up RoC request queue and flush workqueue */
	cds_flush_work(&hdd_ctx->roc_req_work);
	qdf_list_destroy(&hdd_ctx->hdd_roc_req_q);
	qdf_list_destroy(&hdd_ctx->hdd_scan_req_q);

	if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
		hdd_err("Failed to deinit policy manager");
		/* Proceed and complete the clean up */
	}

free_hdd_ctx:

	wiphy_unregister(wiphy);

	hdd_free_context(hdd_ctx);
}

void __hdd_wlan_exit(void)
{
	hdd_context_t *hdd_ctx;

	ENTER();

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("Invalid HDD Context"));
		EXIT();
		return;
	}

	/* Check IPA HW Pipe shutdown */
	hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);

#ifdef WLAN_FEATURE_LPSS
	wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
#endif

	memdump_deinit();

#ifdef QCA_PKT_PROTO_TRACE
	cds_pkt_proto_trace_close();
#endif
	/* Do all the cleanup before deregistering the driver */
	hdd_wlan_exit(hdd_ctx);
	EXIT();
}

#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
void hdd_skip_acs_scan_timer_handler(void *data)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *) data;

	hddLog(LOG1, FL("ACS Scan result expired. Reset ACS scan skip"));
	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;

	if (!hdd_ctx->hHal)
		return;
	sme_scan_flush_result(hdd_ctx->hHal);
}
#endif

#ifdef QCA_HT_2040_COEX
/**
 * hdd_wlan_set_ht2040_mode() - notify FW with HT20/HT40 mode
 * @adapter: pointer to adapter
 * @staId: station id
 * @macAddrSTA: station MAC address
 * @channel_type: channel type
 *
 * This function notifies FW with HT20/HT40 mode
 *
 * Return: 0 if successful, error number otherwise
 */
int hdd_wlan_set_ht2040_mode(hdd_adapter_t *adapter, uint16_t staId,
			     struct qdf_mac_addr macAddrSTA, int channel_type)
{
	int status;
	QDF_STATUS qdf_status;
	hdd_context_t *hdd_ctx = NULL;

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return status;
	}
	if (!hdd_ctx->hHal)
		return -EINVAL;

	qdf_status = sme_notify_ht2040_mode(hdd_ctx->hHal, staId, macAddrSTA,
					    adapter->sessionId, channel_type);
	if (QDF_STATUS_SUCCESS != qdf_status) {
		hddLog(LOGE, "Fail to send notification with ht2040 mode");
		return -EINVAL;
	}

	return 0;
}
#endif

/**
 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
 * @state: state
 *
 * This function notifies FW with modem power status
 *
 * Return: 0 if successful, error number otherwise
 */
int hdd_wlan_notify_modem_power_state(int state)
{
	int status;
	QDF_STATUS qdf_status;
	hdd_context_t *hdd_ctx;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (0 != status) {
		hddLog(LOGE, FL("HDD context is not valid"));
		return status;
	}
	if (!hdd_ctx->hHal)
		return -EINVAL;

	qdf_status = sme_notify_modem_power_state(hdd_ctx->hHal, state);
	if (QDF_STATUS_SUCCESS != qdf_status) {
		hddLog(LOGE,
		       "Fail to send notification with modem power state %d",
		       state);
		return -EINVAL;
	}
	return 0;
}

/**
 *
 * hdd_post_cds_enable_config() - HDD post cds start config helper
 * @adapter - Pointer to the HDD
 *
 * Return: None
 */
QDF_STATUS hdd_post_cds_enable_config(hdd_context_t *hdd_ctx)
{
	QDF_STATUS cdf_ret_status;

	/*
	 * Send ready indication to the HDD.  This will kick off the MAC
	 * into a 'running' state and should kick off an initial scan.
	 */
	cdf_ret_status = sme_hdd_ready_ind(hdd_ctx->hHal);
	if (!QDF_IS_STATUS_SUCCESS(cdf_ret_status)) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL(
			  "sme_hdd_ready_ind() failed with status code %08d [x%08x]"
			 ),
		       cdf_ret_status, cdf_ret_status);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

/* wake lock APIs for HDD */
void hdd_prevent_suspend(uint32_t reason)
{
	cdf_wake_lock_acquire(&wlan_wake_lock, reason);
}

void hdd_allow_suspend(uint32_t reason)
{
	cdf_wake_lock_release(&wlan_wake_lock, reason);
}

void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
{
	cdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout, reason);
}

/**
 * hdd_exchange_version_and_caps() - exchange version and capability with target
 * @hdd_ctx:	Pointer to HDD context
 *
 * This is the HDD function to exchange version and capability information
 * between Host and Target
 *
 * This function gets reported version of FW.
 * It also finds the version of target headers used to compile the host;
 * It compares the above two and prints a warning if they are different;
 * It gets the SW and HW version string;
 * Finally, it exchanges capabilities between host and target i.e. host
 * and target exchange a msg indicating the features they support through a
 * bitmap
 *
 * Return: None
 */
void hdd_exchange_version_and_caps(hdd_context_t *hdd_ctx)
{

	tSirVersionType versionCompiled;
	tSirVersionType versionReported;
	tSirVersionString versionString;
	uint8_t fwFeatCapsMsgSupported = 0;
	QDF_STATUS vstatus;

	memset(&versionCompiled, 0, sizeof(versionCompiled));
	memset(&versionReported, 0, sizeof(versionReported));

	/* retrieve and display WCNSS version information */
	do {

		vstatus = sme_get_wcnss_wlan_compiled_version(hdd_ctx->hHal,
							      &versionCompiled);
		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL(
				  "unable to retrieve WCNSS WLAN compiled version"
				 ));
			break;
		}

		vstatus = sme_get_wcnss_wlan_reported_version(hdd_ctx->hHal,
							      &versionReported);
		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL(
				  "unable to retrieve WCNSS WLAN reported version"
				 ));
			break;
		}

		if ((versionCompiled.major != versionReported.major) ||
		    (versionCompiled.minor != versionReported.minor) ||
		    (versionCompiled.version != versionReported.version) ||
		    (versionCompiled.revision != versionReported.revision)) {
			pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
			       "Host expected %u.%u.%u.%u\n",
			       WLAN_MODULE_NAME,
			       (int)versionReported.major,
			       (int)versionReported.minor,
			       (int)versionReported.version,
			       (int)versionReported.revision,
			       (int)versionCompiled.major,
			       (int)versionCompiled.minor,
			       (int)versionCompiled.version,
			       (int)versionCompiled.revision);
		} else {
			pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
				WLAN_MODULE_NAME,
				(int)versionReported.major,
				(int)versionReported.minor,
				(int)versionReported.version,
				(int)versionReported.revision);
		}

		vstatus = sme_get_wcnss_software_version(hdd_ctx->hHal,
							 versionString,
							 sizeof(versionString));
		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL(
				  "unable to retrieve WCNSS software version string"
				 ));
			break;
		}

		pr_info("%s: WCNSS software version %s\n",
			WLAN_MODULE_NAME, versionString);

		vstatus = sme_get_wcnss_hardware_version(hdd_ctx->hHal,
							 versionString,
							 sizeof(versionString));
		if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
			hddLog(CDF_TRACE_LEVEL_FATAL,
			       FL(
				  "unable to retrieve WCNSS hardware version string"
				 ));
			break;
		}

		pr_info("%s: WCNSS hardware version %s\n",
			WLAN_MODULE_NAME, versionString);

		/*
		 * 1.Check if FW version is greater than 0.1.1.0. Only then
		 * send host-FW capability exchange message
		 * 2.Host-FW capability exchange message  is only present on
		 * target 1.1 so send the message only if it the target is 1.1
		 * minor numbers for different target branches:
		 * 0 -> (1.0)Mainline Build
		 * 1 -> (1.1)Mainline Build
		 * 2->(1.04) Stability Build
		 */
		if (((versionReported.major > 0) || (versionReported.minor > 1)
		     || ((versionReported.minor >= 1)
			 && (versionReported.version >= 1)))
		    && ((versionReported.major == 1)
			&& (versionReported.minor >= 1)))
			fwFeatCapsMsgSupported = 1;

		if (fwFeatCapsMsgSupported) {
			/*
			 * Indicate if IBSS heartbeat monitoring needs to be
			 * offloaded
			 */
			if (!hdd_ctx->config->enableIbssHeartBeatOffload) {
				sme_disable_feature_capablity
					(IBSS_HEARTBEAT_OFFLOAD);
			}

			sme_feature_caps_exchange(hdd_ctx->hHal);
		}

	} while (0);

}

/* Initialize channel list in sme based on the country code */
QDF_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx)
{
	return sme_init_chan_list(hdd_ctx->hHal, hdd_ctx->reg.alpha2,
				  hdd_ctx->reg.cc_src);
}

/**
 * hdd_is_5g_supported() - check if hardware supports 5GHz
 * @hdd_ctx:	Pointer to the hdd context
 *
 * HDD function to know if hardware supports 5GHz
 *
 * Return:  true if hardware supports 5GHz
 */
bool hdd_is_5g_supported(hdd_context_t *hdd_ctx)
{
	/*
	 * If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
	 * then hardware support 5Ghz.
	 */
	return true;
}

static QDF_STATUS wlan_hdd_regulatory_init(hdd_context_t *hdd_ctx)
{
	struct wiphy *wiphy;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	wiphy = hdd_ctx->wiphy;

	/*
	 * The channel information in
	 * wiphy needs to be initialized before wiphy registration
	 */
	status = cds_regulatory_init();
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("cds_init_wiphy failed"));
		return status;
	}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
	wiphy->wowlan = &wowlan_support_reg_init;
#else
	wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
			      WIPHY_WOWLAN_MAGIC_PKT |
			      WIPHY_WOWLAN_DISCONNECT |
			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
			      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
			      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
			      WIPHY_WOWLAN_4WAY_HANDSHAKE |
			      WIPHY_WOWLAN_RFKILL_RELEASE;

	wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
				    WOW_MAX_FILTERS_PER_LIST);
	wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
	wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
#endif

	/* registration of wiphy dev with cfg80211 */
	if (0 > wlan_hdd_cfg80211_register(wiphy)) {
		hddLog(CDF_TRACE_LEVEL_ERROR, FL("wiphy register failed"));
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}

#ifdef MSM_PLATFORM
void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx,
			const uint64_t tx_packets, const uint64_t rx_packets)
{
#ifdef CONFIG_CNSS
	uint64_t total = tx_packets + rx_packets;
	uint64_t temp_rx = 0;
	uint64_t temp_tx = 0;
	enum cnss_bus_width_type next_vote_level = CNSS_BUS_WIDTH_NONE;
	enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;


	if (total > hdd_ctx->config->busBandwidthHighThreshold)
		next_vote_level = CNSS_BUS_WIDTH_HIGH;
	else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
		next_vote_level = CNSS_BUS_WIDTH_MEDIUM;
	else if (total > hdd_ctx->config->busBandwidthLowThreshold)
		next_vote_level = CNSS_BUS_WIDTH_LOW;
	else
		next_vote_level = CNSS_BUS_WIDTH_NONE;

	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level =
							next_vote_level;

	if (hdd_ctx->cur_vote_level != next_vote_level) {
		hddLog(CDF_TRACE_LEVEL_DEBUG,
		       FL(
			  "trigger level %d, tx_packets: %lld, rx_packets: %lld"
			 ),
		       next_vote_level, tx_packets, rx_packets);
		hdd_ctx->cur_vote_level = next_vote_level;
		cnss_request_bus_bandwidth(next_vote_level);
	}

	/* fine-tuning parameters for RX Flows */
	temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;

	hdd_ctx->prev_rx = rx_packets;
	if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh)
		next_rx_level = WLAN_SVC_TP_HIGH;
	else
		next_rx_level = WLAN_SVC_TP_LOW;

	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level =
								next_rx_level;

	if (hdd_ctx->cur_rx_level != next_rx_level) {
		hddLog(CDF_TRACE_LEVEL_DEBUG,
		       FL("TCP DELACK trigger level %d, average_rx: %llu"),
		       next_rx_level, temp_rx);
		hdd_ctx->cur_rx_level = next_rx_level;
		wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND,
					    &next_rx_level,
					    sizeof(next_rx_level));
	}

	/* fine-tuning parameters for TX Flows */
	temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
	hdd_ctx->prev_tx = tx_packets;
	if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
		next_tx_level = WLAN_SVC_TP_HIGH;
	else
		next_tx_level = WLAN_SVC_TP_LOW;

	 if (hdd_ctx->cur_tx_level != next_tx_level) {
		hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
				next_tx_level, temp_tx);
		hdd_ctx->cur_tx_level = next_tx_level;
		wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_TX_IND,
				&next_tx_level,
				sizeof(next_tx_level));
	}

	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_tx_level =
								next_tx_level;
	hdd_ctx->hdd_txrx_hist_idx++;
	hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
#endif
}

#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
static void hdd_bus_bw_compute_cbk(void *priv)
{
	hdd_context_t *hdd_ctx = (hdd_context_t *) priv;
	hdd_adapter_t *adapter = NULL;
	uint64_t tx_packets = 0, rx_packets = 0;
	uint64_t total_tx = 0, total_rx = 0;
	hdd_adapter_list_node_t *adapterNode = NULL;
	QDF_STATUS status = 0;
	bool connected = false;
	uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;

	for (status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
	     NULL != adapterNode && QDF_STATUS_SUCCESS == status;
	     status =
		     hdd_get_next_adapter(hdd_ctx, adapterNode, &adapterNode)) {

		if (adapterNode->pAdapter == NULL)
			continue;
		adapter = adapterNode->pAdapter;

		if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
		     adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
		    WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
		    != eConnectionState_Associated) {

			continue;
		}

		if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
		     adapter->device_mode == WLAN_HDD_P2P_GO) &&
		    WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive == false) {

			continue;
		}

		tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
					      adapter->prev_tx_packets);
		rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
					      adapter->prev_rx_packets);

		total_rx += adapter->stats.rx_packets;
		total_tx += adapter->stats.tx_packets;

		spin_lock_bh(&hdd_ctx->bus_bw_lock);
		adapter->prev_tx_packets = adapter->stats.tx_packets;
		adapter->prev_rx_packets = adapter->stats.rx_packets;
		spin_unlock_bh(&hdd_ctx->bus_bw_lock);
		connected = true;
	}

	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_rx = total_rx;
	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_tx = total_tx;
	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_rx =
								rx_packets;
	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_tx =
								tx_packets;

	hdd_ipa_uc_stat_query(hdd_ctx, &ipa_tx_packets, &ipa_rx_packets);
	tx_packets += (uint64_t)ipa_tx_packets;
	rx_packets += (uint64_t)ipa_rx_packets;

	if (!connected) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("bus bandwidth timer running in disconnected state"));
		return;
	}

	hdd_cnss_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);

	hdd_ipa_set_perf_level(hdd_ctx, tx_packets, rx_packets);
	hdd_ipa_uc_stat_request(adapter, 2);

	cdf_mc_timer_start(&hdd_ctx->bus_bw_timer,
			   hdd_ctx->config->busBandwidthComputeInterval);
}
#endif

/**
 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
 * @hdd_ctx: hdd context
 *
 * Return: none
 */
void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx)
{
	int i;

#ifdef MSM_PLATFORM
	hddLog(CDF_TRACE_LEVEL_ERROR, "BW Interval: %d curr_index %d",
		hdd_ctx->config->busBandwidthComputeInterval,
		hdd_ctx->hdd_txrx_hist_idx);
	hddLog(CDF_TRACE_LEVEL_ERROR,
		"BW High TH: %d BW Med TH: %d BW Low TH: %d",
		hdd_ctx->config->busBandwidthHighThreshold,
		hdd_ctx->config->busBandwidthMediumThreshold,
		hdd_ctx->config->busBandwidthLowThreshold);
	hddLog(CDF_TRACE_LEVEL_ERROR, "TCP DEL High TH: %d TCP DEL Low TH: %d",
		hdd_ctx->config->tcpDelackThresholdHigh,
		hdd_ctx->config->tcpDelackThresholdLow);
#endif

	hddLog(CDF_TRACE_LEVEL_ERROR,
		"index, total_rx, interval_rx, total_tx, interval_tx, next_vote_level, next_rx_level, next_tx_level");

	for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
			"%d: %llu, %llu, %llu, %llu, %d, %d, %d",
			i, hdd_ctx->hdd_txrx_hist[i].total_rx,
			hdd_ctx->hdd_txrx_hist[i].interval_rx,
			hdd_ctx->hdd_txrx_hist[i].total_tx,
			hdd_ctx->hdd_txrx_hist[i].interval_tx,
			hdd_ctx->hdd_txrx_hist[i].next_vote_level,
			hdd_ctx->hdd_txrx_hist[i].next_rx_level,
			hdd_ctx->hdd_txrx_hist[i].next_tx_level);
	}
	return;
}

/**
 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
 * @hdd_ctx: hdd context
 *
 * Return: none
 */
void wlan_hdd_clear_tx_rx_histogram(hdd_context_t *hdd_ctx)
{
	hdd_ctx->hdd_txrx_hist_idx = 0;
	cdf_mem_zero(hdd_ctx->hdd_txrx_hist, sizeof(hdd_ctx->hdd_txrx_hist));
}

/**
 * wlan_hdd_display_netif_queue_history() - display netif queue operation history
 * @pHddCtx: hdd context
 *
 * Return: none
 */
void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx)
{

	hdd_adapter_t *adapter = NULL;
	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
	QDF_STATUS status;
	int i;

	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
		adapter = adapter_node->pAdapter;

		hddLog(CDF_TRACE_LEVEL_ERROR,
			"Session_id %d device mode %d current index %d",
			adapter->sessionId, adapter->device_mode,
			adapter->history_index);

		hddLog(CDF_TRACE_LEVEL_ERROR,
			"Netif queue operation statistics:");
		hddLog(CDF_TRACE_LEVEL_ERROR,
			"Current pause_map value %x", adapter->pause_map);
		hddLog(CDF_TRACE_LEVEL_ERROR,
			"  reason_type: pause_cnt: unpause_cnt");

		for (i = 0; i < WLAN_REASON_TYPE_MAX; i++) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
				"%s: %d: %d",
				hdd_reason_type_to_string(i),
				adapter->queue_oper_stats[i].pause_count,
				adapter->queue_oper_stats[i].unpause_count);
		}

		hddLog(CDF_TRACE_LEVEL_ERROR,
			"Netif queue operation history:");
		hddLog(CDF_TRACE_LEVEL_ERROR,
			"index: time: action_type: reason_type: pause_map");

		for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
			hddLog(CDF_TRACE_LEVEL_ERROR,
				"%d: %u: %s: %s: %x",
				i, qdf_system_ticks_to_msecs(
					adapter->queue_oper_history[i].time),
				hdd_action_type_to_string(
				adapter->queue_oper_history[i].netif_action),
				hdd_reason_type_to_string(
				adapter->queue_oper_history[i].netif_reason),
				adapter->queue_oper_history[i].pause_map);
		}

		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
		adapter_node = next;
	}


}

/**
 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
 * @hdd_ctx: hdd context
 *
 * Return: none
 */
void wlan_hdd_clear_netif_queue_history(hdd_context_t *hdd_ctx)
{
	hdd_adapter_t *adapter = NULL;
	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
	QDF_STATUS status;

	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
		adapter = adapter_node->pAdapter;

		cdf_mem_zero(adapter->queue_oper_stats,
					sizeof(adapter->queue_oper_stats));
		cdf_mem_zero(adapter->queue_oper_history,
					sizeof(adapter->queue_oper_history));

		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
		adapter_node = next;
	}
}

/**
 * hdd_11d_scan_done() - callback for 11d scan completion of flushing results
 * @halHandle:	Hal handle
 * @pContext:	Pointer to the context
 * @sessionId:	Session ID
 * @scanId:	Scan ID
 * @status:	Status
 *
 * This is the callback to be executed when 11d scan is completed to flush out
 * the scan results
 *
 * 11d scan is done during driver load and is a passive scan on all
 * channels supported by the device, 11d scans may find some APs on
 * frequencies which are forbidden to be used in the regulatory domain
 * the device is operating in. If these APs are notified to the supplicant
 * it may try to connect to these APs, thus flush out all the scan results
 * which are present in SME after 11d scan is done.
 *
 * Return:  QDF_STATUS_SUCCESS
 */
static QDF_STATUS hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
				    uint8_t sessionId, uint32_t scanId,
				    eCsrScanStatus status)
{
	ENTER();

	sme_scan_flush_result(halHandle);

	EXIT();

	return QDF_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
/**
 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
 * @hdd_ctx: hdd global context
 *
 * Return: none
 */
static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
{
	uint8_t i;

	mutex_init(&hdd_ctx->op_ctx.op_lock);
	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
	}
}
#else
static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
{
}
#endif

#ifdef WLAN_FEATURE_FASTPATH
/**
 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
 * @hdd_cfg: hdd config
 * @context: lower layer context
 *
 * Return: none
 */
static void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
				void *context)
{
	if (hdd_cfg->fastpath_enable)
		hif_enable_fastpath(context);
}
#else
static void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
				void *context)
{
}
#endif

#if defined(FEATURE_WLAN_CH_AVOID) && defined(CONFIG_CNSS)
/**
 * hdd_set_thermal_level_cb() - set thermal level callback function
 * @context:	hdd context pointer
 * @level:	thermal level
 *
 * Change IPA data path to SW path when the thermal throttle level greater
 * than 0, and restore the original data path when throttle level is 0
 *
 * Return: none
 */
static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
{
	hdd_context_t *hdd_ctx = context;

	/* Change IPA to SW path when throttle level greater than 0 */
	if (level > THROTTLE_LEVEL_0)
		hdd_ipa_send_mcc_scc_msg(hdd_ctx, true);
	else
		/* restore original concurrency mode */
		hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode);
}

/**
 * hdd_find_prefd_safe_chnl() - find safe channel within preferred channel
 * @hdd_ctxt:	hdd context pointer
 * @ap_adapter: hdd hostapd adapter pointer
 *
 * Try to find safe channel within preferred channel
 * In case auto channel selection enabled
 *  - Preferred and safe channel should be used
 *  - If no overlapping, preferred channel should be used
 *
 * Return: 1: found preferred safe channel
 *         0: could not found preferred safe channel
 */
static uint8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt,
					hdd_adapter_t *ap_adapter)
{
	uint16_t safe_channels[NUM_20MHZ_RF_CHANNELS];
	uint16_t safe_channel_count;
	uint16_t unsafe_channel_count;
	uint8_t is_unsafe = 1;
	uint16_t i;
	uint16_t channel_loop;

	if (!hdd_ctxt || !ap_adapter) {
		hdd_err("invalid context/adapter");
		return 0;
	}

	safe_channel_count = 0;
	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctxt->unsafe_channel_count,
				       (uint16_t)NUM_20MHZ_RF_CHANNELS);

	for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
		is_unsafe = 0;
		for (channel_loop = 0;
		     channel_loop < unsafe_channel_count; channel_loop++) {
			if (CDS_CHANNEL_NUM(i) ==
			    hdd_ctxt->unsafe_channel_list[channel_loop]) {
				is_unsafe = 1;
				break;
			}
		}
		if (!is_unsafe) {
			safe_channels[safe_channel_count] =
			  CDS_CHANNEL_NUM(i);
			hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
			       FL("safe channel %d"),
			       safe_channels[safe_channel_count]);
			safe_channel_count++;
		}
	}
	hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
	       FL("perferred range %d - %d"),
		ap_adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch,
		ap_adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch);
	for (i = 0; i < safe_channel_count; i++) {
		if (safe_channels[i] >=
			ap_adapter->sessionCtx.ap.sapConfig.acs_cfg.start_ch
		    && safe_channels[i] <=
			ap_adapter->sessionCtx.ap.sapConfig.acs_cfg.end_ch) {
			hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
			       FL("safe channel %d is in perferred range"),
			       safe_channels[i]);
			return 1;
		}
	}
	return 0;
}
/**
 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
 * user space
 * @frame_ind: Management frame data to be informed.
 *
 * This function is used to indicate management frame to
 * user space
 *
 * Return: None
 *
 */
void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
{
	hdd_context_t *hdd_ctx = NULL;
	hdd_adapter_t *adapter = NULL;
	void *cds_context = NULL;
	int i;

	/* Get the global VOSS context.*/
	cds_context = cds_get_global_context();
	if (!cds_context) {
		hddLog(LOGE, FL("Global VOS context is Null"));
		return;
	}
	/* Get the HDD context.*/
	hdd_ctx =
	  (hdd_context_t *)cds_get_context(QDF_MODULE_ID_HDD);

	if (0 != wlan_hdd_validate_context(hdd_ctx))
		return;

	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
			adapter =
				hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
			if (adapter)
				break;
		}
	} else {
		adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
					frame_ind->sessionId);
	}

	if ((NULL != adapter) &&
		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
		__hdd_indicate_mgmt_frame(adapter,
						frame_ind->frame_len,
						frame_ind->frameBuf,
						frame_ind->frameType,
						frame_ind->rxChan,
						frame_ind->rxRssi);
	return;
}

/**
 * hdd_ch_avoid_cb() - Avoid notified channels from FW handler
 * @adapter:	HDD adapter pointer
 * @indParam:	Channel avoid notification parameter
 *
 * Avoid channel notification from FW handler.
 * FW will send un-safe channel list to avoid over wrapping.
 * hostapd should not use notified channel
 *
 * Return: None
 */
static void hdd_ch_avoid_cb(void *hdd_context, void *indi_param)
{
	hdd_adapter_t *hostapd_adapter = NULL;
	hdd_context_t *hdd_ctxt;
	tSirChAvoidIndType *ch_avoid_indi;
	uint8_t range_loop;
	enum channel_enum channel_loop, start_channel_idx = INVALID_RF_CHANNEL,
					end_channel_idx = INVALID_RF_CHANNEL;
	uint16_t start_channel;
	uint16_t end_channel;
	v_CONTEXT_t cds_context;
	static int restart_sap_in_progress;
	tHddAvoidFreqList hdd_avoid_freq_list;
	uint32_t i;

	/* Basic sanity */
	if (!hdd_context || !indi_param) {
		hddLog(CDF_TRACE_LEVEL_ERROR, FL("Invalid arguments"));
		return;
	}

	hdd_ctxt = (hdd_context_t *) hdd_context;
	ch_avoid_indi = (tSirChAvoidIndType *) indi_param;
	cds_context = hdd_ctxt->pcds_context;

	/* Make unsafe channel list */
	hddLog(CDF_TRACE_LEVEL_INFO,
	       FL("band count %d"),
	       ch_avoid_indi->avoid_range_count);

	/* generate vendor specific event */
	cdf_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList));
	for (i = 0; i < ch_avoid_indi->avoid_range_count; i++) {
		hdd_avoid_freq_list.avoidFreqRange[i].startFreq =
			ch_avoid_indi->avoid_freq_range[i].start_freq;
		hdd_avoid_freq_list.avoidFreqRange[i].endFreq =
			ch_avoid_indi->avoid_freq_range[i].end_freq;
	}
	hdd_avoid_freq_list.avoidFreqRangeCount =
		ch_avoid_indi->avoid_range_count;

	wlan_hdd_send_avoid_freq_event(hdd_ctxt, &hdd_avoid_freq_list);

	/* clear existing unsafe channel cache */
	hdd_ctxt->unsafe_channel_count = 0;
	cdf_mem_zero(hdd_ctxt->unsafe_channel_list,
					sizeof(hdd_ctxt->unsafe_channel_list));

	for (range_loop = 0; range_loop < ch_avoid_indi->avoid_range_count;
								range_loop++) {
		if (hdd_ctxt->unsafe_channel_count >= NUM_20MHZ_RF_CHANNELS) {
			hddLog(LOGW, FL("LTE Coex unsafe channel list full"));
			break;
		}

		start_channel = ieee80211_frequency_to_channel(
			ch_avoid_indi->avoid_freq_range[range_loop].start_freq);
		end_channel   = ieee80211_frequency_to_channel(
			ch_avoid_indi->avoid_freq_range[range_loop].end_freq);
		hddLog(LOG1, "%s : start %d : %d, end %d : %d", __func__,
			ch_avoid_indi->avoid_freq_range[range_loop].start_freq,
			start_channel,
			ch_avoid_indi->avoid_freq_range[range_loop].end_freq,
			end_channel);

		/* do not process frequency bands that are not mapped to
		 * predefined channels
		 */
		if (start_channel == 0 || end_channel == 0)
			continue;

		for (channel_loop = MIN_20MHZ_RF_CHANNEL; channel_loop <=
					MAX_20MHZ_RF_CHANNEL; channel_loop++) {
			if (CDS_CHANNEL_FREQ(channel_loop) >=
						ch_avoid_indi->avoid_freq_range[
						range_loop].start_freq) {
				start_channel_idx = channel_loop;
				break;
			}
		}
		for (channel_loop = MIN_20MHZ_RF_CHANNEL; channel_loop <=
					MAX_20MHZ_RF_CHANNEL; channel_loop++) {
			if (CDS_CHANNEL_FREQ(channel_loop) >=
						ch_avoid_indi->avoid_freq_range[
						range_loop].end_freq) {
				end_channel_idx = channel_loop;
				if (CDS_CHANNEL_FREQ(channel_loop) >
						ch_avoid_indi->avoid_freq_range[
						range_loop].end_freq)
					end_channel_idx--;
				break;
			}
		}

		if (start_channel_idx == INVALID_RF_CHANNEL ||
					end_channel_idx == INVALID_RF_CHANNEL)
			continue;

		for (channel_loop = start_channel_idx; channel_loop <=
					end_channel_idx; channel_loop++) {
			hdd_ctxt->unsafe_channel_list[
				hdd_ctxt->unsafe_channel_count++] =
				CDS_CHANNEL_FREQ(channel_loop);
			if (hdd_ctxt->unsafe_channel_count >=
							NUM_20MHZ_RF_CHANNELS) {
				hddLog(LOGW, FL("LTECoex unsafe ch list full"));
				break;
			}
		}
	}

	hddLog(CDF_TRACE_LEVEL_INFO,
	       FL("number of unsafe channels is %d "),
	       hdd_ctxt->unsafe_channel_count);

	if (cnss_set_wlan_unsafe_channel(hdd_ctxt->unsafe_channel_list,
				hdd_ctxt->unsafe_channel_count)) {
		hdd_err("Failed to set unsafe channel");

		/* clear existing unsafe channel cache */
		hdd_ctxt->unsafe_channel_count = 0;
		cdf_mem_zero(hdd_ctxt->unsafe_channel_list,
			sizeof(hdd_ctxt->unsafe_channel_list));

		return;
	}

	for (channel_loop = 0;
	     channel_loop < hdd_ctxt->unsafe_channel_count; channel_loop++) {
		hddLog(CDF_TRACE_LEVEL_INFO,
		       FL("channel %d is not safe "),
		       hdd_ctxt->unsafe_channel_list[channel_loop]);
	}

	/*
	 * If auto channel select is enabled
	 * preferred channel is in safe channel,
	 * re-start softap interface with safe channel.
	 * no overlap with preferred channel and safe channel
	 * do not re-start softap interface
	 * stay current operating channel.
	 */
	if (hdd_ctxt->unsafe_channel_count) {
		hostapd_adapter = hdd_get_adapter(hdd_ctxt, WLAN_HDD_SOFTAP);
		if (hostapd_adapter) {
			if ((hostapd_adapter->sessionCtx.ap.sapConfig.
				acs_cfg.acs_mode) &&
				(!hdd_find_prefd_safe_chnl(hdd_ctxt,
				hostapd_adapter)))
				return;

			hddLog(CDF_TRACE_LEVEL_INFO,
			       FL(
				  "Current operation channel %d, sessionCtx.ap.sapConfig.channel %d"
				 ),
			       hostapd_adapter->sessionCtx.ap.
			       operatingChannel,
			       hostapd_adapter->sessionCtx.ap.sapConfig.
			       channel);
			for (channel_loop = 0;
			     channel_loop < hdd_ctxt->unsafe_channel_count;
			     channel_loop++) {
				if (((hdd_ctxt->
					unsafe_channel_list[channel_loop] ==
						hostapd_adapter->sessionCtx.ap.
						      operatingChannel)) &&
					(hostapd_adapter->sessionCtx.ap.
						sapConfig.acs_cfg.acs_mode
								 == true) &&
					!restart_sap_in_progress) {
					hddLog(CDF_TRACE_LEVEL_INFO,
					       FL("Restarting SAP"));
					wlan_hdd_send_svc_nlink_msg
						(WLAN_SVC_LTE_COEX_IND, NULL, 0);
					restart_sap_in_progress = 1;
					/*
					 * current operating channel is un-safe
					 * channel, restart driver
					 */
					hdd_hostapd_stop(hostapd_adapter->dev);
					break;
				}
			}
		}
	}
	return;
}

/**
 * hdd_init_channel_avoidance() - Initialize channel avoidance
 * @hdd_ctx:	HDD global context
 *
 * Initialize the channel avoidance logic by retrieving the unsafe
 * channel list from the CNSS platform driver and plumbing the data
 * down to the lower layers.  Then subscribe to subsequent channel
 * avoidance events.
 *
 * Return: None
 */
static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
{
	uint16_t unsafe_channel_count;
	int index;

	cnss_get_wlan_unsafe_channel(hdd_ctx->unsafe_channel_list,
				     &(hdd_ctx->unsafe_channel_count),
				     sizeof(uint16_t) * NUM_20MHZ_RF_CHANNELS);

	hddLog(CDF_TRACE_LEVEL_INFO, FL("num of unsafe channels is %d"),
	       hdd_ctx->unsafe_channel_count);

	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
				       (uint16_t)NUM_20MHZ_RF_CHANNELS);

	for (index = 0; index < unsafe_channel_count; index++) {
		hddLog(CDF_TRACE_LEVEL_INFO, FL("channel %d is not safe"),
		       hdd_ctx->unsafe_channel_list[index]);

	}

	/* Plug in avoid channel notification callback */
	sme_add_ch_avoid_callback(hdd_ctx->hHal, hdd_ch_avoid_cb);
}
#else
static void hdd_init_channel_avoidance(hdd_context_t *hdd_ctx)
{
}
static void hdd_set_thermal_level_cb(void *context, u_int8_t level)
{
}
#endif /* defined(FEATURE_WLAN_CH_AVOID) && defined(CONFIG_CNSS) */

/**
 * wlan_hdd_disable_all_dual_mac_features() - Disable dual mac features
 * @hdd_ctx: HDD context
 *
 * Disables all the dual mac features like DBS, Agile DFS etc.
 *
 * Return: QDF_STATUS_SUCCESS on success
 */
static QDF_STATUS wlan_hdd_disable_all_dual_mac_features(hdd_context_t *hdd_ctx)
{
	struct sir_dual_mac_config cfg;
	QDF_STATUS status;

	if (!hdd_ctx) {
		hdd_err("HDD context is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	cfg.scan_config = 0;
	cfg.fw_mode_config = 0;
	cfg.set_dual_mac_cb =
		(void *)cds_soc_set_dual_mac_cfg_cb;

	hdd_debug("Disabling all dual mac features...");

	status = sme_soc_set_dual_mac_config(hdd_ctx->hHal, cfg);
	if (status != QDF_STATUS_SUCCESS) {
		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
		return status;
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_override_ini_config - Override INI config
 * @hdd_ctx: HDD context
 *
 * Override INI config based on module parameter.
 *
 * Return: None
 */
static void hdd_override_ini_config(hdd_context_t *hdd_ctx)
{

	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
		hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
		hdd_notice("Module enable_dfs_chan_scan set to %d",
			   enable_dfs_chan_scan);
	}
	if (0 == enable_11d || 1 == enable_11d) {
		hdd_ctx->config->Is11dSupportEnabled = enable_11d;
		hdd_notice("Module enable_11d set to %d", enable_11d);
	}
}

/**
 * hdd_set_trace_level_for_each - Set trace level for each INI config
 * @hdd_ctx - HDD context
 *
 * Set trace level for each module based on INI config.
 *
 * Return: None
 */
static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx)
{
	hdd_cdf_trace_enable(QDF_MODULE_ID_WMI,
			     hdd_ctx->config->cdf_trace_enable_wdi);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HDD,
			     hdd_ctx->config->cdf_trace_enable_hdd);
	hdd_cdf_trace_enable(QDF_MODULE_ID_SME,
			     hdd_ctx->config->cdf_trace_enable_sme);
	hdd_cdf_trace_enable(QDF_MODULE_ID_PE,
			     hdd_ctx->config->cdf_trace_enable_pe);
	hdd_cdf_trace_enable(QDF_MODULE_ID_WMA,
			     hdd_ctx->config->cdf_trace_enable_wma);
	hdd_cdf_trace_enable(QDF_MODULE_ID_SYS,
			     hdd_ctx->config->cdf_trace_enable_sys);
	hdd_cdf_trace_enable(QDF_MODULE_ID_QDF,
			     hdd_ctx->config->cdf_trace_enable_cdf);
	hdd_cdf_trace_enable(QDF_MODULE_ID_SAP,
			     hdd_ctx->config->cdf_trace_enable_sap);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HDD_SOFTAP,
			     hdd_ctx->config->cdf_trace_enable_hdd_sap);
	hdd_cdf_trace_enable(QDF_MODULE_ID_BMI,
				hdd_ctx->config->cdf_trace_enable_bmi);
	hdd_cdf_trace_enable(QDF_MODULE_ID_CFG,
				hdd_ctx->config->cdf_trace_enable_cfg);
	hdd_cdf_trace_enable(QDF_MODULE_ID_EPPING,
				hdd_ctx->config->cdf_trace_enable_epping);
	hdd_cdf_trace_enable(QDF_MODULE_ID_QDF_DEVICE,
				hdd_ctx->config->cdf_trace_enable_cdf_devices);
	hdd_cdf_trace_enable(QDF_MODULE_ID_TXRX,
				hdd_ctx->config->cfd_trace_enable_txrx);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HTC,
				hdd_ctx->config->cdf_trace_enable_htc);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HIF,
				hdd_ctx->config->cdf_trace_enable_hif);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HDD_SAP_DATA,
				hdd_ctx->config->cdf_trace_enable_hdd_sap_data);
	hdd_cdf_trace_enable(QDF_MODULE_ID_HDD_DATA,
				hdd_ctx->config->cdf_trace_enable_hdd_data);

	hdd_cfg_print(hdd_ctx);
}

/**
 * hdd_init_context - Alloc and initialize HDD context
 * @dev:	Pointer to the underlying device
 * @hif_sc:	HIF context
 *
 * Allocate and initialize HDD context. HDD context is allocated as part of
 * wiphy allocation and then context is initialized.
 *
 * Return: HDD context on success and ERR_PTR on failure
 */
hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc)
{
	QDF_STATUS status;
	int ret = 0;
	hdd_context_t *hdd_ctx;
	v_CONTEXT_t p_cds_context;
	struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_sc);

	ENTER();

	p_cds_context = cds_get_global_context();
	if (p_cds_context == NULL) {
		hdd_alert("Failed to get CDS global context");
		ret = -EINVAL;
		goto err_out;
	}

	hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t));

	if (hdd_ctx == NULL) {
		ret = -ENOMEM;
		goto err_out;
	}

	hdd_ctx->pcds_context = p_cds_context;

	hdd_ctx->config = cdf_mem_malloc(sizeof(struct hdd_config));
	if (hdd_ctx->config == NULL) {
		hdd_alert("Failed to alloc memory for HDD config!");
		ret = -ENOMEM;
		goto err_free_hdd_context;
	}

	/* Read and parse the qcom_cfg.ini file */
	status = hdd_parse_config_ini(hdd_ctx);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_alert("Error (status: %d) parsing INI file: %s", status,
			  WLAN_INI_FILE);
		ret = -EINVAL;
		goto err_free_config;
	}

	((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx;

	hdd_ctx->parent_dev = dev;

	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;

	hdd_init_ll_stats_ctx();

	init_completion(&hdd_ctx->mc_sus_event_var);
	init_completion(&hdd_ctx->ready_to_suspend);

	cdf_spinlock_init(&hdd_ctx->connection_status_lock);
	cdf_spinlock_init(&hdd_ctx->sched_scan_lock);

	cdf_spinlock_init(&hdd_ctx->hdd_adapter_lock);
	qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS);

	wlan_hdd_cfg80211_extscan_init(hdd_ctx);

	hdd_tdls_pre_init(hdd_ctx);
	mutex_init(&hdd_ctx->dfs_lock);

	hdd_ctx->target_type = tgt_info->target_type;

	hdd_init_offloaded_packets_ctx(hdd_ctx);

	icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log);

	hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;

	hdd_ctx->configuredMcastBcastFilter =
		hdd_ctx->config->mcastBcastFilterSetting;

	hdd_notice("Setting configuredMcastBcastFilter: %d",
		   hdd_ctx->config->mcastBcastFilterSetting);

	hdd_override_ini_config(hdd_ctx);

	ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config);

	if (ret) {
		hdd_err("CFG80211 wiphy init failed: %d", ret);
		goto err_free_config;
	}

	hdd_enable_fastpath(hdd_ctx->config, hif_sc);

	/* Uses to enabled logging after SSR */
	hdd_ctx->fw_log_settings.enable = hdd_ctx->config->enable_fw_log;

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		goto skip_multicast_logging;

	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);

	ret = hdd_logging_sock_activate_svc(hdd_ctx);
	if (ret)
		goto err_free_config;

	/*
	 * Update CDF trace levels based upon the code. The multicast
	 * levels of the code need not be set when the logger thread
	 * is not enabled.
	 */
	if (cds_is_multicast_logging())
		wlan_logging_set_log_level();

skip_multicast_logging:
	hdd_set_trace_level_for_each(hdd_ctx);

	return hdd_ctx;

err_free_config:
	cdf_mem_free(hdd_ctx->config);

err_free_hdd_context:
	wiphy_free(hdd_ctx->wiphy);

err_out:
	return ERR_PTR(ret);
}

#ifdef WLAN_OPEN_P2P_INTERFACE
/**
 * hdd_open_p2p_interface - Open P2P interface
 * @hdd_ctx:	HDD context
 * @rtnl_held:	True if RTNL lock held
 *
 * Open P2P interface during probe. This function called to open the P2P
 * interface at probe along with STA interface.
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_open_p2p_interface(hdd_context_t *hdd_ctx, bool rtnl_held)
{
	hdd_adapter_t *adapter;
	uint8_t *p2p_dev_addr;

	if (hdd_ctx->config->isP2pDeviceAddrAdministrated &&
	    !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
		cdf_mem_copy(hdd_ctx->p2pDeviceAddress.bytes,
			     hdd_ctx->config->intfMacAddr[0].bytes,
			     sizeof(tSirMacAddr));

		/*
		 * Generate the P2P Device Address.  This consists of
		 * the device's primary MAC address with the locally
		 * administered bit set.
		 */
		hdd_ctx->p2pDeviceAddress.bytes[0] |= 0x02;
	} else {
		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
		if (p2p_dev_addr == NULL) {
			hdd_alert("Failed to allocate mac_address for p2p_device");
			return -ENOSPC;
		}

		cdf_mem_copy(&hdd_ctx->p2pDeviceAddress.bytes[0], p2p_dev_addr,
			     QDF_MAC_ADDR_SIZE);
	}

	adapter = hdd_open_adapter(hdd_ctx, WLAN_HDD_P2P_DEVICE, "p2p%d",
				   &hdd_ctx->p2pDeviceAddress.bytes[0],
				   rtnl_held);

	if (NULL == adapter) {
		hdd_alert("Failed to do hdd_open_adapter for P2P Device Interface");
		return -ENOSPC;
	}

	return 0;
}
#else
static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx,
					 bool rtnl_held)
{
	return 0;
}
#endif

/**
 * hdd_open_interfaces - Open all required interfaces
 * hdd_ctx:	HDD context
 * rtnl_held: True if RTNL lock is held
 *
 * Open all the interfaces like STA, P2P and OCB based on the configuration.
 *
 * Return: Primary adapter on success and PTR_ERR on failure
 */
static hdd_adapter_t *hdd_open_interfaces(hdd_context_t *hdd_ctx,
					  bool rtnl_held)
{
	hdd_adapter_t *adapter = NULL;
	hdd_adapter_t *adapter_11p = NULL;
	int ret;

	/* Create only 802.11p interface */
	if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_STANDALONE) {
		adapter = hdd_open_adapter(hdd_ctx, WLAN_HDD_OCB, "wlanocb%d",
					   wlan_hdd_get_intf_addr(hdd_ctx),
					   rtnl_held);

		if (adapter == NULL)
			return ERR_PTR(-ENOSPC);

		return adapter;
	}

	adapter = hdd_open_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION, "wlan%d",
				   wlan_hdd_get_intf_addr(hdd_ctx),
				   rtnl_held);

	if (adapter == NULL)
		return ERR_PTR(-ENOSPC);

	ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
	if (ret)
		goto err_close_adapter;

	/* Open 802.11p Interface */
	if (hdd_ctx->config->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
		adapter_11p = hdd_open_adapter(hdd_ctx, WLAN_HDD_OCB,
					       "wlanocb%d",
					       wlan_hdd_get_intf_addr(hdd_ctx),
					       rtnl_held);
		if (adapter_11p == NULL) {
			hdd_err("Failed to open 802.11p interface");
			goto err_close_adapter;
		}
	}

	return adapter;

err_close_adapter:
	hdd_close_all_adapters(hdd_ctx, rtnl_held);
	return ERR_PTR(ret);
}

/**
 * hdd_update_country_code - Update country code
 * @hdd_ctx: HDD context
 * @adapter: Primary adapter context
 *
 * Update country code based on module parameter country_code at SME and wait
 * for the settings to take effect.
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_update_country_code(hdd_context_t *hdd_ctx,
				  hdd_adapter_t *adapter)
{
	QDF_STATUS status;
	int ret = 0;
	unsigned long rc;

	if (country_code == NULL)
		return 0;

	INIT_COMPLETION(adapter->change_country_code);

	status = sme_change_country_code(hdd_ctx->hHal,
					 wlan_hdd_change_country_code_callback,
					 country_code, adapter,
					 hdd_ctx->pcds_context, eSIR_TRUE,
					 eSIR_TRUE);


	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("SME Change Country code from module param fail ret=%d",
			ret);
		return -EINVAL;
	}

	rc = wait_for_completion_timeout(&adapter->change_country_code,
			 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
	if (!rc) {
		hdd_err("SME while setting country code timed out");
		ret = -ETIMEDOUT;
	}

	return ret;
}

/**
 * hdd_init_thermal_info - Initialize thermal level
 * @hdd_ctx:	HDD context
 *
 * Initialize thermal level at SME layer and set the thermal level callback
 * which would be called when a configured thermal threshold is hit.
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_init_thermal_info(hdd_context_t *hdd_ctx)
{
	tSmeThermalParams thermal_param;
	QDF_STATUS status;

	thermal_param.smeThermalMgmtEnabled =
		hdd_ctx->config->thermalMitigationEnable;
	thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;

	thermal_param.smeThermalLevels[0].smeMinTempThreshold =
		hdd_ctx->config->thermalTempMinLevel0;
	thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
		hdd_ctx->config->thermalTempMaxLevel0;
	thermal_param.smeThermalLevels[1].smeMinTempThreshold =
		hdd_ctx->config->thermalTempMinLevel1;
	thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
		hdd_ctx->config->thermalTempMaxLevel1;
	thermal_param.smeThermalLevels[2].smeMinTempThreshold =
		hdd_ctx->config->thermalTempMinLevel2;
	thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
		hdd_ctx->config->thermalTempMaxLevel2;
	thermal_param.smeThermalLevels[3].smeMinTempThreshold =
		hdd_ctx->config->thermalTempMinLevel3;
	thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
		hdd_ctx->config->thermalTempMaxLevel3;

	status = sme_init_thermal_info(hdd_ctx->hHal, thermal_param);

	if (!QDF_IS_STATUS_SUCCESS(status))
		return cdf_status_to_os_return(status);

	sme_add_set_thermal_level_callback(hdd_ctx->hHal,
					   hdd_set_thermal_level_cb);

	return 0;

}

#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
/**
 * hdd_hold_rtnl_lock - Hold RTNL lock
 *
 * Hold RTNL lock
 *
 * Return: True if held and false otherwise
 */
static inline bool hdd_hold_rtnl_lock(void)
{
	rtnl_lock();
	return true;
}

/**
 * hdd_release_rtnl_lock - Release RTNL lock
 *
 * Release RTNL lock
 *
 * Return: None
 */
static inline void hdd_release_rtnl_lock(void)
{
	rtnl_unlock();
}
#else
static inline bool hdd_hold_rtnl_lock(void) { return false; }
static inline void hdd_release_rtnl_lock(void) { }
#endif

/**
 * hdd_wlan_startup() - HDD init function
 * @dev:	Pointer to the underlying device
 *
 * This is the driver startup code executed once a WLAN device has been detected
 *
 * Return:  0 for success, < 0 for failure
 */
int hdd_wlan_startup(struct device *dev, void *hif_sc)
{
	QDF_STATUS status;
	hdd_adapter_t *adapter = NULL;
	hdd_context_t *hdd_ctx = NULL;
	int ret;
	tSirTxPowerLimit hddtxlimit;
	bool rtnl_held;
	tSirRetStatus hal_status;

	ENTER();

	if (WLAN_IS_EPPING_ENABLED(con_mode)) {
		ret = epping_enable(dev);
		EXIT();
		return ret;
	}

	hdd_ctx = hdd_init_context(dev, hif_sc);

	if (IS_ERR(hdd_ctx))
		return PTR_ERR(hdd_ctx);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		ret = hdd_enable_ftm(hdd_ctx);

		if (ret)
			goto err_hdd_free_context;

		goto success;
	}

	hdd_wlan_green_ap_init(hdd_ctx);

	status = cds_open();
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("cds_open failed"));
		goto err_hdd_free_context;
	}

	wlan_hdd_update_wiphy(hdd_ctx->wiphy, hdd_ctx->config);

	hdd_ctx->hHal = cds_get_context(QDF_MODULE_ID_SME);

	if (NULL == hdd_ctx->hHal) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("HAL context is null"));
		goto err_cds_close;
	}

	status = cds_pre_enable(hdd_ctx->pcds_context);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("cds_pre_enable failed"));
		goto err_cds_close;
	}

	ol_txrx_register_pause_cb(wlan_hdd_txrx_pause_cb);

	status = wlan_hdd_regulatory_init(hdd_ctx);

	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Failed to init channel list"));
		goto err_cds_close;
	}

	/*
	 * Set 802.11p config
	 * TODO-OCB: This has been temporarily added here to ensure this
	 * parameter is set in CSR when we init the channel list. This should
	 * be removed once the 5.9 GHz channels are added to the regulatory
	 * domain.
	 */
	hdd_set_dot11p_config(hdd_ctx);

	/*
	 * Note that the cds_pre_enable() sequence triggers the cfg download.
	 * The cfg download must occur before we update the SME config
	 * since the SME config operation must access the cfg database
	 */
	status = hdd_set_sme_config(hdd_ctx);

	if (QDF_STATUS_SUCCESS != status) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("Failed hdd_set_sme_config"));
		goto err_wiphy_unregister;
	}

	ret = wma_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS,
				  hdd_ctx->config->tx_chain_mask_1ss,
				  PDEV_CMD);
	if (0 != ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       "%s: WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d",
		       __func__, ret);
	}

	status = hdd_set_sme_chan_list(hdd_ctx);
	if (status != QDF_STATUS_SUCCESS) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Failed to init channel list"));
		goto err_wiphy_unregister;
	}

	/* Apply the cfg.ini to cfg.dat */
	if (false == hdd_update_config_dat(hdd_ctx)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("config update failed"));
		goto err_wiphy_unregister;
	}

	if (QDF_STATUS_SUCCESS != hdd_update_mac_config(hdd_ctx)) {
		hddLog(CDF_TRACE_LEVEL_WARN,
		       FL("can't update mac config, using MAC from ini file"));
	}

	/*
	 * Set the MAC Address Currently this is used by HAL to add self sta.
	 * Remove this once self sta is added as part of session open.
	 */
	hal_status = cfg_set_str(hdd_ctx->hHal, WNI_CFG_STA_ID,
				     hdd_ctx->config->intfMacAddr[0].bytes,
				     sizeof(hdd_ctx->config->intfMacAddr[0]));

	if (!IS_SIR_STATUS_SUCCESS(hal_status)) {
		hdd_err("Failed to set MAC Address. HALStatus is %08d [x%08x]",
			hal_status, hal_status);
		ret = -EINVAL;
		goto err_wiphy_unregister;
	}

	if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE)
		goto err_wiphy_unregister;

	/*
	 * Start CDS which starts up the SME/MAC/HAL modules and everything
	 * else
	 */
	status = cds_enable(hdd_ctx->pcds_context);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("cds_enable failed"));
		goto err_ipa_cleanup;
	}

	hdd_init_channel_avoidance(hdd_ctx);

	status = hdd_post_cds_enable_config(hdd_ctx);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("hdd_post_cds_enable_config failed"));
		goto err_cds_disable;
	}

	cds_pkt_proto_trace_init();

	rtnl_held = hdd_hold_rtnl_lock();

	adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);

	if (IS_ERR(adapter)) {
		ret = PTR_ERR(adapter);
		goto err_cds_disable;
	}

	/*
	 * target hw version/revision would only be retrieved after firmware
	 * donwload
	 */
	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
			&hdd_ctx->target_hw_revision,
			&hdd_ctx->target_hw_name);

	/* Get the wlan hw/fw version */
	hdd_wlan_get_version(adapter, NULL, NULL);

	ret = hdd_update_country_code(hdd_ctx, adapter);

	if (ret)
		goto err_cds_disable;

	sme_register11d_scan_done_callback(hdd_ctx->hHal, hdd_11d_scan_done);

	sme_register_oem_data_rsp_callback(hdd_ctx->hHal,
					hdd_send_oem_data_rsp_msg);

	status = hdd_debugfs_init(adapter);

	if (QDF_IS_STATUS_SUCCESS(status))
		hdd_err("hdd_debugfs_init failed: %d!", status);

	/* FW capabilities received, Set the Dot11 mode */
	sme_setdef_dot11mode(hdd_ctx->hHal);

	/* Initialize the nlink service */
	if (nl_srv_init() != 0) {
		hddLog(CDF_TRACE_LEVEL_FATAL, FL("nl_srv_init failed"));
		goto err_close_adapter;
	}

	ret = oem_activate_service(hdd_ctx);
	if (ret) {
		hdd_alert("oem_activate_service failed: %d", ret);
		goto err_nl_srv;
	}

	ret = ptt_sock_activate_svc();
	if (ret) {
		hdd_alert("ptt_sock_activate_svc failed: %d", ret);
		goto err_nl_srv;
	}

	ret = cnss_diag_activate_service();
	if (ret) {
		hdd_alert("cnss_diag_activate_service failed: %d", ret);
		goto err_nl_srv;
	}

	/*
	 * Action frame registered in one adapter which will
	 * applicable to all interfaces
	 */
	wlan_hdd_cfg80211_register_frames(adapter);

	mutex_init(&hdd_ctx->sap_lock);

	hdd_release_rtnl_lock();
	rtnl_held = false;

	ret = register_netdevice_notifier(&hdd_netdev_notifier);
	if (ret < 0) {
		hdd_err("register_netdevice_notifier failed: %d", ret);
		goto err_nl_srv;
	}

#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
	/* Initialize the wake lcok */
	cdf_wake_lock_init(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
#endif
	/* Initialize the wake lcok */
	cdf_wake_lock_init(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");

	hdd_hostapd_channel_wakelock_init(hdd_ctx);

	if (hdd_ctx->config->fIsImpsEnabled)
		hdd_set_idle_ps_config(hdd_ctx, true);
	else
		hdd_set_idle_ps_config(hdd_ctx, false);
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
	if (hdd_ctx->config->WlanAutoShutdown != 0)
		if (sme_set_auto_shutdown_cb
			    (hdd_ctx->hHal, wlan_hdd_auto_shutdown_cb)
		    != QDF_STATUS_SUCCESS)
			hddLog(LOGE,
			       FL(
				  "Auto shutdown feature could not be enabled"
				 ));
#endif

#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
	status = cdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
				   QDF_TIMER_TYPE_SW,
				   hdd_skip_acs_scan_timer_handler,
				   (void *)hdd_ctx);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hddLog(LOGE, FL("Failed to init ACS Skip timer"));
#endif

	wlan_hdd_nan_init(hdd_ctx);
	status = cds_init_policy_mgr();
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("Policy manager initialization failed");
		goto err_unreg_netdev_notifier;
	}

	ret = hdd_init_thermal_info(hdd_ctx);

	if (ret) {
		hdd_err("Error while initializing thermal information");
		goto err_unreg_netdev_notifier;
	}

	if (0 != hdd_lro_init(hdd_ctx))
		hdd_err("Unable to initialize LRO in fw");

	hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
	hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
	status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);
	if (QDF_IS_STATUS_SUCCESS(status))
		hdd_err("Error setting txlimit in sme: %d", status);

#ifdef MSM_PLATFORM
	spin_lock_init(&hdd_ctx->bus_bw_lock);
	cdf_mc_timer_init(&hdd_ctx->bus_bw_timer,
			  QDF_TIMER_TYPE_SW,
			  hdd_bus_bw_compute_cbk, (void *)hdd_ctx);
#endif

	wlan_hdd_cfg80211_stats_ext_init(hdd_ctx);

	sme_ext_scan_register_callback(hdd_ctx->hHal,
				       wlan_hdd_cfg80211_extscan_callback);

	sme_set_rssi_threshold_breached_cb(hdd_ctx->hHal,
				hdd_rssi_threshold_breached);

	hdd_cfg80211_link_layer_stats_init(hdd_ctx);

	wlan_hdd_send_all_scan_intf_info(hdd_ctx);
	wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version,
				  hdd_ctx->target_hw_version,
				  hdd_ctx->target_hw_name);

	cdf_spinlock_init(&hdd_ctx->hdd_roc_req_q_lock);
	qdf_list_create((&hdd_ctx->hdd_roc_req_q), MAX_ROC_REQ_QUEUE_ENTRY);
	cdf_spinlock_init(&hdd_ctx->hdd_scan_req_q_lock);
	qdf_list_create((&hdd_ctx->hdd_scan_req_q), CFG_MAX_SCAN_COUNT_MAX);
#ifdef CONFIG_CNSS
	cnss_init_delayed_work(&hdd_ctx->roc_req_work,
			wlan_hdd_roc_request_dequeue);
#else
	INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue);
#endif

	/*
	 * Register IPv6 notifier to notify if any change in IP
	 * So that we can reconfigure the offload parameters
	*/
	hdd_wlan_register_ip6_notifier(hdd_ctx);

	/*
	 * Register IPv4 notifier to notify if any change in IP
	 * So that we can reconfigure the offload parameters
	 */
	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
	if (ret)
		hddLog(LOGE, FL("Failed to register IPv4 notifier"));
	else
		hdd_info("Registered IPv4 notifier");

	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);

	if (hdd_ctx->config->dual_mac_feature_disable) {
		status = wlan_hdd_disable_all_dual_mac_features(hdd_ctx);
		if (status != QDF_STATUS_SUCCESS) {
			hdd_err("Failed to disable dual mac features");
			goto err_unreg_netdev_notifier;
		}
	}

	hif_enable_power_gating(hif_sc);

	memdump_init();

	goto success;

err_unreg_netdev_notifier:
	unregister_netdevice_notifier(&hdd_netdev_notifier);

err_nl_srv:
#ifdef WLAN_KD_READY_NOTIFIER
	cnss_diag_notify_wlan_close();
	ptt_sock_deactivate_svc();
#endif /* WLAN_KD_READY_NOTIFIER */
	nl_srv_exit();

	if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
		hdd_err("Failed to deinit policy manager");
		/* Proceed and complete the clean up */
	}

	hdd_debugfs_exit(hdd_ctx);

err_close_adapter:
	hdd_release_rtnl_lock();

	hdd_close_all_adapters(hdd_ctx, false);

err_cds_disable:
	cds_disable(hdd_ctx->pcds_context);

err_ipa_cleanup:
	hdd_ipa_cleanup(hdd_ctx);

err_wiphy_unregister:
	wiphy_unregister(hdd_ctx->wiphy);

err_cds_close:
	status = cds_sched_close(hdd_ctx->pcds_context);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hddLog(CDF_TRACE_LEVEL_FATAL,
		       FL("Failed to close CDS Scheduler"));
		CDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
	}
	cds_close(hdd_ctx->pcds_context);

err_hdd_free_context:
	hdd_free_context(hdd_ctx);
	CDF_BUG(1);

	return -EIO;

success:
	EXIT();
	return 0;
}

/**
 * hdd_softap_sta_deauth() - handle deauth req from HDD
 * @adapter:	Pointer to the HDD
 * @enable:	bool value
 *
 * This to take counter measure to handle deauth req from HDD
 *
 * Return: None
 */
QDF_STATUS hdd_softap_sta_deauth(hdd_adapter_t *adapter,
				 struct tagCsrDelStaParams *pDelStaParams)
{
#ifndef WLAN_FEATURE_MBSSID
	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
#endif
	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;

	ENTER();

	hddLog(LOG1, FL("hdd_softap_sta_deauth:(%p, false)"),
	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);

	/* Ignore request to deauth bcmc station */
	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
		return qdf_status;

#ifdef WLAN_FEATURE_MBSSID
	qdf_status =
		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
				   pDelStaParams);
#else
	qdf_status = wlansap_deauth_sta(p_cds_context, pDelStaParams);
#endif

	EXIT();
	return qdf_status;
}

/**
 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
 * @adapter:	Pointer to the HDD
 *
 * This to take counter measure to handle deauth req from HDD
 *
 * Return: None
 */
void hdd_softap_sta_disassoc(hdd_adapter_t *adapter,
			     uint8_t *pDestMacAddress)
{
#ifndef WLAN_FEATURE_MBSSID
	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
#endif

	ENTER();

	hddLog(LOGE, FL("hdd_softap_sta_disassoc:(%p, false)"),
	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);

	/* Ignore request to disassoc bcmc station */
	if (pDestMacAddress[0] & 0x1)
		return;

#ifdef WLAN_FEATURE_MBSSID
	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
			     pDestMacAddress);
#else
	wlansap_disassoc_sta(p_cds_context, pDestMacAddress);
#endif
}

void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *adapter,
					      bool enable)
{
#ifndef WLAN_FEATURE_MBSSID
	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
#endif

	ENTER();

	hddLog(LOGE, FL("hdd_softap_tkip_mic_fail_counter_measure:(%p, false)"),
	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);

#ifdef WLAN_FEATURE_MBSSID
	wlansap_set_counter_measure(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
				    (bool) enable);
#else
	wlansap_set_counter_measure(p_cds_context, (bool) enable);
#endif
}

/**
 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
 * @hdd_ctx:	HDD Context
 *
 * API to find if there is any STA or P2P-Client is connected
 *
 * Return: true if connected; false otherwise
 */
QDF_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *hdd_ctx)
{
	return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
}

#ifdef WLAN_FEATURE_LPSS
int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
				  hdd_adapter_t *adapter,
				  hdd_station_ctx_t *pHddStaCtx,
				  uint8_t is_on, uint8_t is_connected)
{
	hdd_context_t *hdd_ctx = NULL;
	uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN;

	if (!data) {
		hddLog(LOGE, FL("invalid data pointer"));
		return -EINVAL;
	}
	if (!adapter) {
		if (is_on) {
			/* no active interface */
			data->lpss_support = 0;
			data->is_on = is_on;
			return 0;
		}
		hddLog(LOGE, FL("invalid adapter pointer"));
		return -EINVAL;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (hdd_ctx->lpss_support && hdd_ctx->config->enable_lpass_support)
		data->lpss_support = 1;
	else
		data->lpss_support = 0;
	data->numChannels = WLAN_SVC_MAX_NUM_CHAN;
	sme_get_cfg_valid_channels(hdd_ctx->hHal, data->channel_list,
				   &data->numChannels);
	sme_get_country_code(hdd_ctx->hHal, data->country_code, &buflen);
	data->is_on = is_on;
	data->vdev_id = adapter->sessionId;
	data->vdev_mode = adapter->device_mode;
	if (pHddStaCtx) {
		data->is_connected = is_connected;
		data->rssi = adapter->rssi;
		data->freq =
			cds_chan_to_freq(pHddStaCtx->conn_info.operationChannel);
		if (WLAN_SVC_MAX_SSID_LEN >=
		    pHddStaCtx->conn_info.SSID.SSID.length) {
			data->ssid_len = pHddStaCtx->conn_info.SSID.SSID.length;
			memcpy(data->ssid,
			       pHddStaCtx->conn_info.SSID.SSID.ssId,
			       pHddStaCtx->conn_info.SSID.SSID.length);
		}
		if (QDF_MAC_ADDR_SIZE >=
		    sizeof(pHddStaCtx->conn_info.bssId))
			memcpy(data->bssid, pHddStaCtx->conn_info.bssId.bytes,
			       QDF_MAC_ADDR_SIZE);
	}
	return 0;
}

int wlan_hdd_gen_wlan_version_pack(struct wlan_version_data *data,
				   uint32_t fw_version,
				   uint32_t chip_id, const char *chip_name)
{
	if (!data) {
		hddLog(LOGE, FL("invalid data pointer"));
		return -EINVAL;
	}

	data->chip_id = chip_id;
	strlcpy(data->chip_name, chip_name, WLAN_SVC_MAX_STR_LEN);
	if (strncmp(chip_name, "Unknown", 7))
		strlcpy(data->chip_from, "Qualcomm", WLAN_SVC_MAX_STR_LEN);
	else
		strlcpy(data->chip_from, "Unknown", WLAN_SVC_MAX_STR_LEN);
	strlcpy(data->host_version, QWLAN_VERSIONSTR, WLAN_SVC_MAX_STR_LEN);
	scnprintf(data->fw_version, WLAN_SVC_MAX_STR_LEN, "%d.%d.%d.%d",
		  (fw_version & 0xf0000000) >> 28,
		  (fw_version & 0xf000000) >> 24,
		  (fw_version & 0xf00000) >> 20, (fw_version & 0x7fff));
	return 0;
}
#endif

/**
 * wlan_hdd_disable_roaming() - disable roaming on all STAs except the input one
 * @adapter:	HDD adapter pointer
 *
 * This function loop through each adapter and disable roaming on each STA
 * device mode except the input adapter.
 *
 * Note: On the input adapter roaming is not enabled yet hence no need to
 *       disable.
 *
 * Return: None
 */
void wlan_hdd_disable_roaming(hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	hdd_adapter_t *adapterIdx = NULL;
	hdd_adapter_list_node_t *adapterNode = NULL;
	hdd_adapter_list_node_t *pNext = NULL;
	QDF_STATUS status;

	if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
	    hdd_ctx->config->isRoamOffloadScanEnabled &&
	    WLAN_HDD_INFRA_STATION == adapter->device_mode &&
	    cds_is_sta_active_connection_exists()) {
		hddLog(LOG1, FL("Connect received on STA sessionId(%d)"),
		       adapter->sessionId);
		/*
		 * Loop through adapter and disable roaming for each STA device
		 * mode except the input adapter.
		 */
		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
			adapterIdx = adapterNode->pAdapter;

			if (WLAN_HDD_INFRA_STATION == adapterIdx->device_mode
			    && adapter->sessionId != adapterIdx->sessionId) {
				hddLog(LOG1,
				       FL("Disable Roaming on sessionId(%d)"),
				       adapterIdx->sessionId);
				sme_stop_roaming(WLAN_HDD_GET_HAL_CTX
							 (adapterIdx),
						 adapterIdx->sessionId, 0);
			}

			status = hdd_get_next_adapter(hdd_ctx,
						      adapterNode,
						      &pNext);
			adapterNode = pNext;
		}
	}
}

/**
 * wlan_hdd_enable_roaming() - enable roaming on all STAs except the input one
 * @adapter:	HDD adapter pointer
 *
 * This function loop through each adapter and enable roaming on each STA
 * device mode except the input adapter.
 * Note: On the input adapter no need to enable roaming because link got
 *       disconnected on this.
 *
 * Return: None
 */
void wlan_hdd_enable_roaming(hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	hdd_adapter_t *adapterIdx = NULL;
	hdd_adapter_list_node_t *adapterNode = NULL;
	hdd_adapter_list_node_t *pNext = NULL;
	QDF_STATUS status;

	if (hdd_ctx->config->isFastRoamIniFeatureEnabled &&
	    hdd_ctx->config->isRoamOffloadScanEnabled &&
	    WLAN_HDD_INFRA_STATION == adapter->device_mode &&
	    cds_is_sta_active_connection_exists()) {
		hddLog(LOG1, FL("Disconnect received on STA sessionId(%d)"),
		       adapter->sessionId);
		/*
		 * Loop through adapter and enable roaming for each STA device
		 * mode except the input adapter.
		 */
		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
			adapterIdx = adapterNode->pAdapter;

			if (WLAN_HDD_INFRA_STATION == adapterIdx->device_mode
			    && adapter->sessionId != adapterIdx->sessionId) {
				hddLog(LOG1,
				       FL("Enabling Roaming on sessionId(%d)"),
				       adapterIdx->sessionId);
				sme_start_roaming(WLAN_HDD_GET_HAL_CTX
							  (adapterIdx),
						  adapterIdx->sessionId,
						  REASON_CONNECT);
			}

			status = hdd_get_next_adapter(hdd_ctx,
						      adapterNode,
						      &pNext);
			adapterNode = pNext;
		}
	}
}

void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	tAniMsgHdr *ani_hdr;
	void *nl_data = NULL;
	int flags = GFP_KERNEL;

	if (in_interrupt() || irqs_disabled() || in_atomic())
		flags = GFP_ATOMIC;

	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);

	if (skb == NULL) {
		hddLog(CDF_TRACE_LEVEL_ERROR, FL("alloc_skb failed"));
		return;
	}

	nlh = (struct nlmsghdr *)skb->data;
	nlh->nlmsg_pid = 0;     /* from kernel */
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_seq = 0;
	nlh->nlmsg_type = WLAN_NL_MSG_SVC;

	ani_hdr = NLMSG_DATA(nlh);
	ani_hdr->type = type;

	switch (type) {
	case WLAN_SVC_FW_CRASHED_IND:
	case WLAN_SVC_LTE_COEX_IND:
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
#endif
		ani_hdr->length = 0;
		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
		skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
		break;
	case WLAN_SVC_WLAN_STATUS_IND:
	case WLAN_SVC_WLAN_VERSION_IND:
	case WLAN_SVC_DFS_CAC_START_IND:
	case WLAN_SVC_DFS_CAC_END_IND:
	case WLAN_SVC_DFS_RADAR_DETECT_IND:
	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
	case WLAN_SVC_WLAN_TP_IND:
	case WLAN_SVC_WLAN_TP_TX_IND:
		ani_hdr->length = len;
		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
		memcpy(nl_data, data, len);
		skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
		break;

	default:
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("WLAN SVC: Attempt to send unknown nlink message %d"),
		       type);
		kfree_skb(skb);
		return;
	}

	nl_srv_bcast(skb);

	return;
}

#ifdef WLAN_FEATURE_LPSS
void wlan_hdd_send_status_pkg(hdd_adapter_t *adapter,
			      hdd_station_ctx_t *pHddStaCtx,
			      uint8_t is_on, uint8_t is_connected)
{
	int ret = 0;
	struct wlan_status_data data;

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		return;

	memset(&data, 0, sizeof(struct wlan_status_data));
	if (is_on)
		ret = wlan_hdd_gen_wlan_status_pack(&data, adapter, pHddStaCtx,
						    is_on, is_connected);
	if (!ret)
		wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_STATUS_IND,
					    &data,
					    sizeof(struct wlan_status_data));
}

void wlan_hdd_send_version_pkg(uint32_t fw_version,
			       uint32_t chip_id, const char *chip_name)
{
	int ret = 0;
	struct wlan_version_data data;
#ifdef CONFIG_CNSS
	struct cnss_platform_cap cap;

	ret = cnss_get_platform_cap(&cap);
	if (ret) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("platform capability info from CNSS not available"));
		return;
	}

	if (!(cap.cap_flag & CNSS_HAS_UART_ACCESS))
		return;
#endif

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		return;

	memset(&data, 0, sizeof(struct wlan_version_data));
	ret =
		wlan_hdd_gen_wlan_version_pack(&data, fw_version, chip_id,
					       chip_name);
	if (!ret)
		wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_VERSION_IND,
					    &data,
					    sizeof(struct wlan_version_data));
}

void wlan_hdd_send_all_scan_intf_info(hdd_context_t *hdd_ctx)
{
	hdd_adapter_t *pDataAdapter = NULL;
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	bool scan_intf_found = false;
	QDF_STATUS status;

	if (!hdd_ctx) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("NULL pointer for hdd_ctx"));
		return;
	}

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		pDataAdapter = adapterNode->pAdapter;
		if (pDataAdapter) {
			if (pDataAdapter->device_mode == WLAN_HDD_INFRA_STATION
			    || pDataAdapter->device_mode == WLAN_HDD_P2P_CLIENT
			    || pDataAdapter->device_mode ==
			    WLAN_HDD_P2P_DEVICE) {
				scan_intf_found = true;
				wlan_hdd_send_status_pkg(pDataAdapter, NULL, 1,
							 0);
			}
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	if (!scan_intf_found)
		wlan_hdd_send_status_pkg(pDataAdapter, NULL, 1, 0);
}
#else
static inline void wlan_hdd_send_status_pkg(hdd_adapter_t *pAdapter,
					    hdd_station_ctx_t *pHddStaCtx,
					    uint8_t is_on, uint8_t is_connected)
{
	return;
}

static inline void wlan_hdd_send_version_pkg(uint32_t fw_version, uint32_t
					     chip_id, const char *chip_name)
{
	return;
}

static inline void wlan_hdd_send_all_scan_intf_info(hdd_context_t *pHddCtx)
{
	return;
}
#endif

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
void wlan_hdd_auto_shutdown_cb(void)
{
	hddLog(LOGE, FL("Wlan Idle. Sending Shutdown event.."));
	wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
}

void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, bool enable)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	hdd_adapter_t *adapter;
	bool ap_connected = false, sta_connected = false;
	tHalHandle hal_handle;

	hal_handle = hdd_ctx->hHal;
	if (hal_handle == NULL)
		return;

	if (hdd_ctx->config->WlanAutoShutdown == 0)
		return;

	if (enable == false) {
		if (sme_set_auto_shutdown_timer(hal_handle, 0) !=
							QDF_STATUS_SUCCESS) {
			hddLog(LOGE,
			       FL("Failed to stop wlan auto shutdown timer"));
		}
		return;
	}

	/* To enable shutdown timer check conncurrency */
	if (cds_concurrent_open_sessions_running()) {
		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
			adapter = adapterNode->pAdapter;
			if (adapter
			    && adapter->device_mode ==
			    WLAN_HDD_INFRA_STATION) {
				if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
				    conn_info.connState ==
				    eConnectionState_Associated) {
					sta_connected = true;
					break;
				}
			}
			if (adapter
			    && adapter->device_mode == WLAN_HDD_SOFTAP) {
				if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
				    bApActive == true) {
					ap_connected = true;
					break;
				}
			}
			status = hdd_get_next_adapter(hdd_ctx,
						      adapterNode,
						      &pNext);
			adapterNode = pNext;
		}
	}

	if (ap_connected == true || sta_connected == true) {
		hddLog(LOG1,
		       FL("CC Session active. Shutdown timer not enabled"));
		return;
	} else {
		if (sme_set_auto_shutdown_timer(hal_handle,
						hdd_ctx->config->
						WlanAutoShutdown)
		    != QDF_STATUS_SUCCESS)
			hddLog(LOGE,
			       FL("Failed to start wlan auto shutdown timer"));
		else
			hddLog(LOG1,
			       FL("Auto Shutdown timer for %d seconds enabled"),
			       hdd_ctx->config->WlanAutoShutdown);

	}
}
#endif

hdd_adapter_t *hdd_get_con_sap_adapter(hdd_adapter_t *this_sap_adapter,
							bool check_start_bss)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
	hdd_adapter_t *adapter, *con_sap_adapter;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;

	con_sap_adapter = NULL;

	status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
		adapter = adapterNode->pAdapter;
		if (adapter && ((adapter->device_mode == WLAN_HDD_SOFTAP) ||
				(adapter->device_mode == WLAN_HDD_P2P_GO)) &&
						adapter != this_sap_adapter) {
			if (check_start_bss) {
				if (test_bit(SOFTAP_BSS_STARTED,
						&adapter->event_flags)) {
					con_sap_adapter = adapter;
					break;
				}
			} else {
				con_sap_adapter = adapter;
				break;
			}
		}
		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
		adapterNode = pNext;
	}

	return con_sap_adapter;
}

#ifdef MSM_PLATFORM
void hdd_start_bus_bw_compute_timer(hdd_adapter_t *adapter)
{
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	if (CDF_TIMER_STATE_RUNNING ==
	    cdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer))
		return;

	cdf_mc_timer_start(&hdd_ctx->bus_bw_timer,
			   hdd_ctx->config->busBandwidthComputeInterval);
}

void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *adapter)
{
	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
	QDF_STATUS status;
	bool can_stop = true;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	if (CDF_TIMER_STATE_RUNNING !=
	    cdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) {
		/* trying to stop timer, when not running is not good */
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("bus band width compute timer is not running"));
		return;
	}

	if (cds_concurrent_open_sessions_running()) {
		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);

		while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
			adapter = adapterNode->pAdapter;
			if (adapter
			    && (adapter->device_mode == WLAN_HDD_INFRA_STATION
				|| adapter->device_mode == WLAN_HDD_P2P_CLIENT)
			    && WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
			    conn_info.connState ==
			    eConnectionState_Associated) {
				can_stop = false;
				break;
			}
			if (adapter
			    && (adapter->device_mode == WLAN_HDD_SOFTAP
				|| adapter->device_mode == WLAN_HDD_P2P_GO)
			    && WLAN_HDD_GET_AP_CTX_PTR(adapter)->bApActive ==
			    true) {
				can_stop = false;
				break;
			}
			status = hdd_get_next_adapter(hdd_ctx,
						      adapterNode,
						      &pNext);
			adapterNode = pNext;
		}
	}

	if (can_stop == true)
		cdf_mc_timer_stop(&hdd_ctx->bus_bw_timer);
}
#endif

/**
 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
 *                                            and sta's operating channel.
 * @sta_adapter:  Describe the first argument to foobar.
 * @ap_adapter:   Describe the second argument to foobar.
 * @roam_profile: Roam profile of AP to which STA wants to connect.
 * @concurrent_chnl_same: If both SAP and STA channels are same then
 *                        set this flag to true else false.
 *
 * This function checks the sap's operating channel and sta's operating channel.
 * if both are same then it will return false else it will restart the sap in
 * sta's channel and return true.
 *
 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
 */
QDF_STATUS wlan_hdd_check_custom_con_channel_rules(hdd_adapter_t *sta_adapter,
						  hdd_adapter_t *ap_adapter,
						  tCsrRoamProfile *roam_profile,
						  tScanResultHandle *scan_cache,
						  bool *concurrent_chnl_same)
{
	hdd_ap_ctx_t *hdd_ap_ctx;
	uint8_t channel_id;
	QDF_STATUS status;
	device_mode_t device_mode = ap_adapter->device_mode;
	*concurrent_chnl_same = true;

	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
	status =
	 sme_get_ap_channel_from_scan_cache(WLAN_HDD_GET_HAL_CTX(sta_adapter),
					    roam_profile,
					    scan_cache,
					    &channel_id);
	if ((QDF_STATUS_SUCCESS == status)) {
		if ((WLAN_HDD_SOFTAP == device_mode) &&
			(channel_id < SIR_11A_CHANNEL_BEGIN)) {
			if (hdd_ap_ctx->operatingChannel != channel_id) {
				*concurrent_chnl_same = false;
				hddLog(CDF_TRACE_LEVEL_INFO_MED,
					FL("channels are different"));
			}
		} else if ((WLAN_HDD_P2P_GO == device_mode) &&
				(channel_id >= SIR_11A_CHANNEL_BEGIN)) {
			if (hdd_ap_ctx->operatingChannel != channel_id) {
				*concurrent_chnl_same = false;
				hddLog(CDF_TRACE_LEVEL_INFO_MED,
					FL("channels are different"));
			}
		}
	} else {
		/*
		 * Lets handle worst case scenario here, Scan cache lookup is
		 * failed so we have to stop the SAP to avoid any channel
		 * discrepancy  between SAP's channel and STA's channel.
		 * Return the status as failure so caller function could know
		 * that scan look up is failed.
		 */
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("Finding AP from scan cache failed"));
		return QDF_STATUS_E_FAILURE;
	}
	return QDF_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_MBSSID
/**
 * wlan_hdd_stop_sap() - This function stops bss of SAP.
 * @ap_adapter: SAP adapter
 *
 * This function will process the stopping of sap adapter.
 *
 * Return: None
 */
void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter)
{
	hdd_ap_ctx_t *hdd_ap_ctx;
	hdd_hostapd_state_t *hostapd_state;
	QDF_STATUS qdf_status;
	hdd_context_t *hdd_ctx;
#ifdef CFG80211_DEL_STA_V2
	struct station_del_parameters delStaParams;
#endif

	if (NULL == ap_adapter) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("ap_adapter is NULL here"));
		return;
	}

	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
	if (0 != wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("HDD context is not valid"));
		return;
	}
	mutex_lock(&hdd_ctx->sap_lock);
	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
#ifdef CFG80211_DEL_STA_V2
		delStaParams.mac = NULL;
		delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
		delStaParams.reason_code = eCsrForcedDeauthSta;
		wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy,
				ap_adapter->dev,
				&delStaParams);
#else
		wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy,
				ap_adapter->dev,
				NULL);
#endif
		hdd_cleanup_actionframe(hdd_ctx, ap_adapter);
		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
		hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
		       FL("Now doing SAP STOPBSS"));
		qdf_event_reset(&hostapd_state->cdf_stop_bss_event);
		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
							sapContext)) {
			qdf_status = qdf_wait_single_event(&hostapd_state->
							   cdf_stop_bss_event,
							   BSS_WAIT_TIMEOUT);
			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
				mutex_unlock(&hdd_ctx->sap_lock);
				hddLog(CDF_TRACE_LEVEL_ERROR,
				       FL("SAP Stop Failed"));
				return;
			}
		}
		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
		cds_decr_session_set_pcl(ap_adapter->device_mode,
						ap_adapter->sessionId);
		hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
		       FL("SAP Stop Success"));
	} else {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("Can't stop ap because its not started"));
	}
	mutex_unlock(&hdd_ctx->sap_lock);
	return;
}

/**
 * wlan_hdd_start_sap() - this function starts bss of SAP.
 * @ap_adapter: SAP adapter
 *
 * This function will process the starting of sap adapter.
 *
 * Return: None
 */
void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
{
	hdd_ap_ctx_t *hdd_ap_ctx;
	hdd_hostapd_state_t *hostapd_state;
	QDF_STATUS qdf_status;
	hdd_context_t *hdd_ctx;
	tsap_Config_t *sap_config;

	if (NULL == ap_adapter) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("ap_adapter is NULL here"));
		return;
	}

	if (WLAN_HDD_SOFTAP != ap_adapter->device_mode) {
		hdd_err("SoftAp role has not been enabled");
		return;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
	sap_config = &ap_adapter->sessionCtx.ap.sapConfig;

	if (0 != wlan_hdd_validate_context(hdd_ctx)) {
		hddLog(CDF_TRACE_LEVEL_ERROR,
		       FL("HDD context is not valid"));
		return;
	}
	mutex_lock(&hdd_ctx->sap_lock);
	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
		goto end;

	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
		hddLog(LOGE, FL("SAP Not able to set AP IEs"));
		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
		goto end;
	}

	if (wlansap_start_bss(hdd_ap_ctx->sapContext, hdd_hostapd_sap_event_cb,
			      &hdd_ap_ctx->sapConfig,
			      ap_adapter->dev)
			      != QDF_STATUS_SUCCESS)
		goto end;

	hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
	       FL("Waiting for SAP to start"));
	qdf_status = qdf_wait_single_event(&hostapd_state->cdf_event,
					BSS_WAIT_TIMEOUT);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hddLog(CDF_TRACE_LEVEL_ERROR, FL("SAP Start failed"));
		goto end;
	}
	hddLog(CDF_TRACE_LEVEL_INFO_HIGH, FL("SAP Start Success"));
	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
	cds_incr_active_session(ap_adapter->device_mode,
					ap_adapter->sessionId);
	hostapd_state->bCommit = true;

end:
	mutex_unlock(&hdd_ctx->sap_lock);
	return;
}
#endif

/**
 * hdd_get_fw_version() - Get FW version
 * @hdd_ctx:     pointer to HDD context.
 * @major_spid:  FW version - major spid.
 * @minor_spid:  FW version - minor spid
 * @ssid:        FW version - ssid
 * @crmid:       FW version - crmid
 *
 * This function is called to get the firmware build version stored
 * as part of the HDD context
 *
 * Return:   None
 */
void hdd_get_fw_version(hdd_context_t *hdd_ctx,
			uint32_t *major_spid, uint32_t *minor_spid,
			uint32_t *siid, uint32_t *crmid)
{
	*major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
	*minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
	*siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
	*crmid = hdd_ctx->target_fw_version & 0x7fff;
}

#ifdef QCA_CONFIG_SMP
/**
 * wlan_hdd_get_cpu() - get cpu_index
 *
 * Return: cpu_index
 */
int wlan_hdd_get_cpu(void)
{
	int cpu_index = get_cpu();
	put_cpu();
	return cpu_index;
}
#endif

/**
 * hdd_get_fwpath() - get framework path
 *
 * This function is used to get the string written by
 * userspace to start the wlan driver
 *
 * Return: string
 */
const char *hdd_get_fwpath(void)
{
	return fwpath.string;
}

/**
 * hdd_init() - Initialize Driver
 *
 * This function initilizes CDS global context with the help of cds_init. This
 * has to be the first function called after probe to get a valid global
 * context.
 *
 * Return: 0 for success, errno on failure
 */
int hdd_init(void)
{
	v_CONTEXT_t p_cds_context = NULL;
	int ret = 0;

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
	wlan_logging_sock_init_svc();
#endif
	p_cds_context = cds_init();

	if (p_cds_context == NULL) {
		hdd_alert("Failed to allocate CDS context");
		ret = -ENOMEM;
		goto err_out;
	}

	hdd_trace_init();

err_out:
	return ret;
}

/**
 * hdd_deinit() - Deinitialize Driver
 *
 * This function frees CDS global context with the help of cds_deinit. This
 * has to be the last function call in remove callback to free the global
 * context.
 */
void hdd_deinit(void)
{
	cds_deinit();

#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
	wlan_logging_sock_deinit_svc();
#endif
}

#ifdef QCA_WIFI_3_0_ADRASTEA
#define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
#else
#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
#endif

/**
 * __hdd_module_init - Module init helper
 *
 * Module init helper function used by both module and static driver.
 *
 * Return: 0 for success, errno on failure
 */
static int __hdd_module_init(void)
{
	int ret = 0;

	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);

	cdf_wake_lock_init(&wlan_wake_lock, "wlan");

	hdd_set_conparam((uint32_t) con_mode);

	ret = wlan_hdd_register_driver();
	if (ret) {
		pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
		goto out;
	}

	pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);

	return 0;
out:
	cdf_wake_lock_destroy(&wlan_wake_lock);
	return ret;
}

/**
 * __hdd_module_exit - Module exit helper
 *
 * Module exit helper function used by both module and static driver.
 */
static void __hdd_module_exit(void)
{
	pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
		QWLAN_VERSIONSTR);

	wlan_hdd_unregister_driver();

	cdf_wake_lock_destroy(&wlan_wake_lock);

	return;
}

/**
 * hdd_module_init() - Init Function
 *
 * This is the driver entry point (invoked when module is loaded using insmod)
 *
 * Return: 0 for success, non zero for failure
 */
#ifdef MODULE
static int __init hdd_module_init(void)
{
	return __hdd_module_init();
}
#else /* #ifdef MODULE */
static int __init hdd_module_init(void)
{
	/* Driver initialization is delayed to fwpath_changed_handler */
	return 0;
}
#endif /* #ifdef MODULE */

/**
 * hdd_module_exit() - Exit function
 *
 * This is the driver exit point (invoked when module is unloaded using rmmod)
 *
 * Return: None
 */
static void __exit hdd_module_exit(void)
{
	__hdd_module_exit();
}

#ifdef MODULE
static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
{
	return param_set_copystring(kmessage, kp);
}
#else /* #ifdef MODULE */

/**
 * kickstart_driver() - driver entry point
 *
 * This is the driver entry point
 * - delayed driver initialization when driver is statically linked
 * - invoked when module parameter fwpath is modified from userspace to signal
 *   initializing the WLAN driver or when con_mode is modified from userspace
 *   to signal a switch in operating mode
 *
 * Return: 0 for success, non zero for failure
 */
static int kickstart_driver(void)
{
	int ret = 0;

	if (!wlan_hdd_inited) {
		ret = __hdd_module_init();
		wlan_hdd_inited = ret ? 0 : 1;

		return ret;
	}

	__hdd_module_exit();

	msleep(200);

	ret = __hdd_module_init();

	wlan_hdd_inited = ret ? 0 : 1;

	return ret;
}

/**
 * fwpath_changed_handler() - Handler Function
 *
 * Handle changes to the fwpath parameter
 *
 * Return: 0 for success, non zero for failure
 */
static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
{
	int ret;

	ret = param_set_copystring(kmessage, kp);
	if (0 == ret)
		ret = kickstart_driver();
	return ret;
}

#ifdef QCA_WIFI_FTM
/**
 * con_mode_handler() - Handles module param con_mode change
 *
 * Handler function for module param con_mode when it is changed by userspace
 * Dynamically linked - do nothing
 * Statically linked - exit and init driver, as in rmmod and insmod
 *
 * Return -
 */
static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
{
	int ret;

	ret = param_set_int(kmessage, kp);
	if (0 == ret)
		ret = kickstart_driver();
	return ret;
}
#endif /* QCA_WIFI_FTM */
#endif /* #ifdef MODULE */

/**
 * hdd_get_conparam() - driver exit point
 *
 * This is the driver exit point (invoked when module is unloaded using rmmod)
 *
 * Return: enum tQDF_GLOBAL_CON_MODE
 */
enum tQDF_GLOBAL_CON_MODE hdd_get_conparam(void)
{
	return (enum tQDF_GLOBAL_CON_MODE) curr_con_mode;
}

void hdd_set_conparam(uint32_t con_param)
{
	curr_con_mode = con_param;
}

#ifdef WLAN_FEATURE_LPSS
static inline bool hdd_is_lpass_supported(hdd_context_t *hdd_ctx)
{
	return hdd_ctx->config->enable_lpass_support;
}
#else
static inline bool hdd_is_lpass_supported(hdd_context_t *hdd_ctx)
{
	return false;
}
#endif

/**
 * hdd_update_ol_config - API to update ol configuration parameters
 * @hdd_ctx: HDD context
 *
 * Return: void
 */
static void hdd_update_ol_config(hdd_context_t *hdd_ctx)
{
	struct ol_config_info cfg;
	struct ol_context *ol_ctx = cds_get_context(CDF_MODULE_ID_BMI);

	if (!ol_ctx)
		return;

	cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
	cfg.enable_lpass_support = hdd_is_lpass_supported(hdd_ctx);

	ol_init_ini_config(ol_ctx, &cfg);
}

/**
 * hdd_update_hif_config - API to update HIF configuration parameters
 * @hdd_ctx: HDD Context
 *
 * Return: void
 */
static void hdd_update_hif_config(hdd_context_t *hdd_ctx)
{
	struct hif_opaque_softc *scn = cds_get_context(CDF_MODULE_ID_HIF);
	struct hif_config_info cfg;

	if (!scn)
		return;

	cfg.enable_self_recovery = hdd_ctx->config->enableSelfRecovery;
	hif_init_ini_config(scn, &cfg);
}

/**
 * hdd_update_config() - Initialize driver per module ini parameters
 * @hdd_ctx: HDD Context
 *
 * API is used to initialize all driver per module configuration parameters
 * Return: void
 */
void hdd_update_config(hdd_context_t *hdd_ctx)
{
	hdd_update_ol_config(hdd_ctx);
	hdd_update_hif_config(hdd_ctx);
}

/* Register the module init/exit functions */
module_init(hdd_module_init);
module_exit(hdd_module_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Qualcomm Atheros, Inc.");
MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");

#if !defined(MODULE) && defined(QCA_WIFI_FTM)
module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#else
module_param(con_mode, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif

module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);

module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);

module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
