/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 *
 * 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.
 */

/**
 * DOC:  wlan_hdd_cfg.c
 *
 * WLAN Host Device Driver configuration interface implementation
 */

/* Include Files */

#include <linux/firmware.h>
#include <linux/string.h>
#include <wlan_hdd_includes.h>
#include <wlan_hdd_main.h>
#include <wlan_hdd_assoc.h>
#include <wlan_hdd_cfg.h>
#include <linux/string.h>
#include <qdf_types.h>
#include <csr_api.h>
#include <wlan_hdd_misc.h>
#include <wlan_hdd_napi.h>
#include <cds_api.h>
#include "wlan_hdd_he.h"
#include <wlan_policy_mgr_api.h>
#include "wifi_pos_api.h"
#include "wlan_hdd_green_ap.h"
#include "wlan_hdd_twt.h"
#include "wlan_policy_mgr_ucfg.h"
#include "wlan_mlme_ucfg_api.h"
#include "wlan_mlme_public_struct.h"
#include "wlan_fwol_ucfg_api.h"
#include "cfg_ucfg_api.h"
#include "hdd_dp_cfg.h"

/**
 * get_next_line() - find and locate the new line pointer
 * @str: pointer to string
 *
 * This function returns a pointer to the character after the occurrence
 * of a new line character. It also modifies the original string by replacing
 * the '\n' character with the null character.
 *
 * Return: the pointer to the character at new line,
 *            or NULL if no new line character was found
 */
static char *get_next_line(char *str)
{
	char c;

	if (!str || *str == '\0')
		return NULL;

	c = *str;
	while (c != '\n' && c != '\0' && c != 0xd) {
		str = str + 1;
		c = *str;
	}

	if (c == '\0')
		return NULL;

	*str = '\0';
	return str + 1;
}

/** look for space. Ascii values to look are
 * 0x09 == horizontal tab
 * 0x0a == Newline ("\n")
 * 0x0b == vertical tab
 * 0x0c == Newpage or feed form.
 * 0x0d == carriage return (CR or "\r")
 * Null ('\0') should not considered as space.
 */
#define i_isspace(ch)  (((ch) >= 0x09 && (ch) <= 0x0d) || (ch) == ' ')

/**
 * i_trim() - trims any leading and trailing white spaces
 * @str: pointer to string
 *
 * Return: the pointer of the string
 */
static char *i_trim(char *str)
{
	char *ptr;

	if (*str == '\0')
		return str;

	/* Find the first non white-space */
	ptr = str;
	while (i_isspace(*ptr))
		ptr++;

	if (*ptr == '\0')
		return str;

	/* This is the new start of the string */
	str = ptr;

	/* Find the last non white-space */
	ptr += strlen(ptr) - 1;

	while (ptr != str && i_isspace(*ptr))
		ptr--;

	/* Null terminate the following character */
	ptr[1] = '\0';

	return str;
}

/** struct hdd_cfg_entry - ini configuration entry
 * @name: name of the entry
 * @value: value of the entry
 */
struct hdd_cfg_entry {
	char *name;
	char *value;
};

/**
 * update_mac_from_string() - convert string to 6 bytes mac address
 * @hdd_ctx: the pointer to hdd context
 * @mac_table: the mac_table to carry the conversion
 * @num: number of the interface
 *
 * 00AA00BB00CC -> 0x00 0xAA 0x00 0xBB 0x00 0xCC
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS update_mac_from_string(struct hdd_context *hdd_ctx,
					 struct hdd_cfg_entry *mac_table,
					 int num)
{
	int i = 0, j = 0, res = 0;
	char *candidate = NULL;
	struct qdf_mac_addr macaddr[QDF_MAX_CONCURRENCY_PERSONA];
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	memset(macaddr, 0, sizeof(macaddr));

	for (i = 0; i < num; i++) {
		candidate = mac_table[i].value;
		for (j = 0; j < QDF_MAC_ADDR_SIZE; j++) {
			res =
				hex2bin(&macaddr[i].bytes[j], &candidate[(j << 1)],
					1);
			if (res < 0)
				break;
		}
		if (res == 0 && !qdf_is_macaddr_zero(&macaddr[i])) {
			qdf_mem_copy((uint8_t *)&hdd_ctx->
				     provisioned_mac_addr[i].bytes[0],
				     (uint8_t *) &macaddr[i].bytes[0],
				     QDF_MAC_ADDR_SIZE);
		} else {
			status = QDF_STATUS_E_FAILURE;
			break;
		}
	}
	return status;
}

/**
 * hdd_set_power_save_offload_config() - set power save offload configuration
 * @hdd_ctx: the pointer to hdd context
 *
 * Return: none
 */
