X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=carlfw%2Fsrc%2Fdma.c;h=9a6cc0caa22e2280ec86af7d408a48943f2d0235;hb=b94cc57fa4ee29cb70415b699a1efc5f66eb41c7;hp=3da9f8c328c1de3cbd66c478f764bfcc43fb38b9;hpb=e72388a0aa23da8bc8e24a0cbe9d523c5a9ce294;p=carl9170fw.git diff --git a/carlfw/src/dma.c b/carlfw/src/dma.c index 3da9f8c..9a6cc0c 100644 --- a/carlfw/src/dma.c +++ b/carlfw/src/dma.c @@ -6,7 +6,7 @@ * Copyright (c) 2000-2005 ZyDAS Technology Corporation * Copyright (c) 2007-2009 Atheros Communications, Inc. * Copyright 2009 Johannes Berg - * Copyright 2009, 2010 Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * with this program; If not, see . */ #include "carl9170.h" #include "wl.h" #include "printf.h" -struct ar9170_dma_memory dma_mem __section(sram); +struct ar9170_dma_memory dma_mem __in_section(sram); static void copy_dma_desc(struct dma_desc *dst, struct dma_desc *src) @@ -57,6 +56,11 @@ static void fill_descriptor(struct dma_desc *d, uint16_t size, uint8_t *data) d->nextAddr = NULL; } +static void init_queue(struct dma_queue *q, struct dma_desc *d) +{ + q->head = q->terminator = d; +} + /* * - Init up_queue, down_queue, tx_queue[5], rx_queue. * - Setup descriptors and data buffer address. @@ -74,27 +78,19 @@ void dma_init_descriptors(void) /* Assign terminators to DMA queues */ i = 0; - fw.pta.up_queue.head = fw.pta.up_queue.terminator = &dma_mem.terminator[i++]; - fw.pta.down_queue.head = fw.pta.down_queue.terminator = &dma_mem.terminator[i++]; + init_queue(&fw.pta.up_queue, &dma_mem.terminator[i++]); + init_queue(&fw.pta.down_queue, &dma_mem.terminator[i++]); for (j = 0; j < __AR9170_NUM_TX_QUEUES; j++) - fw.wlan.tx_queue[j].head = fw.wlan.tx_queue[j].terminator = &dma_mem.terminator[i++]; - fw.wlan.rx_queue.head = fw.wlan.rx_queue.terminator = &dma_mem.terminator[i++]; + init_queue(&fw.wlan.tx_queue[j], &dma_mem.terminator[i++]); + init_queue(&fw.wlan.tx_retry, &dma_mem.terminator[i++]); + init_queue(&fw.wlan.rx_queue, &dma_mem.terminator[i++]); fw.usb.int_desc = &dma_mem.terminator[i++]; + fw.wlan.fw_desc = &dma_mem.terminator[i++]; -#ifdef CONFIG_CARL9170FW_CAB_QUEUE - fw.wlan.cab_queue.head = fw.wlan.cab_queue.terminator = &dma_mem.terminator[i++]; -#endif /* CONFIG_CARL9170FW_CAB_QUEUE */ - -#ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ - fw.wlan.ba_desc = &dma_mem.terminator[i++]; -#endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */ + for (j = 0; j < CARL9170_INTF_NUM; j++) + init_queue(&fw.wlan.cab_queue[j], &dma_mem.terminator[i++]); -#ifdef CONFIG_CARL9170FW_DELAYED_TX - fw.wlan.tx_retry.head = fw.wlan.tx_retry.terminator = &dma_mem.terminator[i++]; - - for (j = 0; j < __AR9170_NUM_TX_QUEUES; j++) - fw.wlan.tx_delay[j].head = fw.wlan.tx_delay[j].terminator = &dma_mem.terminator[i++]; -#endif /* CONFIG_CARL9170FW_DELAYED_TX */ + BUG_ON(AR9170_TERMINATOR_NUMBER != i); DBG("Blocks:%d [tx:%d, rx:%d] Terminators:%d/%d\n", AR9170_BLOCK_NUMBER, AR9170_TX_BLOCK_NUMBER, @@ -120,14 +116,8 @@ void dma_init_descriptors(void) set_wlan_txq_dma_addr(i, (uint32_t) fw.wlan.tx_queue[i].head); set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head); - - fw.usb.int_desc->status = AR9170_OWN_BITS_SW; - fw.usb.int_desc->ctrl = (AR9170_CTRL_LS_BIT | AR9170_CTRL_FS_BIT); fw.usb.int_desc->dataSize = AR9170_BLOCK_SIZE; - fw.usb.int_desc->totalLen = 0; - fw.usb.int_desc->lastAddr = fw.usb.int_desc; fw.usb.int_desc->dataAddr = (void *) &dma_mem.reserved.rsp; - fw.usb.int_desc->nextAddr = (void *) 0; memset(DESC_PAYLOAD(fw.usb.int_desc), 0xff, AR9170_INT_MAGIC_HEADER_SIZE); @@ -137,21 +127,8 @@ void dma_init_descriptors(void) /* rsp is now available for use */ fw.usb.int_desc_available = 1; -#ifdef CONFIG_CARL9170FW_HANDLE_BACK_REQ - fw.wlan.ba_desc->status = AR9170_OWN_BITS_SW; - fw.wlan.ba_desc->ctrl = (AR9170_CTRL_LS_BIT | AR9170_CTRL_FS_BIT); - fw.wlan.ba_desc->dataSize = fw.wlan.ba_desc->totalLen = - sizeof(struct carl9170_tx_superdesc) + - sizeof(struct ar9170_tx_hwdesc) + - sizeof(struct ieee80211_ba) + FCS_LEN; - fw.wlan.ba_desc->lastAddr = fw.wlan.ba_desc; - fw.wlan.ba_desc->nextAddr = fw.wlan.ba_desc; - fw.wlan.ba_desc->dataAddr = (void *) &dma_mem.reserved.ba; - - memset(DESC_PAYLOAD(fw.wlan.ba_desc), 0, 128); - - fw.wlan.ba_desc_available = 1; -#endif /* CONFIG_CARL9170FW_HANDLE_BACK_REQ */ + memset(DESC_PAYLOAD(fw.wlan.fw_desc), 0, 128); + fw.wlan.fw_desc_available = 1; } /* @@ -162,11 +139,13 @@ void dma_init_descriptors(void) */ void dma_reclaim(struct dma_queue *q, struct dma_desc *desc) { - struct dma_desc *tmpDesc; + struct dma_desc *tmpDesc, *last; struct dma_desc tdesc; /* 1. Set OWN bit to HW for all TDs to be added, clear ctrl and size */ tmpDesc = desc; + last = desc->lastAddr; + while (1) { tmpDesc->status = AR9170_OWN_BITS_HW; tmpDesc->ctrl = 0; @@ -175,24 +154,28 @@ void dma_reclaim(struct dma_queue *q, struct dma_desc *desc) /* TODO : Exception handle */ - if (desc->lastAddr == tmpDesc) + tmpDesc->lastAddr = tmpDesc; + + if (tmpDesc == last) break; - tmpDesc->lastAddr = desc->lastAddr; tmpDesc = tmpDesc->nextAddr; } /* 2. Next address of Last TD to be added = first TD */ - desc->lastAddr->nextAddr = desc; + tmpDesc->nextAddr = desc; + + /* Link first TD to self */ + desc->lastAddr = q->terminator; /* 3. Copy first TD to be added to TTD */ copy_dma_desc(&tdesc, desc); - /* 4. set first TD OWN bit to SW */ - desc->status = AR9170_OWN_BITS_SW; + /* 4. Initialize new terminator */ + clear_descriptor(desc); /* 5. Copy TTD to last TD */ - tdesc.status &= (~AR9170_OWN_BITS_MASK); + tdesc.status = 0; copy_dma_desc((void *)q->terminator, (void *)&tdesc); q->terminator->status |= AR9170_OWN_BITS_HW; @@ -212,9 +195,6 @@ void dma_put(struct dma_queue *q, struct dma_desc *desc) tmpDesc = desc; - /* force correct CTRL_BITS */ - tmpDesc->ctrl = 0; - tmpDesc->ctrl |= AR9170_CTRL_FS_BIT; while (1) { /* update totalLen */ tmpDesc->totalLen = desc->totalLen; @@ -229,9 +209,7 @@ void dma_put(struct dma_queue *q, struct dma_desc *desc) break; tmpDesc = tmpDesc->nextAddr; - tmpDesc->ctrl = 0; } - tmpDesc->ctrl |= AR9170_CTRL_LS_BIT; /* 2. Next address of Last TD to be added = first TD */ desc->lastAddr->nextAddr = desc; @@ -243,17 +221,11 @@ void dma_put(struct dma_queue *q, struct dma_desc *desc) /* 3. Copy first TD to be added to TTD */ copy_dma_desc(&tdesc, desc); - /* 4. set first TD OWN bit to SW */ - desc->status = AR9170_OWN_BITS_SW; - desc->ctrl = 0; - desc->totalLen = 0; - desc->dataSize = 0; - desc->lastAddr = desc; - desc->nextAddr = desc; - desc->dataAddr = NULL; + /* 4. Initialize new terminator */ + clear_descriptor(desc); /* 5. Copy TTD to last TD */ - tdesc.status &= (~AR9170_OWN_BITS_MASK); + tdesc.status &= (~AR9170_OWN_BITS); copy_dma_desc((void *)q->terminator, (void *)&tdesc); q->terminator->status |= AR9170_OWN_BITS_HW;