Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[cascardo/linux.git] / net / mac80211 / rc80211_pid_algo.c
index 66cae53..c339571 100644 (file)
@@ -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];
@@ -482,6 +496,8 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
        if (spinfo == NULL)
                return NULL;
 
+       spinfo->last_sample = jiffies;
+
 #ifdef CONFIG_MAC80211_DEBUGFS
        spin_lock_init(&spinfo->events.lock);
        init_waitqueue_head(&spinfo->events.waitqueue);
@@ -522,7 +538,7 @@ int __init rc80211_pid_init(void)
        return ieee80211_rate_control_register(&mac80211_rcpid);
 }
 
-void __exit rc80211_pid_exit(void)
+void rc80211_pid_exit(void)
 {
        ieee80211_rate_control_unregister(&mac80211_rcpid);
 }