linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Felix Fietkau <nbd@openwrt.org>
To: linux-wireless@vger.kernel.org
Cc: johannes@sipsolutions.net
Subject: [PATCH 4/5] mac80211/minstrel_ht: use the new rate control API
Date: Sun, 14 Apr 2013 00:03:45 +0200	[thread overview]
Message-ID: <1365890626-86895-4-git-send-email-nbd@openwrt.org> (raw)
In-Reply-To: <1365890626-86895-3-git-send-email-nbd@openwrt.org>

Pass the rate selection table to mac80211 from minstrel_ht_update_stats.
Only rates for sample attempts are set in info->control.rates.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 net/mac80211/rc80211_minstrel_ht.c | 150 ++++++++++++++++++++-----------------
 net/mac80211/rc80211_minstrel_ht.h |   2 +
 2 files changed, 84 insertions(+), 68 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index d2b264d..4f9bdbe 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -126,6 +126,9 @@ const struct mcs_group minstrel_mcs_groups[] = {
 
 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES];
 
+static void
+minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
+
 /*
  * Look up an MCS group index based on mac80211 rate information
  */
@@ -456,7 +459,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	struct ieee80211_tx_rate *ar = info->status.rates;
 	struct minstrel_rate_stats *rate, *rate2;
 	struct minstrel_priv *mp = priv;
-	bool last;
+	bool last, update = false;
 	int i;
 
 	if (!msp->is_ht)
@@ -505,21 +508,29 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	rate = minstrel_get_ratestats(mi, mi->max_tp_rate);
 	if (rate->attempts > 30 &&
 	    MINSTREL_FRAC(rate->success, rate->attempts) <
-	    MINSTREL_FRAC(20, 100))
+	    MINSTREL_FRAC(20, 100)) {
 		minstrel_downgrade_rate(mi, &mi->max_tp_rate, true);
+		update = true;
+	}
 
 	rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2);
 	if (rate2->attempts > 30 &&
 	    MINSTREL_FRAC(rate2->success, rate2->attempts) <
-	    MINSTREL_FRAC(20, 100))
+	    MINSTREL_FRAC(20, 100)) {
 		minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false);
+		update = true;
+	}
 
 	if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {
+		update = true;
 		minstrel_ht_update_stats(mp, mi);
 		if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
 		    mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
 			minstrel_aggr_check(sta, skb);
 	}
+
+	if (update)
+		minstrel_ht_update_rates(mp, mi);
 }
 
 static void
@@ -580,39 +591,73 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 	         (++mr->retry_count < mp->max_retry));
 }
 
-
 static void
 minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
-                     struct ieee80211_tx_rate *rate, int index,
-                     bool sample, bool rtscts)
+                     struct ieee80211_sta_rates *ratetbl, int offset, int index)
 {
 	const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
 	struct minstrel_rate_stats *mr;
+	u8 idx;
+	u16 flags;
 
 	mr = minstrel_get_ratestats(mi, index);
 	if (!mr->retry_updated)
 		minstrel_calc_retransmit(mp, mi, index);
 
-	if (sample)
-		rate->count = 1;
-	else 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;
-
-	rate->flags = 0;
-	if (rtscts)
-		rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
+	if (mr->probability < MINSTREL_FRAC(20, 100) || !mr->retry_count) {
+		ratetbl->rate[offset].count = 2;
+		ratetbl->rate[offset].count_rts = 2;
+		ratetbl->rate[offset].count_cts = 2;
+	} else {
+		ratetbl->rate[offset].count = mr->retry_count;
+		ratetbl->rate[offset].count_cts = mr->retry_count;
+		ratetbl->rate[offset].count_rts = mr->retry_count_rtscts;
+	}
 
 	if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
-		rate->idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
+		idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
+		flags = 0;
+	} else {
+		idx = index % MCS_GROUP_RATES +
+		      (group->streams - 1) * MCS_GROUP_RATES;
+		flags = IEEE80211_TX_RC_MCS | group->flags;
+	}
+
+	if (offset > 0) {
+		ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts;
+		flags |= IEEE80211_TX_RC_USE_RTS_CTS;
+	}
+
+	ratetbl->rate[offset].idx = idx;
+	ratetbl->rate[offset].flags = flags;
+}
+
+static void
+minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
+{
+	struct ieee80211_sta_rates *rates;
+	int i = 0;
+
+	rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
+	if (!rates)
 		return;
+
+	/* Start with max_tp_rate */
+	minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate);
+
+	if (mp->hw->max_rates >= 3) {
+		/* At least 3 tx rates supported, use max_tp_rate2 next */
+		minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate2);
+	}
+
+	if (mp->hw->max_rates >= 2) {
+		/*
+		 * At least 2 tx rates supported, use max_prob_rate next */
+		minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate);
 	}
 
