aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Nissler <mattias.nissler@gmx.de>2007-12-20 07:50:07 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:17 -0500
commit1abbe498e4b5e4f2000dfc30a0fa25be9553530e (patch)
tree8f899d2f623b2316f874fd8ae4b84838ad4e8b40
parent98f0b0a3a412eade153c7cf00c6b863600980d89 (diff)
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 <stefano.brivio@polimi.it> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c46
-rw-r--r--net/mac80211/ieee80211.c6
-rw-r--r--net/mac80211/ieee80211_rate.c47
-rw-r--r--net/mac80211/ieee80211_rate.h73
-rw-r--r--net/mac80211/ieee80211_sta.c13
-rw-r--r--net/mac80211/rc80211_simple.c64
-rw-r--r--net/mac80211/tx.c42
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 c48b1b537d2b..ea7f459e961b 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,
562 return; 562 return;
563} 563}
564 564
565static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local
566 *local)
567{
568 struct ieee80211_hw_mode *mode = local->oper_hw_mode;
569 int i;
570
571 for (i = 0; i < mode->num_rates; i++) {
572 struct ieee80211_rate *rate = &mode->rates[i];
573
574 if (rate->flags & IEEE80211_RATE_SUPPORTED)
575 return rate;
576 }
577
578 return &mode->rates[0];
579}
580
581static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv, 565static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
582 u8 index, u16 rate_mask, int phymode) 566 u8 index, u16 rate_mask, int phymode)
583{ 567{
@@ -656,10 +640,9 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
656 * rate table and must reference the driver allocated rate table 640 * rate table and must reference the driver allocated rate table
657 * 641 *
658 */ 642 */
659static struct ieee80211_rate *rs_get_rate(void *priv_rate, 643static void rs_get_rate(void *priv_rate, struct net_device *dev,
660 struct net_device *dev, 644 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
661 struct sk_buff *skb, 645 struct rate_selection *sel)
662 struct rate_control_extra *extra)
663{ 646{
664 u8 low = IWL_RATE_INVALID; 647 u8 low = IWL_RATE_INVALID;
665 u8 high = IWL_RATE_INVALID; 648 u8 high = IWL_RATE_INVALID;
@@ -676,32 +659,19 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
676 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 659 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
677 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 660 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
678 struct sta_info *sta; 661 struct sta_info *sta;
679 u16 fc, rate_mask; 662 u16 rate_mask;
680 struct iwl_priv *priv = (struct iwl_priv *)priv_rate; 663 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
681 DECLARE_MAC_BUF(mac); 664 DECLARE_MAC_BUF(mac);
682 665
683 IWL_DEBUG_RATE("enter\n"); 666 IWL_DEBUG_RATE("enter\n");
684 667
685 memset(extra, 0, sizeof(*extra));
686
687 fc = le16_to_cpu(hdr->frame_control);
688 if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
689 (is_multicast_ether_addr(hdr->addr1))) {
690 /* Send management frames and broadcast/multicast data using
691 * lowest rate. */
692 /* TODO: this could probably be improved.. */
693 IWL_DEBUG_RATE("leave: lowest rate (not data or is "
694 "multicast)\n");
695
696 return iwl_get_lowest_rate(local);
697 }
698
699 sta = sta_info_get(local, hdr->addr1); 668 sta = sta_info_get(local, hdr->addr1);
700 if (!sta || !sta->rate_ctrl_priv) { 669 if (!sta || !sta->rate_ctrl_priv) {
701 IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); 670 IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
671 sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
702 if (sta) 672 if (sta)
703 sta_info_put(sta); 673 sta_info_put(sta);
704 return NULL; 674 return;
705 } 675 }
706 676
707 rate_mask = sta->supp_rates; 677 rate_mask = sta->supp_rates;
@@ -846,7 +816,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
846 816
847 IWL_DEBUG_RATE("leave: %d\n", index); 817 IWL_DEBUG_RATE("leave: %d\n", index);
848 818
849 return &priv->ieee_rates[index]; 819 sel->rate = &priv->ieee_rates[index];
850} 820}
851 821
852static struct rate_control_ops rs_ops = { 822static 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 8dc78c0bf1ff..62a3b52b3270 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,
1693 return; 1693 return;
1694} 1694}
1695 1695
1696static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local 1696static void rs_get_rate(void *priv_rate, struct net_device *dev,
1697 *local) 1697 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
1698{ 1698 struct rate_selection *sel)
1699 struct ieee80211_hw_mode *mode = local->oper_hw_mode;
1700 int i;
1701
1702 for (i = 0; i < mode->num_rates; i++) {
1703 struct ieee80211_rate *rate = &mode->rates[i];
1704
1705 if (rate->flags & IEEE80211_RATE_SUPPORTED)
1706 return rate;
1707 }
1708
1709 return &mode->rates[0];
1710}
1711
1712static struct ieee80211_rate *rs_get_rate(void *priv_rate,
1713 struct net_device *dev,
1714 struct sk_buff *skb,
1715 struct rate_control_extra
1716 *extra)
1717{ 1699{
1718 1700
1719 int i; 1701 int i;
1720 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1702 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1721 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1703 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1722 struct sta_info *sta; 1704 struct sta_info *sta;
1723 u16 fc;
1724 struct iwl_priv *priv = (struct iwl_priv *)priv_rate; 1705 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
1725 struct iwl_rate_scale_priv *lq; 1706 struct iwl_rate_scale_priv *lq;
1726 1707
1727 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); 1708 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
1728 1709
1729 memset(extra, 0, sizeof(*extra));
1730
1731 fc = le16_to_cpu(hdr->frame_control);
1732 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
1733 /* Send management frames and broadcast/multicast data using
1734 * lowest rate. */
1735 /* TODO: this could probably be improved.. */
1736 return rs_get_lowest_rate(local);
1737 }
1738
1739 sta = sta_info_get(local, hdr->addr1); 1710 sta = sta_info_get(local, hdr->addr1);
1740 1711
1741 if (!sta || !sta->rate_ctrl_priv) { 1712 if (!sta || !sta->rate_ctrl_priv) {
1713 sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
1742 if (sta) 1714 if (sta)
1743 sta_info_put(sta); 1715 sta_info_put(sta);
1744 return rs_get_lowest_rate(local); 1716 return;
1745 } 1717 }
1746 1718
1747 lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv; 1719 lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
@@ -1768,11 +1740,13 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
1768 } 1740 }
1769 1741
1770 done: 1742 done:
1743 if ((i < 0) || (i > IWL_RATE_COUNT)) {
1744 sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
1745 return;
1746 }
1771 sta_info_put(sta); 1747 sta_info_put(sta);
1772 if ((i < 0) || (i > IWL_RATE_COUNT))
1773 return rs_get_lowest_rate(local);
1774 1748
1775 return &priv->ieee_rates[i]; 1749 sel->rate = &priv->ieee_rates[i];
1776} 1750}
1777 1751
1778static void *rs_alloc_sta(void *priv, gfp_t gfp) 1752static void *rs_alloc_sta(void *priv, gfp_t gfp)
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index d6a97a68a62e..5bf7a5bebfc9 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,
859 sta_info_put(sta); 859 sta_info_put(sta);
860 return; 860 return;
861 } 861 }
862 } else { 862 } else
863 /* FIXME: STUPID to call this with both local and local->mdev */ 863 rate_control_tx_status(local->mdev, skb, status);
864 rate_control_tx_status(local, local->mdev, skb, status);
865 }
866 864
867 ieee80211_led_tx(local, 0); 865 ieee80211_led_tx(local, 0);
868 866
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c
index c3f278393741..e495b0998b4d 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)
147 kfree(ctrl_ref); 147 kfree(ctrl_ref);
148} 148}
149 149
150void rate_control_get_rate(struct net_device *dev,
151 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
152 struct rate_selection *sel)
153{
154 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
155 struct rate_control_ref *ref = local->rate_ctrl;
156 struct ieee80211_sub_if_data *sdata;
157 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
158 struct sta_info *sta = sta_info_get(local, hdr->addr1);
159 int i;
160 u16 fc;
161
162 memset(sel, 0, sizeof(struct rate_selection));
163
164 /* Send management frames and broadcast/multicast data using lowest
165 * rate. */
166 fc = le16_to_cpu(hdr->frame_control);
167 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
168 is_multicast_ether_addr(hdr->addr1))
169 sel->rate = rate_lowest(local, mode, sta);
170
171 /* If a forced rate is in effect, select it. */
172 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
173 if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
174 sel->rate = &mode->rates[sdata->bss->force_unicast_rateidx];
175
176 /* If we haven't found the rate yet, ask the rate control algo. */
177 if (!sel->rate)
178 ref->ops->get_rate(ref->priv, dev, mode, skb, sel);
179
180 /* Select a non-ERP backup rate. */
181 if (!sel->nonerp) {
182 for (i = 0; i < mode->num_rates - 1; i++) {
183 struct ieee80211_rate *rate = &mode->rates[i];
184 if (sel->rate->rate < rate->rate)
185 break;
186
187 if (rate_supported(sta, mode, i) &&
188 !(rate->flags & IEEE80211_RATE_ERP))
189 sel->nonerp = rate;
190 }
191 }
192
193 if (sta)
194 sta_info_put(sta);
195}
196
150struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 197struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
151{ 198{
152 kref_get(&ref->kref); 199 kref_get(&ref->kref);
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h
index 23688139ffb3..787134bd6abf 100644
--- a/net/mac80211/ieee80211_rate.h
+++ b/net/mac80211/ieee80211_rate.h
@@ -18,31 +18,24 @@
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "sta_info.h" 19#include "sta_info.h"
20 20
21#define RATE_CONTROL_NUM_DOWN 20 21struct rate_selection {
22#define RATE_CONTROL_NUM_UP 15 22 /* Selected transmission rate */
23 23 struct ieee80211_rate *rate;
24 24 /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
25struct rate_control_extra {
26 /* values from rate_control_get_rate() to the caller: */
27 struct ieee80211_rate *probe; /* probe with this rate, or NULL for no
28 * probing */
29 struct ieee80211_rate *nonerp; 25 struct ieee80211_rate *nonerp;
30 26 /* probe with this rate, or NULL for no probing */
31 /* parameters from the caller to rate_control_get_rate(): */ 27 struct ieee80211_rate *probe;
32 struct ieee80211_hw_mode *mode;
33 u16 ethertype;
34}; 28};
35 29
36
37struct rate_control_ops { 30struct rate_control_ops {
38 struct module *module; 31 struct module *module;
39 const char *name; 32 const char *name;
40 void (*tx_status)(void *priv, struct net_device *dev, 33 void (*tx_status)(void *priv, struct net_device *dev,
41 struct sk_buff *skb, 34 struct sk_buff *skb,
42 struct ieee80211_tx_status *status); 35 struct ieee80211_tx_status *status);
43 struct ieee80211_rate *(*get_rate)(void *priv, struct net_device *dev, 36 void (*get_rate)(void *priv, struct net_device *dev,
44 struct sk_buff *skb, 37 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
45 struct rate_control_extra *extra); 38 struct rate_selection *sel);
46 void (*rate_init)(void *priv, void *priv_sta, 39 void (*rate_init)(void *priv, void *priv_sta,
47 struct ieee80211_local *local, struct sta_info *sta); 40 struct ieee80211_local *local, struct sta_info *sta);
48 void (*clear)(void *priv); 41 void (*clear)(void *priv);
@@ -75,25 +68,20 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
75 * first available algorithm. */ 68 * first available algorithm. */
76struct rate_control_ref *rate_control_alloc(const char *name, 69struct rate_control_ref *rate_control_alloc(const char *name,
77 struct ieee80211_local *local); 70 struct ieee80211_local *local);
71void rate_control_get_rate(struct net_device *dev,
72 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
73 struct rate_selection *sel);
78struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); 74struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
79void rate_control_put(struct rate_control_ref *ref); 75void rate_control_put(struct rate_control_ref *ref);
80 76
81static inline void rate_control_tx_status(struct ieee80211_local *local, 77static inline void rate_control_tx_status(struct net_device *dev,
82 struct net_device *dev,
83 struct sk_buff *skb, 78 struct sk_buff *skb,
84 struct ieee80211_tx_status *status) 79 struct ieee80211_tx_status *status)
85{ 80{
81 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
86 struct rate_control_ref *ref = local->rate_ctrl; 82 struct rate_control_ref *ref = local->rate_ctrl;
87 ref->ops->tx_status(ref->priv, dev, skb, status);
88}
89 83
90 84 ref->ops->tx_status(ref->priv, dev, skb, status);
91static inline struct ieee80211_rate *
92rate_control_get_rate(struct ieee80211_local *local, struct net_device *dev,
93 struct sk_buff *skb, struct rate_control_extra *extra)
94{
95 struct rate_control_ref *ref = local->rate_ctrl;
96 return ref->ops->get_rate(ref->priv, dev, skb, extra);
97} 85}
98 86
99 87
@@ -142,6 +130,37 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
142#endif 130#endif
143} 131}
144 132
133static inline int
134rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index)
135{
136 return (sta == NULL || sta->supp_rates & BIT(index)) &&
137 (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED);
138}
139
140static inline int
141rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
142 struct sta_info *sta)
143{
144 int i;
145
146 for (i = 0; i < mode->num_rates; i++) {
147 if (rate_supported(sta, mode, i))
148 return i;
149 }
150
151 /* warn when we cannot find a rate. */
152 WARN_ON(1);
153
154 return 0;
155}
156
157static inline struct ieee80211_rate *
158rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
159 struct sta_info *sta)
160{
161 return &mode->rates[rate_lowest_index(local, mode, sta)];
162}
163
145 164
146/* functions for rate control related to a device */ 165/* functions for rate control related to a device */
147int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 166int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 3c552fed2af5..3978ad606b5c 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,
2463 struct sk_buff *skb; 2463 struct sk_buff *skb;
2464 struct ieee80211_mgmt *mgmt; 2464 struct ieee80211_mgmt *mgmt;
2465 struct ieee80211_tx_control control; 2465 struct ieee80211_tx_control control;
2466 struct ieee80211_rate *rate;
2467 struct ieee80211_hw_mode *mode; 2466 struct ieee80211_hw_mode *mode;
2468 struct rate_control_extra extra; 2467 struct rate_selection ratesel;
2469 u8 *pos; 2468 u8 *pos;
2470 struct ieee80211_sub_if_data *sdata; 2469 struct ieee80211_sub_if_data *sdata;
2471 2470
@@ -2550,18 +2549,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2550 } 2549 }
2551 2550
2552 memset(&control, 0, sizeof(control)); 2551 memset(&control, 0, sizeof(control));
2553 memset(&extra, 0, sizeof(extra)); 2552 rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel);
2554 extra.mode = local->oper_hw_mode; 2553 if (!ratesel.rate) {
2555 rate = rate_control_get_rate(local, dev, skb, &extra);
2556 if (!rate) {
2557 printk(KERN_DEBUG "%s: Failed to determine TX rate " 2554 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2558 "for IBSS beacon\n", dev->name); 2555 "for IBSS beacon\n", dev->name);
2559 break; 2556 break;
2560 } 2557 }
2561 control.tx_rate = 2558 control.tx_rate =
2562 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && 2559 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
2563 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 2560 (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2564 rate->val2 : rate->val; 2561 ratesel.rate->val2 : ratesel.rate->val;
2565 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2562 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2566 control.power_level = local->hw.conf.power_level; 2563 control.power_level = local->hw.conf.power_level;
2567 control.flags |= IEEE80211_TXCTL_NO_ACK; 2564 control.flags |= IEEE80211_TXCTL_NO_ACK;
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index da72737364e4..c1c8b76a56af 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -23,6 +23,8 @@
23/* This is a minimal implementation of TX rate controlling that can be used 23/* This is a minimal implementation of TX rate controlling that can be used
24 * as the default when no improved mechanisms are available. */ 24 * as the default when no improved mechanisms are available. */
25 25
26#define RATE_CONTROL_NUM_DOWN 20
27#define RATE_CONTROL_NUM_UP 15
26 28
27#define RATE_CONTROL_EMERG_DEC 2 29#define RATE_CONTROL_EMERG_DEC 2
28#define RATE_CONTROL_INTERVAL (HZ / 20) 30#define RATE_CONTROL_INTERVAL (HZ / 20)
@@ -87,26 +89,6 @@ static void rate_control_rate_dec(struct ieee80211_local *local,
87 } 89 }
88} 90}
89 91
90
91static struct ieee80211_rate *
92rate_control_lowest_rate(struct ieee80211_local *local,
93 struct ieee80211_hw_mode *mode)
94{
95 int i;
96
97 for (i = 0; i < mode->num_rates; i++) {
98 struct ieee80211_rate *rate = &mode->rates[i];
99
100 if (rate->flags & IEEE80211_RATE_SUPPORTED)
101 return rate;
102 }
103
104 printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
105 "found\n");
106 return &mode->rates[0];
107}
108
109
110struct global_rate_control { 92struct global_rate_control {
111 int dummy; 93 int dummy;
112}; 94};
@@ -216,56 +198,32 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
216} 198}
217 199
218 200
219static struct ieee80211_rate * 201static void
220rate_control_simple_get_rate(void *priv, struct net_device *dev, 202rate_control_simple_get_rate(void *priv, struct net_device *dev,
203 struct ieee80211_hw_mode *mode,
221 struct sk_buff *skb, 204 struct sk_buff *skb,
222 struct rate_control_extra *extra) 205 struct rate_selection *sel)
223{ 206{
224 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 207 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
225 struct ieee80211_sub_if_data *sdata;
226 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
227 struct ieee80211_hw_mode *mode = extra->mode;
228 struct sta_info *sta; 209 struct sta_info *sta;
229 int rateidx, nonerp_idx; 210 int rateidx;
230 u16 fc;
231
232 memset(extra, 0, sizeof(*extra));
233
234 fc = le16_to_cpu(hdr->frame_control);
235 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
236 (hdr->addr1[0] & 0x01)) {
237 /* Send management frames and broadcast/multicast data using
238 * lowest rate. */
239 /* TODO: this could probably be improved.. */
240 return rate_control_lowest_rate(local, mode);
241 }
242 211
243 sta = sta_info_get(local, hdr->addr1); 212 sta = sta_info_get(local, hdr->addr1);
244 213
245 if (!sta) 214 if (!sta) {
246 return rate_control_lowest_rate(local, mode); 215 sel->rate = rate_lowest(local, mode, NULL);
247 216 return;
248 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 217 }
249 if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
250 sta->txrate = sdata->bss->force_unicast_rateidx;
251 218
252 rateidx = sta->txrate; 219 rateidx = sta->txrate;
253 220
254 if (rateidx >= mode->num_rates) 221 if (rateidx >= mode->num_rates)
255 rateidx = mode->num_rates - 1; 222 rateidx = mode->num_rates - 1;
256 223
257 sta->last_txrate = rateidx;
258 nonerp_idx = rateidx;
259 while (nonerp_idx > 0 &&
260 ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
261 !(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
262 !(sta->supp_rates & BIT(nonerp_idx))))
263 nonerp_idx--;
264 extra->nonerp = &mode->rates[nonerp_idx];
265
266 sta_info_put(sta); 224 sta_info_put(sta);
267 225
268 return &mode->rates[rateidx]; 226 sel->rate = &mode->rates[rateidx];
269} 227}
270 228
271 229
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 12c15588af68..4655e3038658 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -569,21 +569,17 @@ ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
569static ieee80211_txrx_result 569static ieee80211_txrx_result
570ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) 570ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
571{ 571{
572 struct rate_control_extra extra; 572 struct rate_selection rsel;
573 573
574 if (likely(!tx->u.tx.rate)) { 574 if (likely(!tx->u.tx.rate)) {
575 memset(&extra, 0, sizeof(extra)); 575 rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel);
576 extra.mode = tx->u.tx.mode; 576 tx->u.tx.rate = rsel.rate;
577 extra.ethertype = tx->ethertype; 577 if (unlikely(rsel.probe != NULL)) {
578
579 tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
580 tx->skb, &extra);
581 if (unlikely(extra.probe != NULL)) {
582 tx->u.tx.control->flags |= 578 tx->u.tx.control->flags |=
583 IEEE80211_TXCTL_RATE_CTRL_PROBE; 579 IEEE80211_TXCTL_RATE_CTRL_PROBE;
584 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 580 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
585 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; 581 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
586 tx->u.tx.rate = extra.probe; 582 tx->u.tx.rate = rsel.probe;
587 } else 583 } else
588 tx->u.tx.control->alt_retry_rate = -1; 584 tx->u.tx.control->alt_retry_rate = -1;
589 585
@@ -594,14 +590,14 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
594 590
595 if (tx->u.tx.mode->mode == MODE_IEEE80211G && 591 if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
596 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) && 592 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
597 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) { 593 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) {
598 tx->u.tx.last_frag_rate = tx->u.tx.rate; 594 tx->u.tx.last_frag_rate = tx->u.tx.rate;
599 if (extra.probe) 595 if (rsel.probe)
600 tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 596 tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
601 else 597 else
602 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 598 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
603 tx->u.tx.rate = extra.nonerp; 599 tx->u.tx.rate = rsel.nonerp;
604 tx->u.tx.control->rate = extra.nonerp; 600 tx->u.tx.control->rate = rsel.nonerp;
605 tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; 601 tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
606 } else { 602 } else {
607 tx->u.tx.last_frag_rate = tx->u.tx.rate; 603 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,
1667 struct net_device *bdev; 1663 struct net_device *bdev;
1668 struct ieee80211_sub_if_data *sdata = NULL; 1664 struct ieee80211_sub_if_data *sdata = NULL;
1669 struct ieee80211_if_ap *ap = NULL; 1665 struct ieee80211_if_ap *ap = NULL;
1670 struct ieee80211_rate *rate; 1666 struct rate_selection rsel;
1671 struct rate_control_extra extra;
1672 u8 *b_head, *b_tail; 1667 u8 *b_head, *b_tail;
1673 int bh_len, bt_len; 1668 int bh_len, bt_len;
1674 1669
@@ -1712,14 +1707,13 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1712 } 1707 }
1713 1708
1714 if (control) { 1709 if (control) {
1715 memset(&extra, 0, sizeof(extra)); 1710 rate_control_get_rate(local->mdev, local->oper_hw_mode, skb,
1716 extra.mode = local->oper_hw_mode; 1711 &rsel);
1717 1712 if (!rsel.rate) {
1718 rate = rate_control_get_rate(local, local->mdev, skb, &extra);
1719 if (!rate) {
1720 if (net_ratelimit()) { 1713 if (net_ratelimit()) {
1721 printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate " 1714 printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
1722 "found\n", wiphy_name(local->hw.wiphy)); 1715 "no rate found\n",
1716 wiphy_name(local->hw.wiphy));
1723 } 1717 }
1724 dev_kfree_skb(skb); 1718 dev_kfree_skb(skb);
1725 return NULL; 1719 return NULL;
@@ -1727,8 +1721,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1727 1721
1728 control->tx_rate = 1722 control->tx_rate =
1729 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && 1723 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
1730 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 1724 (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
1731 rate->val2 : rate->val; 1725 rsel.rate->val2 : rsel.rate->val;
1732 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1726 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1733 control->power_level = local->hw.conf.power_level; 1727 control->power_level = local->hw.conf.power_level;
1734 control->flags |= IEEE80211_TXCTL_NO_ACK; 1728 control->flags |= IEEE80211_TXCTL_NO_ACK;