static void hdd_set_power_save_offload_config(struct hdd_context *hdd_ctx)
{
	uint32_t listen_interval = 0;
	char *power_usage = NULL;

	power_usage = ucfg_mlme_get_power_usage(hdd_ctx->psoc);
	if (!power_usage) {
		hdd_err("invalid power usage");
		return;
	}

	if (strcmp(power_usage, "Min") == 0)
		ucfg_mlme_get_bmps_min_listen_interval(hdd_ctx->psoc,
						       &listen_interval);
	else if (strcmp(power_usage, "Max") == 0)
		ucfg_mlme_get_bmps_max_listen_interval(hdd_ctx->psoc,
						       &listen_interval);
	/*
	 * Based on Mode Set the LI
	 * Otherwise default LI value of 1 will
	 * be taken
	 */
	if (listen_interval) {
		/*
		 * setcfg for listenInterval.
		 * Make sure CFG is updated because PE reads this
		 * from CFG at the time of assoc or reassoc
		 */
		ucfg_mlme_set_sap_listen_interval(hdd_ctx->psoc,
						  listen_interval);
	}
}

/**
 * hdd_update_mac_config() - update MAC address from cfg file
 * @hdd_ctx: the pointer to hdd context
 *
 * It overwrites the MAC address if config file exist.
 *
 * Return: QDF_STATUS_SUCCESS if the MAC address is found from cfg file
 *      and overwritten, otherwise QDF_STATUS_E_INVAL
 */
QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx)
{
	int status, i = 0;
	const struct firmware *fw = NULL;
	char *line, *buffer = NULL;
	char *temp = NULL;
	char *name, *value;
	int max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
	struct hdd_cfg_entry mac_table[QDF_MAX_CONCURRENCY_PERSONA];
	tSirMacAddr custom_mac_addr;

	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;

	memset(mac_table, 0, sizeof(mac_table));
	status = request_firmware(&fw, WLAN_MAC_FILE, hdd_ctx->parent_dev);
	if (status) {
		/*
		 * request_firmware "fails" if the file is not found, which is a
		 * valid setup for us, so log using debug instead of error
		 */
		hdd_debug("request_firmware failed; status:%d", status);
		return QDF_STATUS_E_FAILURE;
	}

	if (!fw || !fw->data || !fw->size) {
		hdd_alert("invalid firmware");
		qdf_status = QDF_STATUS_E_INVAL;
		goto config_exit;
	}

	hdd_debug("wlan_mac.bin size %zu", fw->size);

	temp = qdf_mem_malloc(fw->size + 1);

	if (!temp) {
		hdd_err("fail to alloc memory");
		qdf_status = QDF_STATUS_E_NOMEM;
		goto config_exit;
	}
	buffer = temp;
	qdf_mem_copy(buffer, fw->data, fw->size);
	buffer[fw->size] = 0x0;

	/* data format:
	 * Intf0MacAddress=00AA00BB00CC
	 * Intf1MacAddress=00AA00BB00CD
	 * END
	 */
	while (buffer) {
		line = get_next_line(buffer);
		buffer = i_trim(buffer);

		if (strlen((char *)buffer) == 0 || *buffer == '#') {
			buffer = line;
			continue;
		}
		if (strncmp(buffer, "END", 3) == 0)
			break;

		name = buffer;
		buffer = strnchr(buffer, strlen(buffer), '=');
		if (buffer) {
			*buffer++ = '\0';
			i_trim(name);
			if (strlen(name) != 0) {
				buffer = i_trim(buffer);
				if (strlen(buffer) == 12) {
					value = buffer;
					mac_table[i].name = name;
					mac_table[i++].value = value;
					if (i >= QDF_MAX_CONCURRENCY_PERSONA)
						break;
				}
			}
		}
		buffer = line;
	}

	if (i != 0 && i <= QDF_MAX_CONCURRENCY_PERSONA) {
		hdd_debug("%d Mac addresses provided", i);
	} else {
		hdd_err("invalid number of Mac address provided, nMac = %d", i);
		qdf_status = QDF_STATUS_E_INVAL;
		goto config_exit;
	}

	qdf_status = update_mac_from_string(hdd_ctx, &mac_table[0], i);
	if (QDF_IS_STATUS_ERROR(qdf_status)) {
		hdd_err("Invalid MAC addresses provided");
		goto config_exit;
	}
	hdd_ctx->num_provisioned_addr = i;
	hdd_debug("Populating remaining %d Mac addresses",
		   max_mac_addr - i);
	hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - i);

	if (hdd_ctx->num_provisioned_addr)
		qdf_mem_copy(&custom_mac_addr,
			     &hdd_ctx->provisioned_mac_addr[0].bytes[0],
			     sizeof(tSirMacAddr));
	else
		qdf_mem_copy(&custom_mac_addr,
			     &hdd_ctx->derived_mac_addr[0].bytes[0],
			     sizeof(tSirMacAddr));

	sme_set_custom_mac_addr(custom_mac_addr);