-	rate->flags |= IEEE80211_TX_RC_MCS | group->flags;
-	rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES;
+	rates->rate[i].idx = -1;
+	rate_control_set_rates(mp->hw, mi->sta, rates);
 }
 
 static inline int
@@ -702,13 +747,13 @@ static void
 minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
                      struct ieee80211_tx_rate_control *txrc)
 {
+	const struct mcs_group *sample_group;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
-	struct ieee80211_tx_rate *ar = info->status.rates;
+	struct ieee80211_tx_rate *rate = &info->status.rates[0];
 	struct minstrel_ht_sta_priv *msp = priv_sta;
 	struct minstrel_ht_sta *mi = &msp->ht;
 	struct minstrel_priv *mp = priv;
 	int sample_idx;
-	bool sample = false;
 
 	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
@@ -736,51 +781,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 	}
 #endif
 
-	if (sample_idx >= 0) {
-		sample = true;
-		minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
-			true, false);
-		info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-	} else {
-		minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
-			false, false);
-	}
-
-	if (mp->hw->max_rates >= 3) {
-		/*
-		 * At least 3 tx rates supported, use
-		 * sample_rate -> max_tp_rate -> max_prob_rate for sampling and
-		 * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default.
-		 */
-		if (sample_idx >= 0)
-			minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
-				false, false);
-		else
-			minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
-				false, true);
-
-		minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate,
-				     false, !sample);
-
-		ar[3].count = 0;
-		ar[3].idx = -1;
-	} else if (mp->hw->max_rates == 2) {
-		/*
-		 * Only 2 tx rates supported, use
-		 * sample_rate -> max_prob_rate for sampling and
-		 * max_tp_rate -> max_prob_rate by default.
-		 */
-		minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate,
-				     false, !sample);
-
-		ar[2].count = 0;
-		ar[2].idx = -1;
-	} else {
-		/* Not using MRR, only use the first rate */
-		ar[1].count = 0;
-		ar[1].idx = -1;
-	}
-
 	mi->total_packets++;
 
 	/* wraparound */
@@ -788,6 +788,16 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 		mi->total_packets = 0;
 		mi->sample_packets = 0;
 	}
+
+	if (sample_idx < 0)
+		return;
+
+	sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
+	info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+	rate->idx = sample_idx % MCS_GROUP_RATES +
+		    (sample_group->streams - 1) * MCS_GROUP_RATES;
+	rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
+	rate->count = 1;
 }
 
 static void
@@ -837,6 +847,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
 
 	msp->is_ht = true;
 	memset(mi, 0, sizeof(*mi));
+
+	mi->sta = sta;
 	mi->stats_update = jiffies;
 
 	ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1);
@@ -898,6 +910,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
 	if (!n_supported)
 		goto use_legacy;
 
+	minstrel_ht_update_rates(mp, mi);
+
 	return;
 
 use_legacy:
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
index 9b16e9d..d655586 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -65,6 +65,8 @@ struct minstrel_mcs_group_data {
 };
 
 struct minstrel_ht_sta {
+	struct ieee80211_sta *sta;
+
 	/* ampdu length (average, per sampling interval) */
 	unsigned int ampdu_len;
 	unsigned int ampdu_packets;
-- 
1.8.0.2


  reply	other threads:[~2013-04-13 22:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-13 22:03 [PATCH 1/5] mac80211: fix and optimize MCS mask handling Felix Fietkau
2013-04-13 22:03 ` [PATCH 2/5] mac80211: fix CTS protection handling Felix Fietkau
2013-04-13 22:03   ` [PATCH 3/5] mac80211: improve the rate control API Felix Fietkau
2013-04-13 22:03     ` Felix Fietkau [this message]
2013-04-13 22:03       ` [PATCH 5/5] mac80211/minstrel: use the new " Felix Fietkau
2013-04-15 13:44     ` [PATCH 3/5] mac80211: improve the " Johannes Berg
2013-04-15 14:27       ` Felix Fietkau
2013-04-16 10:03     ` Karl Beldan
2013-04-16 10:44       ` Felix Fietkau
2013-04-15 13:40   ` [PATCH 2/5] mac80211: fix CTS protection handling Johannes Berg
2013-04-15 14:24     ` Felix Fietkau
2013-04-15 13:38 ` [PATCH 1/5] mac80211: fix and optimize MCS mask handling Johannes Berg
2013-04-15 14:19   ` Felix Fietkau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1365890626-86895-4-git-send-email-nbd@openwrt.org \
    --to=nbd@openwrt.org \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).