brcmsmac: handle packet drop during transmit correctly
authorPiotr Haber <phaber@broadcom.com>
Wed, 28 Nov 2012 20:44:05 +0000 (21:44 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Feb 2013 00:27:02 +0000 (18:27 -0600)
commit c4dea35e34f5f46e1701156153a09cce429d1ea9 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/brcm80211/brcmsmac/main.h
drivers/net/wireless/brcm80211/brcmsmac/pub.h

index 7d71315116cfcddf1e665a0d31c3780b79a4bde3..36014bf5df9a57631dea4f4a720f515253ed5d58 100644 (file)
@@ -280,8 +280,8 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,
                kfree_skb(skb);
                goto done;
        }
-       brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
-       tx_info->rate_driver_data[0] = control->sta;
+       if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
+               tx_info->rate_driver_data[0] = control->sta;
  done:
        spin_unlock_bh(&wl->lock);
 }
index 75086b37c817b747fe5482bb097a66a859c14214..9fb0a4c96b7878ff849e2fbbb086e32b4c33a44d 100644 (file)
@@ -6095,7 +6095,7 @@ static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
        return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
 }
 
-void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
+bool brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
                     struct sk_buff *sdu, uint prec)
 {
        struct brcms_txq_info *qi = wlc->pkt_queue;     /* Check me */
@@ -6110,7 +6110,9 @@ void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
                 * packet flooding from mac80211 stack
                 */
                brcmu_pkt_buf_free_skb(sdu);
+               return false;
        }
+       return true;
 }
 
 /*
@@ -7273,7 +7275,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
        return 0;
 }
 
-void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
+bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
                              struct ieee80211_hw *hw)
 {
        u8 prio;
@@ -7288,10 +7290,12 @@ void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
        prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
                MAXPRIO;
        fifo = prio2fifo[prio];
-       if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
-               return;
-       brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
+       brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
+       if (!brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)))
+               return false;
        brcms_c_send_q(wlc);
+
+       return true;
 }
 
 void brcms_c_send_q(struct brcms_c_info *wlc)
index 8debc74c54e1a63b5d9be1eae54e3c52d33375ba..b44725c0c23d75fe9c170234c075935e0c6bcf40 100644 (file)
@@ -642,7 +642,7 @@ extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
                           bool commit, s8 txpktpend);
 extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
                                    s8 txpktpend);
-extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
+extern bool brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
                            struct sk_buff *sdu, uint prec);
 extern void brcms_c_print_txstatus(struct tx_status *txs);
 extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
index 5855f4fd16dcd8d0dc473cd73275baae72414728..bfa26306d27f12c6b3c81164c2765dfca5ef0a53 100644 (file)
@@ -321,7 +321,7 @@ extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
 extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
 extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
 extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
-extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
+extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
                                     struct sk_buff *sdu,
                                     struct ieee80211_hw *hw);
 extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);