config_exit:
	qdf_mem_free(temp);
	release_firmware(fw);
	return qdf_status;
}

/**
 * hdd_disable_runtime_pm() - Override to disable runtime_pm.
 * @cfg_ini: Handle to struct hdd_config
 *
 * Return: None
 */
#ifdef FEATURE_RUNTIME_PM
static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
{
	cfg_ini->runtime_pm = 0;
}
#else
static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
{
}
#endif

/**
 * hdd_disable_auto_shutdown() - Override to disable auto_shutdown.
 * @cfg_ini: Handle to struct hdd_config
 *
 * Return: None
 */
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
{
	cfg_ini->wlan_auto_shutdown = 0;
}
#else
static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
{
}
#endif

void hdd_override_all_ps(struct hdd_context *hdd_ctx)
{
	struct hdd_config *cfg_ini = hdd_ctx->config;

	ucfg_mlme_override_bmps_imps(hdd_ctx->psoc);
	hdd_disable_runtime_pm(cfg_ini);
	hdd_disable_auto_shutdown(cfg_ini);
}

/**
 * hdd_cfg_xlate_to_csr_phy_mode() - convert PHY mode
 * @dot11Mode: the mode to convert
 *
 * Convert the configuration PHY mode to CSR PHY mode
 *
 * Return: the CSR phy mode value
 */
eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode(enum hdd_dot11_mode dot11Mode)
{
	if (cds_is_sub_20_mhz_enabled())
		return eCSR_DOT11_MODE_abg;

	switch (dot11Mode) {
	case (eHDD_DOT11_MODE_abg):
		return eCSR_DOT11_MODE_abg;
	case (eHDD_DOT11_MODE_11b):
		return eCSR_DOT11_MODE_11b;
	case (eHDD_DOT11_MODE_11g):
		return eCSR_DOT11_MODE_11g;
	default:
	case (eHDD_DOT11_MODE_11n):
		return eCSR_DOT11_MODE_11n;
	case (eHDD_DOT11_MODE_11g_ONLY):
		return eCSR_DOT11_MODE_11g_ONLY;
	case (eHDD_DOT11_MODE_11n_ONLY):
		return eCSR_DOT11_MODE_11n_ONLY;
	case (eHDD_DOT11_MODE_11b_ONLY):
		return eCSR_DOT11_MODE_11b_ONLY;
	case (eHDD_DOT11_MODE_11ac_ONLY):
		return eCSR_DOT11_MODE_11ac_ONLY;
	case (eHDD_DOT11_MODE_11ac):
		return eCSR_DOT11_MODE_11ac;
	case (eHDD_DOT11_MODE_AUTO):
		return eCSR_DOT11_MODE_AUTO;
	case (eHDD_DOT11_MODE_11a):
		return eCSR_DOT11_MODE_11a;
	case (eHDD_DOT11_MODE_11ax_ONLY):
		return eCSR_DOT11_MODE_11ax_ONLY;
	case (eHDD_DOT11_MODE_11ax):
		return eCSR_DOT11_MODE_11ax;
	}

}

/**
 * hdd_set_idle_ps_config() - set idle power save configuration
 * @hdd_ctx: the pointer to hdd context
 * @val: the value to configure
 *
 * Return: QDF_STATUS_SUCCESS if command set correctly,
 *		otherwise the QDF_STATUS return from SME layer
 */
QDF_STATUS hdd_set_idle_ps_config(struct hdd_context *hdd_ctx, bool val)
{
	QDF_STATUS status;

	hdd_debug("Enter Val %d", val);

	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
		hdd_debug("Skipping powersave in FTM");
		return QDF_STATUS_SUCCESS;
	}

	if (hdd_ctx->imps_enabled == val) {
		hdd_info("Already in the requested power state:%d", val);
		return QDF_STATUS_SUCCESS;
	}

	status = sme_set_idle_powersave_config(val);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Fail to Set Idle PS Config val %d", val);
		return status;
	}

	hdd_ctx->imps_enabled = val;

	return status;
}

/**
 * hdd_set_fine_time_meas_cap() - set fine timing measurement capability
 * @hdd_ctx: HDD context
 *
 * This function is used to pass fine timing measurement capability coming
 * from INI to SME. This function make sure that configure INI is supported
 * by the device. Use bit mask to mask out the unsupported capabilities.
 *
 * Return: None
 */
static void hdd_set_fine_time_meas_cap(struct hdd_context *hdd_ctx)
{
	uint32_t capability = 0;

	ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &capability);
	ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, capability);
	hdd_debug("fine time meas capability - Enabled: %04x", capability);
}

