summaryrefslogtreecommitdiff
path: root/fwcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fwcmd.c')
-rw-r--r--fwcmd.c183
1 files changed, 105 insertions, 78 deletions
diff --git a/fwcmd.c b/fwcmd.c
index c055910..9c3ccf9 100644
--- a/fwcmd.c
+++ b/fwcmd.c
@@ -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)
{