ath9k: rework handling of sending BlockAckReq frames, should hopefully lead to fewer latency spikes
SVN-Revision: 27888
This commit is contained in:
parent
3b36e83a29
commit
e7174f44b7
2 changed files with 213 additions and 0 deletions
64
package/mac80211/patches/570-mac80211_send_bar.patch
Normal file
64
package/mac80211/patches/570-mac80211_send_bar.patch
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
--- a/net/mac80211/agg-tx.c
|
||||||
|
+++ b/net/mac80211/agg-tx.c
|
||||||
|
@@ -109,8 +109,9 @@ static void ieee80211_send_addba_request
|
||||||
|
ieee80211_tx_skb(sdata, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
|
||||||
|
+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
|
||||||
|
{
|
||||||
|
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct ieee80211_bar *bar;
|
||||||
|
@@ -138,6 +139,7 @@ void ieee80211_send_bar(struct ieee80211
|
||||||
|
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||||
|
ieee80211_tx_skb(sdata, skb);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL(ieee80211_send_bar);
|
||||||
|
|
||||||
|
void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
|
||||||
|
struct tid_ampdu_tx *tid_tx)
|
||||||
|
--- a/include/net/mac80211.h
|
||||||
|
+++ b/include/net/mac80211.h
|
||||||
|
@@ -3007,6 +3007,19 @@ void ieee80211_remain_on_channel_expired
|
||||||
|
void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
|
||||||
|
const u8 *addr);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * ieee80211_send_bar - send a BlockAckReq frame
|
||||||
|
+ *
|
||||||
|
+ * can be used to flush pending frames from the peer's aggregation reorder
|
||||||
|
+ * buffer.
|
||||||
|
+ *
|
||||||
|
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||||
|
+ * @ra: the peer's destination address
|
||||||
|
+ * @tid: the TID of the aggregation session
|
||||||
|
+ * @ssn: the new starting sequence number for the receiver
|
||||||
|
+ */
|
||||||
|
+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
|
||||||
|
+
|
||||||
|
/* Rate control API */
|
||||||
|
|
||||||
|
/**
|
||||||
|
--- a/net/mac80211/ieee80211_i.h
|
||||||
|
+++ b/net/mac80211/ieee80211_i.h
|
||||||
|
@@ -1225,7 +1225,6 @@ struct ieee80211_tx_status_rtap_hdr {
|
||||||
|
void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
|
||||||
|
struct ieee80211_ht_cap *ht_cap_ie,
|
||||||
|
struct ieee80211_sta_ht_cap *ht_cap);
|
||||||
|
-void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
|
||||||
|
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
|
||||||
|
const u8 *da, u16 tid,
|
||||||
|
u16 initiator, u16 reason_code);
|
||||||
|
--- a/net/mac80211/status.c
|
||||||
|
+++ b/net/mac80211/status.c
|
||||||
|
@@ -239,7 +239,7 @@ void ieee80211_tx_status(struct ieee8021
|
||||||
|
tid = qc[0] & 0xf;
|
||||||
|
ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
|
||||||
|
& IEEE80211_SCTL_SEQ);
|
||||||
|
- ieee80211_send_bar(sta->sdata, hdr->addr1,
|
||||||
|
+ ieee80211_send_bar(&sta->sdata->vif, hdr->addr1,
|
||||||
|
tid, ssn);
|
||||||
|
}
|
||||||
|
|
149
package/mac80211/patches/571-ath9k_send_bar_fix.patch
Normal file
149
package/mac80211/patches/571-ath9k_send_bar_fix.patch
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
@@ -275,7 +275,6 @@ struct ath_tx_control {
|
||||||
|
|
||||||
|
#define ATH_TX_ERROR 0x01
|
||||||
|
#define ATH_TX_XRETRY 0x02
|
||||||
|
-#define ATH_TX_BAR 0x04
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @txq_map: Index is mac80211 queue number. This is
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
@@ -1801,6 +1801,7 @@ static int ath9k_sta_add(struct ieee8021
|
||||||
|
struct ieee80211_key_conf ps_key = { };
|
||||||
|
|
||||||
|
ath_node_attach(sc, sta);
|
||||||
|
+ an->vif = vif;
|
||||||
|
|
||||||
|
if (vif->type != NL80211_IFTYPE_AP &&
|
||||||
|
vif->type != NL80211_IFTYPE_AP_VLAN)
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||||
|
@@ -51,7 +51,7 @@ static void ath_tx_send_normal(struct at
|
||||||
|
struct list_head *bf_head);
|
||||||
|
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||||
|
struct ath_txq *txq, struct list_head *bf_q,
|
||||||
|
- struct ath_tx_status *ts, int txok, int sendbar);
|
||||||
|
+ struct ath_tx_status *ts, int txok);
|
||||||
|
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
|
struct list_head *head, bool internal);
|
||||||
|
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
|
||||||
|
@@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
|
||||||
|
fi = get_frame_info(bf->bf_mpdu);
|
||||||
|
if (fi->retries) {
|
||||||
|
ath_tx_update_baw(sc, tid, fi->seqno);
|
||||||
|
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
|
||||||
|
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||||
|
} else {
|
||||||
|
ath_tx_send_normal(sc, txq, NULL, &bf_head);
|
||||||
|
}
|
||||||
|
@@ -238,7 +238,7 @@ static void ath_tid_drain(struct ath_sof
|
||||||
|
ath_tx_update_baw(sc, tid, fi->seqno);
|
||||||
|
|
||||||
|
spin_unlock(&txq->axq_lock);
|
||||||
|
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
|
||||||
|
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||||
|
spin_lock(&txq->axq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -381,8 +381,7 @@ static void ath_tx_complete_aggr(struct
|
||||||
|
list_move_tail(&bf->list, &bf_head);
|
||||||
|
|
||||||
|
ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
|
||||||
|
- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||||
|
- 0, 0);
|
||||||
|
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
|
||||||
|
|
||||||
|
bf = bf_next;
|
||||||
|
}
|
||||||
|
@@ -426,7 +425,7 @@ static void ath_tx_complete_aggr(struct
|
||||||
|
|
||||||
|
ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
|
||||||
|
while (bf) {
|
||||||
|
- txfail = txpending = sendbar = 0;
|
||||||
|
+ txfail = txpending = 0;
|
||||||
|
bf_next = bf->bf_next;
|
||||||
|
|
||||||
|
skb = bf->bf_mpdu;
|
||||||
|
@@ -489,7 +488,7 @@ static void ath_tx_complete_aggr(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||||
|
- !txfail, sendbar);
|
||||||
|
+ !txfail);
|
||||||
|
} else {
|
||||||
|
/* retry the un-acked ones */
|
||||||
|
ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
|
||||||
|
@@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct
|
||||||
|
nbad, 0, false);
|
||||||
|
ath_tx_complete_buf(sc, bf, txq,
|
||||||
|
&bf_head,
|
||||||
|
- ts, 0, 0);
|
||||||
|
+ ts, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -564,6 +563,9 @@ static void ath_tx_complete_aggr(struct
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (sendbar || (tid->state & AGGR_CLEANUP))
|
||||||
|
+ ieee80211_send_bar(an->vif, sta->addr, tidno, tid->seq_start << 4);
|
||||||
|
+
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
if (needreset)
|
||||||
|
@@ -900,6 +902,7 @@ void ath_tx_aggr_stop(struct ath_softc *
|
||||||
|
spin_unlock_bh(&txq->axq_lock);
|
||||||
|
|
||||||
|
ath_tx_flush_tid(sc, txtid);
|
||||||
|
+ ieee80211_send_bar(an->vif, sta->addr, tid, txtid->seq_start << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
|
||||||
|
@@ -1178,7 +1181,7 @@ static void ath_drain_txq_list(struct at
|
||||||
|
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
|
||||||
|
retry_tx);
|
||||||
|
else
|
||||||
|
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
|
||||||
|
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||||
|
spin_lock_bh(&txq->axq_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1885,9 +1888,6 @@ static void ath_tx_complete(struct ath_s
|
||||||
|
|
||||||
|
ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
|
||||||
|
|
||||||
|
- if (tx_flags & ATH_TX_BAR)
|
||||||
|
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||||
|
-
|
||||||
|
if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
|
||||||
|
/* Frame was ACKed */
|
||||||
|
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||||
|
@@ -1932,15 +1932,12 @@ static void ath_tx_complete(struct ath_s
|
||||||
|
|
||||||
|
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||||
|
struct ath_txq *txq, struct list_head *bf_q,
|
||||||
|
- struct ath_tx_status *ts, int txok, int sendbar)
|
||||||
|
+ struct ath_tx_status *ts, int txok)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb = bf->bf_mpdu;
|
||||||
|
unsigned long flags;
|
||||||
|
int tx_flags = 0;
|
||||||
|
|
||||||
|
- if (sendbar)
|
||||||
|
- tx_flags = ATH_TX_BAR;
|
||||||
|
-
|
||||||
|
if (!txok) {
|
||||||
|
tx_flags |= ATH_TX_ERROR;
|
||||||
|
|
||||||
|
@@ -2056,7 +2053,7 @@ static void ath_tx_process_buffer(struct
|
||||||
|
if (ts->ts_status & ATH9K_TXERR_XRETRY)
|
||||||
|
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||||
|
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
|
||||||
|
- ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
|
||||||
|
+ ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
|
||||||
|
} else
|
||||||
|
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
|
||||||
|
|
Loading…
Reference in a new issue