/**
 * hdd_convert_string_to_u8_array() - used to convert string into u8 array
 * @str: String to be converted
 * @hex_array: Array where converted value is stored
 * @len: Length of the populated array
 * @array_max_len: Maximum length of the array
 * @to_hex: true, if conversion required for hex string
 *
 * This API is called to convert string (each byte separated by
 * a comma) into an u8 array
 *
 * Return: QDF_STATUS
 */

static QDF_STATUS hdd_convert_string_to_array(char *str, uint8_t *array,
			     uint8_t *len, uint16_t array_max_len, bool to_hex)
{
	char *format, *s = str;

	if (!str || !array || !len)
		return QDF_STATUS_E_INVAL;

	format = (to_hex) ? "%02x" : "%d";

	*len = 0;
	while ((s) && (*len < array_max_len)) {
		int val;
		/* Increment length only if sscanf successfully extracted
		 * one element. Any other return value means error.
		 * Ignore it.
		 */
		if (sscanf(s, format, &val) == 1) {
			array[*len] = (uint8_t) val;
			*len += 1;
		}

		s = strpbrk(s, ",");
		if (s)
			s++;
	}

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS hdd_string_to_u8_array(char *str, uint8_t *array,
				  uint8_t *len, uint16_t array_max_len)
{
	return hdd_convert_string_to_array(str, array, len,
					   array_max_len, false);
}

/**
 * hdd_hex_string_to_u16_array() - convert a hex string to a uint16 array
 * @str: input string
 * @int_array: pointer to input array of type uint16
 * @len: pointer to number of elements which the function adds to the array
 * @int_array_max_len: maximum number of elements in input uint16 array
 *
 * This function is used to convert a space separated hex string to an array of
 * uint16_t. For example, an input string str = "a b c d" would be converted to
 * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4.
 * This assumes that input value int_array_max_len >= 4.
 *
 * Return: QDF_STATUS_SUCCESS - if the conversion is successful
 *         non zero value     - if the conversion is a failure
 */
QDF_STATUS hdd_hex_string_to_u16_array(char *str,
		uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len)
{
	char *s = str;
	uint32_t val = 0;

	if (!str || !int_array || !len)
		return QDF_STATUS_E_INVAL;

	hdd_debug("str %pK intArray %pK intArrayMaxLen %d",
		s, int_array, int_array_max_len);

	*len = 0;

	while ((s) && (*len < int_array_max_len)) {
		/*
		 * Increment length only if sscanf successfully extracted one
		 * element. Any other return value means error. Ignore it.
		 */
		if (sscanf(s, "%x", &val) == 1) {
			int_array[*len] = (uint16_t) val;
			hdd_debug("s %pK val %x intArray[%d]=0x%x",
				s, val, *len, int_array[*len]);
			*len += 1;
		}
		s = strpbrk(s, " ");
		if (s)
			s++;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_update_config_cfg() - API to update INI setting based on hw/fw caps
 * @hdd_ctx: pointer to hdd_ctx
 *
 * This API reads the cfg file which is updated with hardware/firmware
 * capabilities and intersect it with INI setting provided by user. After
 * taking intersection it adjust cfg it self. For example, if user has enabled
 * RX LDPC through INI but hardware/firmware doesn't support it then disable
 * it in CFG file here.
 *
 * Return: true or false based on outcome.
 */
bool hdd_update_config_cfg(struct hdd_context *hdd_ctx)
{
	bool status = true;

	/*
	 * During the initialization both 2G and 5G capabilities should be same.
	 * So read 5G HT capablity and update 2G and 5G capablities.
	 */

	if (0 != hdd_update_he_cap_in_cfg(hdd_ctx)) {
		status = false;
		hdd_err("Couldn't set HE CAP in cfg");
	}

	return status;
}

/**
 * hdd_set_policy_mgr_user_cfg() -initializes the policy manager
 * configuration parameters
 *
 * @hdd_ctx: the pointer to hdd context
 *
 * Return: QDF_STATUS_SUCCESS if configuration is correctly applied,
 *		otherwise the appropriate QDF_STATUS would be returned
 */
QDF_STATUS hdd_set_policy_mgr_user_cfg(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status;
	struct policy_mgr_user_cfg *user_cfg;

	user_cfg = qdf_mem_malloc(sizeof(*user_cfg));
	if (!user_cfg) {
		hdd_err("unable to allocate user_cfg");
		return QDF_STATUS_E_NOMEM;
	}

	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc,
					     &user_cfg->enable2x2);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("unable to get vht_enable2x2");

	user_cfg->sub_20_mhz_enabled = cds_is_sub_20_mhz_enabled();
	status = policy_mgr_set_user_cfg(hdd_ctx->psoc, user_cfg);
	qdf_mem_free(user_cfg);

	return status;
}

eCsrRoamWmmUserModeType hdd_to_csr_wmm_mode(uint8_t mode)
{
	switch (mode) {
	case HDD_WMM_USER_MODE_QBSS_ONLY:
		return eCsrRoamWmmQbssOnly;
	case HDD_WMM_USER_MODE_NO_QOS:
		return eCsrRoamWmmNoQos;
	case HDD_WMM_USER_MODE_AUTO:
	default:
		return eCsrRoamWmmAuto;
	}
}

static QDF_STATUS
hdd_set_sme_cfgs_related_to_plcy_mgr(struct hdd_context *hdd_ctx,
				     struct sme_config_params *sme_cfg)
{
	uint8_t mcc_to_scc_switch = 0, is_force_1x1 = 0, allow_diff_bi = 0;
	uint8_t conc_rule1 = 0, conc_rule2 = 0, sta_cxn_5g = 0;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
					       &mcc_to_scc_switch)) {
		hdd_err("can't get mcc to scc switch");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.cc_switch_mode = mcc_to_scc_switch;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc,
					   &conc_rule1)) {
		hdd_err("can't get conc rule1");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.conc_custom_rule1 = conc_rule1;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_conc_rule2(hdd_ctx->psoc,
					   &conc_rule2)) {
		hdd_err("can't get conc rule2");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.conc_custom_rule2 = conc_rule2;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_sta_cxn_5g_band(hdd_ctx->psoc,
						&sta_cxn_5g)) {
		hdd_err("can't get conc rule2");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.is_sta_connection_in_5gz_enabled = sta_cxn_5g;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc,
					  &is_force_1x1)) {
		hdd_err("can't get force 1x1 flag");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.is_force_1x1 = is_force_1x1;

	if (QDF_STATUS_SUCCESS !=
	    ucfg_policy_mgr_get_allow_mcc_go_diff_bi(hdd_ctx->psoc,
						     &allow_diff_bi)) {
		hdd_err("can't get allow mcc go diff BI flag");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.fAllowMCCGODiffBI = allow_diff_bi;

	return QDF_STATUS_SUCCESS;
}

#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
static QDF_STATUS hdd_set_sap_mcc_chnl_avoid(struct sme_config_params *sme_cfg,
					     uint8_t val)
{
	sme_cfg->csr_config.sap_channel_avoidance = val;
	return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS hdd_set_sap_mcc_chnl_avoid(struct sme_config_params *sme_cfg,
					     uint8_t val)
{
	return QDF_STATUS_SUCCESS;
}
#endif

static
QDF_STATUS hdd_set_sme_cfgs_related_to_mlme(struct hdd_context *hdd_ctx,
					    struct sme_config_params *sme_cfg)
{
	QDF_STATUS status;
	uint8_t wmm_mode = 0, enable_mcc = 0, sap_mcc_avoid = 0;
	uint8_t mcc_rts_cts = 0, mcc_bcast_prob_rsp = 0;
	uint32_t mcast_mcc_rest_time = 0;
	bool b80211e_enabled = 0;

	status = ucfg_mlme_get_80211e_is_enabled(hdd_ctx->psoc,
						 &b80211e_enabled);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("Get b80211e_enabled failed");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.Is11eSupportEnabled = b80211e_enabled;

	status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("Get wmm_mode failed");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.WMMSupportMode = hdd_to_csr_wmm_mode(wmm_mode);
	hdd_debug("wmm_mode=%d 802_11e_enabled=%d", wmm_mode, b80211e_enabled);

	status = ucfg_mlme_get_mcc_feature(hdd_ctx->psoc, &enable_mcc);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("ucfg_mlme_get_mcc_feature fail, use def");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.fEnableMCCMode = enable_mcc;

	status = ucfg_mlme_get_mcc_rts_cts_prot(hdd_ctx->psoc, &mcc_rts_cts);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("ucfg_mlme_get_mcc_rts_cts_prot fail, use def");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.mcc_rts_cts_prot_enable = mcc_rts_cts;

	status = ucfg_mlme_get_mcc_bcast_prob_resp(hdd_ctx->psoc,
						   &mcc_bcast_prob_rsp);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("ucfg_mlme_get_mcc_bcast_prob_resp fail, use def");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.mcc_bcast_prob_resp_enable = mcc_bcast_prob_rsp;

	status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
							  &mcast_mcc_rest_time);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
		return QDF_STATUS_E_FAILURE;
	}
	sme_cfg->csr_config.f_sta_miracast_mcc_rest_time_val =
							mcast_mcc_rest_time;
	status = ucfg_mlme_get_sap_mcc_chnl_avoid(hdd_ctx->psoc,
						  &sap_mcc_avoid);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("ucfg_mlme_get_sap_mcc_chnl_avoid, use def");
		return QDF_STATUS_E_FAILURE;
	}
	status = hdd_set_sap_mcc_chnl_avoid(sme_cfg, sap_mcc_avoid);

	return status;
}

