aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath9k/recv.c57
1 files changed, 26 insertions, 31 deletions
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 20f83779278a..6eae2542392a 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -81,29 +81,6 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
81 return skb; 81 return skb;
82} 82}
83 83
84static void ath_rx_requeue(struct ath_softc *sc, struct ath_buf *bf)
85{
86 struct sk_buff *skb;
87
88 ASSERT(bf != NULL);
89
90 if (bf->bf_mpdu == NULL) {
91 skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
92 if (skb != NULL) {
93 bf->bf_mpdu = skb;
94 bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
95 skb_end_pointer(skb) - skb->head,
96 PCI_DMA_FROMDEVICE);
97 bf->bf_dmacontext = bf->bf_buf_addr;
98
99 }
100 }
101
102 list_move_tail(&bf->list, &sc->sc_rxbuf);
103 ath_rx_buf_link(sc, bf);
104}
105
106
107static int ath_rate2idx(struct ath_softc *sc, int rate) 84static int ath_rate2idx(struct ath_softc *sc, int rate)
108{ 85{
109 int i = 0, cur_band, n_rates; 86 int i = 0, cur_band, n_rates;
@@ -445,7 +422,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
445 422
446 struct ath_buf *bf; 423 struct ath_buf *bf;
447 struct ath_desc *ds; 424 struct ath_desc *ds;
448 struct sk_buff *skb = NULL; 425 struct sk_buff *skb = NULL, *requeue_skb;
449 struct ieee80211_rx_status rx_status; 426 struct ieee80211_rx_status rx_status;
450 struct ath_hal *ah = sc->sc_ah; 427 struct ath_hal *ah = sc->sc_ah;
451 struct ieee80211_hdr *hdr; 428 struct ieee80211_hdr *hdr;
@@ -522,17 +499,28 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
522 * chain it back at the queue without processing it. 499 * chain it back at the queue without processing it.
523 */ 500 */
524 if (flush) 501 if (flush)
525 goto rx_next; 502 goto requeue;
526 503
527 if (!ds->ds_rxstat.rs_datalen) 504 if (!ds->ds_rxstat.rs_datalen)
528 goto rx_next; 505 goto requeue;
529 506
530 /* The status portion of the descriptor could get corrupted. */ 507 /* The status portion of the descriptor could get corrupted. */
531 if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen) 508 if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
532 goto rx_next; 509 goto requeue;
533 510
534 if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) 511 if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
535 goto rx_next; 512 goto requeue;
513
514 /* Ensure we always have an skb to requeue once we are done
515 * processing the current buffer's skb */
516 requeue_skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
517
518 /* If there is no memory we ignore the current RX'd frame,
519 * tell hardware it can give us a new frame using the old
520 * skb and put it at the tail of the sc->sc_rxbuf list for
521 * processing. */
522 if (!requeue_skb)
523 goto requeue;
536 524
537 /* Sync and unmap the frame */ 525 /* Sync and unmap the frame */
538 pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, 526 pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
@@ -569,7 +557,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
569 557
570 /* Send the frame to mac80211 */ 558 /* Send the frame to mac80211 */
571 __ieee80211_rx(sc->hw, skb, &rx_status); 559 __ieee80211_rx(sc->hw, skb, &rx_status);
572 bf->bf_mpdu = NULL; 560
561 /* We will now give hardware our shiny new allocated skb */
562 bf->bf_mpdu = requeue_skb;
563 bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
564 sc->sc_rxbufsize,
565 PCI_DMA_FROMDEVICE);
566 bf->bf_dmacontext = bf->bf_buf_addr;
573 567
574 /* 568 /*
575 * change the default rx antenna if rx diversity chooses the 569 * change the default rx antenna if rx diversity chooses the
@@ -581,8 +575,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
581 } else { 575 } else {
582 sc->sc_rxotherant = 0; 576 sc->sc_rxotherant = 0;
583 } 577 }
584rx_next: 578requeue:
585 ath_rx_requeue(sc, bf); 579 list_move_tail(&bf->list, &sc->sc_rxbuf);
580 ath_rx_buf_link(sc, bf);
586 } while (1); 581 } while (1);
587 582
588 spin_unlock_bh(&sc->sc_rxbuflock); 583 spin_unlock_bh(&sc->sc_rxbuflock);