ath9k: improve dma map failure handling
authorFelix Fietkau <nbd@openwrt.org>
Sun, 7 Apr 2013 22:04:10 +0000 (00:04 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 10 Apr 2013 18:10:33 +0000 (14:10 -0400)
Instead of leaving the buffer without skb and breaking out of the loop
(which could leak the rx buffer), use the common error path.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/recv.c

index d7c06af..3d0f02d 100644 (file)
@@ -1166,6 +1166,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
        u64 tsf = 0;
        u32 tsf_lower = 0;
        unsigned long flags;
+       dma_addr_t new_buf_addr;
 
        if (edma)
                dma_type = DMA_BIDIRECTIONAL;
@@ -1264,10 +1265,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                        goto requeue_drop_frag;
                }
 
+               /* We will now give hardware our shiny new allocated skb */
+               new_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
+                                             common->rx_bufsize, dma_type);
+               if (unlikely(dma_mapping_error(sc->dev, new_buf_addr))) {
+                       dev_kfree_skb_any(requeue_skb);
+                       goto requeue_drop_frag;
+               }
+
+               bf->bf_mpdu = requeue_skb;
+               bf->bf_buf_addr = new_buf_addr;
+
                /* Unmap the frame */
                dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                common->rx_bufsize,
-                                dma_type);
+                                common->rx_bufsize, dma_type);
 
                skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
                if (ah->caps.rx_status_len)
@@ -1277,21 +1288,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                        ath9k_rx_skb_postprocess(common, hdr_skb, &rs,
                                                 rxs, decrypt_error);
 
-               /* We will now give hardware our shiny new allocated skb */
-               bf->bf_mpdu = requeue_skb;
-               bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
-                                                common->rx_bufsize,
-                                                dma_type);
-               if (unlikely(dma_mapping_error(sc->dev,
-                         bf->bf_buf_addr))) {
-                       dev_kfree_skb_any(requeue_skb);
-                       bf->bf_mpdu = NULL;
-                       bf->bf_buf_addr = 0;
-                       ath_err(common, "dma_mapping_error() on RX\n");
-                       ieee80211_rx(hw, skb);
-                       break;
-               }
-
                if (rs.rs_more) {
                        RX_STAT_INC(rx_frags);
                        /*