mirror of https://github.com/hak5/openwrt.git
mac80211: update A-MSDU tx support to the latest version
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 48743lede-17.01
parent
c834c83f0f
commit
42fc062d47
|
@ -26,7 +26,23 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1961,6 +1963,12 @@ struct ieee80211_txq {
|
@@ -1728,6 +1730,7 @@ struct ieee80211_sta_rates {
|
||||||
|
* size is min(max_amsdu_len, 7935) bytes.
|
||||||
|
* Both additional HT limits must be enforced by the low level driver.
|
||||||
|
* This is defined by the spec (IEEE 802.11-2012 section 8.3.2.2 NOTE 2).
|
||||||
|
+ * @max_rc_amsdu_len: Maximum A-MSDU size in bytes recommended by rate control.
|
||||||
|
* @txq: per-TID data TX queues (if driver uses the TXQ abstraction)
|
||||||
|
*/
|
||||||
|
struct ieee80211_sta {
|
||||||
|
@@ -1748,6 +1751,7 @@ struct ieee80211_sta {
|
||||||
|
bool mfp;
|
||||||
|
u8 max_amsdu_subframes;
|
||||||
|
u16 max_amsdu_len;
|
||||||
|
+ u16 max_rc_amsdu_len;
|
||||||
|
|
||||||
|
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
|
||||||
|
|
||||||
|
@@ -1961,6 +1965,12 @@ struct ieee80211_txq {
|
||||||
* order and does not need to manage its own reorder buffer or BA session
|
* order and does not need to manage its own reorder buffer or BA session
|
||||||
* timeout.
|
* timeout.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||||
*/
|
*/
|
||||||
enum ieee80211_hw_flags {
|
enum ieee80211_hw_flags {
|
||||||
@@ -1998,6 +2006,8 @@ enum ieee80211_hw_flags {
|
@@ -1998,6 +2008,8 @@ enum ieee80211_hw_flags {
|
||||||
IEEE80211_HW_BEACON_TX_STATUS,
|
IEEE80211_HW_BEACON_TX_STATUS,
|
||||||
IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
|
IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
|
||||||
IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
|
IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
|
||||||
|
@ -48,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
|
|
||||||
/* keep last, obviously */
|
/* keep last, obviously */
|
||||||
NUM_IEEE80211_HW_FLAGS
|
NUM_IEEE80211_HW_FLAGS
|
||||||
@@ -2070,6 +2080,8 @@ enum ieee80211_hw_flags {
|
@@ -2070,6 +2082,8 @@ enum ieee80211_hw_flags {
|
||||||
* size is smaller (an example is LinkSys WRT120N with FW v1.0.07
|
* size is smaller (an example is LinkSys WRT120N with FW v1.0.07
|
||||||
* build 002 Jun 18 2012).
|
* build 002 Jun 18 2012).
|
||||||
*
|
*
|
||||||
|
@ -57,7 +73,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
* @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX
|
* @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX
|
||||||
* (if %IEEE80211_HW_QUEUE_CONTROL is set)
|
* (if %IEEE80211_HW_QUEUE_CONTROL is set)
|
||||||
*
|
*
|
||||||
@@ -2124,6 +2136,7 @@ struct ieee80211_hw {
|
@@ -2124,6 +2138,7 @@ struct ieee80211_hw {
|
||||||
u8 max_rate_tries;
|
u8 max_rate_tries;
|
||||||
u8 max_rx_aggregation_subframes;
|
u8 max_rx_aggregation_subframes;
|
||||||
u8 max_tx_aggregation_subframes;
|
u8 max_tx_aggregation_subframes;
|
||||||
|
@ -120,7 +136,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_tx_dequeue);
|
EXPORT_SYMBOL(ieee80211_tx_dequeue);
|
||||||
@@ -2757,6 +2761,158 @@ void ieee80211_clear_fast_xmit(struct st
|
@@ -2757,6 +2761,165 @@ void ieee80211_clear_fast_xmit(struct st
|
||||||
kfree_rcu(fast_tx, rcu_head);
|
kfree_rcu(fast_tx, rcu_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +164,9 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
+ void *data;
|
+ void *data;
|
||||||
+ u8 *qc;
|
+ u8 *qc;
|
||||||
+
|
+
|
||||||
|
+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
+ if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
|
+ if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
|
||||||
+ return true;
|
+ return true;
|
||||||
+
|
+
|
||||||
|
@ -193,7 +212,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
+ int subframe_len = skb->len - ETH_ALEN;
|
+ int subframe_len = skb->len - ETH_ALEN;
|
||||||
+ u8 max_subframes = sta->sta.max_amsdu_subframes;
|
+ u8 max_subframes = sta->sta.max_amsdu_subframes;
|
||||||
+ int max_frags = local->hw.max_tx_fragments;
|
+ int max_frags = local->hw.max_tx_fragments;
|
||||||
+ int max_amsdu_len;
|
+ int max_amsdu_len = sta->sta.max_amsdu_len;
|
||||||
+ __be16 len;
|
+ __be16 len;
|
||||||
+ void *data;
|
+ void *data;
|
||||||
+ bool ret = false;
|
+ bool ret = false;
|
||||||
|
@ -209,6 +228,10 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
+ if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags))
|
+ if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags))
|
||||||
+ return false;
|
+ return false;
|
||||||
+
|
+
|
||||||
|
+ if (sta->sta.max_rc_amsdu_len)
|
||||||
|
+ max_amsdu_len = min_t(int, max_amsdu_len,
|
||||||
|
+ sta->sta.max_rc_amsdu_len);
|
||||||
|
+
|
||||||
+ spin_lock_bh(&txqi->queue.lock);
|
+ spin_lock_bh(&txqi->queue.lock);
|
||||||
+
|
+
|
||||||
+ head = skb_peek_tail(&txqi->queue);
|
+ head = skb_peek_tail(&txqi->queue);
|
||||||
|
@ -279,7 +302,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||||
struct net_device *dev, struct sta_info *sta,
|
struct net_device *dev, struct sta_info *sta,
|
||||||
struct ieee80211_fast_tx *fast_tx,
|
struct ieee80211_fast_tx *fast_tx,
|
||||||
@@ -2811,6 +2967,10 @@ static bool ieee80211_xmit_fast(struct i
|
@@ -2811,6 +2974,10 @@ static bool ieee80211_xmit_fast(struct i
|
||||||
|
|
||||||
ieee80211_tx_stats(dev, skb->len + extra_head);
|
ieee80211_tx_stats(dev, skb->len + extra_head);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
From: Felix Fietkau <nbd@openwrt.org>
|
||||||
|
Date: Thu, 18 Feb 2016 19:30:05 +0100
|
||||||
|
Subject: [PATCH] mac80211: minstrel_ht: set A-MSDU tx limits based on selected
|
||||||
|
max_prob_rate
|
||||||
|
|
||||||
|
Prevents excessive A-MSDU aggregation at low data rates or bad
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||||
|
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||||
|
@@ -883,6 +883,39 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||||
|
ratetbl->rate[offset].flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
|
||||||
|
+{
|
||||||
|
+ int group = mi->max_prob_rate / MCS_GROUP_RATES;
|
||||||
|
+ const struct mcs_group *g = &minstrel_mcs_groups[group];
|
||||||
|
+ int rate = mi->max_prob_rate % MCS_GROUP_RATES;
|
||||||
|
+
|
||||||
|
+ /* Disable A-MSDU if max_prob_rate is bad */
|
||||||
|
+ if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */
|
||||||
|
+ if (g->duration[rate] > MCS_DURATION(1, 0, 52))
|
||||||
|
+ return 500;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If the rate is slower than single-stream MCS4, limit A-MSDU to usual
|
||||||
|
+ * data packet size
|
||||||
|
+ */
|
||||||
|
+ if (g->duration[rate] > MCS_DURATION(1, 0, 104))
|
||||||
|
+ return 1500;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If the rate is slower than single-stream MCS7, limit A-MSDU to twice
|
||||||
|
+ * the usual data packet size
|
||||||
|
+ */
|
||||||
|
+ if (g->duration[rate] > MCS_DURATION(1, 0, 260))
|
||||||
|
+ return 3000;
|
||||||
|
+
|
||||||
|
+ /* unlimited */
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||||
|
{
|
||||||
|
@@ -907,6 +940,7 @@ minstrel_ht_update_rates(struct minstrel
|
||||||
|
minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mi->sta->max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi);
|
||||||
|
rates->rate[i].idx = -1;
|
||||||
|
rate_control_set_rates(mp->hw, mi->sta, rates);
|
||||||
|
}
|
Loading…
Reference in New Issue