Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1abbe498e4b5e4f2000dfc30a0fa25be9553530e
Commit:     1abbe498e4b5e4f2000dfc30a0fa25be9553530e
Parent:     98f0b0a3a412eade153c7cf00c6b863600980d89
Author:     Mattias Nissler <[EMAIL PROTECTED]>
AuthorDate: Thu Dec 20 13:50:07 2007 +0100
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 14:59:17 2008 -0800

    mac80211: clean up rate selection
    
    Move some code out of rc80211_simple since it's probably needed for all rate
    selection algorithms, and fix iwlwifi accordingly. While at it, clean up the
    rate_control_get_rate() interface.
    
    Signed-off-by: Stefano Brivio <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 drivers/net/wireless/iwlwifi/iwl-3945-rs.c |   44 +++--------------
 drivers/net/wireless/iwlwifi/iwl-4965-rs.c |   46 ++++--------------
 net/mac80211/ieee80211.c                   |    6 +--
 net/mac80211/ieee80211_rate.c              |   47 ++++++++++++++++++
 net/mac80211/ieee80211_rate.h              |   73 +++++++++++++++++----------
 net/mac80211/ieee80211_sta.c               |   13 ++---
 net/mac80211/rc80211_simple.c              |   64 ++++--------------------
 net/mac80211/tx.c                          |   42 +++++++---------
 8 files changed, 146 insertions(+), 189 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c 
b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index c48b1b5..ea7f459 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -562,22 +562,6 @@ static void rs_tx_status(void *priv_rate,
        return;
 }
 
-static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local
-                                                 *local)
-{
-       struct ieee80211_hw_mode *mode = local->oper_hw_mode;
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       return &mode->rates[0];
-}
-
 static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
                                 u8 index, u16 rate_mask, int phymode)
 {
@@ -656,10 +640,9 @@ static u16 iwl_get_adjacent_rate(struct 
iwl_rate_scale_priv *rs_priv,
  * rate table and must reference the driver allocated rate table
  *
  */
-static struct ieee80211_rate *rs_get_rate(void *priv_rate,
-                                         struct net_device *dev,
-                                         struct sk_buff *skb,
-                                         struct rate_control_extra *extra)
+static void rs_get_rate(void *priv_rate, struct net_device *dev,
+                       struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                       struct rate_selection *sel)
 {
        u8 low = IWL_RATE_INVALID;
        u8 high = IWL_RATE_INVALID;
@@ -676,32 +659,19 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct sta_info *sta;
-       u16 fc, rate_mask;
+       u16 rate_mask;
        struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RATE("enter\n");
 
-       memset(extra, 0, sizeof(*extra));
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
-           (is_multicast_ether_addr(hdr->addr1))) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               IWL_DEBUG_RATE("leave: lowest rate (not data or is "
-                              "multicast)\n");
-
-               return iwl_get_lowest_rate(local);
-       }
-
        sta = sta_info_get(local, hdr->addr1);
        if (!sta || !sta->rate_ctrl_priv) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
                if (sta)
                        sta_info_put(sta);
-               return NULL;
+               return;
        }
 
        rate_mask = sta->supp_rates;
@@ -846,7 +816,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
 
        IWL_DEBUG_RATE("leave: %d\n", index);
 
-       return &priv->ieee_rates[index];
+       sel->rate = &priv->ieee_rates[index];
 }
 
 static struct rate_control_ops rs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c 
b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 8dc78c0..62a3b52 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -1693,55 +1693,27 @@ static void rs_initialize_lq(struct iwl_priv *priv,
        return;
 }
 
-static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local
-                                                *local)
-{
-       struct ieee80211_hw_mode *mode = local->oper_hw_mode;
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       return &mode->rates[0];
-}
-
-static struct ieee80211_rate *rs_get_rate(void *priv_rate,
-                                              struct net_device *dev,
-                                              struct sk_buff *skb,
-                                              struct rate_control_extra
-                                              *extra)
+static void rs_get_rate(void *priv_rate, struct net_device *dev,
+                       struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                       struct rate_selection *sel)
 {
 
        int i;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct sta_info *sta;
-       u16 fc;
        struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
        struct iwl_rate_scale_priv *lq;
 
        IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
-       memset(extra, 0, sizeof(*extra));
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               return rs_get_lowest_rate(local);
-       }
-
        sta = sta_info_get(local, hdr->addr1);
 
        if (!sta || !sta->rate_ctrl_priv) {
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
                if (sta)
                        sta_info_put(sta);
-               return rs_get_lowest_rate(local);
+               return;
        }
 
        lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
@@ -1768,11 +1740,13 @@ static struct ieee80211_rate *rs_get_rate(void 
*priv_rate,
        }
 
  done:
+       if ((i < 0) || (i > IWL_RATE_COUNT)) {
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
+               return;
+       }
        sta_info_put(sta);
-       if ((i < 0) || (i > IWL_RATE_COUNT))
-               return rs_get_lowest_rate(local);
 
-       return &priv->ieee_rates[i];
+       sel->rate = &priv->ieee_rates[i];
 }
 
 static void *rs_alloc_sta(void *priv, gfp_t gfp)
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index d6a97a6..5bf7a5b 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -859,10 +859,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct 
sk_buff *skb,
                        sta_info_put(sta);
                        return;
                }
-       } else {
-               /* FIXME: STUPID to call this with both local and local->mdev */
-               rate_control_tx_status(local, local->mdev, skb, status);
-       }
+       } else
+               rate_control_tx_status(local->mdev, skb, status);
 
        ieee80211_led_tx(local, 0);
 
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c
index c3f2783..e495b09 100644
--- a/net/mac80211/ieee80211_rate.c
+++ b/net/mac80211/ieee80211_rate.c
@@ -147,6 +147,53 @@ static void rate_control_release(struct kref *kref)
        kfree(ctrl_ref);
 }
 
+void rate_control_get_rate(struct net_device *dev,
+                          struct ieee80211_hw_mode *mode, 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);
+       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);
+
+       /* 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];
+
+       /* 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);
+
+       /* 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)
+                               break;
+
+                       if (rate_supported(sta, mode, i) &&
+                           !(rate->flags & IEEE80211_RATE_ERP))
+                               sel->nonerp = rate;
+               }
+       }
+
+       if (sta)
+               sta_info_put(sta);
+}
+
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
 {
        kref_get(&ref->kref);
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h
index 2368813..787134b 100644
--- a/net/mac80211/ieee80211_rate.h
+++ b/net/mac80211/ieee80211_rate.h
@@ -18,31 +18,24 @@
 #include "ieee80211_i.h"
 #include "sta_info.h"
 
-#define RATE_CONTROL_NUM_DOWN 20
-#define RATE_CONTROL_NUM_UP   15
-
-
-struct rate_control_extra {
-       /* values from rate_control_get_rate() to the caller: */
-       struct ieee80211_rate *probe; /* probe with this rate, or NULL for no
-                                      * probing */
+struct rate_selection {
+       /* Selected transmission rate */
+       struct ieee80211_rate *rate;
+       /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
        struct ieee80211_rate *nonerp;
-
-       /* parameters from the caller to rate_control_get_rate(): */
-       struct ieee80211_hw_mode *mode;
-       u16 ethertype;
+       /* probe with this rate, or NULL for no probing */
+       struct ieee80211_rate *probe;
 };
 
