aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorBrian Cavagnolo <brian@cozybit.com>2011-03-17 14:58:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-03-30 14:15:12 -0400
commit73b46320209e9fe0d65aba1b8c21489278047574 (patch)
tree66c6b49a01259ae2b1b3ad1946a8f2000b4979a6 /drivers/net/wireless/mwl8k.c
parentc835b21405fa551cd5af2c7bfe1c3ae129c5f8ef (diff)
mwl8k: refactor in preparation for APIv2 update
Specifically, APIv2 will specify a variable number of AMPDU queues in the MWL8K_CMD_GET_HW_SPEC. So init the tx queues after MWL8K_CMD_GET_HW_SPEC for ap fw. Also, we make it safe to deinit queues that have not been init'd. This happens if the mwl8k_get_hw_spec_ap routine fails, for example. Signed-off-by: Nishant Sarmukadam <nishants@marvell.com> Signed-off-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 36952274950e..8fefed2342d7 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -191,6 +191,7 @@ struct mwl8k_priv {
191 191
192 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 192 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
193 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 193 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
194 u32 txq_offset[MWL8K_TX_QUEUES];
194 195
195 bool radio_on; 196 bool radio_on;
196 bool radio_short_preamble; 197 bool radio_short_preamble;
@@ -1126,6 +1127,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
1126 struct mwl8k_rx_queue *rxq = priv->rxq + index; 1127 struct mwl8k_rx_queue *rxq = priv->rxq + index;
1127 int i; 1128 int i;
1128 1129
1130 if (rxq->rxd == NULL)
1131 return;
1132
1129 for (i = 0; i < MWL8K_RX_DESCS; i++) { 1133 for (i = 0; i < MWL8K_RX_DESCS; i++) {
1130 if (rxq->buf[i].skb != NULL) { 1134 if (rxq->buf[i].skb != NULL) {
1131 pci_unmap_single(priv->pdev, 1135 pci_unmap_single(priv->pdev,
@@ -1560,6 +1564,9 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1560 struct mwl8k_priv *priv = hw->priv; 1564 struct mwl8k_priv *priv = hw->priv;
1561 struct mwl8k_tx_queue *txq = priv->txq + index; 1565 struct mwl8k_tx_queue *txq = priv->txq + index;
1562 1566
1567 if (txq->txd == NULL)
1568 return;
1569
1563 mwl8k_txq_reclaim(hw, index, INT_MAX, 1); 1570 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1564 1571
1565 kfree(txq->skb); 1572 kfree(txq->skb);
@@ -2058,23 +2065,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2058 priv->ap_macids_supported = 0x000000ff; 2065 priv->ap_macids_supported = 0x000000ff;
2059 priv->sta_macids_supported = 0x00000000; 2066 priv->sta_macids_supported = 0x00000000;
2060 2067
2061 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
2062 iowrite32(priv->txq[0].txd_dma, priv->sram + off);
2063
2064 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; 2068 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
2065 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2069 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2066 2070
2067 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; 2071 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
2068 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2072 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2069 2073
2070 off = le32_to_cpu(cmd->wcbbase1) & 0xffff; 2074 priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
2071 iowrite32(priv->txq[1].txd_dma, priv->sram + off); 2075 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
2072 2076 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
2073 off = le32_to_cpu(cmd->wcbbase2) & 0xffff; 2077 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2074 iowrite32(priv->txq[2].txd_dma, priv->sram + off);
2075
2076 off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2077 iowrite32(priv->txq[3].txd_dma, priv->sram + off);
2078 } 2078 }
2079 2079
2080done: 2080done:
@@ -4600,6 +4600,23 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
4600 return rc; 4600 return rc;
4601} 4601}
4602 4602
4603static int mwl8k_init_txqs(struct ieee80211_hw *hw)
4604{
4605 struct mwl8k_priv *priv = hw->priv;
4606 int rc = 0;
4607 int i;
4608
4609 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
4610 rc = mwl8k_txq_init(hw, i);
4611 if (rc)
4612 break;
4613 if (priv->ap_fw)
4614 iowrite32(priv->txq[i].txd_dma,
4615 priv->sram + priv->txq_offset[i]);
4616 }
4617 return rc;
4618}
4619
4603/* initialize hw after successfully loading a firmware image */ 4620/* initialize hw after successfully loading a firmware image */
4604static int mwl8k_probe_hw(struct ieee80211_hw *hw) 4621static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4605{ 4622{
@@ -4627,8 +4644,14 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4627 goto err_stop_firmware; 4644 goto err_stop_firmware;
4628 rxq_refill(hw, 0, INT_MAX); 4645 rxq_refill(hw, 0, INT_MAX);
4629 4646
4630 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 4647 /* For the sta firmware, we need to know the dma addresses of tx queues
4631 rc = mwl8k_txq_init(hw, i); 4648 * before sending MWL8K_CMD_GET_HW_SPEC. So we must initialize them
4649 * prior to issuing this command. But for the AP case, we learn the
4650 * total number of queues from the result CMD_GET_HW_SPEC, so for this
4651 * case we must initialize the tx queues after.
4652 */
4653 if (!priv->ap_fw) {
4654 rc = mwl8k_init_txqs(hw);
4632 if (rc) 4655 if (rc)
4633 goto err_free_queues; 4656 goto err_free_queues;
4634 } 4657 }
@@ -4657,6 +4680,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4657 if (priv->ap_fw) { 4680 if (priv->ap_fw) {
4658 rc = mwl8k_cmd_get_hw_spec_ap(hw); 4681 rc = mwl8k_cmd_get_hw_spec_ap(hw);
4659 if (!rc) 4682 if (!rc)
4683 rc = mwl8k_init_txqs(hw);
4684 if (!rc)
4660 rc = mwl8k_cmd_set_hw_spec(hw); 4685 rc = mwl8k_cmd_set_hw_spec(hw);
4661 } else { 4686 } else {
4662 rc = mwl8k_cmd_get_hw_spec_sta(hw); 4687 rc = mwl8k_cmd_get_hw_spec_sta(hw);