/**
 * hdd_set_sme_config() -initializes the sme configuration parameters
 *
 * @hdd_ctx: the pointer to hdd context
 *
 * Return: QDF_STATUS_SUCCESS if configuration is correctly applied,
 *		otherwise the appropriate QDF_STATUS would be returned
 */
QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	struct sme_config_params *sme_config;
	mac_handle_t mac_handle = hdd_ctx->mac_handle;
	bool roam_scan_enabled;
	bool enable_dfs_scan = true;
	uint32_t channel_bonding_mode;

#ifdef FEATURE_WLAN_ESE
	bool ese_enabled;
#endif
	struct wlan_mlme_ibss_cfg ibss_cfg = {0};

	struct hdd_config *config = hdd_ctx->config;

	if (QDF_IS_STATUS_ERROR(ucfg_mlme_get_ibss_cfg(
				hdd_ctx->psoc, &ibss_cfg))) {
		hdd_err("Unable to get IBSS config params");
		return QDF_STATUS_E_FAILURE;
	}

	sme_config = qdf_mem_malloc(sizeof(*sme_config));
	if (!sme_config) {
		hdd_err("unable to allocate sme_config");
		return QDF_STATUS_E_NOMEM;
	}

	/* Config params obtained from the registry
	 * To Do: set regulatory information here
	 */
	sme_config->csr_config.phyMode =
		hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);

	if (config->dot11Mode == eHDD_DOT11_MODE_abg ||
	    config->dot11Mode == eHDD_DOT11_MODE_11b ||
	    config->dot11Mode == eHDD_DOT11_MODE_11g ||
	    config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY ||
	    config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY) {
		sme_config->csr_config.channelBondingMode24GHz = 0;
		sme_config->csr_config.channelBondingMode5GHz = 0;
	} else {
		ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
						    &channel_bonding_mode);
		sme_config->csr_config.channelBondingMode24GHz =
			channel_bonding_mode;
		ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
						   &channel_bonding_mode);
		sme_config->csr_config.channelBondingMode5GHz =
			channel_bonding_mode;
	}
	/* Remaining config params not obtained from registry
	 * On RF EVB beacon using channel 1.
	 */
	/* This param cannot be configured from INI */
	sme_config->csr_config.send_smps_action = true;
	sme_config->csr_config.ad_hoc_ch_freq_5g = ibss_cfg.adhoc_ch_5g;
	sme_config->csr_config.ad_hoc_ch_freq_2g = ibss_cfg.adhoc_ch_2g;
	sme_config->csr_config.ProprietaryRatesEnabled = 0;
	sme_config->csr_config.HeartbeatThresh50 = 40;
	ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc,
						&enable_dfs_scan);
	sme_config->csr_config.fEnableDFSChnlScan = enable_dfs_scan;
	sme_config->csr_config.Csr11dinfo.Channels.numChannels = 0;

	hdd_set_power_save_offload_config(hdd_ctx);

