diff options
author | Felix Fietkau <nbd@openwrt.org> | 2012-03-03 09:17:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-07 13:51:38 -0500 |
commit | 3a2923e83c6036f55ad4a39c8ee9a7d4accd9539 (patch) | |
tree | cfb344bda144fe1198aca0736b0ed03182435c7d /drivers/net/wireless/ath/ath9k | |
parent | fc16fd8808968063929bbb198eb8bb46d40e36ce (diff) |
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: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mac.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 45 |
3 files changed, 28 insertions, 36 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 01d5c1a4d746..a66a13b76848 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -436,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, | |||
436 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; | 436 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; |
437 | unsigned int phyerr; | 437 | unsigned int phyerr; |
438 | 438 | ||
439 | /* TODO: byte swap on big endian for ar9300_10 */ | 439 | if ((rxsp->status11 & AR_RxDone) == 0) |
440 | 440 | return -EINPROGRESS; | |
441 | if (!rxs) { | ||
442 | if ((rxsp->status11 & AR_RxDone) == 0) | ||
443 | return -EINPROGRESS; | ||
444 | |||
445 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) | ||
446 | return -EINVAL; | ||
447 | 441 | ||
448 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) | 442 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) |
449 | return -EINPROGRESS; | 443 | return -EINVAL; |
450 | 444 | ||
451 | return 0; | 445 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) |
452 | } | 446 | return -EINPROGRESS; |
453 | 447 | ||
454 | rxs->rs_status = 0; | 448 | rxs->rs_status = 0; |
455 | rxs->rs_flags = 0; | 449 | rxs->rs_flags = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ccba676eca..3d8e51cd5d8f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -299,7 +299,6 @@ struct ath_tx { | |||
299 | 299 | ||
300 | struct ath_rx_edma { | 300 | struct ath_rx_edma { |
301 | struct sk_buff_head rx_fifo; | 301 | struct sk_buff_head rx_fifo; |
302 | struct sk_buff_head rx_buffers; | ||
303 | u32 rx_fifo_hwsize; | 302 | u32 rx_fifo_hwsize; |
304 | }; | 303 | }; |
305 | 304 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 4633f513a80b..c95b77cdf3bb 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -227,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) | |||
227 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) | 227 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) |
228 | { | 228 | { |
229 | skb_queue_head_init(&rx_edma->rx_fifo); | 229 | skb_queue_head_init(&rx_edma->rx_fifo); |
230 | skb_queue_head_init(&rx_edma->rx_buffers); | ||
231 | rx_edma->rx_fifo_hwsize = size; | 230 | rx_edma->rx_fifo_hwsize = size; |
232 | } | 231 | } |
233 | 232 | ||
@@ -653,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
653 | } | 652 | } |
654 | 653 | ||
655 | static bool ath_edma_get_buffers(struct ath_softc *sc, | 654 | static bool ath_edma_get_buffers(struct ath_softc *sc, |
656 | enum ath9k_rx_qtype qtype) | 655 | enum ath9k_rx_qtype qtype, |
656 | struct ath_rx_status *rs, | ||
657 | struct ath_buf **dest) | ||
657 | { | 658 | { |
658 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 659 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; |
659 | struct ath_hw *ah = sc->sc_ah; | 660 | struct ath_hw *ah = sc->sc_ah; |
@@ -672,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
672 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | 673 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
673 | common->rx_bufsize, DMA_FROM_DEVICE); | 674 | common->rx_bufsize, DMA_FROM_DEVICE); |
674 | 675 | ||
675 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); | 676 | ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); |
676 | if (ret == -EINPROGRESS) { | 677 | if (ret == -EINPROGRESS) { |
677 | /*let device gain the buffer again*/ | 678 | /*let device gain the buffer again*/ |
678 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | 679 | 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 | /* corrupt descriptor, skip this one and the following one */ | 686 | /* corrupt descriptor, skip this one and the following one */ |
686 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 687 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
687 | ath_rx_edma_buf_link(sc, qtype); | 688 | ath_rx_edma_buf_link(sc, qtype); |
688 | skb = skb_peek(&rx_edma->rx_fifo); | ||
689 | if (!skb) | ||
690 | return true; | ||
691 | 689 | ||
692 | bf = SKB_CB_ATHBUF(skb); | 690 | skb = skb_peek(&rx_edma->rx_fifo); |
693 | BUG_ON(!bf); | 691 | if (skb) { |
692 | bf = SKB_CB_ATHBUF(skb); | ||
693 | BUG_ON(!bf); | ||
694 | 694 | ||
695 | __skb_unlink(skb, &rx_edma->rx_fifo); | 695 | __skb_unlink(skb, &rx_edma->rx_fifo); |
696 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 696 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
697 | ath_rx_edma_buf_link(sc, qtype); | 697 | ath_rx_edma_buf_link(sc, qtype); |
698 | return true; | 698 | } else { |
699 | bf = NULL; | ||
700 | } | ||
699 | } | 701 | } |
700 | skb_queue_tail(&rx_edma->rx_buffers, skb); | ||
701 | 702 | ||
703 | *dest = bf; | ||
702 | return true; | 704 | return true; |
703 | } | 705 | } |
704 | 706 | ||
@@ -706,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, | |||
706 | struct ath_rx_status *rs, | 708 | struct ath_rx_status *rs, |
707 | enum ath9k_rx_qtype qtype) | 709 | enum ath9k_rx_qtype qtype) |
708 | { | 710 | { |
709 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 711 | struct ath_buf *bf = NULL; |
710 | struct sk_buff *skb; | ||
711 | struct ath_buf *bf; | ||
712 | 712 | ||
713 | while (ath_edma_get_buffers(sc, qtype)); | 713 | while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { |
714 | skb = __skb_dequeue(&rx_edma->rx_buffers); | 714 | if (!bf) |
715 | if (!skb) | 715 | continue; |
716 | return NULL; | ||
717 | 716 | ||
718 | bf = SKB_CB_ATHBUF(skb); | 717 | return bf; |
719 | ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); | 718 | } |
720 | return bf; | 719 | return NULL; |
721 | } | 720 | } |
722 | 721 | ||
723 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | 722 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, |