mac80211/drivers: rewrite the rate control API

So after the previous changes we were still unhappy with how
convoluted the API is and decided to make things simpler for
everybody. This completely changes the rate control API, now
taking into account 802.11n with MCS rates and more control,
most drivers don't support that though.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index f6d69da..759ddd8 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -169,30 +169,20 @@
 {
 	struct minstrel_sta_info *mi = priv_sta;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_tx_altrate *ar = info->status.retries;
-	struct minstrel_priv *mp = priv;
-	int i, ndx, tries;
-	int success = 0;
+	struct ieee80211_tx_rate *ar = info->status.rates;
+	int i, ndx;
+	int success;
 
-	if (!info->status.excessive_retries)
-		success = 1;
+	success = !!(info->flags & IEEE80211_TX_STAT_ACK);
 
-	if (!mp->has_mrr || (ar[0].rate_idx < 0)) {
-		ndx = rix_to_ndx(mi, info->tx_rate_idx);
-		tries = info->status.retry_count + 1;
-		mi->r[ndx].success += success;
-		mi->r[ndx].attempts += tries;
-		return;
-	}
-
-	for (i = 0; i < 4; i++) {
-		if (ar[i].rate_idx < 0)
+	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+		if (ar[i].idx < 0)
 			break;
 
-		ndx = rix_to_ndx(mi, ar[i].rate_idx);
-		mi->r[ndx].attempts += ar[i].limit + 1;
+		ndx = rix_to_ndx(mi, ar[i].idx);
+		mi->r[ndx].attempts += ar[i].count;
 
-		if ((i != 3) && (ar[i + 1].rate_idx < 0))
+		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
 			mi->r[ndx].success += success;
 	}
 
@@ -210,9 +200,9 @@
 {
 	unsigned int retry = mr->adjusted_retry_count;
 
-	if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
 		retry = max(2U, min(mr->retry_count_rtscts, retry));
-	else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+	else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
 		retry = max(2U, min(mr->retry_count_cts, retry));
 	return retry;
 }
@@ -234,14 +224,15 @@
 }
 
 void
-minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
-                  struct ieee80211_sta *sta, void *priv_sta,
-                  struct sk_buff *skb, struct rate_selection *sel)
+minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
+		  void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
+	struct sk_buff *skb = txrc->skb;
+	struct ieee80211_supported_band *sband = txrc->sband;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct minstrel_sta_info *mi = priv_sta;
 	struct minstrel_priv *mp = priv;
-	struct ieee80211_tx_altrate *ar = info->control.retries;
+	struct ieee80211_tx_rate *ar = info->control.rates;
 	unsigned int ndx, sample_ndx = 0;
 	bool mrr;
 	bool sample_slower = false;
@@ -251,16 +242,12 @@
 	int sample_rate;
 
 	if (!sta || !mi || use_low_rate(skb)) {
-		sel->rate_idx = rate_lowest_index(sband, sta);
+		ar[0].idx = rate_lowest_index(sband, sta);
+		ar[0].count = mp->max_retry;
 		return;
 	}
 
-	mrr = mp->has_mrr;
-
-	/* mac80211 does not allow mrr for RTS/CTS */
-	if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-	    (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
-		mrr = false;
+	mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
 
 	if (time_after(jiffies, mi->stats_update + (mp->update_interval *
 			HZ) / 1000))
@@ -315,13 +302,12 @@
 			mi->sample_deferred++;
 		}
 	}
-	sel->rate_idx = mi->r[ndx].rix;
-	info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info);
+	ar[0].idx = mi->r[ndx].rix;
+	ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
 
 	if (!mrr) {
-		ar[0].rate_idx = mi->lowest_rix;
-		ar[0].limit = mp->max_retry;
-		ar[1].rate_idx = -1;
+		ar[1].idx = mi->lowest_rix;
+		ar[1].count = mp->max_retry;
 		return;
 	}
 
@@ -336,9 +322,9 @@
 	}
 	mrr_ndx[1] = mi->max_prob_rate;
 	mrr_ndx[2] = 0;
-	for (i = 0; i < 3; i++) {
-		ar[i].rate_idx = mi->r[mrr_ndx[i]].rix;
-		ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count;
+	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;
 	}
 }
 
@@ -532,13 +518,13 @@
 	/* maximum time that the hw is allowed to stay in one MRR segment */
 	mp->segment_size = 6000;
 
-	if (hw->max_altrate_tries > 0)
-		mp->max_retry = hw->max_altrate_tries;
+	if (hw->max_rate_tries > 0)
+		mp->max_retry = hw->max_rate_tries;
 	else
 		/* safe default, does not necessarily have to match hw properties */
 		mp->max_retry = 7;
 
-	if (hw->max_altrates >= 3)
+	if (hw->max_rates >= 4)
 		mp->has_mrr = true;
 
 	mp->hw = hw;