[PATCH 3/4] dxe: Free mem pools and ctrl blocks

Pontus Fuchs pontus.fuchs at gmail.com
Thu May 23 05:20:46 EDT 2013


Signed-off-by: Pontus Fuchs <pontus.fuchs at gmail.com>
---
 dxe.c  | 41 ++++++++++++++++++++++++++++++++++++++++-
 dxe.h  |  2 ++
 main.c |  5 +++++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/dxe.c b/dxe.c
index 8d798f2..70dd603 100644
--- a/dxe.c
+++ b/dxe.c
@@ -78,9 +78,9 @@ static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch)
 		cur_dxe_ctl->frame = NULL;
 		cur_dxe_ctl->ctl_blk_order = i;
 
+		ch->tail_blk_ctl = cur_dxe_ctl;
 		if (i == 0) {
 			ch->head_blk_ctl = cur_dxe_ctl;
-			ch->tail_blk_ctl = cur_dxe_ctl;
 		} else if (ch->desc_num - 1 == i){
 			prev_dxe_ctl->next = cur_dxe_ctl;
 			cur_dxe_ctl->next = ch->head_blk_ctl;
@@ -92,6 +92,18 @@ static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch)
 	return 0;
 }
 
+static void wcn36xx_dxe_free_ctl_block(struct wcn36xx_dxe_ch *ch)
+{
+	struct wcn36xx_dxe_ctl *cur_dxe_ctl = ch->head_blk_ctl, *next;
+	while (1) {
+		next = cur_dxe_ctl->next;
+		kfree(cur_dxe_ctl);
+		if (ch->tail_blk_ctl == cur_dxe_ctl)
+			break;
+		cur_dxe_ctl = next;
+	}
+}
+
 int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
 {
 	int ret = 0;
@@ -122,6 +134,7 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
 	wcn->dxe_tx_h_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_H;
 
 	//DEX control block allocation
+	//TODO: Error handling
 	wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_l_ch);
 	wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_h_ch);
 	wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_l_ch);
@@ -136,6 +149,14 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
 	return ret;
 }
 
+void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn)
+{
+	wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_l_ch);
+	wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_h_ch);
+	wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_l_ch);
+	wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_h_ch);
+}
+
 static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch)
 {
 	struct wcn36xx_dxe_desc *cur_dxe_desc = NULL;
@@ -391,6 +412,24 @@ int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn)
 		sizeof(u32), GFP_KERNEL);
 	return 0;
 }
+
+void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn)
+{
+	if (wcn->mgmt_mem_pool.virt_addr)
+		dma_free_coherent(NULL, wcn->mgmt_mem_pool.chunk_size *
+				  WCN36XX_DXE_CH_DESC_NUMB_TX_H,
+				  wcn->mgmt_mem_pool.virt_addr,
+				  (dma_addr_t) wcn->data_mem_pool.phy_addr);
+	if (wcn->data_mem_pool.virt_addr) {
+		dma_free_coherent(NULL, wcn->data_mem_pool.chunk_size *
+				  WCN36XX_DXE_CH_DESC_NUMB_TX_L,
+				  wcn->data_mem_pool.virt_addr,
+				  (dma_addr_t) wcn->data_mem_pool.phy_addr);
+	}
+	kfree(wcn->data_mem_pool.bitmap);
+	kfree(wcn->mgmt_mem_pool.bitmap);
+}
+
 int wcn36xx_dxe_tx(struct wcn36xx *wcn, struct sk_buff *skb, u8 broadcast, bool is_high)
 {
 	struct wcn36xx_dxe_ctl *cur_dxe_ctl = NULL;
diff --git a/dxe.h b/dxe.h
index 2bdc8b8..f67a89d 100644
--- a/dxe.h
+++ b/dxe.h
@@ -229,8 +229,10 @@ struct wcn36xx_dxe_mem_pool {
 };
 struct wcn36xx;
 int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
+void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
 void wcn36xx_rx_ready_work(struct work_struct *work);
 int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn);
+void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn);
 int wcn36xx_dxe_init(struct wcn36xx *wcn);
 void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
 int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
diff --git a/main.c b/main.c
index ab5ceed..166812f 100644
--- a/main.c
+++ b/main.c
@@ -84,6 +84,11 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
 	wcn36xx_dxe_deinit(wcn);
 	wcn36xx_smd_close(wcn);
 
+	wcn36xx_dxe_free_mem_pools(wcn);
+	wcn36xx_dxe_free_ctl_blks(wcn);
+
+	release_firmware(wcn->nv);
+
 	kfree(wcn->smd_buf);
 }
 
-- 
1.8.1.2




More information about the wcn36xx mailing list