]> err.no Git - linux-2.6/blobdiff - net/mac80211/rc80211_simple.c
Merge branch 'async-tx-for-linus' of git://lost.foo-projects.org/~dwillia2/git/iop...
[linux-2.6] / net / mac80211 / rc80211_simple.c
index 33de6f967e551d991c7247e97d819e416a05d35e..9a78b116acffbdca0b00ba2df579ce87ec6cd2f2 100644 (file)
@@ -207,21 +207,36 @@ rate_control_simple_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);
+       /* 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];
@@ -374,7 +389,7 @@ int __init rc80211_simple_init(void)
        return ieee80211_rate_control_register(&mac80211_rcsimple);
 }
 
-void __exit rc80211_simple_exit(void)
+void rc80211_simple_exit(void)
 {
        ieee80211_rate_control_unregister(&mac80211_rcsimple);
 }