Skip to content

Commit

Permalink
ath5k: fix error handling in ath5k_beacon_send
Browse files Browse the repository at this point in the history
This cleans up error handling for the beacon in case of dma mapping
failure.  We need to free the skb when dma mapping fails instead of
nulling and leaking the pointer, and we should bail out to avoid
giving the hardware the bad descriptor.

Finally, we need to perform the null check after trying to update
the beacon, or else beacons will never be sent after a single
mapping failure.

Cc: stable@kernel.org
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Bob Copeland authored and John W. Linville committed Aug 9, 2011
1 parent 276b02e commit bdc71bc
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,8 @@ ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)

if (dma_mapping_error(ah->dev, bf->skbaddr)) {
ATH5K_ERR(ah, "beacon DMA mapping failed\n");
dev_kfree_skb_any(skb);
bf->skb = NULL;
return -EIO;
}

Expand Down Expand Up @@ -1819,8 +1821,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
ath5k_txbuf_free_skb(ah, avf->bbuf);
avf->bbuf->skb = skb;
ret = ath5k_beacon_setup(ah, avf->bbuf);
if (ret)
avf->bbuf->skb = NULL;
out:
return ret;
}
Expand All @@ -1840,6 +1840,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
struct ath5k_vif *avf;
struct ath5k_buf *bf;
struct sk_buff *skb;
int err;

ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n");

Expand Down Expand Up @@ -1888,11 +1889,6 @@ ath5k_beacon_send(struct ath5k_hw *ah)

avf = (void *)vif->drv_priv;
bf = avf->bbuf;
if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION ||
ah->opmode == NL80211_IFTYPE_MONITOR)) {
ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
return;
}

/*
* Stop any current dma and put the new frame on the queue.
Expand All @@ -1906,8 +1902,17 @@ ath5k_beacon_send(struct ath5k_hw *ah)

/* refresh the beacon for AP or MESH mode */
if (ah->opmode == NL80211_IFTYPE_AP ||
ah->opmode == NL80211_IFTYPE_MESH_POINT)
ath5k_beacon_update(ah->hw, vif);
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
err = ath5k_beacon_update(ah->hw, vif);
if (err)
return;
}

if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION ||
ah->opmode == NL80211_IFTYPE_MONITOR)) {
ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf->skb);
return;
}

trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]);

Expand Down

0 comments on commit bdc71bc

Please sign in to comment.