]> err.no Git - linux-2.6/blobdiff - net/mac80211/rc80211_pid_algo.c
mac80211: fixing null qos data frames check for reordering buffer
[linux-2.6] / net / mac80211 / rc80211_pid_algo.c
index 66cae53a647de66c0e0dadd526e9115db7bf8a6e..554c4baed6fbd3d4bdb164eaeea024fcf919bcfb 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);