[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