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: Felix Fietkau <nbd@openwrt.org> Cc: stable@vger.kernel.org Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
ceb26a6013
commit
249ee72249
3 changed files with 31 additions and 26 deletions
|
@ -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,
|
||||||
|
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue