]> err.no Git - linux-2.6/blobdiff - net/mac80211/ieee80211_rate.c
mac80211: fix mesh_path and sta_info get_by_idx functions
[linux-2.6] / net / mac80211 / ieee80211_rate.c
index 65fc9ad615e9a40f0bec56ccebdcc12147647221..4de06f128d9017102981da7bc4298ed69d63233f 100644 (file)
@@ -115,6 +115,10 @@ ieee80211_rate_control_ops_get(const char *name)
                /* try default if specific alg requested but not found */
                ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
 
+       /* try built-in one if specific alg requested but not found */
+       if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
+               ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
+
        return ops;
 }
 
@@ -159,50 +163,37 @@ static void rate_control_release(struct kref *kref)
 }
 
 void rate_control_get_rate(struct net_device *dev,
-                          struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                          struct ieee80211_supported_band *sband,
+                          struct sk_buff *skb,
                           struct rate_selection *sel)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct rate_control_ref *ref = local->rate_ctrl;
-       struct ieee80211_sub_if_data *sdata;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct sta_info *sta = sta_info_get(local, hdr->addr1);
+       struct sta_info *sta;
        int i;
-       u16 fc;
-
-       memset(sel, 0, sizeof(struct rate_selection));
 
-       /* 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))
-               sel->rate = rate_lowest(local, mode, sta);
+       rcu_read_lock();
+       sta = sta_info_get(local, hdr->addr1);
 
-       /* 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)
-               sel->rate = &mode->rates[sdata->bss->force_unicast_rateidx];
+       memset(sel, 0, sizeof(struct rate_selection));
 
-       /* If we haven't found the rate yet, ask the rate control algo. */
-       if (!sel->rate)
-               ref->ops->get_rate(ref->priv, dev, mode, skb, sel);
+       ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
 
        /* Select a non-ERP backup rate. */
        if (!sel->nonerp) {
-               for (i = 0; i < mode->num_rates - 1; i++) {
-                       struct ieee80211_rate *rate = &mode->rates[i];
-                       if (sel->rate->rate < rate->rate)
+               for (i = 0; i < sband->n_bitrates; i++) {
+                       struct ieee80211_rate *rate = &sband->bitrates[i];
+                       if (sel->rate->bitrate < rate->bitrate)
                                break;
 
-                       if (rate_supported(sta, mode, i) &&
-                           !(rate->flags & IEEE80211_RATE_ERP))
+                       if (rate_supported(sta, sband->band, i) &&
+                           !(rate->flags & IEEE80211_RATE_ERP_G))
                                sel->nonerp = rate;
                }
        }
 
-       if (sta)
-               sta_info_put(sta);
+       rcu_read_unlock();
 }
 
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)