| /** @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-2009, Marvell International Ltd. |
| * All Rights Reserved |
| * |
| */ |
| |
| /****************************************************** |
| 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" |
| |
| /******************************************************** |
| Local Variables |
| ********************************************************/ |
| |
| /******************************************************** |
| Global Variables |
| ********************************************************/ |
| |
| /******************************************************** |
| Local Functions |
| ********************************************************/ |
| /** |
| * @brief This function prepares command of get_hw_spec. |
| * |
| * @param pmpriv A pointer to mlan_private structure |
| * @param pcmd A pointer to HostCmd_DS_COMMAND structure |
| * |
| * @return MLAN_STATUS_SUCCESS |
| */ |
| static mlan_status |
| wlan_cmd_get_hw_spec(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND * pcmd) |
| { |
| HostCmd_DS_GET_HW_SPEC *hw_spec = &pcmd->params.hw_spec; |
| |
| ENTER(); |
| |
| pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_HW_SPEC); |
| pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_HW_SPEC) + S_DS_GEN); |
| memcpy(hw_spec->permanent_addr, pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH); |
| |
| LEAVE(); |
| return MLAN_STATUS_SUCCESS; |
| } |
| |
| /** |
| * @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 |
| */ |
| 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(MCMND, "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; |
| |
| default: |
| break; |
| } |
| cmd->size = wlan_cpu_to_le16(cmd->size); |
| PRINTM(MCMND, "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 radio_control. |
| * |
| * @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_radio_control(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, IN t_u16 cmd_action) |
| { |
| mlan_adapter *pmadapter = pmpriv->adapter; |
| HostCmd_DS_802_11_RADIO_CONTROL *pradio_control = &cmd->params.radio; |
| |
| ENTER(); |
| cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RADIO_CONTROL)) |
| + S_DS_GEN); |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RADIO_CONTROL); |
| pradio_control->action = wlan_cpu_to_le16(cmd_action); |
| pradio_control->control = wlan_cpu_to_le16(pmadapter->radio_on); |
| LEAVE(); |
| return MLAN_STATUS_SUCCESS; |
| } |
| |
| /** |
| * @brief This function prepares command of tx_rate_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_rate_cfg(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, |
| IN t_u16 cmd_action, IN t_void * pdata_buf) |
| { |
| HostCmd_DS_TX_RATE_CFG *rate_cfg = &cmd->params.tx_rate_cfg; |
| MrvlRateScope_t *rate_scope; |
| MrvlRateDropPattern_t *rate_drop; |
| t_u16 *pbitmap_rates = (t_u16 *) pdata_buf; |
| |
| t_u32 i; |
| |
| ENTER(); |
| |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); |
| |
| rate_cfg->action = wlan_cpu_to_le16(cmd_action); |
| rate_cfg->cfg_index = 0; |
| |
| rate_scope = (MrvlRateScope_t *) ((t_u8 *) rate_cfg + |
| sizeof(HostCmd_DS_TX_RATE_CFG)); |
| rate_scope->type = wlan_cpu_to_le16(TLV_TYPE_RATE_SCOPE); |
| rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) - |
| sizeof(MrvlIEtypesHeader_t)); |
| if (pbitmap_rates != MNULL) { |
| rate_scope->hr_dsss_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[0]); |
| rate_scope->ofdm_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[1]); |
| for (i = 0; i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16); |
| i++) |
| rate_scope->ht_mcs_rate_bitmap[i] = |
| wlan_cpu_to_le16(pbitmap_rates[2 + i]); |
| } else { |
| rate_scope->hr_dsss_rate_bitmap = |
| wlan_cpu_to_le16(pmpriv->bitmap_rates[0]); |
| rate_scope->ofdm_rate_bitmap = |
| wlan_cpu_to_le16(pmpriv->bitmap_rates[1]); |
| for (i = 0; i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16); |
| i++) |
| rate_scope->ht_mcs_rate_bitmap[i] = |
| wlan_cpu_to_le16(pmpriv->bitmap_rates[2 + i]); |
| } |
| |
| rate_drop = (MrvlRateDropPattern_t *) ((t_u8 *) rate_scope + |
| sizeof(MrvlRateScope_t)); |
| rate_drop->type = wlan_cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); |
| rate_drop->length = wlan_cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); |
| rate_drop->rate_drop_mode = 0; |
| |
| cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) + |
| sizeof(MrvlRateScope_t) + |
| sizeof(MrvlRateDropPattern_t)); |
| |
| 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_u32) pdata_buf + |
| sizeof(HostCmd_DS_TXPWR_CFG)); |
| memmove(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(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 enhanced ps_mode. |
| * |
| * @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_opt_ps_mode(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, |
| IN t_u16 cmd_action, IN t_void * pdata_buf) |
| { |
| pmlan_adapter pmadapter = pmpriv->adapter; |
| |
| ENTER(); |
| |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); |
| cmd->size = |
| wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_PS_MODE_ENH)); |
| ((HostCmd_DS_802_11_PS_MODE_ENH *) (&cmd->params.psmode_enh))->action = |
| wlan_cpu_to_le16(cmd_action); |
| |
| switch (cmd_action) { |
| case EN_PS: |
| { |
| ps_param *pps_mode = &cmd->params.psmode_enh.params.opt_ps; |
| PRINTM(MCMND, "PS Command: Enter PS\n"); |
| |
| pps_mode->null_pkt_interval = |
| wlan_cpu_to_le16(pmadapter->null_pkt_interval); |
| pps_mode->multiple_dtims = |
| wlan_cpu_to_le16(pmadapter->multiple_dtim); |
| pps_mode->bcn_miss_timeout = |
| wlan_cpu_to_le16(pmadapter->bcn_miss_time_out); |
| pps_mode->local_listen_interval = |
| wlan_cpu_to_le16(pmadapter->local_listen_interval); |
| pps_mode->adhoc_wake_period = |
| wlan_cpu_to_le16(pmadapter->adhoc_awake_period); |
| pps_mode->delay_to_ps = wlan_cpu_to_le16(pmadapter->delay_to_ps); |
| pps_mode->mode = wlan_cpu_to_le16(pmadapter->enhanced_ps_mode); |
| break; |
| } |
| case DIS_PS: |
| PRINTM(MCMND, "PS Command: Exit PS\n"); |
| break; |
| case EN_AUTO_DS: |
| { |
| t_u16 idletime = 0; |
| auto_ds_param *pps_mode = &cmd->params.psmode_enh.params.auto_ds; |
| if (pdata_buf) { |
| idletime = ((mlan_ds_auto_ds *) pdata_buf)->idletime; |
| } |
| |
| PRINTM(MCMND, "PS Command: Enter Auto Deep Sleep\n"); |
| pps_mode->deep_sleep_timeout = wlan_cpu_to_le16(idletime); |
| break; |
| } |
| case DIS_AUTO_DS: |
| PRINTM(MCMND, "PS Command: Exit Auto Deep Sleep\n"); |
| break; |
| case SLEEP_CONFIRM: |
| { |
| sleep_confirm_param *pps_mode = |
| &cmd->params.psmode_enh.params.sleep_cfm; |
| PRINTM(MCMND, "PS Command: Sleep Confirm\n"); |
| |
| pps_mode->resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED); |
| break; |
| } |
| default: |
| 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 HostCmd_DS_802_11_HS_CFG_ENH * 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->params.hs_config.conditions != HOST_SLEEP_CFG_CANCEL) |
| && ((pmadapter->arp_filter_size > 0) |
| && (pmadapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { |
| PRINTM(MCMND, "Attach %d bytes ArpFilter to HSCfg cmd\n", |
| pmadapter->arp_filter_size); |
| memcpy(((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 = HS_ACTIVATE; |
| phs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; |
| } else { |
| phs_cfg->action = HS_CONFIGURE; |
| phs_cfg->params.hs_config.conditions = |
| wlan_cpu_to_le32(pdata_buf->params.hs_config.conditions); |
| phs_cfg->params.hs_config.gpio = pdata_buf->params.hs_config.gpio; |
| phs_cfg->params.hs_config.gap = pdata_buf->params.hs_config.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(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(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 |
| */ |
| 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(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]); |
| |
| /** 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 |
| */ |
| 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, 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(&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(&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(&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] = 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(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(&pkey_material->key_param_set.key[2], pkey->key_material, |
| pkey->key_len); |
| memcpy(&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 & 0x40000000) /* 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 & 0x40000000) /* 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(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 |
| */ |
| 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) psk->ssid.ssid_len; |
| memcpy((char *) pssid_tlv->ssid, psk->ssid.ssid, 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((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(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) psk->psk.passphrase.passphrase_len; |
| memcpy(ppassphrase_tlv->passphrase, psk->psk.passphrase.passphrase, |
| 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_PMK_LENGTH; |
| memcpy(ppmk_tlv->pmk, psk->psk.pmk.pmk, MLAN_MAX_PMK_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 |
| */ |
| 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_offset); |
| 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 rf_antenna. |
| * |
| * @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_rf_antenna(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, |
| IN t_u16 cmd_action, IN t_void * pdata_buf) |
| { |
| HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna; |
| |
| ENTER(); |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA); |
| cmd->size = |
| wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN); |
| |
| if (cmd_action == HostCmd_ACT_GEN_SET) { |
| pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH); |
| pantenna->antenna_mode = wlan_cpu_to_le16(*(t_u16 *) pdata_buf); |
| } else |
| pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH); |
| 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 or MLAN_STATUS_FAILURE |
| */ |
| 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; |
| } |
| |
| #ifdef MFG_CMD_SUPPORT |
| /** |
| * @brief This function sends general command to firmware. |
| * |
| * @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 or MLAN_STATUS_FAILURE |
| */ |
| static mlan_status |
| wlan_cmd_mfg_cmd(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf) |
| { |
| mlan_ds_misc_cmd *pcmd_ptr = (mlan_ds_misc_cmd *) pdata_buf; |
| |
| ENTER(); |
| |
| /* Copy the MFG command to command buffer */ |
| memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); |
| PRINTM(MCMND, "MFG command size = %d\n", pcmd_ptr->len); |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND); |
| cmd->size = wlan_cpu_to_le16(cmd->size); |
| cmd->result = 0; |
| |
| LEAVE(); |
| |
| return MLAN_STATUS_SUCCESS; |
| } |
| #endif /* MFG_CMD_SUPPORT */ |
| |
| /** |
| * @brief This function prepares LDO cfg command |
| * |
| * @param priv 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_ldo_cfg(IN pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, |
| IN t_u16 cmd_action, IN t_void * pdata_buf) |
| { |
| t_u16 *pmsource = (t_u16 *) pdata_buf; |
| |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_LDO_CONFIG); |
| cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_LDO_CFG) + S_DS_GEN); |
| |
| cmd->params.ldo_cfg.action = wlan_cpu_to_le16(cmd_action); |
| cmd->params.ldo_cfg.pmsource = wlan_cpu_to_le16(*pmsource); |
| |
| 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 or MLAN_STATUS_FAILURE |
| */ |
| 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; |
| |
| 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]); |
| |
| 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_PMIC_REG_ACCESS: |
| { |
| HostCmd_DS_PMIC_REG_ACCESS *pmic_reg; |
| cmd->size = |
| wlan_cpu_to_le16(sizeof(HostCmd_DS_PMIC_REG_ACCESS) + S_DS_GEN); |
| pmic_reg = (HostCmd_DS_PMIC_REG_ACCESS *) & cmd->params.pmic_reg; |
| pmic_reg->action = wlan_cpu_to_le16(cmd_action); |
| pmic_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset); |
| pmic_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 or MLAN_STATUS_FAILURE |
| */ |
| 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 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 or MLAN_STATUS_FAILURE |
| */ |
| 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; |
| } |
| |
| /** |
| * @brief This function prepares command of bca_timeshare. |
| * |
| * @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_bca_timeshare(pmlan_private pmpriv, |
| IN HostCmd_DS_COMMAND * cmd, |
| IN t_u16 cmd_action, IN t_void * pdata_buf) |
| { |
| mlan_ds_bca_ts *pdata_bca_ts = (mlan_ds_bca_ts *) pdata_buf; |
| HostCmd_DS_802_11_BCA_TIMESHARE *bca_ts = &cmd->params.bca_timeshare; |
| |
| ENTER(); |
| |
| cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_BCA_TIMESHARE)) + |
| S_DS_GEN); |
| cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE); |
| |
| if (cmd_action == HostCmd_ACT_GEN_GET) { |
| memset(bca_ts, 0, sizeof(HostCmd_DS_802_11_BCA_TIMESHARE)); |
| bca_ts->action = wlan_cpu_to_le16(cmd_action); |
| bca_ts->traffic_type = wlan_cpu_to_le16(pdata_bca_ts->traffic_type); |
| } else if (cmd_action == HostCmd_ACT_GEN_SET) { |
| bca_ts->action = wlan_cpu_to_le16(cmd_action); |
| bca_ts->traffic_type = wlan_cpu_to_le16(pdata_bca_ts->traffic_type); |
| bca_ts->timeshare_interval = |
| wlan_cpu_to_le32(pdata_bca_ts->timeshare_interval); |
| bca_ts->bt_time = wlan_cpu_to_le32(pdata_bca_ts->bt_time); |
| } |
| |
| 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 |
| mlan_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; |
| /* Prepare command */ |
| switch (cmd_no) { |
| case HostCmd_CMD_GET_HW_SPEC: |
| ret = wlan_cmd_get_hw_spec(pmpriv, cmd_ptr); |
| 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_PS_MODE_ENH: |
| ret = |
| wlan_cmd_802_11_opt_ps_mode(pmpriv, cmd_ptr, cmd_action, pdata_buf); |
| break; |
| case HostCmd_CMD_802_11_HS_CFG_ENH: |
| ret = wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action, |
| (HostCmd_DS_802_11_HS_CFG_ENH *) |
| 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_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); |
| 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)); |
| memcpy(&cmd_ptr->params, pdata_buf, sizeof(HostCmd_DS_VERSION_EXT)); |
| cmd_ptr->size = |
| wlan_cpu_to_le16(sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN); |
| ret = MLAN_STATUS_SUCCESS; |
| 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 = WlanHardwareStatusReady; |
| 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_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: |
| 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_WMM_GET_STATUS: |
| PRINTM(MCMND, "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; |
| #ifdef MFG_CMD_SUPPORT |
| case HostCmd_CMD_MFG_COMMAND: |
| ret = wlan_cmd_mfg_cmd(pmpriv, cmd_ptr, pdata_buf); |
| break; |
| #endif /* MFG_CMD_SUPPORT */ |
| case HostCmd_CMD_802_11_LDO_CONFIG: |
| ret = wlan_cmd_ldo_cfg(pmpriv, cmd_ptr, cmd_action, 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_PMIC_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_802_11_BCA_CONFIG_TIMESHARE: |
| ret = |
| wlan_cmd_802_11_bca_timeshare(pmpriv, cmd_ptr, cmd_action, |
| pdata_buf); |
| break; |
| default: |
| PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no); |
| ret = MLAN_STATUS_FAILURE; |
| break; |
| } |
| return ret; |
| } |
| |
| /** |
| * @brief This function issues commands to initialize firmware |
| * |
| * @param priv A pointer to mlan_private structure |
| * @param first_sta flag for first station |
| * |
| * @return MLAN_STATUS_SUCCESS or error code |
| */ |
| mlan_status |
| mlan_sta_init_cmd(IN t_void * priv, IN t_u8 first_sta) |
| { |
| 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_sta == MTRUE) { |
| |
| ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_INIT, |
| HostCmd_ACT_GEN_SET, 0, MNULL, MNULL); |
| if (ret) { |
| ret = MLAN_STATUS_FAILURE; |
| goto done; |
| } |
| /* |
| * Read MAC address from HW |
| */ |
| ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GET_HW_SPEC, |
| HostCmd_ACT_GEN_GET, 0, MNULL, MNULL); |
| if (ret) { |
| ret = MLAN_STATUS_FAILURE; |
| goto done; |
| } |
| |
| /* Reconfigure tx buf size */ |
| ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RECONFIGURE_TX_BUFF, |
| HostCmd_ACT_GEN_SET, 0, MNULL, |
| &pmpriv->adapter->tx_buf_size); |
| if (ret) { |
| 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_TXPWR_CFG, |
| 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(&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; |
| ret = MLAN_STATUS_PENDING; |
| done: |
| LEAVE(); |
| return ret; |
| } |