Commit 3a2923e8 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k: get rid of double queueing of rx frames on EDMA

Process rx status directly instead of separating the completion test from
the actual rx status processing.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fc16fd88
...@@ -436,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, ...@@ -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; struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
unsigned int phyerr; unsigned int phyerr;
/* TODO: byte swap on big endian for ar9300_10 */ if ((rxsp->status11 & AR_RxDone) == 0)
return -EINPROGRESS;
if (!rxs) {
if ((rxsp->status11 & AR_RxDone) == 0)
return -EINPROGRESS;
if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
return -EINVAL;
if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
return -EINPROGRESS; return -EINVAL;
return 0; if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
} return -EINPROGRESS;
rxs->rs_status = 0; rxs->rs_status = 0;
rxs->rs_flags = 0; rxs->rs_flags = 0;
......
...@@ -299,7 +299,6 @@ struct ath_tx { ...@@ -299,7 +299,6 @@ struct ath_tx {
struct ath_rx_edma { struct ath_rx_edma {
struct sk_buff_head rx_fifo; struct sk_buff_head rx_fifo;
struct sk_buff_head rx_buffers;
u32 rx_fifo_hwsize; u32 rx_fifo_hwsize;
}; };
......
...@@ -227,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) ...@@ -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) 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_fifo);
skb_queue_head_init(&rx_edma->rx_buffers);
rx_edma->rx_fifo_hwsize = size; rx_edma->rx_fifo_hwsize = size;
} }
...@@ -653,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) ...@@ -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, 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_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
...@@ -672,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, ...@@ -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, dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, DMA_FROM_DEVICE); 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) { if (ret == -EINPROGRESS) {
/*let device gain the buffer again*/ /*let device gain the buffer again*/
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
...@@ -685,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, ...@@ -685,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
/* corrupt descriptor, skip this one and the following one */ /* corrupt descriptor, skip this one and the following one */
list_add_tail(&bf->list, &sc->rx.rxbuf); list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype); ath_rx_edma_buf_link(sc, qtype);
skb = skb_peek(&rx_edma->rx_fifo);
if (!skb)
return true;
bf = SKB_CB_ATHBUF(skb); skb = skb_peek(&rx_edma->rx_fifo);
BUG_ON(!bf); if (skb) {
bf = SKB_CB_ATHBUF(skb);
BUG_ON(!bf);
__skb_unlink(skb, &rx_edma->rx_fifo); __skb_unlink(skb, &rx_edma->rx_fifo);
list_add_tail(&bf->list, &sc->rx.rxbuf); list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype); ath_rx_edma_buf_link(sc, qtype);
return true; } else {
bf = NULL;
}
} }
skb_queue_tail(&rx_edma->rx_buffers, skb);
*dest = bf;
return true; return true;
} }
...@@ -706,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, ...@@ -706,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
struct ath_rx_status *rs, struct ath_rx_status *rs,
enum ath9k_rx_qtype qtype) enum ath9k_rx_qtype qtype)
{ {
struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; struct ath_buf *bf = NULL;
struct sk_buff *skb;
struct ath_buf *bf;
while (ath_edma_get_buffers(sc, qtype)); while (ath_edma_get_buffers(sc, qtype, rs, &bf)) {
skb = __skb_dequeue(&rx_edma->rx_buffers); if (!bf)
if (!skb) continue;
return NULL;
bf = SKB_CB_ATHBUF(skb); return bf;
ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); }
return bf; return NULL;
} }
static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment