summary refs log tree commit diff
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-12-25 19:33:16 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 15:09:42 -0800
commit2bc454b0b30b3645d114689b64321cb49be99923 (patch)
treea6c2bc87e02586f43a71dbb5f1808079df120dec /net/mac80211/rc80211_pid_algo.c
parent9ab461732a3cd8e7a7cf13cc46ed4c1ac7907824 (diff)
downloadlinux-2bc454b0b30b3645d114689b64321cb49be99923.tar.gz
mac80211: Fix rate reporting regression
Mattias Nissler's "clean up rate selection" patch incorrectly changes
the behavior of txrate setting in sta_info. This patch backs out parts
of the rate selection consolidation in order to fix this issue for now.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r--net/mac80211/rc80211_pid_algo.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 66cae53a647d..962286d893d6 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -310,22 +310,36 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_sub_if_data *sdata;
 	struct sta_info *sta;
 	int rateidx;
+	u16 fc;
 
 	sta = sta_info_get(local, hdr->addr1);
 
-	if (!sta) {
-		sel->rate = rate_lowest(local, mode, NULL);
-		sta_info_put(sta);
+	/* Send management frames and broadcast/multicast data using lowest
+	 * rate. */
+	fc = le16_to_cpu(hdr->frame_control);
+	if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
+	    is_multicast_ether_addr(hdr->addr1) || !sta) {
+		sel->rate = rate_lowest(local, mode, sta);
+		if (sta)
+			sta_info_put(sta);
 		return;
 	}
 
+	/* If a forced rate is in effect, select it. */
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
+		sta->txrate = sdata->bss->force_unicast_rateidx;
+
 	rateidx = sta->txrate;
 
 	if (rateidx >= mode->num_rates)
 		rateidx = mode->num_rates - 1;
 
+	sta->last_txrate = rateidx;
+
 	sta_info_put(sta);
 
 	sel->rate = &mode->rates[rateidx];