ath9k: get rid of double queueing of rx frames on EDMA
authorFelix Fietkau <nbd@openwrt.org>
Sat, 3 Mar 2012 14:17:05 +0000 (15:17 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 7 Mar 2012 18:51:38 +0000 (13:51 -0500)
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>
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/recv.c

index 01d5c1a4d74678b9601aa868edd4a0d8415c7558..a66a13b768487746b96c1ebdca96c87df89681f4 100644 (file)
@@ -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;
index c2ccba676ecabc4b3f7976f2551a925d25a4837e..3d8e51cd5d8f1bbd9227fbf394433d3742193753 100644 (file)
@@ -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;
 };
 
index 4633f513a80b8da6e393c5b14ddf3c09560855df..c95b77cdf3bb63f56e1c268d977c513c057fe131 100644 (file)
@@ -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;
 }
 
@@ -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;
@@ -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,
@@ -685,20 +686,21 @@ 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;
 }
 
@@ -706,18 +708,15 @@ 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,