Commit e882efc9 authored by Yogesh Ashok Powar's avatar Yogesh Ashok Powar Committed by John W. Linville

mwl8k: Stop bsses before hw specific commands

For the commands, that might change the hw characteristics
of the PHY device, stop the running bsses and resume them
once command is complete.
Signed-off-by: default avatarYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: default avatarNishant Sarmukadam <nishants@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 73e4dbe4
...@@ -285,6 +285,9 @@ struct mwl8k_priv { ...@@ -285,6 +285,9 @@ struct mwl8k_priv {
char *fw_pref; char *fw_pref;
char *fw_alt; char *fw_alt;
struct completion firmware_loading_complete; struct completion firmware_loading_complete;
/* bitmap of running BSSes */
u32 running_bsses;
}; };
#define MAX_WEP_KEY_LEN 13 #define MAX_WEP_KEY_LEN 13
...@@ -2156,6 +2159,8 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw) ...@@ -2156,6 +2159,8 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
} }
} }
static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable,
u32 bitmap);
/* /*
* Command processing. * Command processing.
...@@ -2174,6 +2179,34 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) ...@@ -2174,6 +2179,34 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
int rc; int rc;
unsigned long timeout = 0; unsigned long timeout = 0;
u8 buf[32]; u8 buf[32];
u32 bitmap = 0;
wiphy_dbg(hw->wiphy, "Posting %s [%d]\n",
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid);
/* Before posting firmware commands that could change the hardware
* characteristics, make sure that all BSSes are stopped temporary.
* Enable these stopped BSSes after completion of the commands
*/
rc = mwl8k_fw_lock(hw);
if (rc)
return rc;
if (priv->ap_fw && priv->running_bsses) {
switch (le16_to_cpu(cmd->code)) {
case MWL8K_CMD_SET_RF_CHANNEL:
case MWL8K_CMD_RADIO_CONTROL:
case MWL8K_CMD_RF_TX_POWER:
case MWL8K_CMD_TX_POWER:
case MWL8K_CMD_RF_ANTENNA:
case MWL8K_CMD_RTS_THRESHOLD:
case MWL8K_CMD_MIMO_CONFIG:
bitmap = priv->running_bsses;
mwl8k_enable_bsses(hw, false, bitmap);
break;
}
}
cmd->result = (__force __le16) 0xffff; cmd->result = (__force __le16) 0xffff;
dma_size = le16_to_cpu(cmd->length); dma_size = le16_to_cpu(cmd->length);
...@@ -2182,13 +2215,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) ...@@ -2182,13 +2215,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
if (pci_dma_mapping_error(priv->pdev, dma_addr)) if (pci_dma_mapping_error(priv->pdev, dma_addr))
return -ENOMEM; return -ENOMEM;
rc = mwl8k_fw_lock(hw);
if (rc) {
pci_unmap_single(priv->pdev, dma_addr, dma_size,
PCI_DMA_BIDIRECTIONAL);
return rc;
}
priv->hostcmd_wait = &cmd_wait; priv->hostcmd_wait = &cmd_wait;
iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
iowrite32(MWL8K_H2A_INT_DOORBELL, iowrite32(MWL8K_H2A_INT_DOORBELL,
...@@ -2201,7 +2227,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) ...@@ -2201,7 +2227,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
priv->hostcmd_wait = NULL; priv->hostcmd_wait = NULL;
mwl8k_fw_unlock(hw);
pci_unmap_single(priv->pdev, dma_addr, dma_size, pci_unmap_single(priv->pdev, dma_addr, dma_size,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
...@@ -2228,6 +2253,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) ...@@ -2228,6 +2253,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
ms); ms);
} }
if (bitmap)
mwl8k_enable_bsses(hw, true, bitmap);
mwl8k_fw_unlock(hw);
return rc; return rc;
} }
...@@ -3680,8 +3710,16 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, ...@@ -3680,8 +3710,16 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int enable) struct ieee80211_vif *vif, int enable)
{ {
struct mwl8k_cmd_bss_start *cmd; struct mwl8k_cmd_bss_start *cmd;
struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
struct mwl8k_priv *priv = hw->priv;
int rc; int rc;
if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid)))
return 0;
if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid)))
return 0;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL) if (cmd == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -3693,9 +3731,31 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, ...@@ -3693,9 +3731,31 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
kfree(cmd); kfree(cmd);
if (!rc) {
if (enable)
priv->running_bsses |= (1 << mwl8k_vif->macid);
else
priv->running_bsses &= ~(1 << mwl8k_vif->macid);
}
return rc; return rc;
} }
static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable, u32 bitmap)
{
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_vif *mwl8k_vif, *tmp_vif;
struct ieee80211_vif *vif;
list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) {
vif = mwl8k_vif->vif;
if (!(bitmap & (1 << mwl8k_vif->macid)))
continue;
if (vif->type == NL80211_IFTYPE_AP)
mwl8k_cmd_bss_start(hw, vif, enable);
}
}
/* /*
* CMD_BASTREAM. * CMD_BASTREAM.
*/ */
...@@ -5948,6 +6008,8 @@ static int mwl8k_probe(struct pci_dev *pdev, ...@@ -5948,6 +6008,8 @@ static int mwl8k_probe(struct pci_dev *pdev,
priv->hw_restart_in_progress = false; priv->hw_restart_in_progress = false;
priv->running_bsses = 0;
return rc; return rc;
err_stop_firmware: err_stop_firmware:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment