]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/wireless/ath/ath9k/recv.c
ath9k: fix dma direction for map/unmap in ath_rx_tasklet
[net-next-2.6.git] / drivers / net / wireless / ath / ath9k / recv.c
index ac60c4ee62d3fb7c41858d6b78da17f86a62701d..e3e52913d83a49326e3319cd67e1a0275b302d39 100644 (file)
 
 #define SKB_CB_ATHBUF(__skb)   (*((struct ath_buf **)__skb->cb))
 
+static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
+{
+       return sc->ps_enabled &&
+              (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP);
+}
+
 static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
                                             struct ieee80211_hdr *hdr)
 {
@@ -150,11 +156,9 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
 static void ath_rx_addbuffer_edma(struct ath_softc *sc,
                                  enum ath9k_rx_qtype qtype, int size)
 {
-       struct ath_rx_edma *rx_edma;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        u32 nbuf = 0;
 
-       rx_edma = &sc->rx.rx_edma[qtype];
        if (list_empty(&sc->rx.rxbuf)) {
                ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
                return;
@@ -618,8 +622,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
        hdr = (struct ieee80211_hdr *)skb->data;
 
        /* Process Beacon and CAB receive in PS state */
-       if ((sc->ps_flags & PS_WAIT_FOR_BEACON) &&
-           ieee80211_is_beacon(hdr->frame_control))
+       if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc))
+           && ieee80211_is_beacon(hdr->frame_control))
                ath_rx_ps_beacon(sc, skb);
        else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
                 (ieee80211_is_data(hdr->frame_control) ||
@@ -718,6 +722,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
                __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_queue_tail(&rx_edma->rx_buffers, skb);
 
@@ -839,9 +844,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
        int dma_type;
 
        if (edma)
-               dma_type = DMA_FROM_DEVICE;
-       else
                dma_type = DMA_BIDIRECTIONAL;
+       else
+               dma_type = DMA_FROM_DEVICE;
 
        qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
        spin_lock_bh(&sc->rx.rxbuflock);
@@ -933,9 +938,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                        sc->rx.rxotherant = 0;
                }
 
-               if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON |
-                                            PS_WAIT_FOR_CAB |
-                                            PS_WAIT_FOR_PSPOLL_DATA)))
+               if (unlikely(ath9k_check_auto_sleep(sc) ||
+                            (sc->ps_flags & (PS_WAIT_FOR_BEACON |
+                                             PS_WAIT_FOR_CAB |
+                                             PS_WAIT_FOR_PSPOLL_DATA))))
                        ath_rx_ps(sc, skb);
 
                ath_rx_send_to_mac80211(hw, sc, skb, rxs);