mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-24 05:34:36 +02:00
ath9k: use ieee80211_free_txskb, might fix hostapd stability issues
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@33611 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
8cd09b08a0
commit
f8a329d566
@ -0,0 +1,149 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
@@ -66,8 +66,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,
|
||||
@@ -176,7 +175,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);
|
||||
@@ -785,10 +792,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;
|
||||
@@ -1731,9 +1741,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);
|
||||
@@ -1757,11 +1769,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);
|
||||
@@ -1835,8 +1842,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);
|
||||
@@ -1848,7 +1854,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);
|
||||
@@ -1877,18 +1883,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 */
|
||||
@@ -1917,9 +1917,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;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -775,7 +775,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/beacon.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
|
||||
@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee802
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user