summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c')
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c1888
1 files changed, 1888 insertions, 0 deletions
diff --git a/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
new file mode 100644
index 000000000000..c3a3b956aa61
--- /dev/null
+++ b/drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c
@@ -0,0 +1,1888 @@
+/** @file mlan_sta_cmd.c
+ *
+ * @brief This file contains the handling of command.
+ * it prepares command and sends it to firmware when
+ * it is ready.
+ *
+ * Copyright (C) 2008-2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************
+Change log:
+ 10/21/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+#include "mlan_sdio.h"
+#include "mlan_meas.h"
+
+/********************************************************
+ Local Variables
+********************************************************/
+
+/********************************************************
+ Global Variables
+********************************************************/
+
+/********************************************************
+ Local Functions
+********************************************************/
+
+/**
+ * @brief This function prepares command of RSSI info.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param pcmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action Command action
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_rssi_info(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * pcmd, IN t_u16 cmd_action)
+{
+ ENTER();
+
+ pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_RSSI_INFO);
+ pcmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RSSI_INFO) + S_DS_GEN);
+ pcmd->params.rssi_info.action = wlan_cpu_to_le16(cmd_action);
+ pcmd->params.rssi_info.ndata = wlan_cpu_to_le16(pmpriv->data_avg_factor);
+ pcmd->params.rssi_info.nbcn = wlan_cpu_to_le16(pmpriv->bcn_avg_factor);
+
+ /* Reset SNR/NF/RSSI values in private structure */
+ pmpriv->data_rssi_last = 0;
+ pmpriv->data_nf_last = 0;
+ pmpriv->data_rssi_avg = 0;
+ pmpriv->data_nf_avg = 0;
+ pmpriv->bcn_rssi_last = 0;
+ pmpriv->bcn_nf_last = 0;
+ pmpriv->bcn_rssi_avg = 0;
+ pmpriv->bcn_nf_avg = 0;
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of mac_control.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param pcmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action Command action
+ * @param pdata_buf A pointer to command information buffer
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_mac_control(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * pcmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
+ t_u16 action = *((t_u16 *) pdata_buf);
+
+ ENTER();
+
+ if (cmd_action != HostCmd_ACT_GEN_SET) {
+ PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+
+ pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
+ pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
+ pmac->action = wlan_cpu_to_le16(action);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of snmp_mib.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param cmd_oid OID: ENABLE or DISABLE
+ * @param pdata_buf A pointer to command information buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_snmp_mib(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action,
+ IN t_u32 cmd_oid, IN t_void * pdata_buf)
+{
+ HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
+ t_u32 ul_temp;
+
+ ENTER();
+ PRINTM(MINFO, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
+ cmd->size = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1 + S_DS_GEN;
+
+ if (cmd_action == HostCmd_ACT_GEN_GET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(MAX_SNMP_BUF_SIZE);
+ cmd->size += MAX_SNMP_BUF_SIZE;
+ }
+
+ switch (cmd_oid) {
+ case FragThresh_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) FragThresh_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = *((t_u32 *) pdata_buf);
+ *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+ case RtsThresh_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) RtsThresh_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = *((t_u32 *) pdata_buf);
+ *(t_u16 *) (psnmp_mib->value) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+
+ case ShortRetryLim_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) ShortRetryLim_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = (*(t_u32 *) pdata_buf);
+ *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+ case Dot11D_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) Dot11D_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = *(t_u32 *) pdata_buf;
+ *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+ case Dot11H_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) Dot11H_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = *(t_u32 *) pdata_buf;
+ *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+ case WwsMode_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) WwsMode_i);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+ ul_temp = *((t_u32 *) pdata_buf);
+ *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+ cmd->size += sizeof(t_u16);
+ }
+ break;
+ case Thermal_i:
+ psnmp_mib->oid = wlan_cpu_to_le16((t_u16) Thermal_i);
+ break;
+ default:
+ break;
+ }
+ cmd->size = wlan_cpu_to_le16(cmd->size);
+ PRINTM(MINFO, "SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, Value=0x%x\n",
+ cmd_action, cmd_oid, wlan_le16_to_cpu(psnmp_mib->buf_size),
+ wlan_le16_to_cpu(*(t_u16 *) psnmp_mib->value));
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of get_log.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_get_log(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND * cmd)
+{
+ ENTER();
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
+ cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of tx_power_cfg.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_tx_power_cfg(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
+ HostCmd_DS_TXPWR_CFG *ptxp = MNULL;
+ HostCmd_DS_TXPWR_CFG *ptxp_cfg = &cmd->params.txp_cfg;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
+ cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TXPWR_CFG));
+ switch (cmd_action) {
+ case HostCmd_ACT_GEN_SET:
+ ptxp = (HostCmd_DS_TXPWR_CFG *) pdata_buf;
+ if (ptxp->mode) {
+ ppg_tlv =
+ (MrvlTypes_Power_Group_t *) ((t_u8 *) pdata_buf +
+ sizeof(HostCmd_DS_TXPWR_CFG));
+ memmove(pmpriv->adapter, ptxp_cfg, pdata_buf,
+ sizeof(HostCmd_DS_TXPWR_CFG) +
+ sizeof(MrvlTypes_Power_Group_t) + ppg_tlv->length);
+
+ ppg_tlv = (MrvlTypes_Power_Group_t *) ((t_u8 *) ptxp_cfg +
+ sizeof
+ (HostCmd_DS_TXPWR_CFG));
+ cmd->size +=
+ wlan_cpu_to_le16(sizeof(MrvlTypes_Power_Group_t) +
+ ppg_tlv->length);
+ ppg_tlv->type = wlan_cpu_to_le16(ppg_tlv->type);
+ ppg_tlv->length = wlan_cpu_to_le16(ppg_tlv->length);
+ } else {
+ memmove(pmpriv->adapter, ptxp_cfg, pdata_buf,
+ sizeof(HostCmd_DS_TXPWR_CFG));
+ }
+ ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
+ ptxp_cfg->cfg_index = wlan_cpu_to_le16(ptxp_cfg->cfg_index);
+ ptxp_cfg->mode = wlan_cpu_to_le32(ptxp_cfg->mode);
+ break;
+ case HostCmd_ACT_GEN_GET:
+ ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
+ break;
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of rf_tx_power.
+ *
+ * @param pmpriv A pointer to wlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action the action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_rf_tx_power(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+
+ HostCmd_DS_802_11_RF_TX_POWER *prtp = &cmd->params.txp;
+
+ ENTER();
+
+ cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RF_TX_POWER))
+ + S_DS_GEN);
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_TX_POWER);
+ prtp->action = cmd_action;
+
+ PRINTM(MINFO, "RF_TX_POWER_CMD: Size:%d Cmd:0x%x Act:%d\n",
+ cmd->size, cmd->command, prtp->action);
+
+ switch (cmd_action) {
+ case HostCmd_ACT_GEN_GET:
+ prtp->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
+ prtp->current_level = 0;
+ break;
+
+ case HostCmd_ACT_GEN_SET:
+ prtp->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+ prtp->current_level = wlan_cpu_to_le16(*((t_u16 *) pdata_buf));
+ break;
+ }
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of hs_cfg.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN hs_config_param * pdata_buf)
+{
+ pmlan_adapter pmadapter = pmpriv->adapter;
+ HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
+ t_u16 hs_activate = MFALSE;
+
+ ENTER();
+
+ if (pdata_buf == MNULL) {
+ /* New Activate command */
+ hs_activate = MTRUE;
+ }
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
+
+ if (!hs_activate && (pdata_buf->conditions != HOST_SLEEP_CFG_CANCEL)
+ && ((pmadapter->arp_filter_size > 0)
+ && (pmadapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
+ PRINTM(MINFO, "Attach %d bytes ArpFilter to HSCfg cmd\n",
+ pmadapter->arp_filter_size);
+ memcpy(pmpriv->adapter,
+ ((t_u8 *) phs_cfg) + sizeof(HostCmd_DS_802_11_HS_CFG_ENH),
+ pmadapter->arp_filter, pmadapter->arp_filter_size);
+ cmd->size =
+ (t_u16) wlan_cpu_to_le16(pmadapter->arp_filter_size +
+ sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
+ S_DS_GEN);
+ } else
+ cmd->size =
+ wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH));
+
+ if (hs_activate) {
+ phs_cfg->action = wlan_cpu_to_le16(HS_ACTIVATE);
+ phs_cfg->params.hs_activate.resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED);
+ } else {
+ phs_cfg->action = wlan_cpu_to_le16(HS_CONFIGURE);
+ phs_cfg->params.hs_config.conditions =
+ wlan_cpu_to_le32(pdata_buf->conditions);
+ phs_cfg->params.hs_config.gpio = pdata_buf->gpio;
+ phs_cfg->params.hs_config.gap = pdata_buf->gap;
+ PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+ phs_cfg->params.hs_config.conditions,
+ phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of mac_address.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_mac_address(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd, IN t_u16 cmd_action)
+{
+ ENTER();
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
+ cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_MAC_ADDRESS) +
+ S_DS_GEN);
+ cmd->result = 0;
+
+ cmd->params.mac_addr.action = wlan_cpu_to_le16(cmd_action);
+
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ memcpy(pmpriv->adapter, cmd->params.mac_addr.mac_addr,
+ pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH);
+ // HEXDUMP("SET_CMD: MAC ADDRESS-", priv->CurrentAddr, 6);
+ }
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of sleep_period.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_sleep_period(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_u16 * pdata_buf)
+{
+ HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &cmd->params.sleep_pd;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PERIOD);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PERIOD) + S_DS_GEN);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ pcmd_sleep_pd->sleep_pd = wlan_cpu_to_le16(*(t_u16 *) pdata_buf);
+ }
+ pcmd_sleep_pd->action = wlan_cpu_to_le16(cmd_action);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of sleep_params.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_sleep_params(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_u16 * pdata_buf)
+{
+ HostCmd_DS_802_11_SLEEP_PARAMS *pcmd_sp = &cmd->params.sleep_param;
+ mlan_ds_sleep_params *psp = (mlan_ds_sleep_params *) pdata_buf;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PARAMS);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PARAMS) + S_DS_GEN);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ pcmd_sp->reserved = (t_u16) psp->reserved;
+ pcmd_sp->error = (t_u16) psp->error;
+ pcmd_sp->offset = (t_u16) psp->offset;
+ pcmd_sp->stable_time = (t_u16) psp->stable_time;
+ pcmd_sp->cal_control = (t_u8) psp->cal_control;
+ pcmd_sp->external_sleep_clk = (t_u8) psp->ext_sleep_clk;
+
+ pcmd_sp->reserved = wlan_cpu_to_le16(pcmd_sp->reserved);
+ pcmd_sp->error = wlan_cpu_to_le16(pcmd_sp->error);
+ pcmd_sp->offset = wlan_cpu_to_le16(pcmd_sp->offset);
+ pcmd_sp->stable_time = wlan_cpu_to_le16(pcmd_sp->stable_time);
+ }
+ pcmd_sp->action = wlan_cpu_to_le16(cmd_action);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of mac_multicast_adr.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_mac_multicast_adr(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ mlan_multicast_list *pmcast_list = (mlan_multicast_list *) pdata_buf;
+ HostCmd_DS_MAC_MULTICAST_ADR *pmc_addr = &cmd->params.mc_addr;
+
+ ENTER();
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_MULTICAST_ADR) + S_DS_GEN);
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
+
+ pmc_addr->action = wlan_cpu_to_le16(cmd_action);
+ pmc_addr->num_of_adrs =
+ wlan_cpu_to_le16((t_u16) pmcast_list->num_multicast_addr);
+ memcpy(pmpriv->adapter, pmc_addr->mac_list, pmcast_list->mac_list,
+ pmcast_list->num_multicast_addr * MLAN_MAC_ADDR_LENGTH);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of deauthenticate.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_void * pdata_buf)
+{
+ HostCmd_DS_802_11_DEAUTHENTICATE *pdeauth = &cmd->params.deauth;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_DEAUTHENTICATE) + S_DS_GEN);
+
+ /* Set AP MAC address */
+ memcpy(pmpriv->adapter, pdeauth->mac_addr, (t_u8 *) pdata_buf,
+ MLAN_MAC_ADDR_LENGTH);
+
+ PRINTM(MCMND, "Deauth: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pdeauth->mac_addr[0], pdeauth->mac_addr[1], pdeauth->mac_addr[2],
+ pdeauth->mac_addr[3], pdeauth->mac_addr[4], pdeauth->mac_addr[5]);
+
+ if (pmpriv->adapter->state_11h.recvd_chanswann_event) {
+/** Reason code 36 = Requested from peer station as it is leaving the BSS */
+#define REASON_CODE_PEER_STA_LEAVING 36
+ pdeauth->reason_code = wlan_cpu_to_le16(REASON_CODE_PEER_STA_LEAVING);
+ } else {
+/** Reason code 3 = Station is leaving */
+#define REASON_CODE_STA_LEAVING 3
+ pdeauth->reason_code = wlan_cpu_to_le16(REASON_CODE_STA_LEAVING);
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of ad_hoc_stop.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_ad_hoc_stop(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd)
+{
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
+ cmd->size = wlan_cpu_to_le16(S_DS_GEN);
+
+ if (wlan_11h_is_active(pmpriv))
+ wlan_11h_activate(pmpriv, MNULL, MFALSE);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/** Length of WEP 40 bit key */
+#define WEP_40_BIT_LEN 5
+/** Length of WEP 104 bit key */
+#define WEP_104_BIT_LEN 13
+
+/**
+ * @brief This function sets WEP key(s) to key_param_set TLV(s).
+ *
+ * @param priv A pointer to mlan_private structure
+ * @param key_param_set A pointer to MrvlIEtype_KeyParamSet_t structure
+ * @param key_param_len A pointer to the length variable
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_set_keyparamset_wep(mlan_private * priv,
+ MrvlIEtype_KeyParamSet_t * key_param_set,
+ t_u16 * key_param_len)
+{
+ int cur_key_param_len = 0;
+ t_u8 i;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+
+ ENTER();
+
+ /* Multi-key_param_set TLV is supported */
+ for (i = 0; i < MRVL_NUM_WEP_KEY; i++) {
+ if ((priv->wep_key[i].key_length == WEP_40_BIT_LEN) ||
+ (priv->wep_key[i].key_length == WEP_104_BIT_LEN)) {
+ key_param_set->type = wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+/** Key_param_set WEP fixed length */
+#define KEYPARAMSET_WEP_FIXED_LEN 8
+ key_param_set->length =
+ wlan_cpu_to_le16((t_u16)
+ (priv->wep_key[i].key_length +
+ KEYPARAMSET_WEP_FIXED_LEN));
+ key_param_set->key_type_id = wlan_cpu_to_le16(KEY_TYPE_ID_WEP);
+ key_param_set->key_info = wlan_cpu_to_le16
+ (KEY_INFO_WEP_ENABLED | KEY_INFO_WEP_UNICAST |
+ KEY_INFO_WEP_MCAST);
+ key_param_set->key_len =
+ (t_u16) wlan_cpu_to_le16(priv->wep_key[i].key_length);
+ /* Set WEP key index */
+ key_param_set->key[0] = i;
+ /* Set default Tx key flag */
+ if (i == (priv->wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
+ key_param_set->key[1] = 1;
+ else
+ key_param_set->key[1] = 0;
+ memmove(priv->adapter, &key_param_set->key[2],
+ priv->wep_key[i].key_material, priv->wep_key[i].key_length);
+
+ cur_key_param_len = priv->wep_key[i].key_length +
+ KEYPARAMSET_WEP_FIXED_LEN + sizeof(MrvlIEtypesHeader_t);
+ *key_param_len += (t_u16) cur_key_param_len;
+ key_param_set =
+ (MrvlIEtype_KeyParamSet_t *) ((t_u8 *) key_param_set +
+ cur_key_param_len);
+ } else if (!priv->wep_key[i].key_length) {
+ continue;
+ } else {
+ PRINTM(MERROR, "key%d Length = %d is incorrect\n", (i + 1),
+ priv->wep_key[i].key_length);
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ }
+
+ done:
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief This function prepares command of key_material.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param cmd_oid OID: ENABLE or DISABLE
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_802_11_key_material(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action,
+ IN t_u32 cmd_oid, IN t_void * pdata_buf)
+{
+ HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
+ mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *) pdata_buf;
+ t_u16 key_param_len = 0;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ const t_u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
+ pkey_material->action = wlan_cpu_to_le16(cmd_action);
+
+ if (cmd_action == HostCmd_ACT_GEN_GET) {
+ cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN);
+ goto done;
+ }
+
+ if (!pkey) {
+ memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
+ (MRVL_NUM_WEP_KEY * sizeof(MrvlIEtype_KeyParamSet_t)));
+ ret =
+ wlan_set_keyparamset_wep(pmpriv, &pkey_material->key_param_set,
+ &key_param_len);
+ cmd->size =
+ wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+ S_DS_GEN);
+ goto done;
+ } else
+ memset(pmpriv->adapter, &pkey_material->key_param_set, 0,
+ sizeof(MrvlIEtype_KeyParamSet_t));
+ if (pkey->is_wapi_key) {
+ PRINTM(MINFO, "Set WAPI Key\n");
+ pkey_material->key_param_set.key_type_id =
+ wlan_cpu_to_le16(KEY_TYPE_ID_WAPI);
+ if (cmd_oid == KEY_INFO_ENABLED)
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED);
+ else
+ pkey_material->key_param_set.key_info =
+ !(wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED));
+
+ pkey_material->key_param_set.key[0] = (t_u8) pkey->key_index;
+ if (!pmpriv->sec_info.wapi_key_on)
+ pkey_material->key_param_set.key[1] = 1;
+ else
+ pkey_material->key_param_set.key[1] = 0; /* set 0 when re-key */
+
+ if (0 != memcmp(pmpriv->adapter, pkey->mac_addr, bc_mac, sizeof(bc_mac))) /* WAPI
+ pairwise
+ key:
+ unicast
+ */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_WAPI_UNICAST);
+ else { /* WAPI group key: multicast */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_WAPI_MCAST);
+ pmpriv->sec_info.wapi_key_on = MTRUE;
+ }
+
+ pkey_material->key_param_set.type =
+ wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+ pkey_material->key_param_set.key_len = wlan_cpu_to_le16(WAPI_KEY_LEN);
+ memcpy(pmpriv->adapter, &pkey_material->key_param_set.key[2],
+ pkey->key_material, pkey->key_len);
+ memcpy(pmpriv->adapter,
+ &pkey_material->key_param_set.key[2 + pkey->key_len], pkey->pn,
+ PN_SIZE);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
+
+ key_param_len =
+ (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
+ sizeof(MrvlIEtypesHeader_t);
+ cmd->size =
+ wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+ S_DS_GEN);
+ goto done;
+ }
+ if (pkey->key_len == WPA_AES_KEY_LEN) {
+ PRINTM(MCMND, "WPA_AES\n");
+ pkey_material->key_param_set.key_type_id =
+ wlan_cpu_to_le16(KEY_TYPE_ID_AES);
+ if (cmd_oid == KEY_INFO_ENABLED)
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(KEY_INFO_AES_ENABLED);
+ else
+ pkey_material->key_param_set.key_info =
+ !(wlan_cpu_to_le16(KEY_INFO_AES_ENABLED));
+
+ if (pkey->key_index & MLAN_KEY_INDEX_UNICAST) /* AES pairwise key:
+ unicast */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_AES_UNICAST);
+ else /* AES group key: multicast */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_AES_MCAST);
+ } else if (pkey->key_len == WPA_TKIP_KEY_LEN) {
+ PRINTM(MCMND, "WPA_TKIP\n");
+ pkey_material->key_param_set.key_type_id =
+ wlan_cpu_to_le16(KEY_TYPE_ID_TKIP);
+ pkey_material->key_param_set.key_info =
+ wlan_cpu_to_le16(KEY_INFO_TKIP_ENABLED);
+
+ if (pkey->key_index & MLAN_KEY_INDEX_UNICAST) /* TKIP pairwise key:
+ unicast */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_TKIP_UNICAST);
+ else /* TKIP group key: multicast */
+ pkey_material->key_param_set.key_info |=
+ wlan_cpu_to_le16(KEY_INFO_TKIP_MCAST);
+ }
+
+ if (pkey_material->key_param_set.key_type_id) {
+ pkey_material->key_param_set.type =
+ wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+ pkey_material->key_param_set.key_len =
+ wlan_cpu_to_le16((t_u16) pkey->key_len);
+ memcpy(pmpriv->adapter, pkey_material->key_param_set.key,
+ pkey->key_material, pkey->key_len);
+ pkey_material->key_param_set.length =
+ wlan_cpu_to_le16((t_u16) pkey->key_len + KEYPARAMSET_FIXED_LEN);
+
+ key_param_len =
+ (t_u16) (pkey->key_len + KEYPARAMSET_FIXED_LEN) +
+ sizeof(MrvlIEtypesHeader_t);
+
+ cmd->size =
+ wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+ S_DS_GEN);
+ }
+ done:
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief This function prepares command of supplicant pmk
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_802_11_supplicant_pmk(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ MrvlIEtypes_PMK_t *ppmk_tlv = MNULL;
+ MrvlIEtypes_Passphrase_t *ppassphrase_tlv = MNULL;
+ MrvlIEtypes_SsIdParamSet_t *pssid_tlv = MNULL;
+ MrvlIEtypes_Bssid_t *pbssid_tlv = MNULL;
+ HostCmd_DS_802_11_SUPPLICANT_PMK *pesupplicant_psk =
+ &cmd->params.esupplicant_psk;
+ t_u8 *ptlv_buffer = (t_u8 *) pesupplicant_psk->tlv_buffer;
+ mlan_ds_passphrase *psk = (mlan_ds_passphrase *) pdata_buf;
+ t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+
+ ENTER();
+ /*
+ * Parse the rest of the buf here
+ * 1) <ssid="valid ssid"> - This will get the passphrase, AKMP
+ * for specified ssid, if none specified then it will get all.
+ * Eg: iwpriv <mlanX> passphrase 0:ssid=marvell
+ * 2) <psk="psk">:<passphrase="passphare">:<bssid="00:50:43:ef:23:f3">
+ * <ssid="valid ssid"> - passphrase and psk cannot be provided to
+ * the same SSID, Takes one SSID at a time, If ssid= is present
+ * the it should contain a passphrase or psk. If no arguments are
+ * provided then AKMP=802.1x, and passphrase should be provided
+ * after association.
+ * End of each parameter should be followed by a ':'(except for the
+ * last parameter) as the delimiter. If ':' has to be used in
+ * an SSID then a '/' should be preceded to ':' as a escape.
+ * Eg:iwpriv <mlanX> passphrase
+ * "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3"
+ * iwpriv <mlanX> passphrase
+ * "1:ssid=mrvl/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3"
+ * iwpriv <mlanX> passphrase "1:ssid=mrvlAP:psk=abcdefgd"
+ * 3) <ssid="valid ssid"> - This will clear the passphrase
+ * for specified ssid, if none specified then it will clear all.
+ * Eg: iwpriv <mlanX> passphrase 2:ssid=marvell
+ */
+
+ /* -1 is for t_u8 TlvBuffer[1] as this should not be included */
+ cmd->size = sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1;
+ if (psk->ssid.ssid_len) {
+ pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *) ptlv_buffer;
+ pssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
+ pssid_tlv->header.len =
+ (t_u16) MIN(MLAN_MAX_SSID_LENGTH, psk->ssid.ssid_len);
+ memcpy(pmpriv->adapter, (char *) pssid_tlv->ssid, psk->ssid.ssid,
+ MIN(MLAN_MAX_SSID_LENGTH, psk->ssid.ssid_len));
+ ptlv_buffer += (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ cmd->size += (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ pssid_tlv->header.len = wlan_cpu_to_le16(pssid_tlv->header.len);
+ }
+ if (memcmp
+ (pmpriv->adapter, (t_u8 *) & psk->bssid, zero_mac, sizeof(zero_mac))) {
+ pbssid_tlv = (MrvlIEtypes_Bssid_t *) ptlv_buffer;
+ pbssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID);
+ pbssid_tlv->header.len = MLAN_MAC_ADDR_LENGTH;
+ memcpy(pmpriv->adapter, pbssid_tlv->bssid, (t_u8 *) & psk->bssid,
+ MLAN_MAC_ADDR_LENGTH);
+ ptlv_buffer += (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ cmd->size += (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ pbssid_tlv->header.len = wlan_cpu_to_le16(pbssid_tlv->header.len);
+ }
+ if (psk->psk_type == MLAN_PSK_PASSPHRASE) {
+ ppassphrase_tlv = (MrvlIEtypes_Passphrase_t *) ptlv_buffer;
+ ppassphrase_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE);
+ ppassphrase_tlv->header.len =
+ (t_u16) MIN(MLAN_MAX_PASSPHRASE_LENGTH,
+ psk->psk.passphrase.passphrase_len);
+ memcpy(pmpriv->adapter, ppassphrase_tlv->passphrase,
+ psk->psk.passphrase.passphrase, MIN(MLAN_MAX_PASSPHRASE_LENGTH,
+ psk->psk.passphrase.
+ passphrase_len));
+ ptlv_buffer +=
+ (ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ cmd->size +=
+ (ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ ppassphrase_tlv->header.len =
+ wlan_cpu_to_le16(ppassphrase_tlv->header.len);
+ }
+ if (psk->psk_type == MLAN_PSK_PMK) {
+ ppmk_tlv = (MrvlIEtypes_PMK_t *) ptlv_buffer;
+ ppmk_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PMK);
+ ppmk_tlv->header.len = MLAN_MAX_KEY_LENGTH;
+ memcpy(pmpriv->adapter, ppmk_tlv->pmk, psk->psk.pmk.pmk,
+ MLAN_MAX_KEY_LENGTH);
+ ptlv_buffer += (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ cmd->size += (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+ ppmk_tlv->header.len = wlan_cpu_to_le16(ppmk_tlv->header.len);
+ }
+ if ((cmd_action == HostCmd_ACT_GEN_SET) &&
+ ((pssid_tlv || pbssid_tlv) && (!ppmk_tlv && !ppassphrase_tlv))) {
+ PRINTM(MERROR,
+ "Invalid case,ssid/bssid present without pmk or passphrase\n");
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK);
+ pesupplicant_psk->action = wlan_cpu_to_le16(cmd_action);
+ pesupplicant_psk->cache_result = 0;
+ cmd->size = wlan_cpu_to_le16(cmd->size);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Handle the supplicant profile command
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_supplicant_profile(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action)
+{
+ HostCmd_DS_802_11_SUPPLICANT_PROFILE *sup_profile =
+ &cmd->params.esupplicant_profile;
+
+ ENTER();
+
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SUPPLICANT_PROFILE) +
+ S_DS_GEN - 1);
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PROFILE);
+ sup_profile->action = wlan_cpu_to_le16(cmd_action);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of rf_channel.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_rf_channel(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ HostCmd_DS_802_11_RF_CHANNEL *prf_chan = &cmd->params.rf_channel;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
+ cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_CHANNEL)
+ + S_DS_GEN);
+
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ if ((pmpriv->adapter->adhoc_start_band & BAND_A)
+ || (pmpriv->adapter->adhoc_start_band & BAND_AN)
+ )
+ prf_chan->rf_type = HostCmd_SCAN_RADIO_TYPE_A;
+ SET_SECONDARYCHAN(prf_chan->rf_type, pmpriv->adapter->chan_bandwidth);
+ prf_chan->rf_type = wlan_cpu_to_le16(prf_chan->rf_type);
+ prf_chan->current_channel = wlan_cpu_to_le16(*((t_u16 *) pdata_buf));
+ }
+ prf_chan->action = wlan_cpu_to_le16(cmd_action);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of ibss_coalescing_status.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer or MNULL
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_ibss_coalescing_status(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ HostCmd_DS_802_11_IBSS_STATUS *pibss_coal = &(cmd->params.ibss_coalescing);
+ t_u16 enable = 0;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_IBSS_STATUS) + S_DS_GEN);
+ cmd->result = 0;
+ pibss_coal->action = wlan_cpu_to_le16(cmd_action);
+
+ switch (cmd_action) {
+ case HostCmd_ACT_GEN_SET:
+ if (pdata_buf != MNULL)
+ enable = *(t_u16 *) pdata_buf;
+ pibss_coal->enable = wlan_cpu_to_le16(enable);
+ break;
+
+ /* In other case.. Nothing to do */
+ case HostCmd_ACT_GEN_GET:
+ default:
+ break;
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of mgmt IE list.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ *
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_mgmt_ie_list(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ t_u16 req_len = 0, travel_len = 0;
+ custom_ie *cptr = MNULL;
+ mlan_ds_misc_custom_ie *cust_ie = MNULL;
+ HostCmd_DS_MGMT_IE_LIST_CFG *pmgmt_ie_list = &(cmd->params.mgmt_ie_list);
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MGMT_IE_LIST);
+ cmd->size = sizeof(HostCmd_DS_MGMT_IE_LIST_CFG) + S_DS_GEN;
+ cmd->result = 0;
+ pmgmt_ie_list->action = wlan_cpu_to_le16(cmd_action);
+
+ cust_ie = (mlan_ds_misc_custom_ie *) pdata_buf;
+ pmgmt_ie_list->ds_mgmt_ie.type = wlan_cpu_to_le16(cust_ie->type);
+ pmgmt_ie_list->ds_mgmt_ie.len = wlan_cpu_to_le16(cust_ie->len);
+
+ if (pmgmt_ie_list->ds_mgmt_ie.ie_data_list && cust_ie->ie_data_list) {
+ req_len = cust_ie->len;
+ travel_len = 0;
+ /* conversion for index, mask, len */
+ if (req_len == sizeof(t_u16))
+ cust_ie->ie_data_list[0].ie_index =
+ wlan_cpu_to_le16(cust_ie->ie_data_list[0].ie_index);
+
+ while (req_len > sizeof(t_u16)) {
+ cptr =
+ (custom_ie *) (((t_u8 *) cust_ie->ie_data_list) + travel_len);
+ travel_len += cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
+ req_len -= cptr->ie_length + sizeof(custom_ie) - MAX_IE_SIZE;
+ cptr->ie_index = wlan_cpu_to_le16(cptr->ie_index);
+ cptr->mgmt_subtype_mask = wlan_cpu_to_le16(cptr->mgmt_subtype_mask);
+ cptr->ie_length = wlan_cpu_to_le16(cptr->ie_length);
+ }
+ if (cust_ie->len)
+ memcpy(pmpriv->adapter, pmgmt_ie_list->ds_mgmt_ie.ie_data_list,
+ cust_ie->ie_data_list, cust_ie->len);
+ }
+
+ cmd->size -=
+ (MAX_MGMT_IE_INDEX * sizeof(custom_ie)) + sizeof(tlvbuf_max_mgmt_ie);
+ cmd->size += cust_ie->len;
+ cmd->size = wlan_cpu_to_le16(cmd->size);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares system clock cfg command
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action The action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_sysclock_cfg(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG *cfg = &cmd->params.sys_clock_cfg;
+ mlan_ds_misc_sys_clock *clk_cfg = (mlan_ds_misc_sys_clock *) pdata_buf;
+ int i = 0;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG);
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG) + S_DS_GEN);
+
+ cfg->action = wlan_cpu_to_le16(cmd_action);
+ cfg->cur_sys_clk = wlan_cpu_to_le16(clk_cfg->cur_sys_clk);
+ cfg->sys_clk_type = wlan_cpu_to_le16(clk_cfg->sys_clk_type);
+ cfg->sys_clk_len = wlan_cpu_to_le16(clk_cfg->sys_clk_num) * sizeof(t_u16);
+ for (i = 0; i < clk_cfg->sys_clk_num; i++)
+ cfg->sys_clk[i] = wlan_cpu_to_le16(clk_cfg->sys_clk[i]);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of reg_access.
+ *
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action the action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_reg_access(IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ mlan_ds_reg_rw *reg_rw;
+
+ ENTER();
+
+ reg_rw = (mlan_ds_reg_rw *) pdata_buf;
+ switch (cmd->command) {
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ {
+ HostCmd_DS_MAC_REG_ACCESS *mac_reg;
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_REG_ACCESS) + S_DS_GEN);
+ mac_reg = (HostCmd_DS_MAC_REG_ACCESS *) & cmd->params.mac_reg;
+ mac_reg->action = wlan_cpu_to_le16(cmd_action);
+ mac_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+ mac_reg->value = wlan_cpu_to_le32(reg_rw->value);
+ break;
+ }
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ {
+ HostCmd_DS_BBP_REG_ACCESS *bbp_reg;
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_BBP_REG_ACCESS) + S_DS_GEN);
+ bbp_reg = (HostCmd_DS_BBP_REG_ACCESS *) & cmd->params.bbp_reg;
+ bbp_reg->action = wlan_cpu_to_le16(cmd_action);
+ bbp_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+ bbp_reg->value = (t_u8) reg_rw->value;
+ break;
+ }
+ case HostCmd_CMD_RF_REG_ACCESS:
+ {
+ HostCmd_DS_RF_REG_ACCESS *rf_reg;
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
+ rf_reg = (HostCmd_DS_RF_REG_ACCESS *) & cmd->params.rf_reg;
+ rf_reg->action = wlan_cpu_to_le16(cmd_action);
+ rf_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+ rf_reg->value = (t_u8) reg_rw->value;
+ break;
+ }
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ {
+ HostCmd_DS_RF_REG_ACCESS *cau_reg;
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
+ cau_reg = (HostCmd_DS_RF_REG_ACCESS *) & cmd->params.rf_reg;
+ cau_reg->action = wlan_cpu_to_le16(cmd_action);
+ cau_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+ cau_reg->value = (t_u8) reg_rw->value;
+ break;
+ }
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ {
+ mlan_ds_read_eeprom *rd_eeprom = (mlan_ds_read_eeprom *) pdata_buf;
+ HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom =
+ (HostCmd_DS_802_11_EEPROM_ACCESS *) & cmd->params.eeprom;
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_EEPROM_ACCESS) +
+ S_DS_GEN);
+ cmd_eeprom->action = wlan_cpu_to_le16(cmd_action);
+ cmd_eeprom->offset = wlan_cpu_to_le16(rd_eeprom->offset);
+ cmd_eeprom->byte_count = wlan_cpu_to_le16(rd_eeprom->byte_count);
+ cmd_eeprom->value = 0;
+ break;
+ }
+ default:
+ LEAVE();
+ return MLAN_STATUS_FAILURE;
+ }
+ cmd->command = wlan_cpu_to_le16(cmd->command);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of mem_access.
+ *
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action the action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_mem_access(IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ mlan_ds_mem_rw *mem_rw = (mlan_ds_mem_rw *) pdata_buf;
+ HostCmd_DS_MEM_ACCESS *mem_access =
+ (HostCmd_DS_MEM_ACCESS *) & cmd->params.mem;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MEM_ACCESS);
+ cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MEM_ACCESS) + S_DS_GEN);
+
+ mem_access->action = wlan_cpu_to_le16(cmd_action);
+ mem_access->addr = wlan_cpu_to_le32(mem_rw->addr);
+ mem_access->value = wlan_cpu_to_le32(mem_rw->value);
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of subscribe event.
+ *
+ * @param pmpriv A pointer to mlan_private structure
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action the action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_subscribe_event(IN pmlan_private pmpriv,
+ IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ mlan_ds_subscribe_evt *sub_evt = (mlan_ds_subscribe_evt *) pdata_buf;
+ HostCmd_DS_SUBSCRIBE_EVENT *evt =
+ (HostCmd_DS_SUBSCRIBE_EVENT *) & cmd->params.subscribe_event;
+ t_u16 cmd_size = 0;
+ t_u8 *tlv = MNULL;
+ MrvlIEtypes_BeaconLowRssiThreshold_t *rssi_low = MNULL;
+ MrvlIEtypes_BeaconLowSnrThreshold_t *snr_low = MNULL;
+ MrvlIEtypes_FailureCount_t *fail_count = MNULL;
+ MrvlIEtypes_BeaconsMissed_t *beacon_missed = MNULL;
+ MrvlIEtypes_BeaconHighRssiThreshold_t *rssi_high = MNULL;
+ MrvlIEtypes_BeaconHighSnrThreshold_t *snr_high = MNULL;
+ MrvlIEtypes_DataLowRssiThreshold_t *data_rssi_low = MNULL;
+ MrvlIEtypes_DataLowSnrThreshold_t *data_snr_low = MNULL;
+ MrvlIEtypes_DataHighRssiThreshold_t *data_rssi_high = MNULL;
+ MrvlIEtypes_DataHighSnrThreshold_t *data_snr_high = MNULL;
+ MrvlIEtypes_LinkQualityThreshold_t *link_quality = MNULL;
+ MrvlIETypes_PreBeaconMissed_t *pre_bcn_missed = MNULL;
+
+ ENTER();
+
+ cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
+ evt->action = wlan_cpu_to_le16(cmd_action);
+ cmd_size = sizeof(HostCmd_DS_SUBSCRIBE_EVENT) + S_DS_GEN;
+ if (cmd_action == HostCmd_ACT_GEN_GET)
+ goto done;
+#define HostCmd_ACT_BITWISE_SET 0x02
+ evt->action = wlan_cpu_to_le16(HostCmd_ACT_BITWISE_SET);
+ evt->event_bitmap = wlan_cpu_to_le16(sub_evt->evt_bitmap);
+ tlv = (t_u8 *) cmd + cmd_size;
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_LOW) {
+ rssi_low = (MrvlIEtypes_BeaconLowRssiThreshold_t *) tlv;
+ rssi_low->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW);
+ rssi_low->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ rssi_low->value = sub_evt->low_rssi;
+ rssi_low->frequency = sub_evt->low_rssi_freq;
+ tlv += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_LOW) {
+ snr_low = (MrvlIEtypes_BeaconLowSnrThreshold_t *) tlv;
+ snr_low->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_LOW);
+ snr_low->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ snr_low->value = sub_evt->low_snr;
+ snr_low->frequency = sub_evt->low_snr_freq;
+ tlv += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_MAX_FAIL) {
+ fail_count = (MrvlIEtypes_FailureCount_t *) tlv;
+ fail_count->header.type = wlan_cpu_to_le16(TLV_TYPE_FAILCOUNT);
+ fail_count->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_FailureCount_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ fail_count->value = sub_evt->failure_count;
+ fail_count->frequency = sub_evt->failure_count_freq;
+ tlv += sizeof(MrvlIEtypes_FailureCount_t);
+ cmd_size += sizeof(MrvlIEtypes_FailureCount_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_BEACON_MISSED) {
+ beacon_missed = (MrvlIEtypes_BeaconsMissed_t *) tlv;
+ beacon_missed->header.type = wlan_cpu_to_le16(TLV_TYPE_BCNMISS);
+ beacon_missed->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconsMissed_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ beacon_missed->value = sub_evt->beacon_miss;
+ beacon_missed->frequency = sub_evt->beacon_miss_freq;
+ tlv += sizeof(MrvlIEtypes_BeaconsMissed_t);
+ cmd_size += sizeof(MrvlIEtypes_BeaconsMissed_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_RSSI_HIGH) {
+ rssi_high = (MrvlIEtypes_BeaconHighRssiThreshold_t *) tlv;
+ rssi_high->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH);
+ rssi_high->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ rssi_high->value = sub_evt->high_rssi;
+ rssi_high->frequency = sub_evt->high_rssi_freq;
+ tlv += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_SNR_HIGH) {
+ snr_high = (MrvlIEtypes_BeaconHighSnrThreshold_t *) tlv;
+ snr_high->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH);
+ snr_high->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ snr_high->value = sub_evt->high_snr;
+ snr_high->frequency = sub_evt->high_snr_freq;
+ tlv += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_LOW) {
+ data_rssi_low = (MrvlIEtypes_DataLowRssiThreshold_t *) tlv;
+ data_rssi_low->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_LOW_DATA);
+ data_rssi_low->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataLowRssiThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ data_rssi_low->value = sub_evt->data_low_rssi;
+ data_rssi_low->frequency = sub_evt->data_low_rssi_freq;
+ tlv += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_DataLowRssiThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_LOW) {
+ data_snr_low = (MrvlIEtypes_DataLowSnrThreshold_t *) tlv;
+ data_snr_low->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_LOW_DATA);
+ data_snr_low->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataLowSnrThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ data_snr_low->value = sub_evt->data_low_snr;
+ data_snr_low->frequency = sub_evt->data_low_snr_freq;
+ tlv += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_DataLowSnrThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_RSSI_HIGH) {
+ data_rssi_high = (MrvlIEtypes_DataHighRssiThreshold_t *) tlv;
+ data_rssi_high->header.type = wlan_cpu_to_le16(TLV_TYPE_RSSI_HIGH_DATA);
+ data_rssi_high->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataHighRssiThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ data_rssi_high->value = sub_evt->data_high_rssi;
+ data_rssi_high->frequency = sub_evt->data_high_rssi_freq;
+ tlv += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_DataHighRssiThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_DATA_SNR_HIGH) {
+ data_snr_high = (MrvlIEtypes_DataHighSnrThreshold_t *) tlv;
+ data_snr_high->header.type = wlan_cpu_to_le16(TLV_TYPE_SNR_HIGH_DATA);
+ data_snr_high->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_DataHighSnrThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ data_snr_high->value = sub_evt->data_high_snr;
+ data_snr_high->frequency = sub_evt->data_high_snr_freq;
+ tlv += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_DataHighSnrThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_LINK_QUALITY) {
+ link_quality = (MrvlIEtypes_LinkQualityThreshold_t *) tlv;
+ link_quality->header.type = wlan_cpu_to_le16(TLV_TYPE_LINK_QUALITY);
+ link_quality->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIEtypes_LinkQualityThreshold_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ link_quality->link_snr = wlan_cpu_to_le16(sub_evt->link_snr);
+ link_quality->link_snr_freq = wlan_cpu_to_le16(sub_evt->link_snr_freq);
+ link_quality->link_rate = wlan_cpu_to_le16(sub_evt->link_rate);
+ link_quality->link_rate_freq =
+ wlan_cpu_to_le16(sub_evt->link_rate_freq);
+ link_quality->link_tx_latency =
+ wlan_cpu_to_le16(sub_evt->link_tx_latency);
+ link_quality->link_tx_lantency_freq =
+ wlan_cpu_to_le16(sub_evt->link_tx_lantency_freq);
+ tlv += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
+ cmd_size += sizeof(MrvlIEtypes_LinkQualityThreshold_t);
+ }
+ if (sub_evt->evt_bitmap & SUBSCRIBE_EVT_PRE_BEACON_LOST) {
+ pre_bcn_missed = (MrvlIETypes_PreBeaconMissed_t *) tlv;
+ pre_bcn_missed->header.type = wlan_cpu_to_le16(TLV_TYPE_PRE_BCNMISS);
+ pre_bcn_missed->header.len =
+ wlan_cpu_to_le16(sizeof(MrvlIETypes_PreBeaconMissed_t) -
+ sizeof(MrvlIEtypesHeader_t));
+ pre_bcn_missed->value = sub_evt->pre_beacon_miss;
+ pre_bcn_missed->frequency = 0;
+ tlv += sizeof(MrvlIETypes_PreBeaconMissed_t);
+ cmd_size += sizeof(MrvlIETypes_PreBeaconMissed_t);
+ }
+ done:
+ cmd->size = wlan_cpu_to_le16(cmd_size);
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares inactivity timeout command
+ *
+ * @param cmd A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action the action: GET or SET
+ * @param pdata_buf A pointer to data buffer
+ * @return MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_inactivity_timeout(IN HostCmd_DS_COMMAND * cmd,
+ IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+ pmlan_ds_inactivity_to inac_to;
+ HostCmd_DS_INACTIVITY_TIMEOUT_EXT *cmd_inac_to = &cmd->params.inactivity_to;
+
+ ENTER();
+
+ inac_to = (mlan_ds_inactivity_to *) pdata_buf;
+
+ cmd->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_INACTIVITY_TIMEOUT_EXT) + S_DS_GEN);
+ cmd->command = wlan_cpu_to_le16(cmd->command);
+ cmd_inac_to->action = wlan_cpu_to_le16(cmd_action);
+ if (cmd_action == HostCmd_ACT_GEN_SET) {
+ cmd_inac_to->timeout_unit =
+ wlan_cpu_to_le16((t_u16) inac_to->timeout_unit);
+ cmd_inac_to->unicast_timeout =
+ wlan_cpu_to_le16((t_u16) inac_to->unicast_timeout);
+ cmd_inac_to->mcast_timeout =
+ wlan_cpu_to_le16((t_u16) inac_to->mcast_timeout);
+ cmd_inac_to->ps_entry_timeout =
+ wlan_cpu_to_le16((t_u16) inac_to->ps_entry_timeout);
+ }
+
+ LEAVE();
+ return MLAN_STATUS_SUCCESS;
+}
+
+/********************************************************
+ Global Functions
+********************************************************/
+
+/**
+ * @brief This function prepare the command before sending to firmware.
+ *
+ * @param priv A pointer to mlan_private structure
+ * @param cmd_no Command number
+ * @param cmd_action Command action: GET or SET
+ * @param cmd_oid Cmd oid: treated as sub command
+ * @param pioctl_buf A pointer to MLAN IOCTL Request buffer
+ * @param pdata_buf A pointer to information buffer
+ * @param pcmd_buf A pointer to cmd buf
+ *
+ * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ops_sta_prepare_cmd(IN t_void * priv,
+ IN t_u16 cmd_no,
+ IN t_u16 cmd_action,
+ IN t_u32 cmd_oid,
+ IN t_void * pioctl_buf,
+ IN t_void * pdata_buf, IN t_void * pcmd_buf)
+{
+ HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *) pcmd_buf;
+ mlan_private *pmpriv = (mlan_private *) priv;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+
+ ENTER();
+
+ /* Prepare command */
+ switch (cmd_no) {
+ case HostCmd_CMD_GET_HW_SPEC:
+ ret = wlan_cmd_get_hw_spec(pmpriv, cmd_ptr);
+ break;
+ case HostCmd_CMD_CFG_DATA:
+ ret = wlan_cmd_cfg_data(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_MAC_CONTROL:
+ ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_MAC_ADDRESS:
+ ret = wlan_cmd_802_11_mac_address(pmpriv, cmd_ptr, cmd_action);
+ break;
+ case HostCmd_CMD_MAC_MULTICAST_ADR:
+ ret =
+ wlan_cmd_mac_multicast_adr(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_TX_RATE_CFG:
+ ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_RF_ANTENNA:
+ ret =
+ wlan_cmd_802_11_rf_antenna(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_TXPWR_CFG:
+ ret = wlan_cmd_tx_power_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_RF_TX_POWER:
+ ret = wlan_cmd_802_11_rf_tx_power(pmpriv, cmd_ptr,
+ cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_PS_MODE_ENH:
+ ret =
+ wlan_cmd_enh_power_mode(pmpriv, cmd_ptr, cmd_action,
+ (t_u16) cmd_oid, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_HS_CFG_ENH:
+ ret =
+ wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action,
+ (hs_config_param *) pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_SLEEP_PERIOD:
+ ret = wlan_cmd_802_11_sleep_period(pmpriv, cmd_ptr,
+ cmd_action, (t_u16 *) pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_SLEEP_PARAMS:
+ ret = wlan_cmd_802_11_sleep_params(pmpriv, cmd_ptr,
+ cmd_action, (t_u16 *) pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_SCAN:
+ ret = wlan_cmd_802_11_scan(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_BG_SCAN_CONFIG:
+ ret = wlan_cmd_bgscan_config(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+ ret = wlan_cmd_802_11_bg_scan_query(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_ASSOCIATE:
+ ret = wlan_cmd_802_11_associate(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_DEAUTHENTICATE:
+ ret = wlan_cmd_802_11_deauthenticate(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_START:
+ ret = wlan_cmd_802_11_ad_hoc_start(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_JOIN:
+ ret = wlan_cmd_802_11_ad_hoc_join(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_AD_HOC_STOP:
+ ret = wlan_cmd_802_11_ad_hoc_stop(pmpriv, cmd_ptr);
+ break;
+ case HostCmd_CMD_802_11_GET_LOG:
+ ret = wlan_cmd_802_11_get_log(pmpriv, cmd_ptr);
+ break;
+ case HostCmd_CMD_RSSI_INFO:
+ ret = wlan_cmd_802_11_rssi_info(pmpriv, cmd_ptr, cmd_action);
+ break;
+ case HostCmd_CMD_802_11_SNMP_MIB:
+ ret =
+ wlan_cmd_802_11_snmp_mib(pmpriv, cmd_ptr, cmd_action, cmd_oid,
+ pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_RADIO_CONTROL:
+ ret =
+ wlan_cmd_802_11_radio_control(pmpriv, cmd_ptr, cmd_action,
+ pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_TX_RATE_QUERY:
+ cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) + S_DS_GEN);
+ pmpriv->tx_rate = 0;
+ ret = MLAN_STATUS_SUCCESS;
+ break;
+ case HostCmd_CMD_VERSION_EXT:
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+ cmd_ptr->params.verext.version_str_sel =
+ (t_u8) (*((t_u32 *) pdata_buf));
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN);
+ ret = MLAN_STATUS_SUCCESS;
+ break;
+ case HostCmd_CMD_RX_MGMT_IND:
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+ cmd_ptr->params.rx_mgmt_ind.action = wlan_cpu_to_le16(cmd_action);
+ cmd_ptr->params.rx_mgmt_ind.mgmt_subtype_mask =
+ wlan_cpu_to_le32((t_u32) (*((t_u32 *) pdata_buf)));
+ cmd_ptr->size = wlan_cpu_to_le16(sizeof(t_u32) + S_DS_GEN);
+ break;
+ case HostCmd_CMD_802_11_RF_CHANNEL:
+ ret =
+ wlan_cmd_802_11_rf_channel(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_FUNC_INIT:
+ if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
+ pmpriv->adapter->hw_status = WlanHardwareStatusInitializing;
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+ cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
+ break;
+ case HostCmd_CMD_FUNC_SHUTDOWN:
+ pmpriv->adapter->hw_status = WlanHardwareStatusReset;
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+ cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
+ break;
+ case HostCmd_CMD_SOFT_RESET:
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+ cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
+ break;
+ case HostCmd_CMD_11N_ADDBA_REQ:
+ ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_11N_DELBA:
+ ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_11N_ADDBA_RSP:
+ ret = wlan_cmd_11n_addba_rspgen(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_KEY_MATERIAL:
+ ret =
+ wlan_cmd_802_11_key_material(pmpriv, cmd_ptr, cmd_action, cmd_oid,
+ pdata_buf);
+ break;
+
+ case HostCmd_CMD_SUPPLICANT_PMK:
+ ret = wlan_cmd_802_11_supplicant_pmk(pmpriv, cmd_ptr, cmd_action,
+ pdata_buf);
+ break;
+ case HostCmd_CMD_SUPPLICANT_PROFILE:
+ ret = wlan_cmd_802_11_supplicant_profile(pmpriv, cmd_ptr, cmd_action);
+ break;
+
+ case HostCmd_CMD_802_11D_DOMAIN_INFO:
+ ret = wlan_cmd_802_11d_domain_info(pmpriv, cmd_ptr, cmd_action);
+ break;
+ case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+ case HostCmd_CMD_802_11_TPC_INFO:
+ case HostCmd_CMD_802_11_CHAN_SW_ANN:
+ case HostCmd_CMD_CHAN_REPORT_REQUEST:
+ ret = wlan_11h_cmd_process(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+ ret = wlan_cmd_recfg_tx_buf(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_AMSDU_AGGR_CTRL:
+ ret = wlan_cmd_amsdu_aggr_ctrl(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_11N_CFG:
+ ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_TX_BF_CFG:
+ ret = wlan_cmd_tx_bf_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_WMM_GET_STATUS:
+ PRINTM(MINFO, "WMM: WMM_GET_STATUS cmd sent\n");
+ cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_WMM_GET_STATUS) + S_DS_GEN);
+ ret = MLAN_STATUS_SUCCESS;
+ break;
+ case HostCmd_CMD_WMM_ADDTS_REQ:
+ ret = wlan_cmd_wmm_addts_req(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_WMM_DELTS_REQ:
+ ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_WMM_QUEUE_CONFIG:
+ ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_WMM_QUEUE_STATS:
+ ret = wlan_cmd_wmm_queue_stats(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_WMM_TS_STATUS:
+ ret = wlan_cmd_wmm_ts_status(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+ ret =
+ wlan_cmd_ibss_coalescing_status(pmpriv, cmd_ptr, cmd_action,
+ pdata_buf);
+ break;
+ case HostCmd_CMD_MGMT_IE_LIST:
+ ret = wlan_cmd_mgmt_ie_list(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_802_11_SCAN_EXT:
+ ret = wlan_cmd_802_11_scan_ext(pmpriv, cmd_ptr, pdata_buf);
+ break;
+ case HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG:
+ ret = wlan_cmd_sysclock_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_MAC_REG_ACCESS:
+ case HostCmd_CMD_BBP_REG_ACCESS:
+ case HostCmd_CMD_RF_REG_ACCESS:
+ case HostCmd_CMD_CAU_REG_ACCESS:
+ case HostCmd_CMD_802_11_EEPROM_ACCESS:
+ ret = wlan_cmd_reg_access(cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_MEM_ACCESS:
+ ret = wlan_cmd_mem_access(cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_INACTIVITY_TIMEOUT_EXT:
+ ret = wlan_cmd_inactivity_timeout(cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_SDIO_GPIO_INT_CONFIG:
+ ret = wlan_cmd_sdio_gpio_int(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HostCmd_CMD_SET_BSS_MODE:
+ cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+#ifdef WIFI_DIRECT_SUPPORT
+ if (pdata_buf) {
+ cmd_ptr->params.bss_mode.con_type = *(t_u8 *) pdata_buf;
+ } else
+#endif
+ if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS)
+ cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_ADHOC;
+ else if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA)
+ cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_INFRA;
+ cmd_ptr->size =
+ wlan_cpu_to_le16(sizeof(HostCmd_DS_SET_BSS_MODE) + S_DS_GEN);
+ ret = MLAN_STATUS_SUCCESS;
+ break;
+ case HostCmd_CMD_MEASUREMENT_REQUEST:
+ case HostCmd_CMD_MEASUREMENT_REPORT:
+ ret = wlan_meas_cmd_process(pmpriv, cmd_ptr, pdata_buf);
+ break;
+#ifdef WIFI_DIRECT_SUPPORT
+ case HostCmd_CMD_802_11_REMAIN_ON_CHANNEL:
+ ret =
+ wlan_cmd_remain_on_channel(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ case HOST_CMD_WIFI_DIRECT_MODE_CONFIG:
+ ret = wlan_cmd_wifi_direct_mode(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+#endif
+ case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
+ ret = wlan_cmd_subscribe_event(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+ break;
+ default:
+ PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
+ ret = MLAN_STATUS_FAILURE;
+ break;
+ }
+
+ LEAVE();
+ return ret;
+}
+
+/**
+ * @brief This function issues commands to initialize firmware
+ *
+ * @param priv A pointer to mlan_private structure
+ * @param first_bss flag for first BSS
+ *
+ * @return MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ops_sta_init_cmd(IN t_void * priv, IN t_u8 first_bss)
+{
+ pmlan_private pmpriv = (pmlan_private) priv;
+ mlan_status ret = MLAN_STATUS_SUCCESS;
+ t_u16 enable = MTRUE;
+ mlan_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+
+ ENTER();
+
+ if (first_bss == MTRUE) {
+ ret = wlan_adapter_init_cmd(pmpriv->adapter);
+ if (ret == MLAN_STATUS_FAILURE)
+ goto done;
+ }
+
+ /* get tx rate */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_TX_RATE_CFG,
+ HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ pmpriv->data_rate = 0;
+
+ /* get tx power */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_802_11_RF_TX_POWER,
+ HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ /* set ibss coalescing_status */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+ HostCmd_ACT_GEN_SET, 0, MNULL, &enable);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+
+ memset(pmpriv->adapter, &amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
+ amsdu_aggr_ctrl.enable = MLAN_ACT_ENABLE;
+ /* Send request to firmware */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_AMSDU_AGGR_CTRL,
+ HostCmd_ACT_GEN_SET, 0, MNULL,
+ (t_void *) & amsdu_aggr_ctrl);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ /* MAC Control must be the last command in init_fw */
+ /* set MAC Control */
+ ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
+ HostCmd_ACT_GEN_SET, 0, MNULL,
+ &pmpriv->curr_pkt_filter);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ /** set last_init_cmd */
+ pmpriv->adapter->last_init_cmd = HostCmd_CMD_MAC_CONTROL;
+
+ if (first_bss == MFALSE) {
+ /* Get MAC address */
+ ret = wlan_prepare_cmd(pmpriv,
+ HostCmd_CMD_802_11_MAC_ADDRESS,
+ HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+ if (ret) {
+ ret = MLAN_STATUS_FAILURE;
+ goto done;
+ }
+ pmpriv->adapter->last_init_cmd = HostCmd_CMD_802_11_MAC_ADDRESS;
+ }
+
+ ret = MLAN_STATUS_PENDING;
+ done:
+ LEAVE();
+ return ret;
+}