diff options
author | Brian Cavagnolo <brian@cozybit.com> | 2011-03-17 14:58:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-03-30 14:15:12 -0400 |
commit | 73b46320209e9fe0d65aba1b8c21489278047574 (patch) | |
tree | 66c6b49a01259ae2b1b3ad1946a8f2000b4979a6 /drivers/net/wireless/mwl8k.c | |
parent | c835b21405fa551cd5af2c7bfe1c3ae129c5f8ef (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.c | 51 |
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 | ||
2080 | done: | 2080 | done: |
@@ -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 | ||
4603 | static 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 */ |
4604 | static int mwl8k_probe_hw(struct ieee80211_hw *hw) | 4621 | static 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); |