Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06d961a8 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg
Browse files

mac80211/minstrel: use the new rate control API



Pass the rate selection table to mac80211 from minstrel_update_stats.
Only rates for sample attempts are set in info->control.rates, with deferred
sampling, only the second slot gets changed.

Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a8566662
Loading
Loading
Loading
Loading
+109 −91
Original line number Diff line number Diff line
@@ -83,6 +83,50 @@ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
		tp_list[j] = i;
}

static void
minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *ratetbl,
		  int offset, int idx)
{
	struct minstrel_rate *r = &mi->r[idx];

	ratetbl->rate[offset].idx = r->rix;
	ratetbl->rate[offset].count = r->adjusted_retry_count;
	ratetbl->rate[offset].count_cts = r->retry_count_cts;
	ratetbl->rate[offset].count_rts = r->retry_count_rtscts;
}

static void
minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
{
	struct ieee80211_sta_rates *ratetbl;
	int i = 0;

	ratetbl = kzalloc(sizeof(*ratetbl), GFP_ATOMIC);
	if (!ratetbl)
		return;

	/* Start with max_tp_rate */
	minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[0]);

	if (mp->hw->max_rates >= 3) {
		/* At least 3 tx rates supported, use max_tp_rate2 next */
		minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[1]);
	}

	if (mp->hw->max_rates >= 2) {
		/* At least 2 tx rates supported, use max_prob_rate next */
		minstrel_set_rate(mi, ratetbl, i++, mi->max_prob_rate);
	}

	/* Use lowest rate last */
	ratetbl->rate[i].idx = mi->lowest_rix;
	ratetbl->rate[i].count = mp->max_retry;
	ratetbl->rate[i].count_cts = mp->max_retry;
	ratetbl->rate[i].count_rts = mp->max_retry;

	rate_control_set_rates(mp->hw, mi->sta, ratetbl);
}

static void
minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
{
@@ -161,6 +205,8 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)

	/* Reset update timer */
	mi->stats_update = jiffies;

	minstrel_update_rates(mp, mi);
}

static void
@@ -240,13 +286,12 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct minstrel_sta_info *mi = priv_sta;
	struct minstrel_priv *mp = priv;
	struct ieee80211_tx_rate *ar = info->control.rates;
	unsigned int ndx, sample_ndx = 0;
	struct ieee80211_tx_rate *rate = &info->control.rates[0];
	struct minstrel_rate *msr, *mr;
	unsigned int ndx;
	bool mrr_capable;
	bool indirect_rate_sampling = false;
	bool rate_sampling = false;
	int i, delta;
	int mrr_ndx[3];
	bool prev_sample = mi->prev_sample;
	int delta;
	int sampling_ratio;

	/* management/no-ack frames do not use rate control */
@@ -262,18 +307,17 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
	else
		sampling_ratio = mp->lookaround_rate;

	/* init rateindex [ndx] with max throughput rate */
	ndx = mi->max_tp_rate[0];

	/* increase sum packet counter */
	mi->packet_count++;

	delta = (mi->packet_count * sampling_ratio / 100) -
			(mi->sample_count + mi->sample_deferred / 2);

	/* delta > 0: sampling required */
	if ((delta > 0) && (mrr_capable || !mi->prev_sample)) {
		struct minstrel_rate *msr;
	/* delta < 0: no sampling required */
	mi->prev_sample = false;
	if (delta < 0 || (!mrr_capable && prev_sample))
		return;

	if (mi->packet_count >= 10000) {
		mi->sample_deferred = 0;
		mi->sample_count = 0;
@@ -292,28 +336,17 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
	}

	/* get next random rate sample */
		sample_ndx = minstrel_get_next_sample(mi);
		msr = &mi->r[sample_ndx];
		rate_sampling = true;
	ndx = minstrel_get_next_sample(mi);
	msr = &mi->r[ndx];
	mr = &mi->r[mi->max_tp_rate[0]];

	/* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage)
	 * rate sampling method should be used.
	 * Respect such rates that are not sampled for 20 interations.
	 */
	if (mrr_capable &&
		    msr->perfect_tx_time > mi->r[ndx].perfect_tx_time &&
		    msr->sample_skipped < 20)
				indirect_rate_sampling = true;

		if (!indirect_rate_sampling) {
			if (msr->sample_limit != 0) {
				ndx = sample_ndx;
				mi->sample_count++;
				if (msr->sample_limit > 0)
					msr->sample_limit--;
			} else
				rate_sampling = false;
		} else {
	    msr->perfect_tx_time > mr->perfect_tx_time &&
	    msr->sample_skipped < 20) {
		/* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
		 * packets that have the sampling rate deferred to the
		 * second MRR stage. Increase the sample counter only
@@ -321,48 +354,28 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
		 * Use the sample_deferred counter to make sure that
		 * the sampling is not done in large bursts */
		info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
		rate++;
		mi->sample_deferred++;
	} else {
		if (!msr->sample_limit != 0)
			return;

		mi->sample_count++;
		if (msr->sample_limit > 0)
			msr->sample_limit--;
	}
	}
	mi->prev_sample = rate_sampling;

	/* If we're not using MRR and the sampling rate already
	 * has a probability of >95%, we shouldn't be attempting
	 * to use it, as this only wastes precious airtime */
	if (!mrr_capable && rate_sampling &&
	if (!mrr_capable &&
	   (mi->r[ndx].probability > MINSTREL_FRAC(95, 100)))
		ndx = mi->max_tp_rate[0];

	/* mrr setup for 1st stage */
	ar[0].idx = mi->r[ndx].rix;
	ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);

	/* non mrr setup for 2nd stage */
	if (!mrr_capable) {
		if (!rate_sampling)
			ar[0].count = mp->max_retry;
		ar[1].idx = mi->lowest_rix;
		ar[1].count = mp->max_retry;
		return;
	}

	/* mrr setup for 2nd stage */
	if (rate_sampling) {
		if (indirect_rate_sampling)
			mrr_ndx[0] = sample_ndx;
		else
			mrr_ndx[0] = mi->max_tp_rate[0];
	} else {
		mrr_ndx[0] = mi->max_tp_rate[1];
	}
	mi->prev_sample = true;

	/* mrr setup for 3rd & 4th stage */
	mrr_ndx[1] = mi->max_prob_rate;
	mrr_ndx[2] = 0;
	for (i = 1; i < 4; i++) {
		ar[i].idx = mi->r[mrr_ndx[i - 1]].rix;
		ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count;
	}
	rate->idx = mi->r[ndx].rix;
	rate->count = minstrel_get_retry_count(&mi->r[ndx], info);
}


@@ -412,12 +425,16 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
	unsigned int i, n = 0;
	unsigned int t_slot = 9; /* FIXME: get real slot time */

	mi->sta = sta;
	mi->lowest_rix = rate_lowest_index(sband, sta);
	ctl_rate = &sband->bitrates[mi->lowest_rix];
	mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10,
				ctl_rate->bitrate,
				!!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1);

	memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate));
	mi->max_prob_rate = 0;

	for (i = 0; i < sband->n_bitrates; i++) {
		struct minstrel_rate *mr = &mi->r[n];
		unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0;
@@ -473,6 +490,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
	mi->stats_update = jiffies;

	init_sample_table(mi);
	minstrel_update_rates(mp, mi);
}

static void *
+2 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ struct minstrel_rate {
};

struct minstrel_sta_info {
	struct ieee80211_sta *sta;

	unsigned long stats_update;
	unsigned int sp_ack_dur;
	unsigned int rate_avg;