diff options
author | Mattias Nissler <mattias.nissler@gmx.de> | 2007-12-20 07:50:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:17 -0500 |
commit | 1abbe498e4b5e4f2000dfc30a0fa25be9553530e (patch) | |
tree | 8f899d2f623b2316f874fd8ae4b84838ad4e8b40 /net/mac80211/rc80211_simple.c | |
parent | 98f0b0a3a412eade153c7cf00c6b863600980d89 (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>
Diffstat (limited to 'net/mac80211/rc80211_simple.c')
-rw-r--r-- | net/mac80211/rc80211_simple.c | 64 |
1 files changed, 11 insertions, 53 deletions
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 | |||
91 | static struct ieee80211_rate * | ||
92 | rate_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 | |||
110 | struct global_rate_control { | 92 | struct 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 | ||
219 | static struct ieee80211_rate * | 201 | static void |
220 | rate_control_simple_get_rate(void *priv, struct net_device *dev, | 202 | rate_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 | ||