#ifdef FEATURE_WLAN_ESE
	ucfg_mlme_is_ese_enabled(hdd_ctx->psoc, &ese_enabled);
	if (ese_enabled)
		ucfg_mlme_set_fast_transition_enabled(hdd_ctx->psoc, true);
#endif

	ucfg_mlme_is_roam_scan_offload_enabled(hdd_ctx->psoc,
					       &roam_scan_enabled);

	if (!roam_scan_enabled) {
		/* Disable roaming in concurrency if roam scan
		 * offload is disabled
		 */
		ucfg_mlme_set_fast_roam_in_concurrency_enabled(
					hdd_ctx->psoc, false);
	}

	sme_config->csr_config.isCoalesingInIBSSAllowed =
						ibss_cfg.coalesing_enable;

	/* Update maximum interfaces information */
	sme_config->csr_config.max_intf_count = hdd_ctx->max_intf_count;

	hdd_set_fine_time_meas_cap(hdd_ctx);

	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);

	sme_config->csr_config.sta_roam_policy_params.dfs_mode =
		CSR_STA_ROAM_POLICY_DFS_ENABLED;
	sme_config->csr_config.sta_roam_policy_params.skip_unsafe_channels = 0;

	status = hdd_set_sme_cfgs_related_to_mlme(hdd_ctx, sme_config);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("hdd_set_sme_cfgs_related_to_mlme() fail: %d", status);
	status = hdd_set_sme_cfgs_related_to_plcy_mgr(hdd_ctx, sme_config);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("hdd_set_sme_cfgs_related_to_plcy_mgr fail: %d",
			status);
	hdd_debug("dot11Mode=%d", config->dot11Mode);
	status = sme_update_config(mac_handle, sme_config);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("sme_update_config() failure: %d", status);

	qdf_mem_free(sme_config);
	return status;
}