-
 struct rate_control_ops {
        struct module *module;
        const char *name;
        void (*tx_status)(void *priv, struct net_device *dev,
                          struct sk_buff *skb,
                          struct ieee80211_tx_status *status);
-       struct ieee80211_rate *(*get_rate)(void *priv, struct net_device *dev,
-                                          struct sk_buff *skb,
-                                          struct rate_control_extra *extra);
+       void (*get_rate)(void *priv, struct net_device *dev,
+                        struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                        struct rate_selection *sel);
        void (*rate_init)(void *priv, void *priv_sta,
                          struct ieee80211_local *local, struct sta_info *sta);
        void (*clear)(void *priv);
@@ -75,25 +68,20 @@ void ieee80211_rate_control_unregister(struct 
rate_control_ops *ops);
  * first available algorithm. */
 struct rate_control_ref *rate_control_alloc(const char *name,
                                            struct ieee80211_local *local);
+void rate_control_get_rate(struct net_device *dev,
+                          struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                          struct rate_selection *sel);
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
 void rate_control_put(struct rate_control_ref *ref);
 
-static inline void rate_control_tx_status(struct ieee80211_local *local,
-                                         struct net_device *dev,
+static inline void rate_control_tx_status(struct net_device *dev,
                                          struct sk_buff *skb,
                                          struct ieee80211_tx_status *status)
 {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct rate_control_ref *ref = local->rate_ctrl;
-       ref->ops->tx_status(ref->priv, dev, skb, status);
-}
 
-
-static inline struct ieee80211_rate *
-rate_control_get_rate(struct ieee80211_local *local, struct net_device *dev,
-                     struct sk_buff *skb, struct rate_control_extra *extra)
-{
-       struct rate_control_ref *ref = local->rate_ctrl;
-       return ref->ops->get_rate(ref->priv, dev, skb, extra);
+       ref->ops->tx_status(ref->priv, dev, skb, status);
 }
 
 
@@ -142,6 +130,37 @@ static inline void rate_control_remove_sta_debugfs(struct 
sta_info *sta)
 #endif
 }
 
+static inline int
+rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index)
+{
+       return (sta == NULL || sta->supp_rates & BIT(index)) &&
+              (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED);
+}
+
+static inline int
+rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode 
*mode,
+                 struct sta_info *sta)
+{
+       int i;
+
+       for (i = 0; i < mode->num_rates; i++) {
+               if (rate_supported(sta, mode, i))
+                       return i;
+       }
+
+       /* warn when we cannot find a rate. */
+       WARN_ON(1);
+
+       return 0;
+}
+
+static inline struct ieee80211_rate *
+rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
+           struct sta_info *sta)
+{
+       return &mode->rates[rate_lowest_index(local, mode, sta)];
+}
+
 
 /* functions for rate control related to a device */
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 3c552fe..3978ad6 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2463,9 +2463,8 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
        struct ieee80211_tx_control control;
-       struct ieee80211_rate *rate;
        struct ieee80211_hw_mode *mode;
-       struct rate_control_extra extra;
+       struct rate_selection ratesel;
        u8 *pos;
        struct ieee80211_sub_if_data *sdata;
 
@@ -2550,18 +2549,16 @@ static int ieee80211_sta_join_ibss(struct net_device 
*dev,
                }
 
                memset(&control, 0, sizeof(control));
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = local->oper_hw_mode;
-               rate = rate_control_get_rate(local, dev, skb, &extra);
-               if (!rate) {
+               rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel);
+               if (!ratesel.rate) {
                        printk(KERN_DEBUG "%s: Failed to determine TX rate "
                               "for IBSS beacon\n", dev->name);
                        break;
                }
                control.tx_rate =
                        ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
-                       (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
-                       rate->val2 : rate->val;
+                       (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
+                       ratesel.rate->val2 : ratesel.rate->val;
                control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control.power_level = local->hw.conf.power_level;
                control.flags |= IEEE80211_TXCTL_NO_ACK;
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index da72737..c1c8b76 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -23,6 +23,8 @@
 /* This is a minimal implementation of TX rate controlling that can be used
  * as the default when no improved mechanisms are available. */
 
+#define RATE_CONTROL_NUM_DOWN 20
+#define RATE_CONTROL_NUM_UP   15
 
 #define RATE_CONTROL_EMERG_DEC 2
 #define RATE_CONTROL_INTERVAL (HZ / 20)
@@ -87,26 +89,6 @@ static void rate_control_rate_dec(struct ieee80211_local 
*local,
        }
 }
 
-
-static struct ieee80211_rate *
-rate_control_lowest_rate(struct ieee80211_local *local,
-                        struct ieee80211_hw_mode *mode)
-{
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
-              "found\n");
-       return &mode->rates[0];
-}
-
-
 struct global_rate_control {
        int dummy;
 };
@@ -216,56 +198,32 @@ static void rate_control_simple_tx_status(void *priv, 
struct net_device *dev,
 }
 
 
-static struct ieee80211_rate *
+static void
 rate_control_simple_get_rate(void *priv, struct net_device *dev,
+                            struct ieee80211_hw_mode *mode,
                             struct sk_buff *skb,
-                            struct rate_control_extra *extra)
+                            struct rate_selection *sel)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_sub_if_data *sdata;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_hw_mode *mode = extra->mode;
        struct sta_info *sta;
