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/ieee80211_rate.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/ieee80211_rate.c')
-rw-r--r-- | net/mac80211/ieee80211_rate.c | 47 |
1 files changed, 47 insertions, 0 deletions
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 | ||
150 | void 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 | |||
150 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) | 197 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) |
151 | { | 198 | { |
152 | kref_get(&ref->kref); | 199 | kref_get(&ref->kref); |