/**
 * hdd_cfg_get_global_config() - get the configuration table
 * @hdd_ctx: pointer to hdd context
 * @buf: buffer to store the configuration
 * @buflen: size of the buffer
 *
 * Return: none
 */
void hdd_cfg_get_global_config(struct hdd_context *hdd_ctx, char *buf,
			       int buflen)
{
	ucfg_cfg_store_print(hdd_ctx->psoc);

	snprintf(buf, buflen,
		 "WLAN configuration written to debug log");
}

/**
 * hdd_cfg_print_global_config() - print the configuration table
 * @hdd_ctx: pointer to hdd context
 *
 * Return: none
 */
void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status;

	status = ucfg_cfg_store_print(hdd_ctx->psoc);
	if (QDF_IS_STATUS_ERROR(status))
		hdd_err("Failed to log cfg ini");
}

/**
 * hdd_get_pmkid_modes() - returns PMKID mode bits
 * @hdd_ctx: the pointer to hdd context
 *
 * Return: value of pmkid_modes
 */
void hdd_get_pmkid_modes(struct hdd_context *hdd_ctx,
			 struct pmkid_mode_bits *pmkid_modes)
{
	uint32_t cur_pmkid_modes;
	QDF_STATUS status;

	status = ucfg_mlme_get_pmkid_modes(hdd_ctx->psoc, &cur_pmkid_modes);
	if (status != QDF_STATUS_SUCCESS)
		hdd_err("get pmkid modes fail");

	pmkid_modes->fw_okc = (cur_pmkid_modes &
			       CFG_PMKID_MODES_OKC) ? 1 : 0;
	pmkid_modes->fw_pmksa_cache = (cur_pmkid_modes &
				       CFG_PMKID_MODES_PMKSA_CACHING) ? 1 : 0;
}

static void
hdd_populate_vdev_nss(struct wlan_mlme_nss_chains *user_cfg,
		      uint8_t tx_nss,
		      uint8_t rx_nss,
		      enum nss_chains_band_info  band)
{
	user_cfg->rx_nss[band] = rx_nss;
	user_cfg->tx_nss[band] = tx_nss;
}

