ath9k: improve dma map failure handling

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>
This commit is contained in:
Felix Fietkau 2013-04-08 00:04:10 +02:00 committed by John W. Linville
parent c60c99298c
commit 2e1cd49546
1 changed files with 13 additions and 17 deletions

View File

@ -1166,6 +1166,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
u64 tsf = 0; u64 tsf = 0;
u32 tsf_lower = 0; u32 tsf_lower = 0;
unsigned long flags; unsigned long flags;
dma_addr_t new_buf_addr;
if (edma) if (edma)
dma_type = DMA_BIDIRECTIONAL; dma_type = DMA_BIDIRECTIONAL;
@ -1264,10 +1265,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
goto requeue_drop_frag; 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 */ /* Unmap the frame */
dma_unmap_single(sc->dev, bf->bf_buf_addr, dma_unmap_single(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, common->rx_bufsize, dma_type);
dma_type);
skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
if (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, ath9k_rx_skb_postprocess(common, hdr_skb, &rs,
rxs, decrypt_error); 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) { if (rs.rs_more) {
RX_STAT_INC(rx_frags); RX_STAT_INC(rx_frags);
/* /*