Skip to content

Commit

Permalink
ath9k: get rid of double queueing of rx frames on EDMA
Browse files Browse the repository at this point in the history
Process rx status directly instead of separating the completion test from
the actual rx status processing.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Felix Fietkau authored and John W. Linville committed Mar 7, 2012
1 parent fc16fd8 commit 3a2923e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 36 deletions.
18 changes: 6 additions & 12 deletions drivers/net/wireless/ath/ath9k/ar9003_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
unsigned int phyerr;

/* TODO: byte swap on big endian for ar9300_10 */

if (!rxs) {
if ((rxsp->status11 & AR_RxDone) == 0)
return -EINPROGRESS;

if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
return -EINVAL;
if ((rxsp->status11 & AR_RxDone) == 0)
return -EINPROGRESS;

if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
return -EINPROGRESS;
if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
return -EINVAL;

return 0;
}
if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
return -EINPROGRESS;

rxs->rs_status = 0;
rxs->rs_flags = 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ struct ath_tx {

struct ath_rx_edma {
struct sk_buff_head rx_fifo;
struct sk_buff_head rx_buffers;
u32 rx_fifo_hwsize;
};

Expand Down
45 changes: 22 additions & 23 deletions drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc)
static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
{
skb_queue_head_init(&rx_edma->rx_fifo);
skb_queue_head_init(&rx_edma->rx_buffers);
rx_edma->rx_fifo_hwsize = size;
}

Expand Down Expand Up @@ -653,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
}

static bool ath_edma_get_buffers(struct ath_softc *sc,
enum ath9k_rx_qtype qtype)
enum ath9k_rx_qtype qtype,
struct ath_rx_status *rs,
struct ath_buf **dest)
{
struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
struct ath_hw *ah = sc->sc_ah;
Expand All @@ -672,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, DMA_FROM_DEVICE);

ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data);
if (ret == -EINPROGRESS) {
/*let device gain the buffer again*/
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
Expand All @@ -685,39 +686,37 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
/* corrupt descriptor, skip this one and the following one */
list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype);
skb = skb_peek(&rx_edma->rx_fifo);
if (!skb)
return true;

bf = SKB_CB_ATHBUF(skb);
BUG_ON(!bf);
skb = skb_peek(&rx_edma->rx_fifo);
if (skb) {
bf = SKB_CB_ATHBUF(skb);
BUG_ON(!bf);

__skb_unlink(skb, &rx_edma->rx_fifo);
list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype);
return true;
__skb_unlink(skb, &rx_edma->rx_fifo);
list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype);
} else {
bf = NULL;
}
}
skb_queue_tail(&rx_edma->rx_buffers, skb);

*dest = bf;
return true;
}

static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
struct ath_rx_status *rs,
enum ath9k_rx_qtype qtype)
{
struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
struct sk_buff *skb;
struct ath_buf *bf;
struct ath_buf *bf = NULL;

while (ath_edma_get_buffers(sc, qtype));
skb = __skb_dequeue(&rx_edma->rx_buffers);
if (!skb)
return NULL;
while (ath_edma_get_buffers(sc, qtype, rs, &bf)) {
if (!bf)
continue;

bf = SKB_CB_ATHBUF(skb);
ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
return bf;
return bf;
}
return NULL;
}

static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
Expand Down

0 comments on commit 3a2923e

Please sign in to comment.