static QDF_STATUS
hdd_set_nss_params(struct hdd_adapter *adapter,
		   uint8_t tx_nss,
		   uint8_t rx_nss)
{
	enum nss_chains_band_info band;
	struct wlan_mlme_nss_chains user_cfg;
	mac_handle_t mac_handle;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	qdf_mem_zero(&user_cfg, sizeof(user_cfg));

	mac_handle = hdd_ctx->mac_handle;
	if (!mac_handle) {
		hdd_err("NULL MAC handle");
		return QDF_STATUS_E_INVAL;
	}

	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++)
		hdd_populate_vdev_nss(&user_cfg, tx_nss,
				      rx_nss, band);
	if (QDF_IS_STATUS_ERROR(
		sme_nss_chains_update(mac_handle,
				      &user_cfg,
				      adapter->vdev_id)))
		return QDF_STATUS_E_FAILURE;

	/* Check TDLS status and update antenna mode */
	if ((adapter->device_mode == QDF_STA_MODE ||
	     adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
	     policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
		wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter, rx_nss);

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_update_nss() - Update the number of spatial streams supported.
 * Ensure that nss is either 1 or 2 before calling this.
 *
 * @adapter: the pointer to adapter
 * @nss: the number of spatial streams to be updated
 *
 * This function is used to modify the number of spatial streams
 * supported when not in connected state.
 *
 * Return: QDF_STATUS_SUCCESS if nss is correctly updated,
 *              otherwise QDF_STATUS_E_FAILURE would be returned
 */
QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	uint32_t rx_supp_data_rate, tx_supp_data_rate;
	bool status = true;
	QDF_STATUS qdf_status;
	qdf_size_t val_len;
	struct mlme_ht_capabilities_info ht_cap_info;
	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET] = {0};
	uint8_t mcs_set_temp[SIZE_OF_SUPPORTED_MCS_SET];
	uint8_t enable2x2;
	mac_handle_t mac_handle;
	bool bval = 0;
	uint8_t tx_nss, rx_nss;
	uint8_t band, max_supp_nss;

	if ((nss == 2) && (hdd_ctx->num_rf_chains != 2)) {
		hdd_err("No support for 2 spatial streams");
		return QDF_STATUS_E_INVAL;
	}

	if (nss > MAX_VDEV_NSS) {
		hdd_debug("Cannot support %d nss streams", nss);
		return QDF_STATUS_E_INVAL;
	}

	qdf_status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("unable to get vht_enable2x2");
		return QDF_STATUS_E_FAILURE;
	}

	mac_handle = hdd_ctx->mac_handle;
	if (!mac_handle) {
		hdd_err("NULL MAC handle");
		return QDF_STATUS_E_INVAL;
	}
	max_supp_nss = MAX_VDEV_NSS;

	/* Till now we dont have support for different rx, tx nss values */
	tx_nss = nss;
	rx_nss = nss;

	/*
	 * If FW is supporting the dynamic nss update, this command is meant to
	 * be per vdev, so update only the ini params of that particular vdev
	 * and not the global param enable2x2
	 */
	if (hdd_ctx->dynamic_nss_chains_support) {
		if (hdd_is_vdev_in_conn_state(adapter))
			return hdd_set_nss_params(adapter, tx_nss, rx_nss);
		hdd_debug("Vdev %d in disconnect state, changing ini nss params",
			  adapter->vdev_id);
		if (!bval) {
			hdd_err("Nss in 1x1, no change required, 2x2 mode disabled");
			return QDF_STATUS_E_FAILURE;
		}

		for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX;
		     band++) {
			/* This API will change the global ini in mlme cfg */
			sme_update_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
						   adapter->device_mode, band);
			/*
			 * This API will change the vdev nss params in mac
			 * context
			 */
			sme_update_vdev_type_nss(mac_handle, max_supp_nss,
						 band);
		}
		/*
		 * This API will change the ini and dynamic nss params in
		 * mlme vdev priv obj.
		 */
		hdd_store_nss_chains_cfg_in_vdev(adapter);

		return QDF_STATUS_SUCCESS;
	}

	/*
	 * The code below is executed only when fw doesn't support dynamic
	 * update of nss and chains per vdev feature, for the upcoming
	 * connection
	 */
	enable2x2 = (nss == 1) ? 0 : 1;

	if (bval == enable2x2) {
		hdd_debug("NSS same as requested");
		return QDF_STATUS_SUCCESS;
	}

	if (sme_is_any_session_in_connected_state(mac_handle)) {
		hdd_err("Connected sessions present, Do not change NSS");
		return QDF_STATUS_E_INVAL;
	}

	qdf_status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, enable2x2);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to set vht_enable2x2");
		return QDF_STATUS_E_FAILURE;
	}

	if (!enable2x2) {
		/* 1x1 */
		rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
		tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
	} else {
		/* 2x2 */
		rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
		tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
	}

	/* Update Rx Highest Long GI data Rate */
	qdf_status =
		ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc,
							rx_supp_data_rate);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to set rx_supp_data_rate");
		status = false;
	}
	/* Update Tx Highest Long GI data Rate */
	qdf_status =
		ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc,
							tx_supp_data_rate);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to set tx_supp_data_rate");
		status = false;
	}

	qdf_status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to get HT Cap info");
		goto skip_ht_cap_update;
	}

	if (!(hdd_ctx->ht_tx_stbc_supported && enable2x2)) {
		ht_cap_info.tx_stbc = 0;
	} else {
		qdf_status =
			ucfg_mlme_cfg_get_vht_tx_stbc(hdd_ctx->psoc, &bval);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			hdd_err("Failed to get vht_tx_stbc");
			ht_cap_info.tx_stbc = bval;
		}
	}

	qdf_status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Could not set the HT_CAP_INFO");
	}
skip_ht_cap_update:
	qdf_status = ucfg_mlme_update_nss_vht_cap(hdd_ctx->psoc);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to set update_nss_vht_cap");
		status = false;
	}

#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
	val_len = SIZE_OF_SUPPORTED_MCS_SET;
	qdf_status = ucfg_mlme_get_supported_mcs_set(hdd_ctx->psoc,
						     mcs_set_temp,
						     &val_len);
	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mcs_set[0] = mcs_set_temp[0];
		if (enable2x2)
			for (val_len = 0; val_len < nss; val_len++)
				mcs_set[val_len] =
				WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
		if (ucfg_mlme_set_supported_mcs_set(
			hdd_ctx->psoc, mcs_set,
			(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET) ==
			QDF_STATUS_E_FAILURE) {
			status = false;
			hdd_err("Could not pass on MCS SET to CFG");
		}
	} else {
		status = false;
		hdd_err("Could not get MCS SET from CFG");
	}
	sme_update_he_cap_nss(mac_handle, adapter->vdev_id, nss);
#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES

	if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, nss))
		status = false;

	hdd_set_policy_mgr_user_cfg(hdd_ctx);

	return (status == false) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
}
