[PATCH 7/7] Return TXed frames to mac80211.
Pontus Fuchs
pontus.fuchs at gmail.com
Tue May 28 10:59:09 EDT 2013
On TX done IRQ reap all transferred skbs.
Signed-off-by: Pontus Fuchs <pontus.fuchs at gmail.com>
---
dxe.c | 31 +++++++++++++++++++++++++++----
dxe.h | 3 +++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/dxe.c b/dxe.c
index 0da108e..8e7f576 100644
--- a/dxe.c
+++ b/dxe.c
@@ -262,6 +262,25 @@ static void wcn36xx_dxe_ch_free_skbs(struct wcn36xx *wcn,
}
}
+static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
+{
+ struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl;
+ struct ieee80211_tx_info *info;
+
+ while (ctl != ch->head_blk_ctl &&
+ !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) {
+ if (ctl->skb) {
+ info = IEEE80211_SKB_CB(ctl->skb);
+ ieee80211_tx_info_clear_status(info);
+ dma_unmap_single(NULL, ctl->desc->src_addr_l,
+ ctl->skb->len, DMA_TO_DEVICE);
+ ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb);
+ ctl->skb = NULL;
+ }
+ ctl = ctl->next;
+ }
+ ch->tail_blk_ctl = ctl;
+}
static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
{
struct wcn36xx *wcn = (struct wcn36xx *)dev;
@@ -281,6 +300,7 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_INT_END_CLR_ADDR,
WCN36XX_INT_MASK_CHAN_TX_H);
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high");
+ reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch);
}
if (int_src & WCN36XX_INT_MASK_CHAN_TX_L) {
wcn36xx_dxe_read_register(wcn,
@@ -294,6 +314,7 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_INT_END_CLR_ADDR,
WCN36XX_INT_MASK_CHAN_TX_L);
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low");
+ reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch);
}
return IRQ_HANDLED;
@@ -482,6 +503,7 @@ int wcn36xx_dxe_tx(struct wcn36xx *wcn,
ch = is_high ? &wcn->dxe_tx_h_ch : &wcn->dxe_tx_l_ch;
ctl = ch->head_blk_ctl;
+ ctl->skb = NULL;
desc = ctl->desc;
BUG_ON(!ctl->bd_cpu_addr);
@@ -512,11 +534,12 @@ int wcn36xx_dxe_tx(struct wcn36xx *wcn,
ctl = ctl->next;
ctl->skb = skb;
desc = ctl->desc;
+ BUG_ON(ctl->bd_cpu_addr);
- desc->src_addr_l = (int)dma_map_single(NULL,
- ctl->skb->data,
- ctl->skb->len,
- DMA_TO_DEVICE );
+ desc->src_addr_l = dma_map_single(NULL,
+ ctl->skb->data,
+ ctl->skb->len,
+ DMA_TO_DEVICE);
desc->dst_addr_l = ch->dxe_wq;
desc->fr_len = ctl->skb->len;
diff --git a/dxe.h b/dxe.h
index 62cefe9..ba05de9 100644
--- a/dxe.h
+++ b/dxe.h
@@ -168,6 +168,9 @@ struct wcn36xx_dxe_desc
u32 phy_next_h;
} __packed;
+/* DXE descriptor control (ctrl) fields */
+#define WCN36XX_DXE_CTRL_VALID_MASK 0x00000001
+
// DXE Control block
struct wcn36xx_dxe_ctl {
struct wcn36xx_dxe_ctl *next;
--
1.8.1.2
More information about the wcn36xx
mailing list