Commit 249ee722 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k: use ieee80211_free_txskb

Using ieee80211_free_txskb for tx frames is required, since mac80211 clones
skbs for which socket tx status is requested.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ceb26a60
...@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
if (ath_tx_start(hw, skb, &txctl) != 0) { if (ath_tx_start(hw, skb, &txctl) != 0) {
ath_dbg(common, XMIT, "CABQ TX failed\n"); ath_dbg(common, XMIT, "CABQ TX failed\n");
dev_kfree_skb_any(skb); ieee80211_free_txskb(hw, skb);
} }
} }
......
...@@ -765,7 +765,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, ...@@ -765,7 +765,7 @@ static void ath9k_tx(struct ieee80211_hw *hw,
return; return;
exit: exit:
dev_kfree_skb_any(skb); ieee80211_free_txskb(hw, skb);
} }
static void ath9k_stop(struct ieee80211_hw *hw) static void ath9k_stop(struct ieee80211_hw *hw)
......
...@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq, struct ath_txq *txq,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct sk_buff *skb, struct sk_buff *skb);
bool dequeue);
enum { enum {
MCS_HT20, MCS_HT20,
...@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ...@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; 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); list_add_tail(&bf->list, &bf_head);
ath_tx_update_baw(sc, tid, bf->bf_state.seqno); ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
...@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ...@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
if (!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; continue;
}
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
seqno = bf->bf_state.seqno; seqno = bf->bf_state.seqno;
...@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return; return;
} }
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
if (!bf) if (!bf) {
ieee80211_free_txskb(sc->hw, skb);
return; return;
}
bf->bf_state.bf_type = BUF_AMPDU; bf->bf_state.bf_type = BUF_AMPDU;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
...@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, ...@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf; struct ath_buf *bf;
bf = fi->bf; bf = fi->bf;
if (!bf)
bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
if (!bf)
return;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
list_add_tail(&bf->list, &bf_head); list_add_tail(&bf->list, &bf_head);
...@@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) ...@@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq, struct ath_txq *txq,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct sk_buff *skb, struct sk_buff *skb)
bool dequeue)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_frame_info *fi = get_frame_info(skb); struct ath_frame_info *fi = get_frame_info(skb);
...@@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ...@@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
bf = ath_tx_get_buffer(sc); bf = ath_tx_get_buffer(sc);
if (!bf) { if (!bf) {
ath_dbg(common, XMIT, "TX buffers are full\n"); ath_dbg(common, XMIT, "TX buffers are full\n");
goto error; return NULL;
} }
ATH_TXBUF_RESET(bf); ATH_TXBUF_RESET(bf);
...@@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ...@@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
ath_err(ath9k_hw_common(sc->sc_ah), ath_err(ath9k_hw_common(sc->sc_ah),
"dma_mapping_error() on TX\n"); "dma_mapping_error() on TX\n");
ath_tx_return_buffer(sc, bf); ath_tx_return_buffer(sc, bf);
goto error; return NULL;
} }
fi->bf = bf; fi->bf = bf;
return bf; return bf;
error:
if (dequeue)
__skb_unlink(skb, &tid->buf_q);
dev_kfree_skb_any(skb);
return NULL;
} }
/* FIXME: tx power */ /* FIXME: tx power */
...@@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
*/ */
ath_tx_send_ampdu(sc, tid, skb, txctl); ath_tx_send_ampdu(sc, tid, skb, txctl);
} else { } else {
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
if (!bf) if (!bf) {
if (txctl->paprd)
dev_kfree_skb_any(skb);
else
ieee80211_free_txskb(sc->hw, skb);
return; return;
}
bf->bf_state.bfs_paprd = txctl->paprd; bf->bf_state.bfs_paprd = txctl->paprd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment