aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-03-03 09:17:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-07 13:51:38 -0500
commit3a2923e83c6036f55ad4a39c8ee9a7d4accd9539 (patch)
treecfb344bda144fe1198aca0736b0ed03182435c7d /drivers/net/wireless/ath/ath9k
parentfc16fd8808968063929bbb198eb8bb46d40e36ce (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.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c45
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
300struct ath_rx_edma { 300struct 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)
227static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) 227static 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
655static bool ath_edma_get_buffers(struct ath_softc *sc, 654static 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
723static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, 722static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,