3.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <n...@openwrt.org>

commit 249ee72249140fe5b9adc988f97298f0aa5db2fc upstream.

Using ieee80211_free_txskb for tx frames is required, since mac80211 clones
skbs for which socket tx status is requested.

Signed-off-by: Felix Fietkau <n...@openwrt.org>
Signed-off-by: John W. Linville <linvi...@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/net/wireless/ath/ath9k/beacon.c |    2 -
 drivers/net/wireless/ath/ath9k/main.c   |    2 -
 drivers/net/wireless/ath/ath9k/xmit.c   |   53 +++++++++++++++++---------------
 3 files changed, 31 insertions(+), 26 deletions(-)

--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -121,7 +121,7 @@ static void ath_tx_cabq(struct ieee80211
 
        if (ath_tx_start(hw, skb, &txctl) != 0) {
                ath_dbg(common, XMIT, "CABQ TX failed\n");
-               dev_kfree_skb_any(skb);
+               ieee80211_free_txskb(hw, skb);
        }
 }
 
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1147,7 +1147,7 @@ static void ath9k_tx(struct ieee80211_hw
 
        return;
 exit:
-       dev_kfree_skb_any(skb);
+       ieee80211_free_txskb(hw, skb);
 }
 
 static void ath9k_stop(struct ieee80211_hw *hw)
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -64,8 +64,7 @@ static void ath_tx_update_baw(struct ath
 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
                                           struct ath_txq *txq,
                                           struct ath_atx_tid *tid,
-                                          struct sk_buff *skb,
-                                          bool dequeue);
+                                          struct sk_buff *skb);
 
 enum {
        MCS_HT20,
@@ -201,7 +200,15 @@ static void ath_tx_flush_tid(struct ath_
                fi = get_frame_info(skb);
                bf = fi->bf;
 
-               if (bf && fi->retries) {
+               if (!bf) {
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+                       if (!bf) {
+                               ieee80211_free_txskb(sc->hw, skb);
+                               continue;
+                       }
+               }
+
+               if (fi->retries) {
                        list_add_tail(&bf->list, &bf_head);
                        ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -812,10 +819,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_
                fi = get_frame_info(skb);
                bf = fi->bf;
                if (!fi->bf)
-                       bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
-               if (!bf)
+               if (!bf) {
+                       __skb_unlink(skb, &tid->buf_q);
+                       ieee80211_free_txskb(sc->hw, skb);
                        continue;
+               }
 
                bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
                seqno = bf->bf_state.seqno;
@@ -1717,9 +1727,11 @@ static void ath_tx_send_ampdu(struct ath
                return;
        }
 
-       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-       if (!bf)
+       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+       if (!bf) {
+               ieee80211_free_txskb(sc->hw, skb);
                return;
+       }
 
        bf->bf_state.bf_type = BUF_AMPDU;
        INIT_LIST_HEAD(&bf_head);
@@ -1743,11 +1755,6 @@ static void ath_tx_send_normal(struct at
        struct ath_buf *bf;
 
        bf = fi->bf;
-       if (!bf)
-               bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
-
-       if (!bf)
-               return;
 
        INIT_LIST_HEAD(&bf_head);
        list_add_tail(&bf->list, &bf_head);
@@ -1820,8 +1827,7 @@ u8 ath_txchainmask_reduction(struct ath_
 static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
                                           struct ath_txq *txq,
                                           struct ath_atx_tid *tid,
-                                          struct sk_buff *skb,
-                                          bool dequeue)
+                                          struct sk_buff *skb)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_frame_info *fi = get_frame_info(skb);
@@ -1833,7 +1839,7 @@ static struct ath_buf *ath_tx_setup_buff
        bf = ath_tx_get_buffer(sc);
        if (!bf) {
                ath_dbg(common, XMIT, "TX buffers are full\n");
-               goto error;
+               return NULL;
        }
 
        ATH_TXBUF_RESET(bf);
@@ -1862,18 +1868,12 @@ static struct ath_buf *ath_tx_setup_buff
                ath_err(ath9k_hw_common(sc->sc_ah),
                        "dma_mapping_error() on TX\n");
                ath_tx_return_buffer(sc, bf);
-               goto error;
+               return NULL;
        }
 
        fi->bf = bf;
 
        return bf;
-
-error:
-       if (dequeue)
-               __skb_unlink(skb, &tid->buf_q);
-       dev_kfree_skb_any(skb);
-       return NULL;
 }
 
 /* FIXME: tx power */
@@ -1902,9 +1902,14 @@ static void ath_tx_start_dma(struct ath_
                 */
                ath_tx_send_ampdu(sc, tid, skb, txctl);
        } else {
-               bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
-               if (!bf)
+               bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+               if (!bf) {
+                       if (txctl->paprd)
+                               dev_kfree_skb_any(skb);
+                       else
+                               ieee80211_free_txskb(sc->hw, skb);
                        return;
+               }
 
                bf->bf_state.bfs_paprd = txctl->paprd;
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to