18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * NXP Wireless LAN device driver: station command handling
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright 2011-2020 NXP
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software file (the "File") is distributed by NXP
78c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License Version 2, June 1991
88c2ecf20Sopenharmony_ci * (the "License").  You may use, redistribute and/or modify this File in
98c2ecf20Sopenharmony_ci * accordance with the terms and conditions of the License, a copy of which
108c2ecf20Sopenharmony_ci * is available by writing to the Free Software Foundation, Inc.,
118c2ecf20Sopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
128c2ecf20Sopenharmony_ci * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
158c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
168c2ecf20Sopenharmony_ci * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
178c2ecf20Sopenharmony_ci * this warranty disclaimer.
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include "decl.h"
218c2ecf20Sopenharmony_ci#include "ioctl.h"
228c2ecf20Sopenharmony_ci#include "util.h"
238c2ecf20Sopenharmony_ci#include "fw.h"
248c2ecf20Sopenharmony_ci#include "main.h"
258c2ecf20Sopenharmony_ci#include "wmm.h"
268c2ecf20Sopenharmony_ci#include "11n.h"
278c2ecf20Sopenharmony_ci#include "11ac.h"
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic bool drcs;
308c2ecf20Sopenharmony_cimodule_param(drcs, bool, 0644);
318c2ecf20Sopenharmony_ciMODULE_PARM_DESC(drcs, "multi-channel operation:1, single-channel operation:0");
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic bool disable_auto_ds;
348c2ecf20Sopenharmony_cimodule_param(disable_auto_ds, bool, 0);
358c2ecf20Sopenharmony_ciMODULE_PARM_DESC(disable_auto_ds,
368c2ecf20Sopenharmony_ci		 "deepsleep enabled=0(default), deepsleep disabled=1");
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * This function prepares command to set/get RSSI information.
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci * Preparation includes -
418c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
428c2ecf20Sopenharmony_ci *      - Setting data/beacon average factors
438c2ecf20Sopenharmony_ci *      - Resetting SNR/NF/RSSI values in private structure
448c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
458c2ecf20Sopenharmony_ci */
468c2ecf20Sopenharmony_cistatic int
478c2ecf20Sopenharmony_cimwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv,
488c2ecf20Sopenharmony_ci			     struct host_cmd_ds_command *cmd, u16 cmd_action)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_RSSI_INFO);
518c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info) +
528c2ecf20Sopenharmony_ci				S_DS_GEN);
538c2ecf20Sopenharmony_ci	cmd->params.rssi_info.action = cpu_to_le16(cmd_action);
548c2ecf20Sopenharmony_ci	cmd->params.rssi_info.ndata = cpu_to_le16(priv->data_avg_factor);
558c2ecf20Sopenharmony_ci	cmd->params.rssi_info.nbcn = cpu_to_le16(priv->bcn_avg_factor);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	/* Reset SNR/NF/RSSI values in private structure */
588c2ecf20Sopenharmony_ci	priv->data_rssi_last = 0;
598c2ecf20Sopenharmony_ci	priv->data_nf_last = 0;
608c2ecf20Sopenharmony_ci	priv->data_rssi_avg = 0;
618c2ecf20Sopenharmony_ci	priv->data_nf_avg = 0;
628c2ecf20Sopenharmony_ci	priv->bcn_rssi_last = 0;
638c2ecf20Sopenharmony_ci	priv->bcn_nf_last = 0;
648c2ecf20Sopenharmony_ci	priv->bcn_rssi_avg = 0;
658c2ecf20Sopenharmony_ci	priv->bcn_nf_avg = 0;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	return 0;
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci/*
718c2ecf20Sopenharmony_ci * This function prepares command to set MAC control.
728c2ecf20Sopenharmony_ci *
738c2ecf20Sopenharmony_ci * Preparation includes -
748c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
758c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_cistatic int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
788c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
798c2ecf20Sopenharmony_ci				   u16 cmd_action, u32 *action)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	if (cmd_action != HostCmd_ACT_GEN_SET) {
848c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
858c2ecf20Sopenharmony_ci			    "mac_control: only support set cmd\n");
868c2ecf20Sopenharmony_ci		return -1;
878c2ecf20Sopenharmony_ci	}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
908c2ecf20Sopenharmony_ci	cmd->size =
918c2ecf20Sopenharmony_ci		cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN);
928c2ecf20Sopenharmony_ci	mac_ctrl->action = cpu_to_le32(*action);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	return 0;
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/*
988c2ecf20Sopenharmony_ci * This function prepares command to set/get SNMP MIB.
998c2ecf20Sopenharmony_ci *
1008c2ecf20Sopenharmony_ci * Preparation includes -
1018c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
1028c2ecf20Sopenharmony_ci *      - Setting SNMP MIB OID number and value
1038c2ecf20Sopenharmony_ci *        (as required)
1048c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
1058c2ecf20Sopenharmony_ci *
1068c2ecf20Sopenharmony_ci * The following SNMP MIB OIDs are supported -
1078c2ecf20Sopenharmony_ci *      - FRAG_THRESH_I     : Fragmentation threshold
1088c2ecf20Sopenharmony_ci *      - RTS_THRESH_I      : RTS threshold
1098c2ecf20Sopenharmony_ci *      - SHORT_RETRY_LIM_I : Short retry limit
1108c2ecf20Sopenharmony_ci *      - DOT11D_I          : 11d support
1118c2ecf20Sopenharmony_ci */
1128c2ecf20Sopenharmony_cistatic int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
1138c2ecf20Sopenharmony_ci				       struct host_cmd_ds_command *cmd,
1148c2ecf20Sopenharmony_ci				       u16 cmd_action, u32 cmd_oid,
1158c2ecf20Sopenharmony_ci				       u16 *ul_temp)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD,
1208c2ecf20Sopenharmony_ci		    "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
1218c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
1228c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
1238c2ecf20Sopenharmony_ci				- 1 + S_DS_GEN);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
1268c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_GET) {
1278c2ecf20Sopenharmony_ci		snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
1288c2ecf20Sopenharmony_ci		snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
1298c2ecf20Sopenharmony_ci		le16_unaligned_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
1308c2ecf20Sopenharmony_ci	} else if (cmd_action == HostCmd_ACT_GEN_SET) {
1318c2ecf20Sopenharmony_ci		snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
1328c2ecf20Sopenharmony_ci		snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
1338c2ecf20Sopenharmony_ci		put_unaligned_le16(*ul_temp, snmp_mib->value);
1348c2ecf20Sopenharmony_ci		le16_unaligned_add_cpu(&cmd->size, sizeof(u16));
1358c2ecf20Sopenharmony_ci	}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD,
1388c2ecf20Sopenharmony_ci		    "cmd: SNMP_CMD: Action=0x%x, OID=0x%x,\t"
1398c2ecf20Sopenharmony_ci		    "OIDSize=0x%x, Value=0x%x\n",
1408c2ecf20Sopenharmony_ci		    cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
1418c2ecf20Sopenharmony_ci		    get_unaligned_le16(snmp_mib->value));
1428c2ecf20Sopenharmony_ci	return 0;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/*
1468c2ecf20Sopenharmony_ci * This function prepares command to get log.
1478c2ecf20Sopenharmony_ci *
1488c2ecf20Sopenharmony_ci * Preparation includes -
1498c2ecf20Sopenharmony_ci *      - Setting command ID and proper size
1508c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
1518c2ecf20Sopenharmony_ci */
1528c2ecf20Sopenharmony_cistatic int
1538c2ecf20Sopenharmony_cimwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
1568c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) +
1578c2ecf20Sopenharmony_ci				S_DS_GEN);
1588c2ecf20Sopenharmony_ci	return 0;
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci/*
1628c2ecf20Sopenharmony_ci * This function prepares command to set/get Tx data rate configuration.
1638c2ecf20Sopenharmony_ci *
1648c2ecf20Sopenharmony_ci * Preparation includes -
1658c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
1668c2ecf20Sopenharmony_ci *      - Setting configuration index, rate scope and rate drop pattern
1678c2ecf20Sopenharmony_ci *        parameters (as required)
1688c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
1698c2ecf20Sopenharmony_ci */
1708c2ecf20Sopenharmony_cistatic int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
1718c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
1728c2ecf20Sopenharmony_ci				   u16 cmd_action, u16 *pbitmap_rates)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg;
1758c2ecf20Sopenharmony_ci	struct mwifiex_rate_scope *rate_scope;
1768c2ecf20Sopenharmony_ci	struct mwifiex_rate_drop_pattern *rate_drop;
1778c2ecf20Sopenharmony_ci	u32 i;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	rate_cfg->action = cpu_to_le16(cmd_action);
1828c2ecf20Sopenharmony_ci	rate_cfg->cfg_index = 0;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
1858c2ecf20Sopenharmony_ci		      sizeof(struct host_cmd_ds_tx_rate_cfg));
1868c2ecf20Sopenharmony_ci	rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
1878c2ecf20Sopenharmony_ci	rate_scope->length = cpu_to_le16
1888c2ecf20Sopenharmony_ci		(sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header));
1898c2ecf20Sopenharmony_ci	if (pbitmap_rates != NULL) {
1908c2ecf20Sopenharmony_ci		rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
1918c2ecf20Sopenharmony_ci		rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
1928c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rate_scope->ht_mcs_rate_bitmap); i++)
1938c2ecf20Sopenharmony_ci			rate_scope->ht_mcs_rate_bitmap[i] =
1948c2ecf20Sopenharmony_ci				cpu_to_le16(pbitmap_rates[2 + i]);
1958c2ecf20Sopenharmony_ci		if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
1968c2ecf20Sopenharmony_ci			for (i = 0;
1978c2ecf20Sopenharmony_ci			     i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap);
1988c2ecf20Sopenharmony_ci			     i++)
1998c2ecf20Sopenharmony_ci				rate_scope->vht_mcs_rate_bitmap[i] =
2008c2ecf20Sopenharmony_ci					cpu_to_le16(pbitmap_rates[10 + i]);
2018c2ecf20Sopenharmony_ci		}
2028c2ecf20Sopenharmony_ci	} else {
2038c2ecf20Sopenharmony_ci		rate_scope->hr_dsss_rate_bitmap =
2048c2ecf20Sopenharmony_ci			cpu_to_le16(priv->bitmap_rates[0]);
2058c2ecf20Sopenharmony_ci		rate_scope->ofdm_rate_bitmap =
2068c2ecf20Sopenharmony_ci			cpu_to_le16(priv->bitmap_rates[1]);
2078c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rate_scope->ht_mcs_rate_bitmap); i++)
2088c2ecf20Sopenharmony_ci			rate_scope->ht_mcs_rate_bitmap[i] =
2098c2ecf20Sopenharmony_ci				cpu_to_le16(priv->bitmap_rates[2 + i]);
2108c2ecf20Sopenharmony_ci		if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
2118c2ecf20Sopenharmony_ci			for (i = 0;
2128c2ecf20Sopenharmony_ci			     i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap);
2138c2ecf20Sopenharmony_ci			     i++)
2148c2ecf20Sopenharmony_ci				rate_scope->vht_mcs_rate_bitmap[i] =
2158c2ecf20Sopenharmony_ci					cpu_to_le16(priv->bitmap_rates[10 + i]);
2168c2ecf20Sopenharmony_ci		}
2178c2ecf20Sopenharmony_ci	}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
2208c2ecf20Sopenharmony_ci					     sizeof(struct mwifiex_rate_scope));
2218c2ecf20Sopenharmony_ci	rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
2228c2ecf20Sopenharmony_ci	rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
2238c2ecf20Sopenharmony_ci	rate_drop->rate_drop_mode = 0;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	cmd->size =
2268c2ecf20Sopenharmony_ci		cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_tx_rate_cfg) +
2278c2ecf20Sopenharmony_ci			    sizeof(struct mwifiex_rate_scope) +
2288c2ecf20Sopenharmony_ci			    sizeof(struct mwifiex_rate_drop_pattern));
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	return 0;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci/*
2348c2ecf20Sopenharmony_ci * This function prepares command to set/get Tx power configuration.
2358c2ecf20Sopenharmony_ci *
2368c2ecf20Sopenharmony_ci * Preparation includes -
2378c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
2388c2ecf20Sopenharmony_ci *      - Setting Tx power mode, power group TLV
2398c2ecf20Sopenharmony_ci *        (as required)
2408c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
2418c2ecf20Sopenharmony_ci */
2428c2ecf20Sopenharmony_cistatic int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
2438c2ecf20Sopenharmony_ci				    u16 cmd_action,
2448c2ecf20Sopenharmony_ci				    struct host_cmd_ds_txpwr_cfg *txp)
2458c2ecf20Sopenharmony_ci{
2468c2ecf20Sopenharmony_ci	struct mwifiex_types_power_group *pg_tlv;
2478c2ecf20Sopenharmony_ci	struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
2508c2ecf20Sopenharmony_ci	cmd->size =
2518c2ecf20Sopenharmony_ci		cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg));
2528c2ecf20Sopenharmony_ci	switch (cmd_action) {
2538c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_SET:
2548c2ecf20Sopenharmony_ci		if (txp->mode) {
2558c2ecf20Sopenharmony_ci			pg_tlv = (struct mwifiex_types_power_group
2568c2ecf20Sopenharmony_ci				  *) ((unsigned long) txp +
2578c2ecf20Sopenharmony_ci				     sizeof(struct host_cmd_ds_txpwr_cfg));
2588c2ecf20Sopenharmony_ci			memmove(cmd_txp_cfg, txp,
2598c2ecf20Sopenharmony_ci				sizeof(struct host_cmd_ds_txpwr_cfg) +
2608c2ecf20Sopenharmony_ci				sizeof(struct mwifiex_types_power_group) +
2618c2ecf20Sopenharmony_ci				le16_to_cpu(pg_tlv->length));
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci			pg_tlv = (struct mwifiex_types_power_group *) ((u8 *)
2648c2ecf20Sopenharmony_ci				  cmd_txp_cfg +
2658c2ecf20Sopenharmony_ci				  sizeof(struct host_cmd_ds_txpwr_cfg));
2668c2ecf20Sopenharmony_ci			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) +
2678c2ecf20Sopenharmony_ci				  sizeof(struct mwifiex_types_power_group) +
2688c2ecf20Sopenharmony_ci				  le16_to_cpu(pg_tlv->length));
2698c2ecf20Sopenharmony_ci		} else {
2708c2ecf20Sopenharmony_ci			memmove(cmd_txp_cfg, txp, sizeof(*txp));
2718c2ecf20Sopenharmony_ci		}
2728c2ecf20Sopenharmony_ci		cmd_txp_cfg->action = cpu_to_le16(cmd_action);
2738c2ecf20Sopenharmony_ci		break;
2748c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_GET:
2758c2ecf20Sopenharmony_ci		cmd_txp_cfg->action = cpu_to_le16(cmd_action);
2768c2ecf20Sopenharmony_ci		break;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	return 0;
2808c2ecf20Sopenharmony_ci}
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci/*
2838c2ecf20Sopenharmony_ci * This function prepares command to get RF Tx power.
2848c2ecf20Sopenharmony_ci */
2858c2ecf20Sopenharmony_cistatic int mwifiex_cmd_rf_tx_power(struct mwifiex_private *priv,
2868c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
2878c2ecf20Sopenharmony_ci				   u16 cmd_action, void *data_buf)
2888c2ecf20Sopenharmony_ci{
2898c2ecf20Sopenharmony_ci	struct host_cmd_ds_rf_tx_pwr *txp = &cmd->params.txp;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr)
2928c2ecf20Sopenharmony_ci				+ S_DS_GEN);
2938c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_RF_TX_PWR);
2948c2ecf20Sopenharmony_ci	txp->action = cpu_to_le16(cmd_action);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	return 0;
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci/*
3008c2ecf20Sopenharmony_ci * This function prepares command to set rf antenna.
3018c2ecf20Sopenharmony_ci */
3028c2ecf20Sopenharmony_cistatic int mwifiex_cmd_rf_antenna(struct mwifiex_private *priv,
3038c2ecf20Sopenharmony_ci				  struct host_cmd_ds_command *cmd,
3048c2ecf20Sopenharmony_ci				  u16 cmd_action,
3058c2ecf20Sopenharmony_ci				  struct mwifiex_ds_ant_cfg *ant_cfg)
3068c2ecf20Sopenharmony_ci{
3078c2ecf20Sopenharmony_ci	struct host_cmd_ds_rf_ant_mimo *ant_mimo = &cmd->params.ant_mimo;
3088c2ecf20Sopenharmony_ci	struct host_cmd_ds_rf_ant_siso *ant_siso = &cmd->params.ant_siso;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_RF_ANTENNA);
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	switch (cmd_action) {
3138c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_SET:
3148c2ecf20Sopenharmony_ci		if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
3158c2ecf20Sopenharmony_ci			cmd->size = cpu_to_le16(sizeof(struct
3168c2ecf20Sopenharmony_ci						host_cmd_ds_rf_ant_mimo)
3178c2ecf20Sopenharmony_ci						+ S_DS_GEN);
3188c2ecf20Sopenharmony_ci			ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_SET_TX);
3198c2ecf20Sopenharmony_ci			ant_mimo->tx_ant_mode = cpu_to_le16((u16)ant_cfg->
3208c2ecf20Sopenharmony_ci							    tx_ant);
3218c2ecf20Sopenharmony_ci			ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_SET_RX);
3228c2ecf20Sopenharmony_ci			ant_mimo->rx_ant_mode = cpu_to_le16((u16)ant_cfg->
3238c2ecf20Sopenharmony_ci							    rx_ant);
3248c2ecf20Sopenharmony_ci		} else {
3258c2ecf20Sopenharmony_ci			cmd->size = cpu_to_le16(sizeof(struct
3268c2ecf20Sopenharmony_ci						host_cmd_ds_rf_ant_siso) +
3278c2ecf20Sopenharmony_ci						S_DS_GEN);
3288c2ecf20Sopenharmony_ci			ant_siso->action = cpu_to_le16(HostCmd_ACT_SET_BOTH);
3298c2ecf20Sopenharmony_ci			ant_siso->ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant);
3308c2ecf20Sopenharmony_ci		}
3318c2ecf20Sopenharmony_ci		break;
3328c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_GET:
3338c2ecf20Sopenharmony_ci		if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
3348c2ecf20Sopenharmony_ci			cmd->size = cpu_to_le16(sizeof(struct
3358c2ecf20Sopenharmony_ci						host_cmd_ds_rf_ant_mimo) +
3368c2ecf20Sopenharmony_ci						S_DS_GEN);
3378c2ecf20Sopenharmony_ci			ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_GET_TX);
3388c2ecf20Sopenharmony_ci			ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_GET_RX);
3398c2ecf20Sopenharmony_ci		} else {
3408c2ecf20Sopenharmony_ci			cmd->size = cpu_to_le16(sizeof(struct
3418c2ecf20Sopenharmony_ci						host_cmd_ds_rf_ant_siso) +
3428c2ecf20Sopenharmony_ci						S_DS_GEN);
3438c2ecf20Sopenharmony_ci			ant_siso->action = cpu_to_le16(HostCmd_ACT_GET_BOTH);
3448c2ecf20Sopenharmony_ci		}
3458c2ecf20Sopenharmony_ci		break;
3468c2ecf20Sopenharmony_ci	}
3478c2ecf20Sopenharmony_ci	return 0;
3488c2ecf20Sopenharmony_ci}
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci/*
3518c2ecf20Sopenharmony_ci * This function prepares command to set Host Sleep configuration.
3528c2ecf20Sopenharmony_ci *
3538c2ecf20Sopenharmony_ci * Preparation includes -
3548c2ecf20Sopenharmony_ci *      - Setting command ID and proper size
3558c2ecf20Sopenharmony_ci *      - Setting Host Sleep action, conditions, ARP filters
3568c2ecf20Sopenharmony_ci *        (as required)
3578c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
3588c2ecf20Sopenharmony_ci */
3598c2ecf20Sopenharmony_cistatic int
3608c2ecf20Sopenharmony_cimwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
3618c2ecf20Sopenharmony_ci			  struct host_cmd_ds_command *cmd,
3628c2ecf20Sopenharmony_ci			  u16 cmd_action,
3638c2ecf20Sopenharmony_ci			  struct mwifiex_hs_config_param *hscfg_param)
3648c2ecf20Sopenharmony_ci{
3658c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
3668c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg;
3678c2ecf20Sopenharmony_ci	u8 *tlv = (u8 *)hs_cfg + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh);
3688c2ecf20Sopenharmony_ci	struct mwifiex_ps_param_in_hs *psparam_tlv = NULL;
3698c2ecf20Sopenharmony_ci	bool hs_activate = false;
3708c2ecf20Sopenharmony_ci	u16 size;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	if (!hscfg_param)
3738c2ecf20Sopenharmony_ci		/* New Activate command */
3748c2ecf20Sopenharmony_ci		hs_activate = true;
3758c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	if (!hs_activate &&
3788c2ecf20Sopenharmony_ci	    (hscfg_param->conditions != cpu_to_le32(HS_CFG_CANCEL)) &&
3798c2ecf20Sopenharmony_ci	    ((adapter->arp_filter_size > 0) &&
3808c2ecf20Sopenharmony_ci	     (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
3818c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, CMD,
3828c2ecf20Sopenharmony_ci			    "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
3838c2ecf20Sopenharmony_ci			    adapter->arp_filter_size);
3848c2ecf20Sopenharmony_ci		memcpy(((u8 *) hs_cfg) +
3858c2ecf20Sopenharmony_ci		       sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
3868c2ecf20Sopenharmony_ci		       adapter->arp_filter, adapter->arp_filter_size);
3878c2ecf20Sopenharmony_ci		size = adapter->arp_filter_size +
3888c2ecf20Sopenharmony_ci			sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
3898c2ecf20Sopenharmony_ci			+ S_DS_GEN;
3908c2ecf20Sopenharmony_ci		tlv = (u8 *)hs_cfg
3918c2ecf20Sopenharmony_ci			+ sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
3928c2ecf20Sopenharmony_ci			+ adapter->arp_filter_size;
3938c2ecf20Sopenharmony_ci	} else {
3948c2ecf20Sopenharmony_ci		size = S_DS_GEN + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh);
3958c2ecf20Sopenharmony_ci	}
3968c2ecf20Sopenharmony_ci	if (hs_activate) {
3978c2ecf20Sopenharmony_ci		hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
3988c2ecf20Sopenharmony_ci		hs_cfg->params.hs_activate.resp_ctrl = cpu_to_le16(RESP_NEEDED);
3998c2ecf20Sopenharmony_ci	} else {
4008c2ecf20Sopenharmony_ci		hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
4018c2ecf20Sopenharmony_ci		hs_cfg->params.hs_config.conditions = hscfg_param->conditions;
4028c2ecf20Sopenharmony_ci		hs_cfg->params.hs_config.gpio = hscfg_param->gpio;
4038c2ecf20Sopenharmony_ci		hs_cfg->params.hs_config.gap = hscfg_param->gap;
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci		size += sizeof(struct mwifiex_ps_param_in_hs);
4068c2ecf20Sopenharmony_ci		psparam_tlv = (struct mwifiex_ps_param_in_hs *)tlv;
4078c2ecf20Sopenharmony_ci		psparam_tlv->header.type =
4088c2ecf20Sopenharmony_ci			cpu_to_le16(TLV_TYPE_PS_PARAMS_IN_HS);
4098c2ecf20Sopenharmony_ci		psparam_tlv->header.len =
4108c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct mwifiex_ps_param_in_hs)
4118c2ecf20Sopenharmony_ci				- sizeof(struct mwifiex_ie_types_header));
4128c2ecf20Sopenharmony_ci		psparam_tlv->hs_wake_int = cpu_to_le32(HS_DEF_WAKE_INTERVAL);
4138c2ecf20Sopenharmony_ci		psparam_tlv->hs_inact_timeout =
4148c2ecf20Sopenharmony_ci			cpu_to_le32(HS_DEF_INACTIVITY_TIMEOUT);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, CMD,
4178c2ecf20Sopenharmony_ci			    "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
4188c2ecf20Sopenharmony_ci			    hs_cfg->params.hs_config.conditions,
4198c2ecf20Sopenharmony_ci			    hs_cfg->params.hs_config.gpio,
4208c2ecf20Sopenharmony_ci			    hs_cfg->params.hs_config.gap);
4218c2ecf20Sopenharmony_ci	}
4228c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(size);
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	return 0;
4258c2ecf20Sopenharmony_ci}
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci/*
4288c2ecf20Sopenharmony_ci * This function prepares command to set/get MAC address.
4298c2ecf20Sopenharmony_ci *
4308c2ecf20Sopenharmony_ci * Preparation includes -
4318c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
4328c2ecf20Sopenharmony_ci *      - Setting MAC address (for SET only)
4338c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
4348c2ecf20Sopenharmony_ci */
4358c2ecf20Sopenharmony_cistatic int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv,
4368c2ecf20Sopenharmony_ci					  struct host_cmd_ds_command *cmd,
4378c2ecf20Sopenharmony_ci					  u16 cmd_action)
4388c2ecf20Sopenharmony_ci{
4398c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
4408c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address) +
4418c2ecf20Sopenharmony_ci				S_DS_GEN);
4428c2ecf20Sopenharmony_ci	cmd->result = 0;
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	cmd->params.mac_addr.action = cpu_to_le16(cmd_action);
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_SET)
4478c2ecf20Sopenharmony_ci		memcpy(cmd->params.mac_addr.mac_addr, priv->curr_addr,
4488c2ecf20Sopenharmony_ci		       ETH_ALEN);
4498c2ecf20Sopenharmony_ci	return 0;
4508c2ecf20Sopenharmony_ci}
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci/*
4538c2ecf20Sopenharmony_ci * This function prepares command to set MAC multicast address.
4548c2ecf20Sopenharmony_ci *
4558c2ecf20Sopenharmony_ci * Preparation includes -
4568c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
4578c2ecf20Sopenharmony_ci *      - Setting MAC multicast address
4588c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
4598c2ecf20Sopenharmony_ci */
4608c2ecf20Sopenharmony_cistatic int
4618c2ecf20Sopenharmony_cimwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd,
4628c2ecf20Sopenharmony_ci			      u16 cmd_action,
4638c2ecf20Sopenharmony_ci			      struct mwifiex_multicast_list *mcast_list)
4648c2ecf20Sopenharmony_ci{
4658c2ecf20Sopenharmony_ci	struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) +
4688c2ecf20Sopenharmony_ci				S_DS_GEN);
4698c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	mcast_addr->action = cpu_to_le16(cmd_action);
4728c2ecf20Sopenharmony_ci	mcast_addr->num_of_adrs =
4738c2ecf20Sopenharmony_ci		cpu_to_le16((u16) mcast_list->num_multicast_addr);
4748c2ecf20Sopenharmony_ci	memcpy(mcast_addr->mac_list, mcast_list->mac_list,
4758c2ecf20Sopenharmony_ci	       mcast_list->num_multicast_addr * ETH_ALEN);
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci	return 0;
4788c2ecf20Sopenharmony_ci}
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci/*
4818c2ecf20Sopenharmony_ci * This function prepares command to deauthenticate.
4828c2ecf20Sopenharmony_ci *
4838c2ecf20Sopenharmony_ci * Preparation includes -
4848c2ecf20Sopenharmony_ci *      - Setting command ID and proper size
4858c2ecf20Sopenharmony_ci *      - Setting AP MAC address and reason code
4868c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
4878c2ecf20Sopenharmony_ci */
4888c2ecf20Sopenharmony_cistatic int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv,
4898c2ecf20Sopenharmony_ci					     struct host_cmd_ds_command *cmd,
4908c2ecf20Sopenharmony_ci					     u8 *mac)
4918c2ecf20Sopenharmony_ci{
4928c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth;
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
4958c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate)
4968c2ecf20Sopenharmony_ci				+ S_DS_GEN);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	/* Set AP MAC address */
4998c2ecf20Sopenharmony_ci	memcpy(deauth->mac_addr, mac, ETH_ALEN);
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD, "cmd: Deauth: %pM\n", deauth->mac_addr);
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	deauth->reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	return 0;
5068c2ecf20Sopenharmony_ci}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci/*
5098c2ecf20Sopenharmony_ci * This function prepares command to stop Ad-Hoc network.
5108c2ecf20Sopenharmony_ci *
5118c2ecf20Sopenharmony_ci * Preparation includes -
5128c2ecf20Sopenharmony_ci *      - Setting command ID and proper size
5138c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
5148c2ecf20Sopenharmony_ci */
5158c2ecf20Sopenharmony_cistatic int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
5188c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(S_DS_GEN);
5198c2ecf20Sopenharmony_ci	return 0;
5208c2ecf20Sopenharmony_ci}
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci/*
5238c2ecf20Sopenharmony_ci * This function sets WEP key(s) to key parameter TLV(s).
5248c2ecf20Sopenharmony_ci *
5258c2ecf20Sopenharmony_ci * Multi-key parameter TLVs are supported, so we can send multiple
5268c2ecf20Sopenharmony_ci * WEP keys in a single buffer.
5278c2ecf20Sopenharmony_ci */
5288c2ecf20Sopenharmony_cistatic int
5298c2ecf20Sopenharmony_cimwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
5308c2ecf20Sopenharmony_ci			    struct mwifiex_ie_type_key_param_set *key_param_set,
5318c2ecf20Sopenharmony_ci			    u16 *key_param_len)
5328c2ecf20Sopenharmony_ci{
5338c2ecf20Sopenharmony_ci	int cur_key_param_len;
5348c2ecf20Sopenharmony_ci	u8 i;
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	/* Multi-key_param_set TLV is supported */
5378c2ecf20Sopenharmony_ci	for (i = 0; i < NUM_WEP_KEYS; i++) {
5388c2ecf20Sopenharmony_ci		if ((priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP40) ||
5398c2ecf20Sopenharmony_ci		    (priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP104)) {
5408c2ecf20Sopenharmony_ci			key_param_set->type =
5418c2ecf20Sopenharmony_ci				cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
5428c2ecf20Sopenharmony_ci/* Key_param_set WEP fixed length */
5438c2ecf20Sopenharmony_ci#define KEYPARAMSET_WEP_FIXED_LEN 8
5448c2ecf20Sopenharmony_ci			key_param_set->length = cpu_to_le16((u16)
5458c2ecf20Sopenharmony_ci					(priv->wep_key[i].
5468c2ecf20Sopenharmony_ci					 key_length +
5478c2ecf20Sopenharmony_ci					 KEYPARAMSET_WEP_FIXED_LEN));
5488c2ecf20Sopenharmony_ci			key_param_set->key_type_id =
5498c2ecf20Sopenharmony_ci				cpu_to_le16(KEY_TYPE_ID_WEP);
5508c2ecf20Sopenharmony_ci			key_param_set->key_info =
5518c2ecf20Sopenharmony_ci				cpu_to_le16(KEY_ENABLED | KEY_UNICAST |
5528c2ecf20Sopenharmony_ci					    KEY_MCAST);
5538c2ecf20Sopenharmony_ci			key_param_set->key_len =
5548c2ecf20Sopenharmony_ci				cpu_to_le16(priv->wep_key[i].key_length);
5558c2ecf20Sopenharmony_ci			/* Set WEP key index */
5568c2ecf20Sopenharmony_ci			key_param_set->key[0] = i;
5578c2ecf20Sopenharmony_ci			/* Set default Tx key flag */
5588c2ecf20Sopenharmony_ci			if (i ==
5598c2ecf20Sopenharmony_ci			    (priv->
5608c2ecf20Sopenharmony_ci			     wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
5618c2ecf20Sopenharmony_ci				key_param_set->key[1] = 1;
5628c2ecf20Sopenharmony_ci			else
5638c2ecf20Sopenharmony_ci				key_param_set->key[1] = 0;
5648c2ecf20Sopenharmony_ci			memmove(&key_param_set->key[2],
5658c2ecf20Sopenharmony_ci				priv->wep_key[i].key_material,
5668c2ecf20Sopenharmony_ci				priv->wep_key[i].key_length);
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci			cur_key_param_len = priv->wep_key[i].key_length +
5698c2ecf20Sopenharmony_ci				KEYPARAMSET_WEP_FIXED_LEN +
5708c2ecf20Sopenharmony_ci				sizeof(struct mwifiex_ie_types_header);
5718c2ecf20Sopenharmony_ci			*key_param_len += (u16) cur_key_param_len;
5728c2ecf20Sopenharmony_ci			key_param_set =
5738c2ecf20Sopenharmony_ci				(struct mwifiex_ie_type_key_param_set *)
5748c2ecf20Sopenharmony_ci						((u8 *)key_param_set +
5758c2ecf20Sopenharmony_ci						 cur_key_param_len);
5768c2ecf20Sopenharmony_ci		} else if (!priv->wep_key[i].key_length) {
5778c2ecf20Sopenharmony_ci			continue;
5788c2ecf20Sopenharmony_ci		} else {
5798c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, ERROR,
5808c2ecf20Sopenharmony_ci				    "key%d Length = %d is incorrect\n",
5818c2ecf20Sopenharmony_ci				    (i + 1), priv->wep_key[i].key_length);
5828c2ecf20Sopenharmony_ci			return -1;
5838c2ecf20Sopenharmony_ci		}
5848c2ecf20Sopenharmony_ci	}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci	return 0;
5878c2ecf20Sopenharmony_ci}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_ci/* This function populates key material v2 command
5908c2ecf20Sopenharmony_ci * to set network key for AES & CMAC AES.
5918c2ecf20Sopenharmony_ci */
5928c2ecf20Sopenharmony_cistatic int mwifiex_set_aes_key_v2(struct mwifiex_private *priv,
5938c2ecf20Sopenharmony_ci				  struct host_cmd_ds_command *cmd,
5948c2ecf20Sopenharmony_ci				  struct mwifiex_ds_encrypt_key *enc_key,
5958c2ecf20Sopenharmony_ci				  struct host_cmd_ds_802_11_key_material_v2 *km)
5968c2ecf20Sopenharmony_ci{
5978c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
5988c2ecf20Sopenharmony_ci	u16 size, len = KEY_PARAMS_FIXED_LEN;
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	if (enc_key->is_igtk_key) {
6018c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
6028c2ecf20Sopenharmony_ci			    "%s: Set CMAC AES Key\n", __func__);
6038c2ecf20Sopenharmony_ci		if (enc_key->is_rx_seq_valid)
6048c2ecf20Sopenharmony_ci			memcpy(km->key_param_set.key_params.cmac_aes.ipn,
6058c2ecf20Sopenharmony_ci			       enc_key->pn, enc_key->pn_len);
6068c2ecf20Sopenharmony_ci		km->key_param_set.key_info &= cpu_to_le16(~KEY_MCAST);
6078c2ecf20Sopenharmony_ci		km->key_param_set.key_info |= cpu_to_le16(KEY_IGTK);
6088c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC;
6098c2ecf20Sopenharmony_ci		km->key_param_set.key_params.cmac_aes.key_len =
6108c2ecf20Sopenharmony_ci					  cpu_to_le16(enc_key->key_len);
6118c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.cmac_aes.key,
6128c2ecf20Sopenharmony_ci		       enc_key->key_material, enc_key->key_len);
6138c2ecf20Sopenharmony_ci		len += sizeof(struct mwifiex_cmac_aes_param);
6148c2ecf20Sopenharmony_ci	} else if (enc_key->is_igtk_def_key) {
6158c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
6168c2ecf20Sopenharmony_ci			    "%s: Set CMAC default Key index\n", __func__);
6178c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC_DEF;
6188c2ecf20Sopenharmony_ci		km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK;
6198c2ecf20Sopenharmony_ci	} else {
6208c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
6218c2ecf20Sopenharmony_ci			    "%s: Set AES Key\n", __func__);
6228c2ecf20Sopenharmony_ci		if (enc_key->is_rx_seq_valid)
6238c2ecf20Sopenharmony_ci			memcpy(km->key_param_set.key_params.aes.pn,
6248c2ecf20Sopenharmony_ci			       enc_key->pn, enc_key->pn_len);
6258c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_AES;
6268c2ecf20Sopenharmony_ci		km->key_param_set.key_params.aes.key_len =
6278c2ecf20Sopenharmony_ci					  cpu_to_le16(enc_key->key_len);
6288c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.aes.key,
6298c2ecf20Sopenharmony_ci		       enc_key->key_material, enc_key->key_len);
6308c2ecf20Sopenharmony_ci		len += sizeof(struct mwifiex_aes_param);
6318c2ecf20Sopenharmony_ci	}
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	km->key_param_set.len = cpu_to_le16(len);
6348c2ecf20Sopenharmony_ci	size = len + sizeof(struct mwifiex_ie_types_header) +
6358c2ecf20Sopenharmony_ci	       sizeof(km->action) + S_DS_GEN;
6368c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(size);
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	return 0;
6398c2ecf20Sopenharmony_ci}
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci/* This function prepares command to set/get/reset network key(s).
6428c2ecf20Sopenharmony_ci * This function prepares key material command for V2 format.
6438c2ecf20Sopenharmony_ci * Preparation includes -
6448c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
6458c2ecf20Sopenharmony_ci *      - Setting WEP keys, WAPI keys or WPA keys along with required
6468c2ecf20Sopenharmony_ci *        encryption (TKIP, AES) (as required)
6478c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
6488c2ecf20Sopenharmony_ci */
6498c2ecf20Sopenharmony_cistatic int
6508c2ecf20Sopenharmony_cimwifiex_cmd_802_11_key_material_v2(struct mwifiex_private *priv,
6518c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
6528c2ecf20Sopenharmony_ci				   u16 cmd_action, u32 cmd_oid,
6538c2ecf20Sopenharmony_ci				   struct mwifiex_ds_encrypt_key *enc_key)
6548c2ecf20Sopenharmony_ci{
6558c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
6568c2ecf20Sopenharmony_ci	u8 *mac = enc_key->mac_addr;
6578c2ecf20Sopenharmony_ci	u16 key_info, len = KEY_PARAMS_FIXED_LEN;
6588c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_key_material_v2 *km =
6598c2ecf20Sopenharmony_ci						&cmd->params.key_material_v2;
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
6628c2ecf20Sopenharmony_ci	km->action = cpu_to_le16(cmd_action);
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_GET) {
6658c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO, "%s: Get key\n", __func__);
6668c2ecf20Sopenharmony_ci		km->key_param_set.key_idx =
6678c2ecf20Sopenharmony_ci					enc_key->key_index & KEY_INDEX_MASK;
6688c2ecf20Sopenharmony_ci		km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
6698c2ecf20Sopenharmony_ci		km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN);
6708c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci		if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
6738c2ecf20Sopenharmony_ci			key_info = KEY_UNICAST;
6748c2ecf20Sopenharmony_ci		else
6758c2ecf20Sopenharmony_ci			key_info = KEY_MCAST;
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci		if (enc_key->is_igtk_key)
6788c2ecf20Sopenharmony_ci			key_info |= KEY_IGTK;
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci		km->key_param_set.key_info = cpu_to_le16(key_info);
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
6838c2ecf20Sopenharmony_ci					S_DS_GEN + KEY_PARAMS_FIXED_LEN +
6848c2ecf20Sopenharmony_ci					sizeof(km->action));
6858c2ecf20Sopenharmony_ci		return 0;
6868c2ecf20Sopenharmony_ci	}
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci	memset(&km->key_param_set, 0,
6898c2ecf20Sopenharmony_ci	       sizeof(struct mwifiex_ie_type_key_param_set_v2));
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	if (enc_key->key_disable) {
6928c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO, "%s: Remove key\n", __func__);
6938c2ecf20Sopenharmony_ci		km->action = cpu_to_le16(HostCmd_ACT_GEN_REMOVE);
6948c2ecf20Sopenharmony_ci		km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
6958c2ecf20Sopenharmony_ci		km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN);
6968c2ecf20Sopenharmony_ci		km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK;
6978c2ecf20Sopenharmony_ci		key_info = KEY_MCAST | KEY_UNICAST;
6988c2ecf20Sopenharmony_ci		km->key_param_set.key_info = cpu_to_le16(key_info);
6998c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
7008c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
7018c2ecf20Sopenharmony_ci					S_DS_GEN + KEY_PARAMS_FIXED_LEN +
7028c2ecf20Sopenharmony_ci					sizeof(km->action));
7038c2ecf20Sopenharmony_ci		return 0;
7048c2ecf20Sopenharmony_ci	}
7058c2ecf20Sopenharmony_ci
7068c2ecf20Sopenharmony_ci	km->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
7078c2ecf20Sopenharmony_ci	km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK;
7088c2ecf20Sopenharmony_ci	km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2);
7098c2ecf20Sopenharmony_ci	key_info = KEY_ENABLED;
7108c2ecf20Sopenharmony_ci	memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN);
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci	if (enc_key->key_len <= WLAN_KEY_LEN_WEP104) {
7138c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO, "%s: Set WEP Key\n", __func__);
7148c2ecf20Sopenharmony_ci		len += sizeof(struct mwifiex_wep_param);
7158c2ecf20Sopenharmony_ci		km->key_param_set.len = cpu_to_le16(len);
7168c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_WEP;
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci		if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
7198c2ecf20Sopenharmony_ci				key_info |= KEY_MCAST | KEY_UNICAST;
7208c2ecf20Sopenharmony_ci		} else {
7218c2ecf20Sopenharmony_ci			if (enc_key->is_current_wep_key) {
7228c2ecf20Sopenharmony_ci				key_info |= KEY_MCAST | KEY_UNICAST;
7238c2ecf20Sopenharmony_ci				if (km->key_param_set.key_idx ==
7248c2ecf20Sopenharmony_ci				    (priv->wep_key_curr_index & KEY_INDEX_MASK))
7258c2ecf20Sopenharmony_ci					key_info |= KEY_DEFAULT;
7268c2ecf20Sopenharmony_ci			} else {
7278c2ecf20Sopenharmony_ci				if (is_broadcast_ether_addr(mac))
7288c2ecf20Sopenharmony_ci					key_info |= KEY_MCAST;
7298c2ecf20Sopenharmony_ci				else
7308c2ecf20Sopenharmony_ci					key_info |= KEY_UNICAST | KEY_DEFAULT;
7318c2ecf20Sopenharmony_ci			}
7328c2ecf20Sopenharmony_ci		}
7338c2ecf20Sopenharmony_ci		km->key_param_set.key_info = cpu_to_le16(key_info);
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_ci		km->key_param_set.key_params.wep.key_len =
7368c2ecf20Sopenharmony_ci						  cpu_to_le16(enc_key->key_len);
7378c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.wep.key,
7388c2ecf20Sopenharmony_ci		       enc_key->key_material, enc_key->key_len);
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
7418c2ecf20Sopenharmony_ci					len + sizeof(km->action) + S_DS_GEN);
7428c2ecf20Sopenharmony_ci		return 0;
7438c2ecf20Sopenharmony_ci	}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	if (is_broadcast_ether_addr(mac))
7468c2ecf20Sopenharmony_ci		key_info |= KEY_MCAST | KEY_RX_KEY;
7478c2ecf20Sopenharmony_ci	else
7488c2ecf20Sopenharmony_ci		key_info |= KEY_UNICAST | KEY_TX_KEY | KEY_RX_KEY;
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_ci	if (enc_key->is_wapi_key) {
7518c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO, "%s: Set WAPI Key\n", __func__);
7528c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_WAPI;
7538c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.wapi.pn, enc_key->pn,
7548c2ecf20Sopenharmony_ci		       PN_LEN);
7558c2ecf20Sopenharmony_ci		km->key_param_set.key_params.wapi.key_len =
7568c2ecf20Sopenharmony_ci						cpu_to_le16(enc_key->key_len);
7578c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.wapi.key,
7588c2ecf20Sopenharmony_ci		       enc_key->key_material, enc_key->key_len);
7598c2ecf20Sopenharmony_ci		if (is_broadcast_ether_addr(mac))
7608c2ecf20Sopenharmony_ci			priv->sec_info.wapi_key_on = true;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci		if (!priv->sec_info.wapi_key_on)
7638c2ecf20Sopenharmony_ci			key_info |= KEY_DEFAULT;
7648c2ecf20Sopenharmony_ci		km->key_param_set.key_info = cpu_to_le16(key_info);
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_ci		len += sizeof(struct mwifiex_wapi_param);
7678c2ecf20Sopenharmony_ci		km->key_param_set.len = cpu_to_le16(len);
7688c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
7698c2ecf20Sopenharmony_ci					len + sizeof(km->action) + S_DS_GEN);
7708c2ecf20Sopenharmony_ci		return 0;
7718c2ecf20Sopenharmony_ci	}
7728c2ecf20Sopenharmony_ci
7738c2ecf20Sopenharmony_ci	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
7748c2ecf20Sopenharmony_ci		key_info |= KEY_DEFAULT;
7758c2ecf20Sopenharmony_ci		/* Enable unicast bit for WPA-NONE/ADHOC_AES */
7768c2ecf20Sopenharmony_ci		if (!priv->sec_info.wpa2_enabled &&
7778c2ecf20Sopenharmony_ci		    !is_broadcast_ether_addr(mac))
7788c2ecf20Sopenharmony_ci			key_info |= KEY_UNICAST;
7798c2ecf20Sopenharmony_ci	} else {
7808c2ecf20Sopenharmony_ci		/* Enable default key for WPA/WPA2 */
7818c2ecf20Sopenharmony_ci		if (!priv->wpa_is_gtk_set)
7828c2ecf20Sopenharmony_ci			key_info |= KEY_DEFAULT;
7838c2ecf20Sopenharmony_ci	}
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	km->key_param_set.key_info = cpu_to_le16(key_info);
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci	if (enc_key->key_len == WLAN_KEY_LEN_CCMP)
7888c2ecf20Sopenharmony_ci		return mwifiex_set_aes_key_v2(priv, cmd, enc_key, km);
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci	if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
7918c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
7928c2ecf20Sopenharmony_ci			    "%s: Set TKIP Key\n", __func__);
7938c2ecf20Sopenharmony_ci		if (enc_key->is_rx_seq_valid)
7948c2ecf20Sopenharmony_ci			memcpy(km->key_param_set.key_params.tkip.pn,
7958c2ecf20Sopenharmony_ci			       enc_key->pn, enc_key->pn_len);
7968c2ecf20Sopenharmony_ci		km->key_param_set.key_type = KEY_TYPE_ID_TKIP;
7978c2ecf20Sopenharmony_ci		km->key_param_set.key_params.tkip.key_len =
7988c2ecf20Sopenharmony_ci						cpu_to_le16(enc_key->key_len);
7998c2ecf20Sopenharmony_ci		memcpy(km->key_param_set.key_params.tkip.key,
8008c2ecf20Sopenharmony_ci		       enc_key->key_material, enc_key->key_len);
8018c2ecf20Sopenharmony_ci
8028c2ecf20Sopenharmony_ci		len += sizeof(struct mwifiex_tkip_param);
8038c2ecf20Sopenharmony_ci		km->key_param_set.len = cpu_to_le16(len);
8048c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) +
8058c2ecf20Sopenharmony_ci					len + sizeof(km->action) + S_DS_GEN);
8068c2ecf20Sopenharmony_ci	}
8078c2ecf20Sopenharmony_ci
8088c2ecf20Sopenharmony_ci	return 0;
8098c2ecf20Sopenharmony_ci}
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci/*
8128c2ecf20Sopenharmony_ci * This function prepares command to set/get/reset network key(s).
8138c2ecf20Sopenharmony_ci * This function prepares key material command for V1 format.
8148c2ecf20Sopenharmony_ci *
8158c2ecf20Sopenharmony_ci * Preparation includes -
8168c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
8178c2ecf20Sopenharmony_ci *      - Setting WEP keys, WAPI keys or WPA keys along with required
8188c2ecf20Sopenharmony_ci *        encryption (TKIP, AES) (as required)
8198c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
8208c2ecf20Sopenharmony_ci */
8218c2ecf20Sopenharmony_cistatic int
8228c2ecf20Sopenharmony_cimwifiex_cmd_802_11_key_material_v1(struct mwifiex_private *priv,
8238c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
8248c2ecf20Sopenharmony_ci				   u16 cmd_action, u32 cmd_oid,
8258c2ecf20Sopenharmony_ci				   struct mwifiex_ds_encrypt_key *enc_key)
8268c2ecf20Sopenharmony_ci{
8278c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_key_material *key_material =
8288c2ecf20Sopenharmony_ci		&cmd->params.key_material;
8298c2ecf20Sopenharmony_ci	struct host_cmd_tlv_mac_addr *tlv_mac;
8308c2ecf20Sopenharmony_ci	u16 key_param_len = 0, cmd_size;
8318c2ecf20Sopenharmony_ci	int ret = 0;
8328c2ecf20Sopenharmony_ci
8338c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
8348c2ecf20Sopenharmony_ci	key_material->action = cpu_to_le16(cmd_action);
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_GET) {
8378c2ecf20Sopenharmony_ci		cmd->size =
8388c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(key_material->action) + S_DS_GEN);
8398c2ecf20Sopenharmony_ci		return ret;
8408c2ecf20Sopenharmony_ci	}
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	if (!enc_key) {
8438c2ecf20Sopenharmony_ci		memset(&key_material->key_param_set, 0,
8448c2ecf20Sopenharmony_ci		       (NUM_WEP_KEYS *
8458c2ecf20Sopenharmony_ci			sizeof(struct mwifiex_ie_type_key_param_set)));
8468c2ecf20Sopenharmony_ci		ret = mwifiex_set_keyparamset_wep(priv,
8478c2ecf20Sopenharmony_ci						  &key_material->key_param_set,
8488c2ecf20Sopenharmony_ci						  &key_param_len);
8498c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(key_param_len +
8508c2ecf20Sopenharmony_ci				    sizeof(key_material->action) + S_DS_GEN);
8518c2ecf20Sopenharmony_ci		return ret;
8528c2ecf20Sopenharmony_ci	} else
8538c2ecf20Sopenharmony_ci		memset(&key_material->key_param_set, 0,
8548c2ecf20Sopenharmony_ci		       sizeof(struct mwifiex_ie_type_key_param_set));
8558c2ecf20Sopenharmony_ci	if (enc_key->is_wapi_key) {
8568c2ecf20Sopenharmony_ci		struct mwifiex_ie_type_key_param_set *set;
8578c2ecf20Sopenharmony_ci
8588c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, INFO, "info: Set WAPI Key\n");
8598c2ecf20Sopenharmony_ci		set = &key_material->key_param_set;
8608c2ecf20Sopenharmony_ci		set->key_type_id = cpu_to_le16(KEY_TYPE_ID_WAPI);
8618c2ecf20Sopenharmony_ci		if (cmd_oid == KEY_INFO_ENABLED)
8628c2ecf20Sopenharmony_ci			set->key_info = cpu_to_le16(KEY_ENABLED);
8638c2ecf20Sopenharmony_ci		else
8648c2ecf20Sopenharmony_ci			set->key_info = cpu_to_le16(!KEY_ENABLED);
8658c2ecf20Sopenharmony_ci
8668c2ecf20Sopenharmony_ci		set->key[0] = enc_key->key_index;
8678c2ecf20Sopenharmony_ci		if (!priv->sec_info.wapi_key_on)
8688c2ecf20Sopenharmony_ci			set->key[1] = 1;
8698c2ecf20Sopenharmony_ci		else
8708c2ecf20Sopenharmony_ci			/* set 0 when re-key */
8718c2ecf20Sopenharmony_ci			set->key[1] = 0;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci		if (!is_broadcast_ether_addr(enc_key->mac_addr)) {
8748c2ecf20Sopenharmony_ci			/* WAPI pairwise key: unicast */
8758c2ecf20Sopenharmony_ci			set->key_info |= cpu_to_le16(KEY_UNICAST);
8768c2ecf20Sopenharmony_ci		} else {	/* WAPI group key: multicast */
8778c2ecf20Sopenharmony_ci			set->key_info |= cpu_to_le16(KEY_MCAST);
8788c2ecf20Sopenharmony_ci			priv->sec_info.wapi_key_on = true;
8798c2ecf20Sopenharmony_ci		}
8808c2ecf20Sopenharmony_ci
8818c2ecf20Sopenharmony_ci		set->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
8828c2ecf20Sopenharmony_ci		set->key_len = cpu_to_le16(WAPI_KEY_LEN);
8838c2ecf20Sopenharmony_ci		memcpy(&set->key[2], enc_key->key_material, enc_key->key_len);
8848c2ecf20Sopenharmony_ci		memcpy(&set->key[2 + enc_key->key_len], enc_key->pn, PN_LEN);
8858c2ecf20Sopenharmony_ci		set->length = cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci		key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
8888c2ecf20Sopenharmony_ci				 sizeof(struct mwifiex_ie_types_header);
8898c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(key_material->action)
8908c2ecf20Sopenharmony_ci					+ S_DS_GEN +  key_param_len);
8918c2ecf20Sopenharmony_ci		return ret;
8928c2ecf20Sopenharmony_ci	}
8938c2ecf20Sopenharmony_ci	if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
8948c2ecf20Sopenharmony_ci		if (enc_key->is_igtk_key) {
8958c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, CMD, "cmd: CMAC_AES\n");
8968c2ecf20Sopenharmony_ci			key_material->key_param_set.key_type_id =
8978c2ecf20Sopenharmony_ci					cpu_to_le16(KEY_TYPE_ID_AES_CMAC);
8988c2ecf20Sopenharmony_ci			if (cmd_oid == KEY_INFO_ENABLED)
8998c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info =
9008c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_ENABLED);
9018c2ecf20Sopenharmony_ci			else
9028c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info =
9038c2ecf20Sopenharmony_ci						cpu_to_le16(!KEY_ENABLED);
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_ci			key_material->key_param_set.key_info |=
9068c2ecf20Sopenharmony_ci							cpu_to_le16(KEY_IGTK);
9078c2ecf20Sopenharmony_ci		} else {
9088c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, CMD, "cmd: WPA_AES\n");
9098c2ecf20Sopenharmony_ci			key_material->key_param_set.key_type_id =
9108c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_TYPE_ID_AES);
9118c2ecf20Sopenharmony_ci			if (cmd_oid == KEY_INFO_ENABLED)
9128c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info =
9138c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_ENABLED);
9148c2ecf20Sopenharmony_ci			else
9158c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info =
9168c2ecf20Sopenharmony_ci						cpu_to_le16(!KEY_ENABLED);
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_ci			if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
9198c2ecf20Sopenharmony_ci				/* AES pairwise key: unicast */
9208c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info |=
9218c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_UNICAST);
9228c2ecf20Sopenharmony_ci			else	/* AES group key: multicast */
9238c2ecf20Sopenharmony_ci				key_material->key_param_set.key_info |=
9248c2ecf20Sopenharmony_ci							cpu_to_le16(KEY_MCAST);
9258c2ecf20Sopenharmony_ci		}
9268c2ecf20Sopenharmony_ci	} else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
9278c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, CMD, "cmd: WPA_TKIP\n");
9288c2ecf20Sopenharmony_ci		key_material->key_param_set.key_type_id =
9298c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_TYPE_ID_TKIP);
9308c2ecf20Sopenharmony_ci		key_material->key_param_set.key_info =
9318c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_ENABLED);
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci		if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
9348c2ecf20Sopenharmony_ci				/* TKIP pairwise key: unicast */
9358c2ecf20Sopenharmony_ci			key_material->key_param_set.key_info |=
9368c2ecf20Sopenharmony_ci						cpu_to_le16(KEY_UNICAST);
9378c2ecf20Sopenharmony_ci		else		/* TKIP group key: multicast */
9388c2ecf20Sopenharmony_ci			key_material->key_param_set.key_info |=
9398c2ecf20Sopenharmony_ci							cpu_to_le16(KEY_MCAST);
9408c2ecf20Sopenharmony_ci	}
9418c2ecf20Sopenharmony_ci
9428c2ecf20Sopenharmony_ci	if (key_material->key_param_set.key_type_id) {
9438c2ecf20Sopenharmony_ci		key_material->key_param_set.type =
9448c2ecf20Sopenharmony_ci					cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
9458c2ecf20Sopenharmony_ci		key_material->key_param_set.key_len =
9468c2ecf20Sopenharmony_ci					cpu_to_le16((u16) enc_key->key_len);
9478c2ecf20Sopenharmony_ci		memcpy(key_material->key_param_set.key, enc_key->key_material,
9488c2ecf20Sopenharmony_ci		       enc_key->key_len);
9498c2ecf20Sopenharmony_ci		key_material->key_param_set.length =
9508c2ecf20Sopenharmony_ci			cpu_to_le16((u16) enc_key->key_len +
9518c2ecf20Sopenharmony_ci				    KEYPARAMSET_FIXED_LEN);
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci		key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
9548c2ecf20Sopenharmony_ci				+ sizeof(struct mwifiex_ie_types_header);
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci		if (le16_to_cpu(key_material->key_param_set.key_type_id) ==
9578c2ecf20Sopenharmony_ci							KEY_TYPE_ID_AES_CMAC) {
9588c2ecf20Sopenharmony_ci			struct mwifiex_cmac_param *param =
9598c2ecf20Sopenharmony_ci					(void *)key_material->key_param_set.key;
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci			memcpy(param->ipn, enc_key->pn, IGTK_PN_LEN);
9628c2ecf20Sopenharmony_ci			memcpy(param->key, enc_key->key_material,
9638c2ecf20Sopenharmony_ci			       WLAN_KEY_LEN_AES_CMAC);
9648c2ecf20Sopenharmony_ci
9658c2ecf20Sopenharmony_ci			key_param_len = sizeof(struct mwifiex_cmac_param);
9668c2ecf20Sopenharmony_ci			key_material->key_param_set.key_len =
9678c2ecf20Sopenharmony_ci						cpu_to_le16(key_param_len);
9688c2ecf20Sopenharmony_ci			key_param_len += KEYPARAMSET_FIXED_LEN;
9698c2ecf20Sopenharmony_ci			key_material->key_param_set.length =
9708c2ecf20Sopenharmony_ci						cpu_to_le16(key_param_len);
9718c2ecf20Sopenharmony_ci			key_param_len += sizeof(struct mwifiex_ie_types_header);
9728c2ecf20Sopenharmony_ci		}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
9758c2ecf20Sopenharmony_ci					+ key_param_len);
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci		if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
9788c2ecf20Sopenharmony_ci			tlv_mac = (void *)((u8 *)&key_material->key_param_set +
9798c2ecf20Sopenharmony_ci					   key_param_len);
9808c2ecf20Sopenharmony_ci			tlv_mac->header.type =
9818c2ecf20Sopenharmony_ci					cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
9828c2ecf20Sopenharmony_ci			tlv_mac->header.len = cpu_to_le16(ETH_ALEN);
9838c2ecf20Sopenharmony_ci			memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
9848c2ecf20Sopenharmony_ci			cmd_size = key_param_len + S_DS_GEN +
9858c2ecf20Sopenharmony_ci				   sizeof(key_material->action) +
9868c2ecf20Sopenharmony_ci				   sizeof(struct host_cmd_tlv_mac_addr);
9878c2ecf20Sopenharmony_ci		} else {
9888c2ecf20Sopenharmony_ci			cmd_size = key_param_len + S_DS_GEN +
9898c2ecf20Sopenharmony_ci				   sizeof(key_material->action);
9908c2ecf20Sopenharmony_ci		}
9918c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(cmd_size);
9928c2ecf20Sopenharmony_ci	}
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	return ret;
9958c2ecf20Sopenharmony_ci}
9968c2ecf20Sopenharmony_ci
9978c2ecf20Sopenharmony_ci/* Wrapper function for setting network key depending upon FW KEY API version */
9988c2ecf20Sopenharmony_cistatic int
9998c2ecf20Sopenharmony_cimwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
10008c2ecf20Sopenharmony_ci				struct host_cmd_ds_command *cmd,
10018c2ecf20Sopenharmony_ci				u16 cmd_action, u32 cmd_oid,
10028c2ecf20Sopenharmony_ci				struct mwifiex_ds_encrypt_key *enc_key)
10038c2ecf20Sopenharmony_ci{
10048c2ecf20Sopenharmony_ci	if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
10058c2ecf20Sopenharmony_ci		return mwifiex_cmd_802_11_key_material_v2(priv, cmd,
10068c2ecf20Sopenharmony_ci							  cmd_action, cmd_oid,
10078c2ecf20Sopenharmony_ci							  enc_key);
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci	else
10108c2ecf20Sopenharmony_ci		return mwifiex_cmd_802_11_key_material_v1(priv, cmd,
10118c2ecf20Sopenharmony_ci							  cmd_action, cmd_oid,
10128c2ecf20Sopenharmony_ci							  enc_key);
10138c2ecf20Sopenharmony_ci}
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci/*
10168c2ecf20Sopenharmony_ci * This function prepares command to set/get 11d domain information.
10178c2ecf20Sopenharmony_ci *
10188c2ecf20Sopenharmony_ci * Preparation includes -
10198c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
10208c2ecf20Sopenharmony_ci *      - Setting domain information fields (for SET only)
10218c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
10228c2ecf20Sopenharmony_ci */
10238c2ecf20Sopenharmony_cistatic int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
10248c2ecf20Sopenharmony_ci					   struct host_cmd_ds_command *cmd,
10258c2ecf20Sopenharmony_ci					   u16 cmd_action)
10268c2ecf20Sopenharmony_ci{
10278c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
10288c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11d_domain_info *domain_info =
10298c2ecf20Sopenharmony_ci		&cmd->params.domain_info;
10308c2ecf20Sopenharmony_ci	struct mwifiex_ietypes_domain_param_set *domain =
10318c2ecf20Sopenharmony_ci		&domain_info->domain;
10328c2ecf20Sopenharmony_ci	u8 no_of_triplet = adapter->domain_reg.no_of_triplet;
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci	mwifiex_dbg(adapter, INFO,
10358c2ecf20Sopenharmony_ci		    "info: 11D: no_of_triplet=0x%x\n", no_of_triplet);
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
10388c2ecf20Sopenharmony_ci	domain_info->action = cpu_to_le16(cmd_action);
10398c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_GET) {
10408c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
10418c2ecf20Sopenharmony_ci		return 0;
10428c2ecf20Sopenharmony_ci	}
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci	/* Set domain info fields */
10458c2ecf20Sopenharmony_ci	domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
10468c2ecf20Sopenharmony_ci	memcpy(domain->country_code, adapter->domain_reg.country_code,
10478c2ecf20Sopenharmony_ci	       sizeof(domain->country_code));
10488c2ecf20Sopenharmony_ci
10498c2ecf20Sopenharmony_ci	domain->header.len =
10508c2ecf20Sopenharmony_ci		cpu_to_le16((no_of_triplet *
10518c2ecf20Sopenharmony_ci			     sizeof(struct ieee80211_country_ie_triplet))
10528c2ecf20Sopenharmony_ci			    + sizeof(domain->country_code));
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_ci	if (no_of_triplet) {
10558c2ecf20Sopenharmony_ci		memcpy(domain->triplet, adapter->domain_reg.triplet,
10568c2ecf20Sopenharmony_ci		       no_of_triplet * sizeof(struct
10578c2ecf20Sopenharmony_ci					      ieee80211_country_ie_triplet));
10588c2ecf20Sopenharmony_ci
10598c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(domain_info->action) +
10608c2ecf20Sopenharmony_ci					le16_to_cpu(domain->header.len) +
10618c2ecf20Sopenharmony_ci					sizeof(struct mwifiex_ie_types_header)
10628c2ecf20Sopenharmony_ci					+ S_DS_GEN);
10638c2ecf20Sopenharmony_ci	} else {
10648c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
10658c2ecf20Sopenharmony_ci	}
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci	return 0;
10688c2ecf20Sopenharmony_ci}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_ci/*
10718c2ecf20Sopenharmony_ci * This function prepares command to set/get IBSS coalescing status.
10728c2ecf20Sopenharmony_ci *
10738c2ecf20Sopenharmony_ci * Preparation includes -
10748c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
10758c2ecf20Sopenharmony_ci *      - Setting status to enable or disable (for SET only)
10768c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
10778c2ecf20Sopenharmony_ci */
10788c2ecf20Sopenharmony_cistatic int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd,
10798c2ecf20Sopenharmony_ci					      u16 cmd_action, u16 *enable)
10808c2ecf20Sopenharmony_ci{
10818c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_ibss_status *ibss_coal =
10828c2ecf20Sopenharmony_ci		&(cmd->params.ibss_coalescing);
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
10858c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) +
10868c2ecf20Sopenharmony_ci				S_DS_GEN);
10878c2ecf20Sopenharmony_ci	cmd->result = 0;
10888c2ecf20Sopenharmony_ci	ibss_coal->action = cpu_to_le16(cmd_action);
10898c2ecf20Sopenharmony_ci
10908c2ecf20Sopenharmony_ci	switch (cmd_action) {
10918c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_SET:
10928c2ecf20Sopenharmony_ci		if (enable)
10938c2ecf20Sopenharmony_ci			ibss_coal->enable = cpu_to_le16(*enable);
10948c2ecf20Sopenharmony_ci		else
10958c2ecf20Sopenharmony_ci			ibss_coal->enable = 0;
10968c2ecf20Sopenharmony_ci		break;
10978c2ecf20Sopenharmony_ci
10988c2ecf20Sopenharmony_ci		/* In other case.. Nothing to do */
10998c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_GET:
11008c2ecf20Sopenharmony_ci	default:
11018c2ecf20Sopenharmony_ci		break;
11028c2ecf20Sopenharmony_ci	}
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_ci	return 0;
11058c2ecf20Sopenharmony_ci}
11068c2ecf20Sopenharmony_ci
11078c2ecf20Sopenharmony_ci/* This function prepares command buffer to get/set memory location value.
11088c2ecf20Sopenharmony_ci */
11098c2ecf20Sopenharmony_cistatic int
11108c2ecf20Sopenharmony_cimwifiex_cmd_mem_access(struct host_cmd_ds_command *cmd, u16 cmd_action,
11118c2ecf20Sopenharmony_ci		       void *pdata_buf)
11128c2ecf20Sopenharmony_ci{
11138c2ecf20Sopenharmony_ci	struct mwifiex_ds_mem_rw *mem_rw = (void *)pdata_buf;
11148c2ecf20Sopenharmony_ci	struct host_cmd_ds_mem_access *mem_access = (void *)&cmd->params.mem;
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_MEM_ACCESS);
11178c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mem_access) +
11188c2ecf20Sopenharmony_ci				S_DS_GEN);
11198c2ecf20Sopenharmony_ci
11208c2ecf20Sopenharmony_ci	mem_access->action = cpu_to_le16(cmd_action);
11218c2ecf20Sopenharmony_ci	mem_access->addr = cpu_to_le32(mem_rw->addr);
11228c2ecf20Sopenharmony_ci	mem_access->value = cpu_to_le32(mem_rw->value);
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ci	return 0;
11258c2ecf20Sopenharmony_ci}
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci/*
11288c2ecf20Sopenharmony_ci * This function prepares command to set/get register value.
11298c2ecf20Sopenharmony_ci *
11308c2ecf20Sopenharmony_ci * Preparation includes -
11318c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
11328c2ecf20Sopenharmony_ci *      - Setting register offset (for both GET and SET) and
11338c2ecf20Sopenharmony_ci *        register value (for SET only)
11348c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
11358c2ecf20Sopenharmony_ci *
11368c2ecf20Sopenharmony_ci * The following type of registers can be accessed with this function -
11378c2ecf20Sopenharmony_ci *      - MAC register
11388c2ecf20Sopenharmony_ci *      - BBP register
11398c2ecf20Sopenharmony_ci *      - RF register
11408c2ecf20Sopenharmony_ci *      - PMIC register
11418c2ecf20Sopenharmony_ci *      - CAU register
11428c2ecf20Sopenharmony_ci *      - EEPROM
11438c2ecf20Sopenharmony_ci */
11448c2ecf20Sopenharmony_cistatic int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
11458c2ecf20Sopenharmony_ci				  u16 cmd_action, void *data_buf)
11468c2ecf20Sopenharmony_ci{
11478c2ecf20Sopenharmony_ci	struct mwifiex_ds_reg_rw *reg_rw = data_buf;
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_ci	switch (le16_to_cpu(cmd->command)) {
11508c2ecf20Sopenharmony_ci	case HostCmd_CMD_MAC_REG_ACCESS:
11518c2ecf20Sopenharmony_ci	{
11528c2ecf20Sopenharmony_ci		struct host_cmd_ds_mac_reg_access *mac_reg;
11538c2ecf20Sopenharmony_ci
11548c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
11558c2ecf20Sopenharmony_ci		mac_reg = &cmd->params.mac_reg;
11568c2ecf20Sopenharmony_ci		mac_reg->action = cpu_to_le16(cmd_action);
11578c2ecf20Sopenharmony_ci		mac_reg->offset = cpu_to_le16((u16) reg_rw->offset);
11588c2ecf20Sopenharmony_ci		mac_reg->value = cpu_to_le32(reg_rw->value);
11598c2ecf20Sopenharmony_ci		break;
11608c2ecf20Sopenharmony_ci	}
11618c2ecf20Sopenharmony_ci	case HostCmd_CMD_BBP_REG_ACCESS:
11628c2ecf20Sopenharmony_ci	{
11638c2ecf20Sopenharmony_ci		struct host_cmd_ds_bbp_reg_access *bbp_reg;
11648c2ecf20Sopenharmony_ci
11658c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
11668c2ecf20Sopenharmony_ci		bbp_reg = &cmd->params.bbp_reg;
11678c2ecf20Sopenharmony_ci		bbp_reg->action = cpu_to_le16(cmd_action);
11688c2ecf20Sopenharmony_ci		bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset);
11698c2ecf20Sopenharmony_ci		bbp_reg->value = (u8) reg_rw->value;
11708c2ecf20Sopenharmony_ci		break;
11718c2ecf20Sopenharmony_ci	}
11728c2ecf20Sopenharmony_ci	case HostCmd_CMD_RF_REG_ACCESS:
11738c2ecf20Sopenharmony_ci	{
11748c2ecf20Sopenharmony_ci		struct host_cmd_ds_rf_reg_access *rf_reg;
11758c2ecf20Sopenharmony_ci
11768c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
11778c2ecf20Sopenharmony_ci		rf_reg = &cmd->params.rf_reg;
11788c2ecf20Sopenharmony_ci		rf_reg->action = cpu_to_le16(cmd_action);
11798c2ecf20Sopenharmony_ci		rf_reg->offset = cpu_to_le16((u16) reg_rw->offset);
11808c2ecf20Sopenharmony_ci		rf_reg->value = (u8) reg_rw->value;
11818c2ecf20Sopenharmony_ci		break;
11828c2ecf20Sopenharmony_ci	}
11838c2ecf20Sopenharmony_ci	case HostCmd_CMD_PMIC_REG_ACCESS:
11848c2ecf20Sopenharmony_ci	{
11858c2ecf20Sopenharmony_ci		struct host_cmd_ds_pmic_reg_access *pmic_reg;
11868c2ecf20Sopenharmony_ci
11878c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
11888c2ecf20Sopenharmony_ci		pmic_reg = &cmd->params.pmic_reg;
11898c2ecf20Sopenharmony_ci		pmic_reg->action = cpu_to_le16(cmd_action);
11908c2ecf20Sopenharmony_ci		pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset);
11918c2ecf20Sopenharmony_ci		pmic_reg->value = (u8) reg_rw->value;
11928c2ecf20Sopenharmony_ci		break;
11938c2ecf20Sopenharmony_ci	}
11948c2ecf20Sopenharmony_ci	case HostCmd_CMD_CAU_REG_ACCESS:
11958c2ecf20Sopenharmony_ci	{
11968c2ecf20Sopenharmony_ci		struct host_cmd_ds_rf_reg_access *cau_reg;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
11998c2ecf20Sopenharmony_ci		cau_reg = &cmd->params.rf_reg;
12008c2ecf20Sopenharmony_ci		cau_reg->action = cpu_to_le16(cmd_action);
12018c2ecf20Sopenharmony_ci		cau_reg->offset = cpu_to_le16((u16) reg_rw->offset);
12028c2ecf20Sopenharmony_ci		cau_reg->value = (u8) reg_rw->value;
12038c2ecf20Sopenharmony_ci		break;
12048c2ecf20Sopenharmony_ci	}
12058c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_EEPROM_ACCESS:
12068c2ecf20Sopenharmony_ci	{
12078c2ecf20Sopenharmony_ci		struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf;
12088c2ecf20Sopenharmony_ci		struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom =
12098c2ecf20Sopenharmony_ci			&cmd->params.eeprom;
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci		cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
12128c2ecf20Sopenharmony_ci		cmd_eeprom->action = cpu_to_le16(cmd_action);
12138c2ecf20Sopenharmony_ci		cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset);
12148c2ecf20Sopenharmony_ci		cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count);
12158c2ecf20Sopenharmony_ci		cmd_eeprom->value = 0;
12168c2ecf20Sopenharmony_ci		break;
12178c2ecf20Sopenharmony_ci	}
12188c2ecf20Sopenharmony_ci	default:
12198c2ecf20Sopenharmony_ci		return -1;
12208c2ecf20Sopenharmony_ci	}
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_ci	return 0;
12238c2ecf20Sopenharmony_ci}
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci/*
12268c2ecf20Sopenharmony_ci * This function prepares command to set PCI-Express
12278c2ecf20Sopenharmony_ci * host buffer configuration
12288c2ecf20Sopenharmony_ci *
12298c2ecf20Sopenharmony_ci * Preparation includes -
12308c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
12318c2ecf20Sopenharmony_ci *      - Setting host buffer configuration
12328c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
12338c2ecf20Sopenharmony_ci */
12348c2ecf20Sopenharmony_cistatic int
12358c2ecf20Sopenharmony_cimwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
12368c2ecf20Sopenharmony_ci			   struct host_cmd_ds_command *cmd, u16 action)
12378c2ecf20Sopenharmony_ci{
12388c2ecf20Sopenharmony_ci	struct host_cmd_ds_pcie_details *host_spec =
12398c2ecf20Sopenharmony_ci					&cmd->params.pcie_host_spec;
12408c2ecf20Sopenharmony_ci	struct pcie_service_card *card = priv->adapter->card;
12418c2ecf20Sopenharmony_ci
12428c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS);
12438c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct
12448c2ecf20Sopenharmony_ci					host_cmd_ds_pcie_details) + S_DS_GEN);
12458c2ecf20Sopenharmony_ci	cmd->result = 0;
12468c2ecf20Sopenharmony_ci
12478c2ecf20Sopenharmony_ci	memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details));
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_ci	if (action != HostCmd_ACT_GEN_SET)
12508c2ecf20Sopenharmony_ci		return 0;
12518c2ecf20Sopenharmony_ci
12528c2ecf20Sopenharmony_ci	/* Send the ring base addresses and count to firmware */
12538c2ecf20Sopenharmony_ci	host_spec->txbd_addr_lo = cpu_to_le32((u32)(card->txbd_ring_pbase));
12548c2ecf20Sopenharmony_ci	host_spec->txbd_addr_hi =
12558c2ecf20Sopenharmony_ci			cpu_to_le32((u32)(((u64)card->txbd_ring_pbase) >> 32));
12568c2ecf20Sopenharmony_ci	host_spec->txbd_count = cpu_to_le32(MWIFIEX_MAX_TXRX_BD);
12578c2ecf20Sopenharmony_ci	host_spec->rxbd_addr_lo = cpu_to_le32((u32)(card->rxbd_ring_pbase));
12588c2ecf20Sopenharmony_ci	host_spec->rxbd_addr_hi =
12598c2ecf20Sopenharmony_ci			cpu_to_le32((u32)(((u64)card->rxbd_ring_pbase) >> 32));
12608c2ecf20Sopenharmony_ci	host_spec->rxbd_count = cpu_to_le32(MWIFIEX_MAX_TXRX_BD);
12618c2ecf20Sopenharmony_ci	host_spec->evtbd_addr_lo = cpu_to_le32((u32)(card->evtbd_ring_pbase));
12628c2ecf20Sopenharmony_ci	host_spec->evtbd_addr_hi =
12638c2ecf20Sopenharmony_ci			cpu_to_le32((u32)(((u64)card->evtbd_ring_pbase) >> 32));
12648c2ecf20Sopenharmony_ci	host_spec->evtbd_count = cpu_to_le32(MWIFIEX_MAX_EVT_BD);
12658c2ecf20Sopenharmony_ci	if (card->sleep_cookie_vbase) {
12668c2ecf20Sopenharmony_ci		host_spec->sleep_cookie_addr_lo =
12678c2ecf20Sopenharmony_ci				cpu_to_le32((u32)(card->sleep_cookie_pbase));
12688c2ecf20Sopenharmony_ci		host_spec->sleep_cookie_addr_hi = cpu_to_le32((u32)(((u64)
12698c2ecf20Sopenharmony_ci					(card->sleep_cookie_pbase)) >> 32));
12708c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, INFO,
12718c2ecf20Sopenharmony_ci			    "sleep_cook_lo phy addr: 0x%x\n",
12728c2ecf20Sopenharmony_ci			    host_spec->sleep_cookie_addr_lo);
12738c2ecf20Sopenharmony_ci	}
12748c2ecf20Sopenharmony_ci
12758c2ecf20Sopenharmony_ci	return 0;
12768c2ecf20Sopenharmony_ci}
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ci/*
12798c2ecf20Sopenharmony_ci * This function prepares command for event subscription, configuration
12808c2ecf20Sopenharmony_ci * and query. Events can be subscribed or unsubscribed. Current subscribed
12818c2ecf20Sopenharmony_ci * events can be queried. Also, current subscribed events are reported in
12828c2ecf20Sopenharmony_ci * every FW response.
12838c2ecf20Sopenharmony_ci */
12848c2ecf20Sopenharmony_cistatic int
12858c2ecf20Sopenharmony_cimwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
12868c2ecf20Sopenharmony_ci			     struct host_cmd_ds_command *cmd,
12878c2ecf20Sopenharmony_ci			     struct mwifiex_ds_misc_subsc_evt *subsc_evt_cfg)
12888c2ecf20Sopenharmony_ci{
12898c2ecf20Sopenharmony_ci	struct host_cmd_ds_802_11_subsc_evt *subsc_evt = &cmd->params.subsc_evt;
12908c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_rssi_threshold *rssi_tlv;
12918c2ecf20Sopenharmony_ci	u16 event_bitmap;
12928c2ecf20Sopenharmony_ci	u8 *pos;
12938c2ecf20Sopenharmony_ci
12948c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
12958c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_subsc_evt) +
12968c2ecf20Sopenharmony_ci				S_DS_GEN);
12978c2ecf20Sopenharmony_ci
12988c2ecf20Sopenharmony_ci	subsc_evt->action = cpu_to_le16(subsc_evt_cfg->action);
12998c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD,
13008c2ecf20Sopenharmony_ci		    "cmd: action: %d\n", subsc_evt_cfg->action);
13018c2ecf20Sopenharmony_ci
13028c2ecf20Sopenharmony_ci	/*For query requests, no configuration TLV structures are to be added.*/
13038c2ecf20Sopenharmony_ci	if (subsc_evt_cfg->action == HostCmd_ACT_GEN_GET)
13048c2ecf20Sopenharmony_ci		return 0;
13058c2ecf20Sopenharmony_ci
13068c2ecf20Sopenharmony_ci	subsc_evt->events = cpu_to_le16(subsc_evt_cfg->events);
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_ci	event_bitmap = subsc_evt_cfg->events;
13098c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD, "cmd: event bitmap : %16x\n",
13108c2ecf20Sopenharmony_ci		    event_bitmap);
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci	if (((subsc_evt_cfg->action == HostCmd_ACT_BITWISE_CLR) ||
13138c2ecf20Sopenharmony_ci	     (subsc_evt_cfg->action == HostCmd_ACT_BITWISE_SET)) &&
13148c2ecf20Sopenharmony_ci	    (event_bitmap == 0)) {
13158c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
13168c2ecf20Sopenharmony_ci			    "Error: No event specified\t"
13178c2ecf20Sopenharmony_ci			    "for bitwise action type\n");
13188c2ecf20Sopenharmony_ci		return -EINVAL;
13198c2ecf20Sopenharmony_ci	}
13208c2ecf20Sopenharmony_ci
13218c2ecf20Sopenharmony_ci	/*
13228c2ecf20Sopenharmony_ci	 * Append TLV structures for each of the specified events for
13238c2ecf20Sopenharmony_ci	 * subscribing or re-configuring. This is not required for
13248c2ecf20Sopenharmony_ci	 * bitwise unsubscribing request.
13258c2ecf20Sopenharmony_ci	 */
13268c2ecf20Sopenharmony_ci	if (subsc_evt_cfg->action == HostCmd_ACT_BITWISE_CLR)
13278c2ecf20Sopenharmony_ci		return 0;
13288c2ecf20Sopenharmony_ci
13298c2ecf20Sopenharmony_ci	pos = ((u8 *)subsc_evt) +
13308c2ecf20Sopenharmony_ci			sizeof(struct host_cmd_ds_802_11_subsc_evt);
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci	if (event_bitmap & BITMASK_BCN_RSSI_LOW) {
13338c2ecf20Sopenharmony_ci		rssi_tlv = (struct mwifiex_ie_types_rssi_threshold *) pos;
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci		rssi_tlv->header.type = cpu_to_le16(TLV_TYPE_RSSI_LOW);
13368c2ecf20Sopenharmony_ci		rssi_tlv->header.len =
13378c2ecf20Sopenharmony_ci		    cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold) -
13388c2ecf20Sopenharmony_ci				sizeof(struct mwifiex_ie_types_header));
13398c2ecf20Sopenharmony_ci		rssi_tlv->abs_value = subsc_evt_cfg->bcn_l_rssi_cfg.abs_value;
13408c2ecf20Sopenharmony_ci		rssi_tlv->evt_freq = subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq;
13418c2ecf20Sopenharmony_ci
13428c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, EVENT,
13438c2ecf20Sopenharmony_ci			    "Cfg Beacon Low Rssi event,\t"
13448c2ecf20Sopenharmony_ci			    "RSSI:-%d dBm, Freq:%d\n",
13458c2ecf20Sopenharmony_ci			    subsc_evt_cfg->bcn_l_rssi_cfg.abs_value,
13468c2ecf20Sopenharmony_ci			    subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq);
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci		pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
13498c2ecf20Sopenharmony_ci		le16_unaligned_add_cpu(&cmd->size,
13508c2ecf20Sopenharmony_ci				       sizeof(
13518c2ecf20Sopenharmony_ci				       struct mwifiex_ie_types_rssi_threshold));
13528c2ecf20Sopenharmony_ci	}
13538c2ecf20Sopenharmony_ci
13548c2ecf20Sopenharmony_ci	if (event_bitmap & BITMASK_BCN_RSSI_HIGH) {
13558c2ecf20Sopenharmony_ci		rssi_tlv = (struct mwifiex_ie_types_rssi_threshold *) pos;
13568c2ecf20Sopenharmony_ci
13578c2ecf20Sopenharmony_ci		rssi_tlv->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
13588c2ecf20Sopenharmony_ci		rssi_tlv->header.len =
13598c2ecf20Sopenharmony_ci		    cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold) -
13608c2ecf20Sopenharmony_ci				sizeof(struct mwifiex_ie_types_header));
13618c2ecf20Sopenharmony_ci		rssi_tlv->abs_value = subsc_evt_cfg->bcn_h_rssi_cfg.abs_value;
13628c2ecf20Sopenharmony_ci		rssi_tlv->evt_freq = subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq;
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, EVENT,
13658c2ecf20Sopenharmony_ci			    "Cfg Beacon High Rssi event,\t"
13668c2ecf20Sopenharmony_ci			    "RSSI:-%d dBm, Freq:%d\n",
13678c2ecf20Sopenharmony_ci			    subsc_evt_cfg->bcn_h_rssi_cfg.abs_value,
13688c2ecf20Sopenharmony_ci			    subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq);
13698c2ecf20Sopenharmony_ci
13708c2ecf20Sopenharmony_ci		pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
13718c2ecf20Sopenharmony_ci		le16_unaligned_add_cpu(&cmd->size,
13728c2ecf20Sopenharmony_ci				       sizeof(
13738c2ecf20Sopenharmony_ci				       struct mwifiex_ie_types_rssi_threshold));
13748c2ecf20Sopenharmony_ci	}
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_ci	return 0;
13778c2ecf20Sopenharmony_ci}
13788c2ecf20Sopenharmony_ci
13798c2ecf20Sopenharmony_cistatic int
13808c2ecf20Sopenharmony_cimwifiex_cmd_append_rpn_expression(struct mwifiex_private *priv,
13818c2ecf20Sopenharmony_ci				  struct mwifiex_mef_entry *mef_entry,
13828c2ecf20Sopenharmony_ci				  u8 **buffer)
13838c2ecf20Sopenharmony_ci{
13848c2ecf20Sopenharmony_ci	struct mwifiex_mef_filter *filter = mef_entry->filter;
13858c2ecf20Sopenharmony_ci	int i, byte_len;
13868c2ecf20Sopenharmony_ci	u8 *stack_ptr = *buffer;
13878c2ecf20Sopenharmony_ci
13888c2ecf20Sopenharmony_ci	for (i = 0; i < MWIFIEX_MEF_MAX_FILTERS; i++) {
13898c2ecf20Sopenharmony_ci		filter = &mef_entry->filter[i];
13908c2ecf20Sopenharmony_ci		if (!filter->filt_type)
13918c2ecf20Sopenharmony_ci			break;
13928c2ecf20Sopenharmony_ci		put_unaligned_le32((u32)filter->repeat, stack_ptr);
13938c2ecf20Sopenharmony_ci		stack_ptr += 4;
13948c2ecf20Sopenharmony_ci		*stack_ptr = TYPE_DNUM;
13958c2ecf20Sopenharmony_ci		stack_ptr += 1;
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_ci		byte_len = filter->byte_seq[MWIFIEX_MEF_MAX_BYTESEQ];
13988c2ecf20Sopenharmony_ci		memcpy(stack_ptr, filter->byte_seq, byte_len);
13998c2ecf20Sopenharmony_ci		stack_ptr += byte_len;
14008c2ecf20Sopenharmony_ci		*stack_ptr = byte_len;
14018c2ecf20Sopenharmony_ci		stack_ptr += 1;
14028c2ecf20Sopenharmony_ci		*stack_ptr = TYPE_BYTESEQ;
14038c2ecf20Sopenharmony_ci		stack_ptr += 1;
14048c2ecf20Sopenharmony_ci		put_unaligned_le32((u32)filter->offset, stack_ptr);
14058c2ecf20Sopenharmony_ci		stack_ptr += 4;
14068c2ecf20Sopenharmony_ci		*stack_ptr = TYPE_DNUM;
14078c2ecf20Sopenharmony_ci		stack_ptr += 1;
14088c2ecf20Sopenharmony_ci
14098c2ecf20Sopenharmony_ci		*stack_ptr = filter->filt_type;
14108c2ecf20Sopenharmony_ci		stack_ptr += 1;
14118c2ecf20Sopenharmony_ci
14128c2ecf20Sopenharmony_ci		if (filter->filt_action) {
14138c2ecf20Sopenharmony_ci			*stack_ptr = filter->filt_action;
14148c2ecf20Sopenharmony_ci			stack_ptr += 1;
14158c2ecf20Sopenharmony_ci		}
14168c2ecf20Sopenharmony_ci
14178c2ecf20Sopenharmony_ci		if (stack_ptr - *buffer > STACK_NBYTES)
14188c2ecf20Sopenharmony_ci			return -1;
14198c2ecf20Sopenharmony_ci	}
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_ci	*buffer = stack_ptr;
14228c2ecf20Sopenharmony_ci	return 0;
14238c2ecf20Sopenharmony_ci}
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_cistatic int
14268c2ecf20Sopenharmony_cimwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
14278c2ecf20Sopenharmony_ci		    struct host_cmd_ds_command *cmd,
14288c2ecf20Sopenharmony_ci		    struct mwifiex_ds_mef_cfg *mef)
14298c2ecf20Sopenharmony_ci{
14308c2ecf20Sopenharmony_ci	struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg;
14318c2ecf20Sopenharmony_ci	struct mwifiex_fw_mef_entry *mef_entry = NULL;
14328c2ecf20Sopenharmony_ci	u8 *pos = (u8 *)mef_cfg;
14338c2ecf20Sopenharmony_ci	u16 i;
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG);
14368c2ecf20Sopenharmony_ci
14378c2ecf20Sopenharmony_ci	mef_cfg->criteria = cpu_to_le32(mef->criteria);
14388c2ecf20Sopenharmony_ci	mef_cfg->num_entries = cpu_to_le16(mef->num_entries);
14398c2ecf20Sopenharmony_ci	pos += sizeof(*mef_cfg);
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci	for (i = 0; i < mef->num_entries; i++) {
14428c2ecf20Sopenharmony_ci		mef_entry = (struct mwifiex_fw_mef_entry *)pos;
14438c2ecf20Sopenharmony_ci		mef_entry->mode = mef->mef_entry[i].mode;
14448c2ecf20Sopenharmony_ci		mef_entry->action = mef->mef_entry[i].action;
14458c2ecf20Sopenharmony_ci		pos += sizeof(*mef_cfg->mef_entry);
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci		if (mwifiex_cmd_append_rpn_expression(priv,
14488c2ecf20Sopenharmony_ci						      &mef->mef_entry[i], &pos))
14498c2ecf20Sopenharmony_ci			return -1;
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_ci		mef_entry->exprsize =
14528c2ecf20Sopenharmony_ci			cpu_to_le16(pos - mef_entry->expr);
14538c2ecf20Sopenharmony_ci	}
14548c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN);
14558c2ecf20Sopenharmony_ci
14568c2ecf20Sopenharmony_ci	return 0;
14578c2ecf20Sopenharmony_ci}
14588c2ecf20Sopenharmony_ci
14598c2ecf20Sopenharmony_ci/* This function parse cal data from ASCII to hex */
14608c2ecf20Sopenharmony_cistatic u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
14618c2ecf20Sopenharmony_ci{
14628c2ecf20Sopenharmony_ci	u8 *s = src, *d = dst;
14638c2ecf20Sopenharmony_ci
14648c2ecf20Sopenharmony_ci	while (s - src < len) {
14658c2ecf20Sopenharmony_ci		if (*s && (isspace(*s) || *s == '\t')) {
14668c2ecf20Sopenharmony_ci			s++;
14678c2ecf20Sopenharmony_ci			continue;
14688c2ecf20Sopenharmony_ci		}
14698c2ecf20Sopenharmony_ci		if (isxdigit(*s)) {
14708c2ecf20Sopenharmony_ci			*d++ = simple_strtol(s, NULL, 16);
14718c2ecf20Sopenharmony_ci			s += 2;
14728c2ecf20Sopenharmony_ci		} else {
14738c2ecf20Sopenharmony_ci			s++;
14748c2ecf20Sopenharmony_ci		}
14758c2ecf20Sopenharmony_ci	}
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci	return d - dst;
14788c2ecf20Sopenharmony_ci}
14798c2ecf20Sopenharmony_ci
14808c2ecf20Sopenharmony_ciint mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv,
14818c2ecf20Sopenharmony_ci			    struct device_node *node, const char *prefix)
14828c2ecf20Sopenharmony_ci{
14838c2ecf20Sopenharmony_ci#ifdef CONFIG_OF
14848c2ecf20Sopenharmony_ci	struct property *prop;
14858c2ecf20Sopenharmony_ci	size_t len = strlen(prefix);
14868c2ecf20Sopenharmony_ci	int ret;
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_ci	/* look for all matching property names */
14898c2ecf20Sopenharmony_ci	for_each_property_of_node(node, prop) {
14908c2ecf20Sopenharmony_ci		if (len > strlen(prop->name) ||
14918c2ecf20Sopenharmony_ci		    strncmp(prop->name, prefix, len))
14928c2ecf20Sopenharmony_ci			continue;
14938c2ecf20Sopenharmony_ci
14948c2ecf20Sopenharmony_ci		/* property header is 6 bytes, data must fit in cmd buffer */
14958c2ecf20Sopenharmony_ci		if (prop->value && prop->length > 6 &&
14968c2ecf20Sopenharmony_ci		    prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) {
14978c2ecf20Sopenharmony_ci			ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
14988c2ecf20Sopenharmony_ci					       HostCmd_ACT_GEN_SET, 0,
14998c2ecf20Sopenharmony_ci					       prop, true);
15008c2ecf20Sopenharmony_ci			if (ret)
15018c2ecf20Sopenharmony_ci				return ret;
15028c2ecf20Sopenharmony_ci		}
15038c2ecf20Sopenharmony_ci	}
15048c2ecf20Sopenharmony_ci#endif
15058c2ecf20Sopenharmony_ci	return 0;
15068c2ecf20Sopenharmony_ci}
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_ci/* This function prepares command of set_cfg_data. */
15098c2ecf20Sopenharmony_cistatic int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
15108c2ecf20Sopenharmony_ci				struct host_cmd_ds_command *cmd, void *data_buf)
15118c2ecf20Sopenharmony_ci{
15128c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
15138c2ecf20Sopenharmony_ci	struct property *prop = data_buf;
15148c2ecf20Sopenharmony_ci	u32 len;
15158c2ecf20Sopenharmony_ci	u8 *data = (u8 *)cmd + S_DS_GEN;
15168c2ecf20Sopenharmony_ci	int ret;
15178c2ecf20Sopenharmony_ci
15188c2ecf20Sopenharmony_ci	if (prop) {
15198c2ecf20Sopenharmony_ci		len = prop->length;
15208c2ecf20Sopenharmony_ci		ret = of_property_read_u8_array(adapter->dt_node, prop->name,
15218c2ecf20Sopenharmony_ci						data, len);
15228c2ecf20Sopenharmony_ci		if (ret)
15238c2ecf20Sopenharmony_ci			return ret;
15248c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
15258c2ecf20Sopenharmony_ci			    "download cfg_data from device tree: %s\n",
15268c2ecf20Sopenharmony_ci			    prop->name);
15278c2ecf20Sopenharmony_ci	} else if (adapter->cal_data->data && adapter->cal_data->size > 0) {
15288c2ecf20Sopenharmony_ci		len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
15298c2ecf20Sopenharmony_ci					    adapter->cal_data->size, data);
15308c2ecf20Sopenharmony_ci		mwifiex_dbg(adapter, INFO,
15318c2ecf20Sopenharmony_ci			    "download cfg_data from config file\n");
15328c2ecf20Sopenharmony_ci	} else {
15338c2ecf20Sopenharmony_ci		return -1;
15348c2ecf20Sopenharmony_ci	}
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
15378c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(S_DS_GEN + len);
15388c2ecf20Sopenharmony_ci
15398c2ecf20Sopenharmony_ci	return 0;
15408c2ecf20Sopenharmony_ci}
15418c2ecf20Sopenharmony_ci
15428c2ecf20Sopenharmony_cistatic int
15438c2ecf20Sopenharmony_cimwifiex_cmd_set_mc_policy(struct mwifiex_private *priv,
15448c2ecf20Sopenharmony_ci			  struct host_cmd_ds_command *cmd,
15458c2ecf20Sopenharmony_ci			  u16 cmd_action, void *data_buf)
15468c2ecf20Sopenharmony_ci{
15478c2ecf20Sopenharmony_ci	struct host_cmd_ds_multi_chan_policy *mc_pol = &cmd->params.mc_policy;
15488c2ecf20Sopenharmony_ci	const u16 *drcs_info = data_buf;
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_ci	mc_pol->action = cpu_to_le16(cmd_action);
15518c2ecf20Sopenharmony_ci	mc_pol->policy = cpu_to_le16(*drcs_info);
15528c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_MC_POLICY);
15538c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_multi_chan_policy) +
15548c2ecf20Sopenharmony_ci				S_DS_GEN);
15558c2ecf20Sopenharmony_ci	return 0;
15568c2ecf20Sopenharmony_ci}
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_cistatic int mwifiex_cmd_robust_coex(struct mwifiex_private *priv,
15598c2ecf20Sopenharmony_ci				   struct host_cmd_ds_command *cmd,
15608c2ecf20Sopenharmony_ci				   u16 cmd_action, bool *is_timeshare)
15618c2ecf20Sopenharmony_ci{
15628c2ecf20Sopenharmony_ci	struct host_cmd_ds_robust_coex *coex = &cmd->params.coex;
15638c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_robust_coex *coex_tlv;
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_ROBUST_COEX);
15668c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(*coex) + sizeof(*coex_tlv) + S_DS_GEN);
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci	coex->action = cpu_to_le16(cmd_action);
15698c2ecf20Sopenharmony_ci	coex_tlv = (struct mwifiex_ie_types_robust_coex *)
15708c2ecf20Sopenharmony_ci				((u8 *)coex + sizeof(*coex));
15718c2ecf20Sopenharmony_ci	coex_tlv->header.type = cpu_to_le16(TLV_TYPE_ROBUST_COEX);
15728c2ecf20Sopenharmony_ci	coex_tlv->header.len = cpu_to_le16(sizeof(coex_tlv->mode));
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci	if (coex->action == HostCmd_ACT_GEN_GET)
15758c2ecf20Sopenharmony_ci		return 0;
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_ci	if (*is_timeshare)
15788c2ecf20Sopenharmony_ci		coex_tlv->mode = cpu_to_le32(MWIFIEX_COEX_MODE_TIMESHARE);
15798c2ecf20Sopenharmony_ci	else
15808c2ecf20Sopenharmony_ci		coex_tlv->mode = cpu_to_le32(MWIFIEX_COEX_MODE_SPATIAL);
15818c2ecf20Sopenharmony_ci
15828c2ecf20Sopenharmony_ci	return 0;
15838c2ecf20Sopenharmony_ci}
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_cistatic int mwifiex_cmd_gtk_rekey_offload(struct mwifiex_private *priv,
15868c2ecf20Sopenharmony_ci					 struct host_cmd_ds_command *cmd,
15878c2ecf20Sopenharmony_ci					 u16 cmd_action,
15888c2ecf20Sopenharmony_ci					 struct cfg80211_gtk_rekey_data *data)
15898c2ecf20Sopenharmony_ci{
15908c2ecf20Sopenharmony_ci	struct host_cmd_ds_gtk_rekey_params *rekey = &cmd->params.rekey;
15918c2ecf20Sopenharmony_ci	u64 rekey_ctr;
15928c2ecf20Sopenharmony_ci
15938c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG);
15948c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(*rekey) + S_DS_GEN);
15958c2ecf20Sopenharmony_ci
15968c2ecf20Sopenharmony_ci	rekey->action = cpu_to_le16(cmd_action);
15978c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_SET) {
15988c2ecf20Sopenharmony_ci		memcpy(rekey->kek, data->kek, NL80211_KEK_LEN);
15998c2ecf20Sopenharmony_ci		memcpy(rekey->kck, data->kck, NL80211_KCK_LEN);
16008c2ecf20Sopenharmony_ci		rekey_ctr = be64_to_cpup((__be64 *)data->replay_ctr);
16018c2ecf20Sopenharmony_ci		rekey->replay_ctr_low = cpu_to_le32((u32)rekey_ctr);
16028c2ecf20Sopenharmony_ci		rekey->replay_ctr_high =
16038c2ecf20Sopenharmony_ci			cpu_to_le32((u32)((u64)rekey_ctr >> 32));
16048c2ecf20Sopenharmony_ci	}
16058c2ecf20Sopenharmony_ci
16068c2ecf20Sopenharmony_ci	return 0;
16078c2ecf20Sopenharmony_ci}
16088c2ecf20Sopenharmony_ci
16098c2ecf20Sopenharmony_cistatic int mwifiex_cmd_chan_region_cfg(struct mwifiex_private *priv,
16108c2ecf20Sopenharmony_ci				       struct host_cmd_ds_command *cmd,
16118c2ecf20Sopenharmony_ci				       u16 cmd_action)
16128c2ecf20Sopenharmony_ci{
16138c2ecf20Sopenharmony_ci	struct host_cmd_ds_chan_region_cfg *reg = &cmd->params.reg_cfg;
16148c2ecf20Sopenharmony_ci
16158c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REGION_CFG);
16168c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(*reg) + S_DS_GEN);
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_GET)
16198c2ecf20Sopenharmony_ci		reg->action = cpu_to_le16(cmd_action);
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_ci	return 0;
16228c2ecf20Sopenharmony_ci}
16238c2ecf20Sopenharmony_ci
16248c2ecf20Sopenharmony_cistatic int
16258c2ecf20Sopenharmony_cimwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv,
16268c2ecf20Sopenharmony_ci			 struct host_cmd_ds_command *cmd,
16278c2ecf20Sopenharmony_ci			 u16 cmd_action, void *data_buf)
16288c2ecf20Sopenharmony_ci{
16298c2ecf20Sopenharmony_ci	struct host_cmd_ds_coalesce_cfg *coalesce_cfg =
16308c2ecf20Sopenharmony_ci						&cmd->params.coalesce_cfg;
16318c2ecf20Sopenharmony_ci	struct mwifiex_ds_coalesce_cfg *cfg = data_buf;
16328c2ecf20Sopenharmony_ci	struct coalesce_filt_field_param *param;
16338c2ecf20Sopenharmony_ci	u16 cnt, idx, length;
16348c2ecf20Sopenharmony_ci	struct coalesce_receive_filt_rule *rule;
16358c2ecf20Sopenharmony_ci
16368c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_COALESCE_CFG);
16378c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(S_DS_GEN);
16388c2ecf20Sopenharmony_ci
16398c2ecf20Sopenharmony_ci	coalesce_cfg->action = cpu_to_le16(cmd_action);
16408c2ecf20Sopenharmony_ci	coalesce_cfg->num_of_rules = cpu_to_le16(cfg->num_of_rules);
16418c2ecf20Sopenharmony_ci	rule = coalesce_cfg->rule;
16428c2ecf20Sopenharmony_ci
16438c2ecf20Sopenharmony_ci	for (cnt = 0; cnt < cfg->num_of_rules; cnt++) {
16448c2ecf20Sopenharmony_ci		rule->header.type = cpu_to_le16(TLV_TYPE_COALESCE_RULE);
16458c2ecf20Sopenharmony_ci		rule->max_coalescing_delay =
16468c2ecf20Sopenharmony_ci			cpu_to_le16(cfg->rule[cnt].max_coalescing_delay);
16478c2ecf20Sopenharmony_ci		rule->pkt_type = cfg->rule[cnt].pkt_type;
16488c2ecf20Sopenharmony_ci		rule->num_of_fields = cfg->rule[cnt].num_of_fields;
16498c2ecf20Sopenharmony_ci
16508c2ecf20Sopenharmony_ci		length = 0;
16518c2ecf20Sopenharmony_ci
16528c2ecf20Sopenharmony_ci		param = rule->params;
16538c2ecf20Sopenharmony_ci		for (idx = 0; idx < cfg->rule[cnt].num_of_fields; idx++) {
16548c2ecf20Sopenharmony_ci			param->operation = cfg->rule[cnt].params[idx].operation;
16558c2ecf20Sopenharmony_ci			param->operand_len =
16568c2ecf20Sopenharmony_ci					cfg->rule[cnt].params[idx].operand_len;
16578c2ecf20Sopenharmony_ci			param->offset =
16588c2ecf20Sopenharmony_ci				cpu_to_le16(cfg->rule[cnt].params[idx].offset);
16598c2ecf20Sopenharmony_ci			memcpy(param->operand_byte_stream,
16608c2ecf20Sopenharmony_ci			       cfg->rule[cnt].params[idx].operand_byte_stream,
16618c2ecf20Sopenharmony_ci			       param->operand_len);
16628c2ecf20Sopenharmony_ci
16638c2ecf20Sopenharmony_ci			length += sizeof(struct coalesce_filt_field_param);
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_ci			param++;
16668c2ecf20Sopenharmony_ci		}
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci		/* Total rule length is sizeof max_coalescing_delay(u16),
16698c2ecf20Sopenharmony_ci		 * num_of_fields(u8), pkt_type(u8) and total length of the all
16708c2ecf20Sopenharmony_ci		 * params
16718c2ecf20Sopenharmony_ci		 */
16728c2ecf20Sopenharmony_ci		rule->header.len = cpu_to_le16(length + sizeof(u16) +
16738c2ecf20Sopenharmony_ci					       sizeof(u8) + sizeof(u8));
16748c2ecf20Sopenharmony_ci
16758c2ecf20Sopenharmony_ci		/* Add the rule length to the command size*/
16768c2ecf20Sopenharmony_ci		le16_unaligned_add_cpu(&cmd->size,
16778c2ecf20Sopenharmony_ci				       le16_to_cpu(rule->header.len) +
16788c2ecf20Sopenharmony_ci				       sizeof(struct mwifiex_ie_types_header));
16798c2ecf20Sopenharmony_ci
16808c2ecf20Sopenharmony_ci		rule = (void *)((u8 *)rule->params + length);
16818c2ecf20Sopenharmony_ci	}
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci	/* Add sizeof action, num_of_rules to total command length */
16848c2ecf20Sopenharmony_ci	le16_unaligned_add_cpu(&cmd->size, sizeof(u16) + sizeof(u16));
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci	return 0;
16878c2ecf20Sopenharmony_ci}
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_cistatic int
16908c2ecf20Sopenharmony_cimwifiex_cmd_tdls_config(struct mwifiex_private *priv,
16918c2ecf20Sopenharmony_ci			struct host_cmd_ds_command *cmd,
16928c2ecf20Sopenharmony_ci			u16 cmd_action, void *data_buf)
16938c2ecf20Sopenharmony_ci{
16948c2ecf20Sopenharmony_ci	struct host_cmd_ds_tdls_config *tdls_config = &cmd->params.tdls_config;
16958c2ecf20Sopenharmony_ci	struct mwifiex_tdls_init_cs_params *config;
16968c2ecf20Sopenharmony_ci	struct mwifiex_tdls_config *init_config;
16978c2ecf20Sopenharmony_ci	u16 len;
16988c2ecf20Sopenharmony_ci
16998c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_CONFIG);
17008c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(S_DS_GEN);
17018c2ecf20Sopenharmony_ci	tdls_config->tdls_action = cpu_to_le16(cmd_action);
17028c2ecf20Sopenharmony_ci	le16_unaligned_add_cpu(&cmd->size, sizeof(tdls_config->tdls_action));
17038c2ecf20Sopenharmony_ci
17048c2ecf20Sopenharmony_ci	switch (cmd_action) {
17058c2ecf20Sopenharmony_ci	case ACT_TDLS_CS_ENABLE_CONFIG:
17068c2ecf20Sopenharmony_ci		init_config = data_buf;
17078c2ecf20Sopenharmony_ci		len = sizeof(*init_config);
17088c2ecf20Sopenharmony_ci		memcpy(tdls_config->tdls_data, init_config, len);
17098c2ecf20Sopenharmony_ci		break;
17108c2ecf20Sopenharmony_ci	case ACT_TDLS_CS_INIT:
17118c2ecf20Sopenharmony_ci		config = data_buf;
17128c2ecf20Sopenharmony_ci		len = sizeof(*config);
17138c2ecf20Sopenharmony_ci		memcpy(tdls_config->tdls_data, config, len);
17148c2ecf20Sopenharmony_ci		break;
17158c2ecf20Sopenharmony_ci	case ACT_TDLS_CS_STOP:
17168c2ecf20Sopenharmony_ci		len = sizeof(struct mwifiex_tdls_stop_cs_params);
17178c2ecf20Sopenharmony_ci		memcpy(tdls_config->tdls_data, data_buf, len);
17188c2ecf20Sopenharmony_ci		break;
17198c2ecf20Sopenharmony_ci	case ACT_TDLS_CS_PARAMS:
17208c2ecf20Sopenharmony_ci		len = sizeof(struct mwifiex_tdls_config_cs_params);
17218c2ecf20Sopenharmony_ci		memcpy(tdls_config->tdls_data, data_buf, len);
17228c2ecf20Sopenharmony_ci		break;
17238c2ecf20Sopenharmony_ci	default:
17248c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
17258c2ecf20Sopenharmony_ci			    "Unknown TDLS configuration\n");
17268c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
17278c2ecf20Sopenharmony_ci	}
17288c2ecf20Sopenharmony_ci
17298c2ecf20Sopenharmony_ci	le16_unaligned_add_cpu(&cmd->size, len);
17308c2ecf20Sopenharmony_ci	return 0;
17318c2ecf20Sopenharmony_ci}
17328c2ecf20Sopenharmony_ci
17338c2ecf20Sopenharmony_cistatic int
17348c2ecf20Sopenharmony_cimwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
17358c2ecf20Sopenharmony_ci		      struct host_cmd_ds_command *cmd,
17368c2ecf20Sopenharmony_ci		      void *data_buf)
17378c2ecf20Sopenharmony_ci{
17388c2ecf20Sopenharmony_ci	struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper;
17398c2ecf20Sopenharmony_ci	struct mwifiex_ds_tdls_oper *oper = data_buf;
17408c2ecf20Sopenharmony_ci	struct host_cmd_tlv_rates *tlv_rates;
17418c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_htcap *ht_capab;
17428c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_qos_info *wmm_qos_info;
17438c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_extcap *extcap;
17448c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_vhtcap *vht_capab;
17458c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_aid *aid;
17468c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_tdls_idle_timeout *timeout;
17478c2ecf20Sopenharmony_ci	u8 *pos;
17488c2ecf20Sopenharmony_ci	u16 config_len = 0;
17498c2ecf20Sopenharmony_ci	struct station_parameters *params = priv->sta_params;
17508c2ecf20Sopenharmony_ci
17518c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER);
17528c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(S_DS_GEN);
17538c2ecf20Sopenharmony_ci	le16_unaligned_add_cpu(&cmd->size,
17548c2ecf20Sopenharmony_ci			       sizeof(struct host_cmd_ds_tdls_oper));
17558c2ecf20Sopenharmony_ci
17568c2ecf20Sopenharmony_ci	tdls_oper->reason = 0;
17578c2ecf20Sopenharmony_ci	memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
17588c2ecf20Sopenharmony_ci
17598c2ecf20Sopenharmony_ci	pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper);
17608c2ecf20Sopenharmony_ci
17618c2ecf20Sopenharmony_ci	switch (oper->tdls_action) {
17628c2ecf20Sopenharmony_ci	case MWIFIEX_TDLS_DISABLE_LINK:
17638c2ecf20Sopenharmony_ci		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE);
17648c2ecf20Sopenharmony_ci		break;
17658c2ecf20Sopenharmony_ci	case MWIFIEX_TDLS_CREATE_LINK:
17668c2ecf20Sopenharmony_ci		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE);
17678c2ecf20Sopenharmony_ci		break;
17688c2ecf20Sopenharmony_ci	case MWIFIEX_TDLS_CONFIG_LINK:
17698c2ecf20Sopenharmony_ci		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CONFIG);
17708c2ecf20Sopenharmony_ci
17718c2ecf20Sopenharmony_ci		if (!params) {
17728c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, ERROR,
17738c2ecf20Sopenharmony_ci				    "TDLS config params not available for %pM\n",
17748c2ecf20Sopenharmony_ci				    oper->peer_mac);
17758c2ecf20Sopenharmony_ci			return -ENODATA;
17768c2ecf20Sopenharmony_ci		}
17778c2ecf20Sopenharmony_ci
17788c2ecf20Sopenharmony_ci		put_unaligned_le16(params->capability, pos);
17798c2ecf20Sopenharmony_ci		config_len += sizeof(params->capability);
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci		wmm_qos_info = (void *)(pos + config_len);
17828c2ecf20Sopenharmony_ci		wmm_qos_info->header.type = cpu_to_le16(WLAN_EID_QOS_CAPA);
17838c2ecf20Sopenharmony_ci		wmm_qos_info->header.len =
17848c2ecf20Sopenharmony_ci				cpu_to_le16(sizeof(wmm_qos_info->qos_info));
17858c2ecf20Sopenharmony_ci		wmm_qos_info->qos_info = 0;
17868c2ecf20Sopenharmony_ci		config_len += sizeof(struct mwifiex_ie_types_qos_info);
17878c2ecf20Sopenharmony_ci
17888c2ecf20Sopenharmony_ci		if (params->ht_capa) {
17898c2ecf20Sopenharmony_ci			ht_capab = (struct mwifiex_ie_types_htcap *)(pos +
17908c2ecf20Sopenharmony_ci								    config_len);
17918c2ecf20Sopenharmony_ci			ht_capab->header.type =
17928c2ecf20Sopenharmony_ci					    cpu_to_le16(WLAN_EID_HT_CAPABILITY);
17938c2ecf20Sopenharmony_ci			ht_capab->header.len =
17948c2ecf20Sopenharmony_ci				   cpu_to_le16(sizeof(struct ieee80211_ht_cap));
17958c2ecf20Sopenharmony_ci			memcpy(&ht_capab->ht_cap, params->ht_capa,
17968c2ecf20Sopenharmony_ci			       sizeof(struct ieee80211_ht_cap));
17978c2ecf20Sopenharmony_ci			config_len += sizeof(struct mwifiex_ie_types_htcap);
17988c2ecf20Sopenharmony_ci		}
17998c2ecf20Sopenharmony_ci
18008c2ecf20Sopenharmony_ci		if (params->supported_rates && params->supported_rates_len) {
18018c2ecf20Sopenharmony_ci			tlv_rates = (struct host_cmd_tlv_rates *)(pos +
18028c2ecf20Sopenharmony_ci								  config_len);
18038c2ecf20Sopenharmony_ci			tlv_rates->header.type =
18048c2ecf20Sopenharmony_ci					       cpu_to_le16(WLAN_EID_SUPP_RATES);
18058c2ecf20Sopenharmony_ci			tlv_rates->header.len =
18068c2ecf20Sopenharmony_ci				       cpu_to_le16(params->supported_rates_len);
18078c2ecf20Sopenharmony_ci			memcpy(tlv_rates->rates, params->supported_rates,
18088c2ecf20Sopenharmony_ci			       params->supported_rates_len);
18098c2ecf20Sopenharmony_ci			config_len += sizeof(struct host_cmd_tlv_rates) +
18108c2ecf20Sopenharmony_ci				      params->supported_rates_len;
18118c2ecf20Sopenharmony_ci		}
18128c2ecf20Sopenharmony_ci
18138c2ecf20Sopenharmony_ci		if (params->ext_capab && params->ext_capab_len) {
18148c2ecf20Sopenharmony_ci			extcap = (struct mwifiex_ie_types_extcap *)(pos +
18158c2ecf20Sopenharmony_ci								    config_len);
18168c2ecf20Sopenharmony_ci			extcap->header.type =
18178c2ecf20Sopenharmony_ci					   cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
18188c2ecf20Sopenharmony_ci			extcap->header.len = cpu_to_le16(params->ext_capab_len);
18198c2ecf20Sopenharmony_ci			memcpy(extcap->ext_capab, params->ext_capab,
18208c2ecf20Sopenharmony_ci			       params->ext_capab_len);
18218c2ecf20Sopenharmony_ci			config_len += sizeof(struct mwifiex_ie_types_extcap) +
18228c2ecf20Sopenharmony_ci				      params->ext_capab_len;
18238c2ecf20Sopenharmony_ci		}
18248c2ecf20Sopenharmony_ci		if (params->vht_capa) {
18258c2ecf20Sopenharmony_ci			vht_capab = (struct mwifiex_ie_types_vhtcap *)(pos +
18268c2ecf20Sopenharmony_ci								    config_len);
18278c2ecf20Sopenharmony_ci			vht_capab->header.type =
18288c2ecf20Sopenharmony_ci					   cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
18298c2ecf20Sopenharmony_ci			vht_capab->header.len =
18308c2ecf20Sopenharmony_ci				  cpu_to_le16(sizeof(struct ieee80211_vht_cap));
18318c2ecf20Sopenharmony_ci			memcpy(&vht_capab->vht_cap, params->vht_capa,
18328c2ecf20Sopenharmony_ci			       sizeof(struct ieee80211_vht_cap));
18338c2ecf20Sopenharmony_ci			config_len += sizeof(struct mwifiex_ie_types_vhtcap);
18348c2ecf20Sopenharmony_ci		}
18358c2ecf20Sopenharmony_ci		if (params->aid) {
18368c2ecf20Sopenharmony_ci			aid = (struct mwifiex_ie_types_aid *)(pos + config_len);
18378c2ecf20Sopenharmony_ci			aid->header.type = cpu_to_le16(WLAN_EID_AID);
18388c2ecf20Sopenharmony_ci			aid->header.len = cpu_to_le16(sizeof(params->aid));
18398c2ecf20Sopenharmony_ci			aid->aid = cpu_to_le16(params->aid);
18408c2ecf20Sopenharmony_ci			config_len += sizeof(struct mwifiex_ie_types_aid);
18418c2ecf20Sopenharmony_ci		}
18428c2ecf20Sopenharmony_ci
18438c2ecf20Sopenharmony_ci		timeout = (void *)(pos + config_len);
18448c2ecf20Sopenharmony_ci		timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
18458c2ecf20Sopenharmony_ci		timeout->header.len = cpu_to_le16(sizeof(timeout->value));
18468c2ecf20Sopenharmony_ci		timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC);
18478c2ecf20Sopenharmony_ci		config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout);
18488c2ecf20Sopenharmony_ci
18498c2ecf20Sopenharmony_ci		break;
18508c2ecf20Sopenharmony_ci	default:
18518c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS operation\n");
18528c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
18538c2ecf20Sopenharmony_ci	}
18548c2ecf20Sopenharmony_ci
18558c2ecf20Sopenharmony_ci	le16_unaligned_add_cpu(&cmd->size, config_len);
18568c2ecf20Sopenharmony_ci
18578c2ecf20Sopenharmony_ci	return 0;
18588c2ecf20Sopenharmony_ci}
18598c2ecf20Sopenharmony_ci
18608c2ecf20Sopenharmony_ci/* This function prepares command of sdio rx aggr info. */
18618c2ecf20Sopenharmony_cistatic int mwifiex_cmd_sdio_rx_aggr_cfg(struct host_cmd_ds_command *cmd,
18628c2ecf20Sopenharmony_ci					u16 cmd_action, void *data_buf)
18638c2ecf20Sopenharmony_ci{
18648c2ecf20Sopenharmony_ci	struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
18658c2ecf20Sopenharmony_ci					&cmd->params.sdio_rx_aggr_cfg;
18668c2ecf20Sopenharmony_ci
18678c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_SDIO_SP_RX_AGGR_CFG);
18688c2ecf20Sopenharmony_ci	cmd->size =
18698c2ecf20Sopenharmony_ci		cpu_to_le16(sizeof(struct host_cmd_sdio_sp_rx_aggr_cfg) +
18708c2ecf20Sopenharmony_ci			    S_DS_GEN);
18718c2ecf20Sopenharmony_ci	cfg->action = cmd_action;
18728c2ecf20Sopenharmony_ci	if (cmd_action == HostCmd_ACT_GEN_SET)
18738c2ecf20Sopenharmony_ci		cfg->enable = *(u8 *)data_buf;
18748c2ecf20Sopenharmony_ci
18758c2ecf20Sopenharmony_ci	return 0;
18768c2ecf20Sopenharmony_ci}
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci/* This function prepares command to get HS wakeup reason.
18798c2ecf20Sopenharmony_ci *
18808c2ecf20Sopenharmony_ci * Preparation includes -
18818c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
18828c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
18838c2ecf20Sopenharmony_ci */
18848c2ecf20Sopenharmony_cistatic int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private *priv,
18858c2ecf20Sopenharmony_ci					 struct host_cmd_ds_command *cmd)
18868c2ecf20Sopenharmony_ci{
18878c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_HS_WAKEUP_REASON);
18888c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_wakeup_reason) +
18898c2ecf20Sopenharmony_ci				S_DS_GEN);
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_ci	return 0;
18928c2ecf20Sopenharmony_ci}
18938c2ecf20Sopenharmony_ci
18948c2ecf20Sopenharmony_cistatic int mwifiex_cmd_get_chan_info(struct host_cmd_ds_command *cmd,
18958c2ecf20Sopenharmony_ci				     u16 cmd_action)
18968c2ecf20Sopenharmony_ci{
18978c2ecf20Sopenharmony_ci	struct host_cmd_ds_sta_configure *sta_cfg_cmd = &cmd->params.sta_cfg;
18988c2ecf20Sopenharmony_ci	struct host_cmd_tlv_channel_band *tlv_band_channel =
18998c2ecf20Sopenharmony_ci	(struct host_cmd_tlv_channel_band *)sta_cfg_cmd->tlv_buffer;
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_STA_CONFIGURE);
19028c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(*sta_cfg_cmd) +
19038c2ecf20Sopenharmony_ci				sizeof(*tlv_band_channel) + S_DS_GEN);
19048c2ecf20Sopenharmony_ci	sta_cfg_cmd->action = cpu_to_le16(cmd_action);
19058c2ecf20Sopenharmony_ci	memset(tlv_band_channel, 0, sizeof(*tlv_band_channel));
19068c2ecf20Sopenharmony_ci	tlv_band_channel->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
19078c2ecf20Sopenharmony_ci	tlv_band_channel->header.len  = cpu_to_le16(sizeof(*tlv_band_channel) -
19088c2ecf20Sopenharmony_ci					sizeof(struct mwifiex_ie_types_header));
19098c2ecf20Sopenharmony_ci
19108c2ecf20Sopenharmony_ci	return 0;
19118c2ecf20Sopenharmony_ci}
19128c2ecf20Sopenharmony_ci
19138c2ecf20Sopenharmony_ci/* This function check if the command is supported by firmware */
19148c2ecf20Sopenharmony_cistatic int mwifiex_is_cmd_supported(struct mwifiex_private *priv, u16 cmd_no)
19158c2ecf20Sopenharmony_ci{
19168c2ecf20Sopenharmony_ci	if (!ISSUPP_ADHOC_ENABLED(priv->adapter->fw_cap_info)) {
19178c2ecf20Sopenharmony_ci		switch (cmd_no) {
19188c2ecf20Sopenharmony_ci		case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
19198c2ecf20Sopenharmony_ci		case HostCmd_CMD_802_11_AD_HOC_START:
19208c2ecf20Sopenharmony_ci		case HostCmd_CMD_802_11_AD_HOC_JOIN:
19218c2ecf20Sopenharmony_ci		case HostCmd_CMD_802_11_AD_HOC_STOP:
19228c2ecf20Sopenharmony_ci			return -EOPNOTSUPP;
19238c2ecf20Sopenharmony_ci		default:
19248c2ecf20Sopenharmony_ci			break;
19258c2ecf20Sopenharmony_ci		}
19268c2ecf20Sopenharmony_ci	}
19278c2ecf20Sopenharmony_ci
19288c2ecf20Sopenharmony_ci	return 0;
19298c2ecf20Sopenharmony_ci}
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci/*
19328c2ecf20Sopenharmony_ci * This function prepares the commands before sending them to the firmware.
19338c2ecf20Sopenharmony_ci *
19348c2ecf20Sopenharmony_ci * This is a generic function which calls specific command preparation
19358c2ecf20Sopenharmony_ci * routines based upon the command number.
19368c2ecf20Sopenharmony_ci */
19378c2ecf20Sopenharmony_ciint mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
19388c2ecf20Sopenharmony_ci			    u16 cmd_action, u32 cmd_oid,
19398c2ecf20Sopenharmony_ci			    void *data_buf, void *cmd_buf)
19408c2ecf20Sopenharmony_ci{
19418c2ecf20Sopenharmony_ci	struct host_cmd_ds_command *cmd_ptr = cmd_buf;
19428c2ecf20Sopenharmony_ci	int ret = 0;
19438c2ecf20Sopenharmony_ci
19448c2ecf20Sopenharmony_ci	if (mwifiex_is_cmd_supported(priv, cmd_no)) {
19458c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
19468c2ecf20Sopenharmony_ci			    "0x%x command not supported by firmware\n",
19478c2ecf20Sopenharmony_ci			    cmd_no);
19488c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
19498c2ecf20Sopenharmony_ci	}
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ci	/* Prepare command */
19528c2ecf20Sopenharmony_ci	switch (cmd_no) {
19538c2ecf20Sopenharmony_ci	case HostCmd_CMD_GET_HW_SPEC:
19548c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
19558c2ecf20Sopenharmony_ci		break;
19568c2ecf20Sopenharmony_ci	case HostCmd_CMD_CFG_DATA:
19578c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, data_buf);
19588c2ecf20Sopenharmony_ci		break;
19598c2ecf20Sopenharmony_ci	case HostCmd_CMD_MAC_CONTROL:
19608c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
19618c2ecf20Sopenharmony_ci					      data_buf);
19628c2ecf20Sopenharmony_ci		break;
19638c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_MAC_ADDRESS:
19648c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_mac_address(priv, cmd_ptr,
19658c2ecf20Sopenharmony_ci						     cmd_action);
19668c2ecf20Sopenharmony_ci		break;
19678c2ecf20Sopenharmony_ci	case HostCmd_CMD_MAC_MULTICAST_ADR:
19688c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action,
19698c2ecf20Sopenharmony_ci						    data_buf);
19708c2ecf20Sopenharmony_ci		break;
19718c2ecf20Sopenharmony_ci	case HostCmd_CMD_TX_RATE_CFG:
19728c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_tx_rate_cfg(priv, cmd_ptr, cmd_action,
19738c2ecf20Sopenharmony_ci					      data_buf);
19748c2ecf20Sopenharmony_ci		break;
19758c2ecf20Sopenharmony_ci	case HostCmd_CMD_TXPWR_CFG:
19768c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
19778c2ecf20Sopenharmony_ci					       data_buf);
19788c2ecf20Sopenharmony_ci		break;
19798c2ecf20Sopenharmony_ci	case HostCmd_CMD_RF_TX_PWR:
19808c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_rf_tx_power(priv, cmd_ptr, cmd_action,
19818c2ecf20Sopenharmony_ci					      data_buf);
19828c2ecf20Sopenharmony_ci		break;
19838c2ecf20Sopenharmony_ci	case HostCmd_CMD_RF_ANTENNA:
19848c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_rf_antenna(priv, cmd_ptr, cmd_action,
19858c2ecf20Sopenharmony_ci					     data_buf);
19868c2ecf20Sopenharmony_ci		break;
19878c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_PS_MODE_ENH:
19888c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
19898c2ecf20Sopenharmony_ci						 (uint16_t)cmd_oid, data_buf);
19908c2ecf20Sopenharmony_ci		break;
19918c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_HS_CFG_ENH:
19928c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action,
19938c2ecf20Sopenharmony_ci				(struct mwifiex_hs_config_param *) data_buf);
19948c2ecf20Sopenharmony_ci		break;
19958c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_SCAN:
19968c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf);
19978c2ecf20Sopenharmony_ci		break;
19988c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_BG_SCAN_CONFIG:
19998c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_bg_scan_config(priv, cmd_ptr,
20008c2ecf20Sopenharmony_ci							data_buf);
20018c2ecf20Sopenharmony_ci		break;
20028c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_BG_SCAN_QUERY:
20038c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr);
20048c2ecf20Sopenharmony_ci		break;
20058c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_ASSOCIATE:
20068c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf);
20078c2ecf20Sopenharmony_ci		break;
20088c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_DEAUTHENTICATE:
20098c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_deauthenticate(priv, cmd_ptr,
20108c2ecf20Sopenharmony_ci							data_buf);
20118c2ecf20Sopenharmony_ci		break;
20128c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_AD_HOC_START:
20138c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_ad_hoc_start(priv, cmd_ptr,
20148c2ecf20Sopenharmony_ci						      data_buf);
20158c2ecf20Sopenharmony_ci		break;
20168c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_GET_LOG:
20178c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_get_log(cmd_ptr);
20188c2ecf20Sopenharmony_ci		break;
20198c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_AD_HOC_JOIN:
20208c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr,
20218c2ecf20Sopenharmony_ci						     data_buf);
20228c2ecf20Sopenharmony_ci		break;
20238c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_AD_HOC_STOP:
20248c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr);
20258c2ecf20Sopenharmony_ci		break;
20268c2ecf20Sopenharmony_ci	case HostCmd_CMD_RSSI_INFO:
20278c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action);
20288c2ecf20Sopenharmony_ci		break;
20298c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_SNMP_MIB:
20308c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_snmp_mib(priv, cmd_ptr, cmd_action,
20318c2ecf20Sopenharmony_ci						  cmd_oid, data_buf);
20328c2ecf20Sopenharmony_ci		break;
20338c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_TX_RATE_QUERY:
20348c2ecf20Sopenharmony_ci		cmd_ptr->command =
20358c2ecf20Sopenharmony_ci			cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
20368c2ecf20Sopenharmony_ci		cmd_ptr->size =
20378c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query) +
20388c2ecf20Sopenharmony_ci				    S_DS_GEN);
20398c2ecf20Sopenharmony_ci		priv->tx_rate = 0;
20408c2ecf20Sopenharmony_ci		ret = 0;
20418c2ecf20Sopenharmony_ci		break;
20428c2ecf20Sopenharmony_ci	case HostCmd_CMD_VERSION_EXT:
20438c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20448c2ecf20Sopenharmony_ci		cmd_ptr->params.verext.version_str_sel =
20458c2ecf20Sopenharmony_ci			(u8)(get_unaligned((u32 *)data_buf));
20468c2ecf20Sopenharmony_ci		memcpy(&cmd_ptr->params, data_buf,
20478c2ecf20Sopenharmony_ci		       sizeof(struct host_cmd_ds_version_ext));
20488c2ecf20Sopenharmony_ci		cmd_ptr->size =
20498c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_version_ext) +
20508c2ecf20Sopenharmony_ci				    S_DS_GEN);
20518c2ecf20Sopenharmony_ci		ret = 0;
20528c2ecf20Sopenharmony_ci		break;
20538c2ecf20Sopenharmony_ci	case HostCmd_CMD_MGMT_FRAME_REG:
20548c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20558c2ecf20Sopenharmony_ci		cmd_ptr->params.reg_mask.action = cpu_to_le16(cmd_action);
20568c2ecf20Sopenharmony_ci		cmd_ptr->params.reg_mask.mask = cpu_to_le32(
20578c2ecf20Sopenharmony_ci						get_unaligned((u32 *)data_buf));
20588c2ecf20Sopenharmony_ci		cmd_ptr->size =
20598c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_mgmt_frame_reg) +
20608c2ecf20Sopenharmony_ci				    S_DS_GEN);
20618c2ecf20Sopenharmony_ci		ret = 0;
20628c2ecf20Sopenharmony_ci		break;
20638c2ecf20Sopenharmony_ci	case HostCmd_CMD_REMAIN_ON_CHAN:
20648c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20658c2ecf20Sopenharmony_ci		memcpy(&cmd_ptr->params, data_buf,
20668c2ecf20Sopenharmony_ci		       sizeof(struct host_cmd_ds_remain_on_chan));
20678c2ecf20Sopenharmony_ci		cmd_ptr->size =
20688c2ecf20Sopenharmony_ci		      cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
20698c2ecf20Sopenharmony_ci				  S_DS_GEN);
20708c2ecf20Sopenharmony_ci		break;
20718c2ecf20Sopenharmony_ci	case HostCmd_CMD_11AC_CFG:
20728c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_11ac_cfg(priv, cmd_ptr, cmd_action, data_buf);
20738c2ecf20Sopenharmony_ci		break;
20748c2ecf20Sopenharmony_ci	case HostCmd_CMD_PACKET_AGGR_CTRL:
20758c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20768c2ecf20Sopenharmony_ci		cmd_ptr->params.pkt_aggr_ctrl.action = cpu_to_le16(cmd_action);
20778c2ecf20Sopenharmony_ci		cmd_ptr->params.pkt_aggr_ctrl.enable =
20788c2ecf20Sopenharmony_ci						cpu_to_le16(*(u16 *)data_buf);
20798c2ecf20Sopenharmony_ci		cmd_ptr->size =
20808c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_pkt_aggr_ctrl) +
20818c2ecf20Sopenharmony_ci				    S_DS_GEN);
20828c2ecf20Sopenharmony_ci		break;
20838c2ecf20Sopenharmony_ci	case HostCmd_CMD_P2P_MODE_CFG:
20848c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20858c2ecf20Sopenharmony_ci		cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
20868c2ecf20Sopenharmony_ci		cmd_ptr->params.mode_cfg.mode = cpu_to_le16(
20878c2ecf20Sopenharmony_ci						get_unaligned((u16 *)data_buf));
20888c2ecf20Sopenharmony_ci		cmd_ptr->size =
20898c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg) +
20908c2ecf20Sopenharmony_ci				    S_DS_GEN);
20918c2ecf20Sopenharmony_ci		break;
20928c2ecf20Sopenharmony_ci	case HostCmd_CMD_FUNC_INIT:
20938c2ecf20Sopenharmony_ci		if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
20948c2ecf20Sopenharmony_ci			priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
20958c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
20968c2ecf20Sopenharmony_ci		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
20978c2ecf20Sopenharmony_ci		break;
20988c2ecf20Sopenharmony_ci	case HostCmd_CMD_FUNC_SHUTDOWN:
20998c2ecf20Sopenharmony_ci		priv->adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
21008c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
21018c2ecf20Sopenharmony_ci		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
21028c2ecf20Sopenharmony_ci		break;
21038c2ecf20Sopenharmony_ci	case HostCmd_CMD_11N_ADDBA_REQ:
21048c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf);
21058c2ecf20Sopenharmony_ci		break;
21068c2ecf20Sopenharmony_ci	case HostCmd_CMD_11N_DELBA:
21078c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf);
21088c2ecf20Sopenharmony_ci		break;
21098c2ecf20Sopenharmony_ci	case HostCmd_CMD_11N_ADDBA_RSP:
21108c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf);
21118c2ecf20Sopenharmony_ci		break;
21128c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_KEY_MATERIAL:
21138c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
21148c2ecf20Sopenharmony_ci						      cmd_action, cmd_oid,
21158c2ecf20Sopenharmony_ci						      data_buf);
21168c2ecf20Sopenharmony_ci		break;
21178c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11D_DOMAIN_INFO:
21188c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
21198c2ecf20Sopenharmony_ci						      cmd_action);
21208c2ecf20Sopenharmony_ci		break;
21218c2ecf20Sopenharmony_ci	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
21228c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
21238c2ecf20Sopenharmony_ci					       data_buf);
21248c2ecf20Sopenharmony_ci		break;
21258c2ecf20Sopenharmony_ci	case HostCmd_CMD_AMSDU_AGGR_CTRL:
21268c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action,
21278c2ecf20Sopenharmony_ci						  data_buf);
21288c2ecf20Sopenharmony_ci		break;
21298c2ecf20Sopenharmony_ci	case HostCmd_CMD_11N_CFG:
21308c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, data_buf);
21318c2ecf20Sopenharmony_ci		break;
21328c2ecf20Sopenharmony_ci	case HostCmd_CMD_WMM_GET_STATUS:
21338c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, CMD,
21348c2ecf20Sopenharmony_ci			    "cmd: WMM: WMM_GET_STATUS cmd sent\n");
21358c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
21368c2ecf20Sopenharmony_ci		cmd_ptr->size =
21378c2ecf20Sopenharmony_ci			cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status) +
21388c2ecf20Sopenharmony_ci				    S_DS_GEN);
21398c2ecf20Sopenharmony_ci		ret = 0;
21408c2ecf20Sopenharmony_ci		break;
21418c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
21428c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action,
21438c2ecf20Sopenharmony_ci							 data_buf);
21448c2ecf20Sopenharmony_ci		break;
21458c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_SCAN_EXT:
21468c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_scan_ext(priv, cmd_ptr, data_buf);
21478c2ecf20Sopenharmony_ci		break;
21488c2ecf20Sopenharmony_ci	case HostCmd_CMD_MEM_ACCESS:
21498c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_mem_access(cmd_ptr, cmd_action, data_buf);
21508c2ecf20Sopenharmony_ci		break;
21518c2ecf20Sopenharmony_ci	case HostCmd_CMD_MAC_REG_ACCESS:
21528c2ecf20Sopenharmony_ci	case HostCmd_CMD_BBP_REG_ACCESS:
21538c2ecf20Sopenharmony_ci	case HostCmd_CMD_RF_REG_ACCESS:
21548c2ecf20Sopenharmony_ci	case HostCmd_CMD_PMIC_REG_ACCESS:
21558c2ecf20Sopenharmony_ci	case HostCmd_CMD_CAU_REG_ACCESS:
21568c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_EEPROM_ACCESS:
21578c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_reg_access(cmd_ptr, cmd_action, data_buf);
21588c2ecf20Sopenharmony_ci		break;
21598c2ecf20Sopenharmony_ci	case HostCmd_CMD_SET_BSS_MODE:
21608c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
21618c2ecf20Sopenharmony_ci		if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
21628c2ecf20Sopenharmony_ci			cmd_ptr->params.bss_mode.con_type =
21638c2ecf20Sopenharmony_ci				CONNECTION_TYPE_ADHOC;
21648c2ecf20Sopenharmony_ci		else if (priv->bss_mode == NL80211_IFTYPE_STATION ||
21658c2ecf20Sopenharmony_ci			 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT)
21668c2ecf20Sopenharmony_ci			cmd_ptr->params.bss_mode.con_type =
21678c2ecf20Sopenharmony_ci				CONNECTION_TYPE_INFRA;
21688c2ecf20Sopenharmony_ci		else if (priv->bss_mode == NL80211_IFTYPE_AP ||
21698c2ecf20Sopenharmony_ci			 priv->bss_mode == NL80211_IFTYPE_P2P_GO)
21708c2ecf20Sopenharmony_ci			cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_AP;
21718c2ecf20Sopenharmony_ci		cmd_ptr->size = cpu_to_le16(sizeof(struct
21728c2ecf20Sopenharmony_ci				host_cmd_ds_set_bss_mode) + S_DS_GEN);
21738c2ecf20Sopenharmony_ci		ret = 0;
21748c2ecf20Sopenharmony_ci		break;
21758c2ecf20Sopenharmony_ci	case HostCmd_CMD_PCIE_DESC_DETAILS:
21768c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action);
21778c2ecf20Sopenharmony_ci		break;
21788c2ecf20Sopenharmony_ci	case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
21798c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_802_11_subsc_evt(priv, cmd_ptr, data_buf);
21808c2ecf20Sopenharmony_ci		break;
21818c2ecf20Sopenharmony_ci	case HostCmd_CMD_MEF_CFG:
21828c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_mef_cfg(priv, cmd_ptr, data_buf);
21838c2ecf20Sopenharmony_ci		break;
21848c2ecf20Sopenharmony_ci	case HostCmd_CMD_COALESCE_CFG:
21858c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_coalesce_cfg(priv, cmd_ptr, cmd_action,
21868c2ecf20Sopenharmony_ci					       data_buf);
21878c2ecf20Sopenharmony_ci		break;
21888c2ecf20Sopenharmony_ci	case HostCmd_CMD_TDLS_OPER:
21898c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_tdls_oper(priv, cmd_ptr, data_buf);
21908c2ecf20Sopenharmony_ci		break;
21918c2ecf20Sopenharmony_ci	case HostCmd_CMD_TDLS_CONFIG:
21928c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_tdls_config(priv, cmd_ptr, cmd_action,
21938c2ecf20Sopenharmony_ci					      data_buf);
21948c2ecf20Sopenharmony_ci		break;
21958c2ecf20Sopenharmony_ci	case HostCmd_CMD_CHAN_REPORT_REQUEST:
21968c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr,
21978c2ecf20Sopenharmony_ci							    data_buf);
21988c2ecf20Sopenharmony_ci		break;
21998c2ecf20Sopenharmony_ci	case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
22008c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action,
22018c2ecf20Sopenharmony_ci						   data_buf);
22028c2ecf20Sopenharmony_ci		break;
22038c2ecf20Sopenharmony_ci	case HostCmd_CMD_HS_WAKEUP_REASON:
22048c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_get_wakeup_reason(priv, cmd_ptr);
22058c2ecf20Sopenharmony_ci		break;
22068c2ecf20Sopenharmony_ci	case HostCmd_CMD_MC_POLICY:
22078c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_set_mc_policy(priv, cmd_ptr, cmd_action,
22088c2ecf20Sopenharmony_ci						data_buf);
22098c2ecf20Sopenharmony_ci		break;
22108c2ecf20Sopenharmony_ci	case HostCmd_CMD_ROBUST_COEX:
22118c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_robust_coex(priv, cmd_ptr, cmd_action,
22128c2ecf20Sopenharmony_ci					      data_buf);
22138c2ecf20Sopenharmony_ci		break;
22148c2ecf20Sopenharmony_ci	case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG:
22158c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_gtk_rekey_offload(priv, cmd_ptr, cmd_action,
22168c2ecf20Sopenharmony_ci						    data_buf);
22178c2ecf20Sopenharmony_ci		break;
22188c2ecf20Sopenharmony_ci	case HostCmd_CMD_CHAN_REGION_CFG:
22198c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_chan_region_cfg(priv, cmd_ptr, cmd_action);
22208c2ecf20Sopenharmony_ci		break;
22218c2ecf20Sopenharmony_ci	case HostCmd_CMD_FW_DUMP_EVENT:
22228c2ecf20Sopenharmony_ci		cmd_ptr->command = cpu_to_le16(cmd_no);
22238c2ecf20Sopenharmony_ci		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
22248c2ecf20Sopenharmony_ci		break;
22258c2ecf20Sopenharmony_ci	case HostCmd_CMD_STA_CONFIGURE:
22268c2ecf20Sopenharmony_ci		ret = mwifiex_cmd_get_chan_info(cmd_ptr, cmd_action);
22278c2ecf20Sopenharmony_ci		break;
22288c2ecf20Sopenharmony_ci	default:
22298c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
22308c2ecf20Sopenharmony_ci			    "PREP_CMD: unknown cmd- %#x\n", cmd_no);
22318c2ecf20Sopenharmony_ci		ret = -1;
22328c2ecf20Sopenharmony_ci		break;
22338c2ecf20Sopenharmony_ci	}
22348c2ecf20Sopenharmony_ci	return ret;
22358c2ecf20Sopenharmony_ci}
22368c2ecf20Sopenharmony_ci
22378c2ecf20Sopenharmony_ci/*
22388c2ecf20Sopenharmony_ci * This function issues commands to initialize firmware.
22398c2ecf20Sopenharmony_ci *
22408c2ecf20Sopenharmony_ci * This is called after firmware download to bring the card to
22418c2ecf20Sopenharmony_ci * working state.
22428c2ecf20Sopenharmony_ci * Function is also called during reinitialization of virtual
22438c2ecf20Sopenharmony_ci * interfaces.
22448c2ecf20Sopenharmony_ci *
22458c2ecf20Sopenharmony_ci * The following commands are issued sequentially -
22468c2ecf20Sopenharmony_ci *      - Set PCI-Express host buffer configuration (PCIE only)
22478c2ecf20Sopenharmony_ci *      - Function init (for first interface only)
22488c2ecf20Sopenharmony_ci *      - Read MAC address (for first interface only)
22498c2ecf20Sopenharmony_ci *      - Reconfigure Tx buffer size (for first interface only)
22508c2ecf20Sopenharmony_ci *      - Enable auto deep sleep (for first interface only)
22518c2ecf20Sopenharmony_ci *      - Get Tx rate
22528c2ecf20Sopenharmony_ci *      - Get Tx power
22538c2ecf20Sopenharmony_ci *      - Set IBSS coalescing status
22548c2ecf20Sopenharmony_ci *      - Set AMSDU aggregation control
22558c2ecf20Sopenharmony_ci *      - Set 11d control
22568c2ecf20Sopenharmony_ci *      - Set MAC control (this must be the last command to initialize firmware)
22578c2ecf20Sopenharmony_ci */
22588c2ecf20Sopenharmony_ciint mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
22598c2ecf20Sopenharmony_ci{
22608c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
22618c2ecf20Sopenharmony_ci	int ret;
22628c2ecf20Sopenharmony_ci	struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
22638c2ecf20Sopenharmony_ci	struct mwifiex_ds_auto_ds auto_ds;
22648c2ecf20Sopenharmony_ci	enum state_11d_t state_11d;
22658c2ecf20Sopenharmony_ci	struct mwifiex_ds_11n_tx_cfg tx_cfg;
22668c2ecf20Sopenharmony_ci	u8 sdio_sp_rx_aggr_enable;
22678c2ecf20Sopenharmony_ci	u16 packet_aggr_enable;
22688c2ecf20Sopenharmony_ci	int data;
22698c2ecf20Sopenharmony_ci
22708c2ecf20Sopenharmony_ci	if (first_sta) {
22718c2ecf20Sopenharmony_ci		if (priv->adapter->iface_type == MWIFIEX_PCIE) {
22728c2ecf20Sopenharmony_ci			ret = mwifiex_send_cmd(priv,
22738c2ecf20Sopenharmony_ci					       HostCmd_CMD_PCIE_DESC_DETAILS,
22748c2ecf20Sopenharmony_ci					       HostCmd_ACT_GEN_SET, 0, NULL,
22758c2ecf20Sopenharmony_ci					       true);
22768c2ecf20Sopenharmony_ci			if (ret)
22778c2ecf20Sopenharmony_ci				return -1;
22788c2ecf20Sopenharmony_ci		}
22798c2ecf20Sopenharmony_ci
22808c2ecf20Sopenharmony_ci		ret = mwifiex_send_cmd(priv, HostCmd_CMD_FUNC_INIT,
22818c2ecf20Sopenharmony_ci				       HostCmd_ACT_GEN_SET, 0, NULL, true);
22828c2ecf20Sopenharmony_ci		if (ret)
22838c2ecf20Sopenharmony_ci			return -1;
22848c2ecf20Sopenharmony_ci
22858c2ecf20Sopenharmony_ci		/* Download calibration data to firmware.
22868c2ecf20Sopenharmony_ci		 * The cal-data can be read from device tree and/or
22878c2ecf20Sopenharmony_ci		 * a configuration file and downloaded to firmware.
22888c2ecf20Sopenharmony_ci		 */
22898c2ecf20Sopenharmony_ci		if (adapter->dt_node) {
22908c2ecf20Sopenharmony_ci			if (of_property_read_u32(adapter->dt_node,
22918c2ecf20Sopenharmony_ci						 "marvell,wakeup-pin",
22928c2ecf20Sopenharmony_ci						 &data) == 0) {
22938c2ecf20Sopenharmony_ci				pr_debug("Wakeup pin = 0x%x\n", data);
22948c2ecf20Sopenharmony_ci				adapter->hs_cfg.gpio = data;
22958c2ecf20Sopenharmony_ci			}
22968c2ecf20Sopenharmony_ci
22978c2ecf20Sopenharmony_ci			mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node,
22988c2ecf20Sopenharmony_ci						"marvell,caldata");
22998c2ecf20Sopenharmony_ci		}
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_ci		if (adapter->cal_data)
23028c2ecf20Sopenharmony_ci			mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
23038c2ecf20Sopenharmony_ci					 HostCmd_ACT_GEN_SET, 0, NULL, true);
23048c2ecf20Sopenharmony_ci
23058c2ecf20Sopenharmony_ci		/* Read MAC address from HW */
23068c2ecf20Sopenharmony_ci		ret = mwifiex_send_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
23078c2ecf20Sopenharmony_ci				       HostCmd_ACT_GEN_GET, 0, NULL, true);
23088c2ecf20Sopenharmony_ci		if (ret)
23098c2ecf20Sopenharmony_ci			return -1;
23108c2ecf20Sopenharmony_ci
23118c2ecf20Sopenharmony_ci		/** Set SDIO Single Port RX Aggr Info */
23128c2ecf20Sopenharmony_ci		if (priv->adapter->iface_type == MWIFIEX_SDIO &&
23138c2ecf20Sopenharmony_ci		    ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info) &&
23148c2ecf20Sopenharmony_ci		    !priv->adapter->host_disable_sdio_rx_aggr) {
23158c2ecf20Sopenharmony_ci			sdio_sp_rx_aggr_enable = true;
23168c2ecf20Sopenharmony_ci			ret = mwifiex_send_cmd(priv,
23178c2ecf20Sopenharmony_ci					       HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,
23188c2ecf20Sopenharmony_ci					       HostCmd_ACT_GEN_SET, 0,
23198c2ecf20Sopenharmony_ci					       &sdio_sp_rx_aggr_enable,
23208c2ecf20Sopenharmony_ci					       true);
23218c2ecf20Sopenharmony_ci			if (ret) {
23228c2ecf20Sopenharmony_ci				mwifiex_dbg(priv->adapter, ERROR,
23238c2ecf20Sopenharmony_ci					    "error while enabling SP aggregation..disable it");
23248c2ecf20Sopenharmony_ci				adapter->sdio_rx_aggr_enable = false;
23258c2ecf20Sopenharmony_ci			}
23268c2ecf20Sopenharmony_ci		}
23278c2ecf20Sopenharmony_ci
23288c2ecf20Sopenharmony_ci		/* Reconfigure tx buf size */
23298c2ecf20Sopenharmony_ci		ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
23308c2ecf20Sopenharmony_ci				       HostCmd_ACT_GEN_SET, 0,
23318c2ecf20Sopenharmony_ci				       &priv->adapter->tx_buf_size, true);
23328c2ecf20Sopenharmony_ci		if (ret)
23338c2ecf20Sopenharmony_ci			return -1;
23348c2ecf20Sopenharmony_ci
23358c2ecf20Sopenharmony_ci		if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
23368c2ecf20Sopenharmony_ci			/* Enable IEEE PS by default */
23378c2ecf20Sopenharmony_ci			priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
23388c2ecf20Sopenharmony_ci			ret = mwifiex_send_cmd(priv,
23398c2ecf20Sopenharmony_ci					       HostCmd_CMD_802_11_PS_MODE_ENH,
23408c2ecf20Sopenharmony_ci					       EN_AUTO_PS, BITMAP_STA_PS, NULL,
23418c2ecf20Sopenharmony_ci					       true);
23428c2ecf20Sopenharmony_ci			if (ret)
23438c2ecf20Sopenharmony_ci				return -1;
23448c2ecf20Sopenharmony_ci		}
23458c2ecf20Sopenharmony_ci
23468c2ecf20Sopenharmony_ci		if (drcs) {
23478c2ecf20Sopenharmony_ci			adapter->drcs_enabled = true;
23488c2ecf20Sopenharmony_ci			if (ISSUPP_DRCS_ENABLED(adapter->fw_cap_info))
23498c2ecf20Sopenharmony_ci				ret = mwifiex_send_cmd(priv,
23508c2ecf20Sopenharmony_ci						       HostCmd_CMD_MC_POLICY,
23518c2ecf20Sopenharmony_ci						       HostCmd_ACT_GEN_SET, 0,
23528c2ecf20Sopenharmony_ci						       &adapter->drcs_enabled,
23538c2ecf20Sopenharmony_ci						       true);
23548c2ecf20Sopenharmony_ci			if (ret)
23558c2ecf20Sopenharmony_ci				return -1;
23568c2ecf20Sopenharmony_ci		}
23578c2ecf20Sopenharmony_ci
23588c2ecf20Sopenharmony_ci		mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REGION_CFG,
23598c2ecf20Sopenharmony_ci				 HostCmd_ACT_GEN_GET, 0, NULL, true);
23608c2ecf20Sopenharmony_ci	}
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ci	/* get tx rate */
23638c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
23648c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_GET, 0, NULL, true);
23658c2ecf20Sopenharmony_ci	if (ret)
23668c2ecf20Sopenharmony_ci		return -1;
23678c2ecf20Sopenharmony_ci	priv->data_rate = 0;
23688c2ecf20Sopenharmony_ci
23698c2ecf20Sopenharmony_ci	/* get tx power */
23708c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR,
23718c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_GET, 0, NULL, true);
23728c2ecf20Sopenharmony_ci	if (ret)
23738c2ecf20Sopenharmony_ci		return -1;
23748c2ecf20Sopenharmony_ci
23758c2ecf20Sopenharmony_ci	memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
23768c2ecf20Sopenharmony_ci	amsdu_aggr_ctrl.enable = true;
23778c2ecf20Sopenharmony_ci	/* Send request to firmware */
23788c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
23798c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_SET, 0,
23808c2ecf20Sopenharmony_ci			       &amsdu_aggr_ctrl, true);
23818c2ecf20Sopenharmony_ci	if (ret)
23828c2ecf20Sopenharmony_ci		return -1;
23838c2ecf20Sopenharmony_ci	/* MAC Control must be the last command in init_fw */
23848c2ecf20Sopenharmony_ci	/* set MAC Control */
23858c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
23868c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_SET, 0,
23878c2ecf20Sopenharmony_ci			       &priv->curr_pkt_filter, true);
23888c2ecf20Sopenharmony_ci	if (ret)
23898c2ecf20Sopenharmony_ci		return -1;
23908c2ecf20Sopenharmony_ci
23918c2ecf20Sopenharmony_ci	if (!disable_auto_ds && first_sta &&
23928c2ecf20Sopenharmony_ci	    priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
23938c2ecf20Sopenharmony_ci		/* Enable auto deep sleep */
23948c2ecf20Sopenharmony_ci		auto_ds.auto_ds = DEEP_SLEEP_ON;
23958c2ecf20Sopenharmony_ci		auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
23968c2ecf20Sopenharmony_ci		ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
23978c2ecf20Sopenharmony_ci				       EN_AUTO_PS, BITMAP_AUTO_DS,
23988c2ecf20Sopenharmony_ci				       &auto_ds, true);
23998c2ecf20Sopenharmony_ci		if (ret)
24008c2ecf20Sopenharmony_ci			return -1;
24018c2ecf20Sopenharmony_ci	}
24028c2ecf20Sopenharmony_ci
24038c2ecf20Sopenharmony_ci	if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
24048c2ecf20Sopenharmony_ci		/* Send cmd to FW to enable/disable 11D function */
24058c2ecf20Sopenharmony_ci		state_11d = ENABLE_11D;
24068c2ecf20Sopenharmony_ci		ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
24078c2ecf20Sopenharmony_ci				       HostCmd_ACT_GEN_SET, DOT11D_I,
24088c2ecf20Sopenharmony_ci				       &state_11d, true);
24098c2ecf20Sopenharmony_ci		if (ret)
24108c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, ERROR,
24118c2ecf20Sopenharmony_ci				    "11D: failed to enable 11D\n");
24128c2ecf20Sopenharmony_ci	}
24138c2ecf20Sopenharmony_ci
24148c2ecf20Sopenharmony_ci	/* Pacekt aggregation handshake with firmware */
24158c2ecf20Sopenharmony_ci	if (aggr_ctrl) {
24168c2ecf20Sopenharmony_ci		packet_aggr_enable = true;
24178c2ecf20Sopenharmony_ci		mwifiex_send_cmd(priv, HostCmd_CMD_PACKET_AGGR_CTRL,
24188c2ecf20Sopenharmony_ci				 HostCmd_ACT_GEN_SET, 0,
24198c2ecf20Sopenharmony_ci				 &packet_aggr_enable, true);
24208c2ecf20Sopenharmony_ci	}
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci	/* Send cmd to FW to configure 11n specific configuration
24238c2ecf20Sopenharmony_ci	 * (Short GI, Channel BW, Green field support etc.) for transmit
24248c2ecf20Sopenharmony_ci	 */
24258c2ecf20Sopenharmony_ci	tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
24268c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG,
24278c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_SET, 0, &tx_cfg, true);
24288c2ecf20Sopenharmony_ci
24298c2ecf20Sopenharmony_ci	if (init) {
24308c2ecf20Sopenharmony_ci		/* set last_init_cmd before sending the command */
24318c2ecf20Sopenharmony_ci		priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
24328c2ecf20Sopenharmony_ci		ret = -EINPROGRESS;
24338c2ecf20Sopenharmony_ci	}
24348c2ecf20Sopenharmony_ci
24358c2ecf20Sopenharmony_ci	return ret;
24368c2ecf20Sopenharmony_ci}
2437