diff options
Diffstat (limited to 'fwcmd.c')
-rw-r--r-- | fwcmd.c | 183 |
1 files changed, 105 insertions, 78 deletions
@@ -48,16 +48,6 @@ static bool mwl_fwcmd_chk_adapter(struct mwl_priv *priv) static void mwl_fwcmd_send_cmd(struct mwl_priv *priv) { - if (priv->mfg_mode) { - struct cmd_header *cmd_hdr = - (struct cmd_header *)&priv->pcmd_buf[2]; - u16 len = le16_to_cpu(cmd_hdr->len); - - writel(priv->pphys_cmd_buf, priv->iobase1 + 0xcd0); - writel(0x00, priv->iobase1 + 0xcd4); - writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE); - writel(len + 4, priv->iobase1 + 0xc40); - } writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR); writel(MACREG_H2ARIC_BIT_DOOR_BELL, priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS); @@ -111,6 +101,8 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd) { HOSTCMD_CMD_FW_FLUSH_TIMER, "FwFlushTimer" }, { HOSTCMD_CMD_SET_CDD, "SetCDD" }, { HOSTCMD_CMD_GET_TEMP, "GetTemp" }, + { HOSTCMD_CMD_GET_FW_REGION_CODE, "GetFwRegionCode" }, + { HOSTCMD_CMD_GET_DEVICE_PWR_TBL, "GetDevicePwrTbl" }, { HOSTCMD_CMD_QUIET_MODE, "QuietMode" }, }; @@ -129,11 +121,8 @@ static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd) unsigned short int_code = 0; do { - if (priv->mfg_mode) - int_code = le16_to_cpu(*((__le16 *)&priv->pcmd_buf[2])); - else - int_code = le16_to_cpu(*((__le16 *)&priv->pcmd_buf[0])); - mdelay(1); + int_code = le16_to_cpu(*((__le16 *)&priv->pcmd_buf[0])); + usleep_range(1000, 2000); } while ((int_code != cmd) && (--curr_iteration)); if (curr_iteration == 0) { @@ -143,7 +132,7 @@ static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd) return -EIO; } - mdelay(3); + usleep_range(3000, 5000); return 0; } @@ -471,20 +460,6 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv, beacon_info->ie_ht_ptr += elen; } break; -#ifdef CONFIG_MAC80211_MESH - case WLAN_EID_MESH_CONFIG: - beacon_info->ie_meshcfg_len = (elen + 2); - beacon_info->ie_meshcfg_ptr = (pos - 2); - break; - case WLAN_EID_MESH_ID: - beacon_info->ie_meshid_len = (elen + 2); - beacon_info->ie_meshid_ptr = (pos - 2); - break; - case WLAN_EID_CHAN_SWITCH_PARAM: - beacon_info->ie_meshchsw_len = (elen + 2); - beacon_info->ie_meshchsw_ptr = (pos - 2); - break; -#endif case WLAN_EID_VHT_CAPABILITY: case WLAN_EID_VHT_OPERATION: case WLAN_EID_OPMODE_NOTIF: @@ -562,18 +537,6 @@ static int mwl_fwcmd_set_ies(struct mwl_priv *priv, struct mwl_vif *mwl_vif) memcpy(pcmd->ie_list_vht, beacon->ie_vht_ptr, beacon->ie_vht_len); pcmd->ie_list_len_vht = cpu_to_le16(beacon->ie_vht_len); -#ifdef CONFIG_MAC80211_MESH - memcpy(pcmd->ie_list_proprietary, beacon->ie_meshid_ptr, - beacon->ie_meshid_len); - ie_list_len_proprietary = beacon->ie_meshid_len; - memcpy(pcmd->ie_list_proprietary + ie_list_len_proprietary, - beacon->ie_meshcfg_ptr, beacon->ie_meshcfg_len); - ie_list_len_proprietary += beacon->ie_meshcfg_len; - memcpy(pcmd->ie_list_proprietary + ie_list_len_proprietary, - beacon->ie_meshchsw_ptr, beacon->ie_meshchsw_len); - ie_list_len_proprietary += beacon->ie_meshchsw_len; -#endif - if (priv->chip_type == MWL8897) { memcpy(pcmd->ie_list_proprietary + ie_list_len_proprietary, beacon->ie_wmm_ptr, beacon->ie_wmm_len); @@ -873,9 +836,6 @@ int mwl_fwcmd_get_hw_specs(struct ieee80211_hw *hw) int retry; int i; - if (priv->mfg_mode) - return 0; - pcmd = (struct hostcmd_cmd_get_hw_spec *)&priv->pcmd_buf[0]; mutex_lock(&priv->fwcmd_mutex); @@ -929,9 +889,6 @@ int mwl_fwcmd_set_hw_specs(struct ieee80211_hw *hw) struct hostcmd_cmd_set_hw_spec *pcmd; int i; - if (priv->mfg_mode) - return 0; - pcmd = (struct hostcmd_cmd_set_hw_spec *)&priv->pcmd_buf[0]; mutex_lock(&priv->fwcmd_mutex); @@ -1009,9 +966,6 @@ int mwl_fwcmd_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) struct mwl_priv *priv = hw->priv; int rc; - if (priv->mfg_mode) - return 0; - priv->radio_short_preamble = short_preamble; rc = mwl_fwcmd_802_11_radio_control(priv, true, true); @@ -1060,7 +1014,10 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw, u16 band = 0, width = 0, sub_ch = 0; u16 maxtxpow[SYSADPT_TX_POWER_LEVEL_TOTAL]; int i, tmp; - int rc; + int rc = 0; + + if (priv->forbidden_setting) + return rc; switch (fraction) { case 0: @@ -1146,7 +1103,10 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw, u16 txpow[SYSADPT_TX_POWER_LEVEL_TOTAL]; int index, found = 0; int i, tmp; - int rc; + int rc = 0; + + if (priv->forbidden_setting) + return rc; switch (fraction) { case 0: @@ -1272,9 +1232,6 @@ int mwl_fwcmd_rf_antenna(struct ieee80211_hw *hw, int dir, int antenna) struct mwl_priv *priv = hw->priv; struct hostcmd_cmd_802_11_rf_antenna *pcmd; - if (priv->mfg_mode) - return 0; - pcmd = (struct hostcmd_cmd_802_11_rf_antenna *)&priv->pcmd_buf[0]; mutex_lock(&priv->fwcmd_mutex); @@ -1404,6 +1361,11 @@ int mwl_fwcmd_set_rf_channel(struct ieee80211_hw *hw, return -EIO; } + if (pcmd->cmd_hdr.result != 0) { + mutex_unlock(&priv->fwcmd_mutex); + return -EINVAL; + } + mutex_unlock(&priv->fwcmd_mutex); return 0; @@ -1957,21 +1919,6 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw, pcmd->peer_info.vht_rx_channel_width = sta->bandwidth; } - /* Patch mesh interface for VHT based on chip type. Once if mac80211 - * supports VHT for mesh interface, following code should be removed. - */ - if (vif->type == NL80211_IFTYPE_MESH_POINT) { - pcmd->peer_info.vht_max_rx_mcs = cpu_to_le32(0x0000fffa); - pcmd->peer_info.vht_cap = cpu_to_le32(0x33801931); - pcmd->peer_info.vht_rx_channel_width = 2; - if (priv->chip_type == MWL8864) { - if (priv->antenna_rx == ANTENNA_RX_4_AUTO) { - pcmd->peer_info.vht_max_rx_mcs = - cpu_to_le32(0x0000ffea); - } - } - } - pcmd->is_qos_sta = sta->wme; pcmd->qos_info = ((sta->uapsd_queues << 4) | (sta->max_sp << 1)); @@ -2254,15 +2201,10 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw, idx = key->keyidx; - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) action = ENCR_ACTION_TYPE_SET_KEY; - } else { + else action = ENCR_ACTION_TYPE_SET_GROUP_KEY; - if (vif->type == NL80211_IFTYPE_MESH_POINT && - !ether_addr_equal(mwl_vif->bssid, addr)) - pcmd->key_param.key_info |= - cpu_to_le32(ENCR_KEY_FLAG_RXGROUPKEY); - } switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: @@ -2643,6 +2585,14 @@ int mwl_fwcmd_set_wsc_ie(struct ieee80211_hw *hw, u8 len, u8 *data) return -EIO; } + pcmd->ie_type = cpu_to_le16(WSC_IE_SET_PROBE_RESPONSE); + + if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_WSC_IE)) { + mutex_unlock(&priv->fwcmd_mutex); + wiphy_err(hw->wiphy, "failed execution\n"); + return -EIO; + } + mutex_unlock(&priv->fwcmd_mutex); return 0; @@ -2749,6 +2699,83 @@ int mwl_fwcmd_get_temp(struct ieee80211_hw *hw, u32 *temp) return 0; } +int mwl_fwcmd_get_fw_region_code(struct ieee80211_hw *hw, + u32 *fw_region_code) +{ + struct mwl_priv *priv = hw->priv; + struct hostcmd_cmd_get_fw_region_code *pcmd; + int status; + + pcmd = (struct hostcmd_cmd_get_fw_region_code *)&priv->pcmd_buf[0]; + + mutex_lock(&priv->fwcmd_mutex); + + memset(pcmd, 0x00, sizeof(*pcmd)); + pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_GET_FW_REGION_CODE); + pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd)); + + if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_FW_REGION_CODE)) { + mutex_unlock(&priv->fwcmd_mutex); + wiphy_err(hw->wiphy, "failed execution\n"); + return -EIO; + } + + if (pcmd->cmd_hdr.result != 0) { + mutex_unlock(&priv->fwcmd_mutex); + return -EINVAL; + } + + status = le32_to_cpu(pcmd->status); + + if (!status) + *fw_region_code = le32_to_cpu(pcmd->fw_region_code); + + mutex_unlock(&priv->fwcmd_mutex); + + return 0; +} + +int mwl_fwcmd_get_device_pwr_tbl(struct ieee80211_hw *hw, + struct mwl_device_pwr_tbl *device_ch_pwrtbl, + u8 *region_code, + u8 *number_of_channels, + u32 channel_index) +{ + struct mwl_priv *priv = hw->priv; + struct hostcmd_cmd_get_device_pwr_tbl *pcmd; + int status; + + pcmd = (struct hostcmd_cmd_get_device_pwr_tbl *)&priv->pcmd_buf[0]; + + mutex_lock(&priv->fwcmd_mutex); + + memset(pcmd, 0x00, sizeof(*pcmd)); + pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_GET_DEVICE_PWR_TBL); + pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd)); + pcmd->status = cpu_to_le16(HOSTCMD_CMD_GET_DEVICE_PWR_TBL); + pcmd->current_channel_index = cpu_to_le32(channel_index); + + if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_DEVICE_PWR_TBL)) { + mutex_unlock(&priv->fwcmd_mutex); + wiphy_err(hw->wiphy, "failed execution\n"); + return -EIO; + } + + device_ch_pwrtbl->channel = pcmd->channel_pwr_tbl.channel; + memcpy(device_ch_pwrtbl->tx_pwr, pcmd->channel_pwr_tbl.tx_pwr, + SYSADPT_TX_POWER_LEVEL_TOTAL); + device_ch_pwrtbl->dfs_capable = pcmd->channel_pwr_tbl.dfs_capable; + device_ch_pwrtbl->ax_ant = pcmd->channel_pwr_tbl.ax_ant; + device_ch_pwrtbl->cdd = pcmd->channel_pwr_tbl.cdd; + *region_code = pcmd->region_code; + *number_of_channels = pcmd->number_of_channels; + status = le16_to_cpu(pcmd->status); + + mutex_unlock(&priv->fwcmd_mutex); + + return status; +} + int mwl_fwcmd_quiet_mode(struct ieee80211_hw *hw, bool enable, u32 period, u32 duration, u32 next_offset) { |