[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