-       int rateidx, nonerp_idx;
-       u16 fc;
-
-       memset(extra, 0, sizeof(*extra));
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           (hdr->addr1[0] & 0x01)) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               return rate_control_lowest_rate(local, mode);
-       }
+       int rateidx;
 
        sta = sta_info_get(local, hdr->addr1);
 
-       if (!sta)
-               return rate_control_lowest_rate(local, mode);
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
-               sta->txrate = sdata->bss->force_unicast_rateidx;
+       if (!sta) {
+               sel->rate = rate_lowest(local, mode, NULL);
+               return;
+       }
 
        rateidx = sta->txrate;
 
        if (rateidx >= mode->num_rates)
                rateidx = mode->num_rates - 1;
 
-       sta->last_txrate = rateidx;
-       nonerp_idx = rateidx;
-       while (nonerp_idx > 0 &&
-              ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
-               !(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
-               !(sta->supp_rates & BIT(nonerp_idx))))
-               nonerp_idx--;
-       extra->nonerp = &mode->rates[nonerp_idx];
-
        sta_info_put(sta);
 
-       return &mode->rates[rateidx];
+       sel->rate = &mode->rates[rateidx];
 }
 
 
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 12c1558..4655e30 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -569,21 +569,17 @@ ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
 static ieee80211_txrx_result
 ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
 {
-       struct rate_control_extra extra;
+       struct rate_selection rsel;
 
        if (likely(!tx->u.tx.rate)) {
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = tx->u.tx.mode;
-               extra.ethertype = tx->ethertype;
-
-               tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
-                                                     tx->skb, &extra);
-               if (unlikely(extra.probe != NULL)) {
+               rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel);
+               tx->u.tx.rate = rsel.rate;
+               if (unlikely(rsel.probe != NULL)) {
                        tx->u.tx.control->flags |=
                                IEEE80211_TXCTL_RATE_CTRL_PROBE;
                        tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
                        tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
-                       tx->u.tx.rate = extra.probe;
+                       tx->u.tx.rate = rsel.probe;
                } else
                        tx->u.tx.control->alt_retry_rate = -1;
 
@@ -594,14 +590,14 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
 
        if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
            (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
-           (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) {
+           (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) {
                tx->u.tx.last_frag_rate = tx->u.tx.rate;
-               if (extra.probe)
+               if (rsel.probe)
                        tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
                else
                        tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
-               tx->u.tx.rate = extra.nonerp;
-               tx->u.tx.control->rate = extra.nonerp;
+               tx->u.tx.rate = rsel.nonerp;
+               tx->u.tx.control->rate = rsel.nonerp;
                tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
        } else {
                tx->u.tx.last_frag_rate = tx->u.tx.rate;
@@ -1667,8 +1663,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw 
*hw, int if_id,
        struct net_device *bdev;
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_if_ap *ap = NULL;
-       struct ieee80211_rate *rate;
-       struct rate_control_extra extra;
+       struct rate_selection rsel;
        u8 *b_head, *b_tail;
        int bh_len, bt_len;
 
@@ -1712,14 +1707,13 @@ struct sk_buff *ieee80211_beacon_get(struct 
ieee80211_hw *hw, int if_id,
        }
 
        if (control) {
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = local->oper_hw_mode;
-
-               rate = rate_control_get_rate(local, local->mdev, skb, &extra);
-               if (!rate) {
+               rate_control_get_rate(local->mdev, local->oper_hw_mode, skb,
+                                     &rsel);
+               if (!rsel.rate) {
                        if (net_ratelimit()) {
-                               printk(KERN_DEBUG "%s: ieee80211_beacon_get: no 
rate "
-                                      "found\n", wiphy_name(local->hw.wiphy));
+                               printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
+                                      "no rate found\n",
+                                      wiphy_name(local->hw.wiphy));
                        }
                        dev_kfree_skb(skb);
                        return NULL;
@@ -1727,8 +1721,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw 
*hw, int if_id,
 
                control->tx_rate =
                        ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
-                       (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
-                       rate->val2 : rate->val;
+                       (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
+                       rsel.rate->val2 : rsel.rate->val;
                control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control->power_level = local->hw.conf.power_level;
                control->flags |= IEEE80211_TXCTL_NO_ACK;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to