summaryrefslogtreecommitdiff
path: root/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'tx.c')
-rw-r--r--tx.c111
1 files changed, 58 insertions, 53 deletions
diff --git a/tx.c b/tx.c
index 6c1651b..345cc78 100644
--- a/tx.c
+++ b/tx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2015, Marvell International Ltd.
+ * Copyright (C) 2006-2016, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -532,12 +532,6 @@ static inline struct sk_buff *mwl_tx_do_amsdu(struct mwl_priv *priv,
mwl_tx_skb(priv, desc_num, amsdu->skb);
amsdu->num = 0;
amsdu->cur_pos = NULL;
-
- if (!mwl_tx_available(priv, desc_num)) {
- skb_queue_head(&priv->txq[desc_num], tx_skb);
- spin_unlock_bh(&sta_info->amsdu_lock);
- return NULL;
- }
}
spin_unlock_bh(&sta_info->amsdu_lock);
return tx_skb;
@@ -637,47 +631,6 @@ static inline struct sk_buff *mwl_tx_do_amsdu(struct mwl_priv *priv,
return NULL;
}
-static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
-{
- struct mwl_priv *priv = hw->priv;
- int num = SYSADPT_TX_WMM_QUEUES;
- struct sk_buff *tx_skb;
-
- spin_lock_bh(&priv->tx_desc_lock);
- while (num--) {
- while (skb_queue_len(&priv->txq[num]) > 0) {
- struct ieee80211_tx_info *tx_info;
- struct mwl_tx_ctrl *tx_ctrl;
-
- if (!mwl_tx_available(priv, num))
- break;
-
- tx_skb = skb_dequeue(&priv->txq[num]);
- tx_info = IEEE80211_SKB_CB(tx_skb);
- tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
-
- if ((tx_skb->protocol != cpu_to_be16(ETH_P_PAE)) &&
- (tx_ctrl->tx_priority >= SYSADPT_TX_WMM_QUEUES)) {
- tx_skb = mwl_tx_do_amsdu(priv, num,
- tx_skb, tx_info);
- }
-
- if (tx_skb)
- mwl_tx_skb(priv, num, tx_skb);
- }
-
- if (skb_queue_len(&priv->txq[num]) <
- SYSADPT_TX_WAKE_Q_THRESHOLD) {
- int queue;
-
- queue = SYSADPT_TX_WMM_QUEUES - num - 1;
- if (ieee80211_queue_stopped(hw, queue))
- ieee80211_wake_queue(hw, queue);
- }
- }
- spin_unlock_bh(&priv->tx_desc_lock);
-}
-
static inline void mwl_tx_prepare_info(struct ieee80211_hw *hw, u32 rate,
struct ieee80211_tx_info *info)
{
@@ -964,7 +917,7 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
skb_queue_tail(&priv->txq[index], skb);
- mwl_tx_skbs(hw);
+ tasklet_schedule(&priv->tx_task);
/* Initiate the ampdu session here */
if (start_ba_session) {
@@ -1086,6 +1039,52 @@ void mwl_tx_del_ampdu_pkts(struct ieee80211_hw *hw,
spin_unlock_bh(&sta_info->amsdu_lock);
}
+void mwl_tx_skbs(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct mwl_priv *priv = hw->priv;
+ int num = SYSADPT_TX_WMM_QUEUES;
+ struct sk_buff *tx_skb;
+
+ spin_lock_bh(&priv->tx_desc_lock);
+ while (num--) {
+ while (skb_queue_len(&priv->txq[num]) > 0) {
+ struct ieee80211_tx_info *tx_info;
+ struct mwl_tx_ctrl *tx_ctrl;
+
+ if (!mwl_tx_available(priv, num))
+ break;
+
+ tx_skb = skb_dequeue(&priv->txq[num]);
+ tx_info = IEEE80211_SKB_CB(tx_skb);
+ tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
+
+ if ((tx_skb->protocol != cpu_to_be16(ETH_P_PAE)) &&
+ (tx_ctrl->tx_priority >= SYSADPT_TX_WMM_QUEUES)) {
+ tx_skb = mwl_tx_do_amsdu(priv, num,
+ tx_skb, tx_info);
+ }
+
+ if (tx_skb) {
+ if (mwl_tx_available(priv, num))
+ mwl_tx_skb(priv, num, tx_skb);
+ else
+ skb_queue_head(&priv->txq[num], tx_skb);
+ }
+ }
+
+ if (skb_queue_len(&priv->txq[num]) <
+ SYSADPT_TX_WAKE_Q_THRESHOLD) {
+ int queue;
+
+ queue = SYSADPT_TX_WMM_QUEUES - num - 1;
+ if (ieee80211_queue_stopped(hw, queue))
+ ieee80211_wake_queue(hw, queue);
+ }
+ }
+ spin_unlock_bh(&priv->tx_desc_lock);
+}
+
void mwl_tx_done(unsigned long data)
{
struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
@@ -1108,6 +1107,12 @@ void mwl_tx_done(unsigned long data)
tx_hndl = desc->pstale_tx_hndl;
tx_desc = tx_hndl->pdesc;
+ if ((tx_desc->status &
+ cpu_to_le32(EAGLE_TXD_STATUS_FW_OWNED)) &&
+ (tx_hndl->pnext->pdesc->status &
+ cpu_to_le32(EAGLE_TXD_STATUS_OK)))
+ tx_desc->status = cpu_to_le32(EAGLE_TXD_STATUS_OK);
+
while (tx_hndl &&
(tx_desc->status & cpu_to_le32(EAGLE_TXD_STATUS_OK)) &&
(!(tx_desc->status &
@@ -1118,6 +1123,7 @@ void mwl_tx_done(unsigned long data)
PCI_DMA_TODEVICE);
done_skb = tx_hndl->psk_buff;
rate = le32_to_cpu(tx_desc->rate_info);
+ tx_desc->pkt_ptr = 0;
tx_desc->pkt_len = 0;
tx_desc->status =
cpu_to_le32(EAGLE_TXD_STATUS_IDLE);
@@ -1169,7 +1175,7 @@ void mwl_tx_done(unsigned long data)
}
spin_unlock_bh(&priv->tx_desc_lock);
- if (priv->irq != -1) {
+ if (priv->is_tx_done_schedule) {
u32 status_mask;
status_mask = readl(priv->iobase1 +
@@ -1177,10 +1183,9 @@ void mwl_tx_done(unsigned long data)
writel(status_mask | MACREG_A2HRIC_BIT_TX_DONE,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
- mwl_tx_skbs(hw);
+ tasklet_schedule(&priv->tx_task);
+ priv->is_tx_done_schedule = false;
}
-
- priv->is_tx_schedule = false;
}
void mwl_tx_flush_amsdu(unsigned long data)