aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rate.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rate.c')
-rw-r--r--net/mac80211/rate.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 5d786720d935..3fa7ab285066 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -199,48 +199,44 @@ static void rate_control_release(struct kref *kref)
199} 199}
200 200
201void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, 201void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
202 struct ieee80211_supported_band *sband, 202 struct sta_info *sta,
203 struct sta_info *sta, struct sk_buff *skb, 203 struct ieee80211_tx_rate_control *txrc)
204 struct rate_selection *sel)
205{ 204{
206 struct rate_control_ref *ref = sdata->local->rate_ctrl; 205 struct rate_control_ref *ref = sdata->local->rate_ctrl;
207 void *priv_sta = NULL; 206 void *priv_sta = NULL;
208 struct ieee80211_sta *ista = NULL; 207 struct ieee80211_sta *ista = NULL;
208 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
209 int i; 209 int i;
210 210
211 sel->rate_idx = -1;
212 sel->nonerp_idx = -1;
213 sel->probe_idx = -1;
214 sel->max_rate_idx = sdata->max_ratectrl_rateidx;
215
216 if (sta) { 211 if (sta) {
217 ista = &sta->sta; 212 ista = &sta->sta;
218 priv_sta = sta->rate_ctrl_priv; 213 priv_sta = sta->rate_ctrl_priv;
219 } 214 }
220 215
216 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
217 info->control.rates[i].idx = -1;
218 info->control.rates[i].flags = 0;
219 info->control.rates[i].count = 1;
220 }
221
221 if (sta && sdata->force_unicast_rateidx > -1) 222 if (sta && sdata->force_unicast_rateidx > -1)
222 sel->rate_idx = sdata->force_unicast_rateidx; 223 info->control.rates[0].idx = sdata->force_unicast_rateidx;
223 else 224 else
224 ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel); 225 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
225 226
226 if (sdata->max_ratectrl_rateidx > -1 && 227 /*
227 sel->rate_idx > sdata->max_ratectrl_rateidx) 228 * try to enforce the maximum rate the user wanted
228 sel->rate_idx = sdata->max_ratectrl_rateidx; 229 */
229 230 if (sdata->max_ratectrl_rateidx > -1)
230 BUG_ON(sel->rate_idx < 0); 231 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
231 232 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
232 /* Select a non-ERP backup rate. */ 233 continue;
233 if (sel->nonerp_idx < 0) { 234 info->control.rates[i].idx =
234 for (i = 0; i < sband->n_bitrates; i++) { 235 min_t(s8, info->control.rates[i].idx,
235 struct ieee80211_rate *rate = &sband->bitrates[i]; 236 sdata->max_ratectrl_rateidx);
236 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
237 break;
238
239 if (rate_supported(ista, sband->band, i) &&
240 !(rate->flags & IEEE80211_RATE_ERP_G))
241 sel->nonerp_idx = i;
242 }
243 } 237 }
238
239 BUG_ON(info->control.rates[0].idx < 0);
244} 240}
245 241
246struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 242struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)