[PATCH v2 7/9] Improve TX BD handling

Pontus Fuchs pontus.fuchs at gmail.com
Thu May 30 04:12:33 EDT 2013


The same BD was used for all TX's. Change this to use a pre-calculated
buffer address in the dxe ctl structure.

Signed-off-by: Pontus Fuchs <pontus.fuchs at gmail.com>
---
 dxe.c | 53 +++++++++++++++++++++++++++++++++++++++--------------
 dxe.h |  2 ++
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/dxe.c b/dxe.c
index 9b0573b..046bea4 100644
--- a/dxe.c
+++ b/dxe.c
@@ -191,6 +191,31 @@ static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch)
 	}
 	return 0;
 }
+
+static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch,
+				   struct wcn36xx_dxe_mem_pool *pool)
+{
+	int i, chunk_size = pool->chunk_size;
+	dma_addr_t bd_phy_addr = pool->phy_addr;
+	void *bd_cpu_addr = pool->virt_addr;
+
+	struct wcn36xx_dxe_ctl *cur = ch->head_blk_ctl;
+	for (i = 0; i < ch->desc_num; i++) {
+		/* Only every second dxe needs a bd pointer,
+		   the other will point to the skb data */
+		if (!(i & 1)) {
+			cur->bd_phy_addr = bd_phy_addr;
+			cur->bd_cpu_addr = bd_cpu_addr;
+			bd_phy_addr += chunk_size;
+			bd_cpu_addr += chunk_size;
+		} else {
+			cur->bd_phy_addr = 0;
+			cur->bd_cpu_addr = NULL;
+		}
+		cur = cur->next;
+	}
+}
+
 static int wcn36xx_dxe_enable_ch_int(struct wcn36xx *wcn, u16 wcn_ch)
 {
 	int reg_data = 0;
@@ -405,30 +430,27 @@ int wcn36xx_dxe_tx(struct wcn36xx *wcn,
 {
 	struct wcn36xx_dxe_ctl *ctl = NULL;
 	struct wcn36xx_dxe_desc *desc = NULL;
-	struct wcn36xx_dxe_mem_pool *mem_pool = NULL;
 	struct wcn36xx_dxe_ch *ch = NULL;
 
-	if(is_high) {
-		mem_pool = &wcn->mgmt_mem_pool;
-		ch = &wcn->dxe_tx_h_ch;
-	} else {
-		mem_pool = &wcn->data_mem_pool;
-		ch = &wcn->dxe_tx_l_ch;
-	}
+	ch = is_high ? &wcn->dxe_tx_h_ch : &wcn->dxe_tx_l_ch;
 
-	wcn36xx_prepare_tx_bd(mem_pool->virt_addr, skb->len, header_len);
+	ctl = ch->head_blk_ctl;
+	desc = ctl->desc;
+	BUG_ON(!ctl->bd_cpu_addr);
+
+	wcn36xx_prepare_tx_bd(ctl->bd_cpu_addr, skb->len, header_len);
 	if (!is_high && WCN36XX_BSS_KEY == wcn->en_state) {
 		wcn36xx_dbg(WCN36XX_DBG_DXE, "DXE Encription enabled");
-		wcn36xx_fill_tx_bd(wcn, mem_pool->virt_addr, broadcast, 0);
+		wcn36xx_fill_tx_bd(wcn, ctl->bd_cpu_addr, broadcast, 0);
 	} else {
-		wcn36xx_fill_tx_bd(wcn, mem_pool->virt_addr, broadcast, 1);
+		wcn36xx_fill_tx_bd(wcn, ctl->bd_cpu_addr, broadcast, 1);
 	}
 
 	ctl = ch->head_blk_ctl;
 	desc = ctl->desc;
 
 	// Set source address of the BD we send
-	desc->src_addr_l = (int)mem_pool->phy_addr;
+	desc->src_addr_l = ctl->bd_phy_addr;
 
 	desc->dst_addr_l = ch->dxe_wq;
 	desc->fr_len = sizeof(struct wcn36xx_tx_bd);
@@ -439,13 +461,14 @@ int wcn36xx_dxe_tx(struct wcn36xx *wcn,
 	wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC1 >>> ",
 			 (char *)desc, sizeof(*desc));
 	wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP,
-			 "BD   >>> ", (char *)mem_pool->virt_addr,
+			 "BD   >>> ", (char *)ctl->bd_cpu_addr,
 			 sizeof(struct wcn36xx_tx_bd));
 
 	// Set source address of the SKB we send
-	ctl = (struct wcn36xx_dxe_ctl *)ctl->next;
+	ctl = ctl->next;
 	ctl->skb = skb;
 	desc = ctl->desc;
+
 	desc->src_addr_l = (int)dma_map_single(NULL,
 		ctl->skb->data,
 		ctl->skb->len,
@@ -485,6 +508,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 	/* Init descriptors for TX LOW channel */
 	/***************************************/
 	wcn36xx_dxe_init_descs(&wcn->dxe_tx_l_ch);
+	wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_l_ch, &wcn->data_mem_pool);
 
 	// Write chanel head to a NEXT register
 	wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L,
@@ -502,6 +526,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 	/* Init descriptors for TX HIGH channel */
 	/***************************************/
 	wcn36xx_dxe_init_descs(&wcn->dxe_tx_h_ch);
+	wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_h_ch, &wcn->mgmt_mem_pool);
 
 	// Write chanel head to a NEXT register
 	wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H,
diff --git a/dxe.h b/dxe.h
index c17d145..b93f13a 100644
--- a/dxe.h
+++ b/dxe.h
@@ -195,6 +195,8 @@ struct wcn36xx_dxe_ctl {
 	unsigned int		desc_phy_addr;
 	int			ctl_blk_order;
 	struct sk_buff		*skb;
+	void			*bd_cpu_addr;
+	dma_addr_t		bd_phy_addr;
 };
 
 struct wcn36xx_dxe_ch {
-- 
1.8.1.2




More information about the wcn36xx mailing list