aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Haber <phaber@broadcom.com>2012-11-28 15:44:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-30 13:38:16 -0500
commitc4dea35e34f5f46e1701156153a09cce429d1ea9 (patch)
tree8548445b7d6e44c974a038ad146a07c26a5095f6
parent006a8f148690774d04965488415ee59269d061c3 (diff)
brcmsmac: handle packet drop during transmit correctly
The .tx() callback function can drop packets when there is no space in the DMA fifo. Propagate that information to caller and make sure the freed sk_buff reference is not accessed. Reviewed-by: Arend van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Piotr Haber <phaber@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h2
3 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 1710ccba8bac..f917d621acca 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -285,8 +285,8 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,
285 kfree_skb(skb); 285 kfree_skb(skb);
286 goto done; 286 goto done;
287 } 287 }
288 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); 288 if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
289 tx_info->rate_driver_data[0] = control->sta; 289 tx_info->rate_driver_data[0] = control->sta;
290 done: 290 done:
291 spin_unlock_bh(&wl->lock); 291 spin_unlock_bh(&wl->lock);
292} 292}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 2a44593f1e37..54ab2f70d362 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -6928,17 +6928,20 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
6928 return ret; 6928 return ret;
6929} 6929}
6930 6930
6931void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, 6931bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
6932 struct ieee80211_hw *hw) 6932 struct ieee80211_hw *hw)
6933{ 6933{
6934 uint fifo; 6934 uint fifo;
6935 struct scb *scb = &wlc->pri_scb; 6935 struct scb *scb = &wlc->pri_scb;
6936 6936
6937 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); 6937 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
6938 if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) 6938 brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
6939 return; 6939 if (!brcms_c_tx(wlc, sdu))
6940 if (brcms_c_tx(wlc, sdu)) 6940 return true;
6941 dev_kfree_skb_any(sdu); 6941
6942 /* packet discarded */
6943 dev_kfree_skb_any(sdu);
6944 return false;
6942} 6945}
6943 6946
6944int 6947int
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 0148dec104f0..0d7af349d864 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -284,7 +284,7 @@ extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
284extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); 284extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
285extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc); 285extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
286extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); 286extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
287extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, 287extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
288 struct sk_buff *sdu, 288 struct sk_buff *sdu,
289 struct ieee80211_hw *hw); 289 struct ieee80211_hw *hw);
290extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); 290extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);