diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-04-07 18:04:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-10 14:10:33 -0400 |
commit | 2e1cd495466d14c7d92e10d709f27161afe44b15 (patch) | |
tree | 5c15aa082527ce0f790cb2e38fbafa8346cff62e /drivers/net/wireless/ath/ath9k/recv.c | |
parent | c60c99298c50b698b0bbbe0e0146c965c322b8c1 (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d7c06af1778d..3d0f02ddcf5b 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1166,6 +1166,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1166 | u64 tsf = 0; | 1166 | u64 tsf = 0; |
1167 | u32 tsf_lower = 0; | 1167 | u32 tsf_lower = 0; |
1168 | unsigned long flags; | 1168 | unsigned long flags; |
1169 | dma_addr_t new_buf_addr; | ||
1169 | 1170 | ||
1170 | if (edma) | 1171 | if (edma) |
1171 | dma_type = DMA_BIDIRECTIONAL; | 1172 | dma_type = DMA_BIDIRECTIONAL; |
@@ -1264,10 +1265,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1264 | goto requeue_drop_frag; | 1265 | goto requeue_drop_frag; |
1265 | } | 1266 | } |
1266 | 1267 | ||
1268 | /* We will now give hardware our shiny new allocated skb */ | ||
1269 | new_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | ||
1270 | common->rx_bufsize, dma_type); | ||
1271 | if (unlikely(dma_mapping_error(sc->dev, new_buf_addr))) { | ||
1272 | dev_kfree_skb_any(requeue_skb); | ||
1273 | goto requeue_drop_frag; | ||
1274 | } | ||
1275 | |||
1276 | bf->bf_mpdu = requeue_skb; | ||
1277 | bf->bf_buf_addr = new_buf_addr; | ||
1278 | |||
1267 | /* Unmap the frame */ | 1279 | /* Unmap the frame */ |
1268 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 1280 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
1269 | common->rx_bufsize, | 1281 | common->rx_bufsize, dma_type); |
1270 | dma_type); | ||
1271 | 1282 | ||
1272 | skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); | 1283 | skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); |
1273 | if (ah->caps.rx_status_len) | 1284 | if (ah->caps.rx_status_len) |
@@ -1277,21 +1288,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1277 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, | 1288 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, |
1278 | rxs, decrypt_error); | 1289 | rxs, decrypt_error); |
1279 | 1290 | ||
1280 | /* We will now give hardware our shiny new allocated skb */ | ||
1281 | bf->bf_mpdu = requeue_skb; | ||
1282 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | ||
1283 | common->rx_bufsize, | ||
1284 | dma_type); | ||
1285 | if (unlikely(dma_mapping_error(sc->dev, | ||
1286 | bf->bf_buf_addr))) { | ||
1287 | dev_kfree_skb_any(requeue_skb); | ||
1288 | bf->bf_mpdu = NULL; | ||
1289 | bf->bf_buf_addr = 0; | ||
1290 | ath_err(common, "dma_mapping_error() on RX\n"); | ||
1291 | ieee80211_rx(hw, skb); | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | if (rs.rs_more) { | 1291 | if (rs.rs_more) { |
1296 | RX_STAT_INC(rx_frags); | 1292 | RX_STAT_INC(rx_frags); |
1297 | /* | 1293 | /* |