X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=package%2Fmac80211%2Fpatches%2F560-minstrel_ht.patch;h=c51d541fbb9ed3379cbd7a70c2b895fd4cb5a627;hb=9797b6ea4302eedaa3a0fd3c71841c037c9a78fa;hp=bc50ca67e27b66deb4f46122ed9e5f62ffc1590b;hpb=d5addb90c4fe370edc37babff27f5a30f8e70319;p=openwrt%2Fsvn-archive%2Farchive.git diff --git a/package/mac80211/patches/560-minstrel_ht.patch b/package/mac80211/patches/560-minstrel_ht.patch index bc50ca67e2..c51d541fbb 100644 --- a/package/mac80211/patches/560-minstrel_ht.patch +++ b/package/mac80211/patches/560-minstrel_ht.patch @@ -68,7 +68,7 @@ --- /dev/null +++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -0,0 +1,800 @@ +@@ -0,0 +1,815 @@ +/* + * Copyright (C) 2010 Felix Fietkau + * @@ -262,6 +262,14 @@ + int cur_prob, cur_prob_tp, cur_tp, cur_tp2; + int group, i, index; + ++ if (mi->ampdu_packets > 0) { ++ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, ++ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL); ++ mi->ampdu_len = 0; ++ mi->ampdu_packets = 0; ++ } ++ ++ mi->sample_slow = 0; + mi->sample_count = 0; + mi->max_tp_rate = 0; + mi->max_tp_rate2 = 0; @@ -414,6 +422,25 @@ + } +} + ++static void ++minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; ++ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); ++ u16 tid; ++ ++ if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) ++ return; ++ ++ if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) ++ return; ++ ++ tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; ++ if (likely(sta->ampdu_mlme.tid_state_tx[tid] != HT_AGG_STATE_IDLE)) ++ return; ++ ++ ieee80211_start_tx_ba_session(pubsta, tid); ++} + +static void +minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, @@ -443,8 +470,8 @@ + info->status.ampdu_len = 1; + } + -+ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, -+ MINSTREL_FRAC(info->status.ampdu_len, 1), 90); ++ mi->ampdu_packets++; ++ mi->ampdu_len += info->status.ampdu_len; + + if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { + mi->sample_wait = 4 + MINSTREL_TRUNC(mi->avg_ampdu_len); @@ -478,17 +505,21 @@ + * downgrade to a lower number of streams if necessary. + */ + rate = minstrel_get_ratestats(mi, mi->max_tp_rate); -+ if (MINSTREL_FRAC(rate->success, rate->attempts) < -+ MINSTREL_FRAC(20, 100) && rate->attempts > 30) ++ if (rate->attempts > 30 && ++ MINSTREL_FRAC(rate->success, rate->attempts) < ++ MINSTREL_FRAC(20, 100)) + minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); + + rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); -+ if (MINSTREL_FRAC(rate->success, rate->attempts) < -+ MINSTREL_FRAC(20, 100) && rate->attempts > 30) ++ if (rate->attempts > 30 && ++ MINSTREL_FRAC(rate->success, rate->attempts) < ++ MINSTREL_FRAC(20, 100)) + minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); + -+ if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) ++ if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { + minstrel_ht_update_stats(mp, mi); ++ minstrel_aggr_check(mp, sta, skb); ++ } +} + +static void @@ -542,7 +573,9 @@ + if (!mr->retry_updated) + minstrel_calc_retransmit(mp, mi, index); + -+ if (rtscts) ++ if (mr->probability < MINSTREL_FRAC(20, 100)) ++ rate->count = 2; ++ else if (rtscts) + rate->count = mr->retry_count_rtscts; + else + rate->count = mr->retry_count; @@ -595,9 +628,13 @@ + * if the link is working perfectly. + */ + if (minstrel_get_duration(sample_idx) > -+ minstrel_get_duration(mi->max_tp_rate) && -+ mr->sample_skipped < 10) -+ goto next; ++ minstrel_get_duration(mi->max_tp_rate)) { ++ if (mr->sample_skipped < 10) ++ goto next; ++ ++ if (mi->sample_slow++ > 2) ++ goto next; ++ } + + return sample_idx; + @@ -607,26 +644,6 @@ +} + +static void -+minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, struct sk_buff *skb) -+{ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+ u16 tid; -+ -+ if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) -+ return; -+ -+ if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) -+ return; -+ -+ tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; -+ if (likely(sta->ampdu_mlme.tid_state_tx[tid] != HT_AGG_STATE_IDLE)) -+ return; -+ -+ ieee80211_start_tx_ba_session(pubsta, tid); -+} -+ -+static void +minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, + struct ieee80211_tx_rate_control *txrc) +{ @@ -643,8 +660,6 @@ + if (!msp->is_ht) + return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); + -+ minstrel_aggr_check(mp, sta, txrc->skb); -+ + sample_idx = minstrel_get_sample_rate(mp, mi); + if (sample_idx >= 0) { + minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, @@ -871,7 +886,7 @@ +} --- /dev/null +++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -0,0 +1,120 @@ +@@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Felix Fietkau + * @@ -942,7 +957,11 @@ +}; + +struct minstrel_ht_sta { -+ /* ampdu length average (EWMA) */ ++ /* ampdu length (average, per sampling interval) */ ++ unsigned int ampdu_len; ++ unsigned int ampdu_packets; ++ ++ /* ampdu length (EWMA) */ + unsigned int avg_ampdu_len; + + /* best throughput rate */ @@ -967,6 +986,7 @@ + u8 sample_wait; + u8 sample_tries; + u8 sample_count; ++ u8 sample_slow; + + /* current MCS group to be sampled */ + u8 sample_group; @@ -1054,7 +1074,7 @@ + struct minstrel_rate_stats *mr = &mi->groups[i].rates[j]; + int idx = i * MCS_GROUP_RATES + j; + -+ if (!mi->groups[i].supported & BIT(j)) ++ if (!(mi->groups[i].supported & BIT(j))) + continue; + + p += sprintf(p, "HT%c0/%cGI ", htmode, gimode);