diff options
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 124 |
1 files changed, 71 insertions, 53 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 3b77410588e7..a849b745bdb5 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/debugfs.h> | 15 | #include <linux/debugfs.h> |
16 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
17 | #include "ieee80211_rate.h" | 17 | #include "rate.h" |
18 | 18 | #include "mesh.h" | |
19 | #include "rc80211_pid.h" | 19 | #include "rc80211_pid.h" |
20 | 20 | ||
21 | 21 | ||
@@ -63,6 +63,7 @@ | |||
63 | * RC_PID_ARITH_SHIFT. | 63 | * RC_PID_ARITH_SHIFT. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | |||
66 | /* Adjust the rate while ensuring that we won't switch to a lower rate if it | 67 | /* Adjust the rate while ensuring that we won't switch to a lower rate if it |
67 | * exhibited a worse failed frames behaviour and we'll choose the highest rate | 68 | * exhibited a worse failed frames behaviour and we'll choose the highest rate |
68 | * whose failed frames behaviour is not worse than the one of the original rate | 69 | * whose failed frames behaviour is not worse than the one of the original rate |
@@ -72,14 +73,14 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
72 | struct rc_pid_rateinfo *rinfo) | 73 | struct rc_pid_rateinfo *rinfo) |
73 | { | 74 | { |
74 | struct ieee80211_sub_if_data *sdata; | 75 | struct ieee80211_sub_if_data *sdata; |
75 | struct ieee80211_hw_mode *mode; | 76 | struct ieee80211_supported_band *sband; |
76 | int cur_sorted, new_sorted, probe, tmp, n_bitrates; | 77 | int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; |
77 | int cur = sta->txrate; | 78 | int cur = sta->txrate_idx; |
78 | |||
79 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
80 | 79 | ||
81 | mode = local->oper_hw_mode; | 80 | sdata = sta->sdata; |
82 | n_bitrates = mode->num_rates; | 81 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
82 | band = sband->band; | ||
83 | n_bitrates = sband->n_bitrates; | ||
83 | 84 | ||
84 | /* Map passed arguments to sorted values. */ | 85 | /* Map passed arguments to sorted values. */ |
85 | cur_sorted = rinfo[cur].rev_index; | 86 | cur_sorted = rinfo[cur].rev_index; |
@@ -97,20 +98,20 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
97 | /* Ensure that the rate decrease isn't disadvantageous. */ | 98 | /* Ensure that the rate decrease isn't disadvantageous. */ |
98 | for (probe = cur_sorted; probe >= new_sorted; probe--) | 99 | for (probe = cur_sorted; probe >= new_sorted; probe--) |
99 | if (rinfo[probe].diff <= rinfo[cur_sorted].diff && | 100 | if (rinfo[probe].diff <= rinfo[cur_sorted].diff && |
100 | rate_supported(sta, mode, rinfo[probe].index)) | 101 | rate_supported(sta, band, rinfo[probe].index)) |
101 | tmp = probe; | 102 | tmp = probe; |
102 | } else { | 103 | } else { |
103 | /* Look for rate increase with zero (or below) cost. */ | 104 | /* Look for rate increase with zero (or below) cost. */ |
104 | for (probe = new_sorted + 1; probe < n_bitrates; probe++) | 105 | for (probe = new_sorted + 1; probe < n_bitrates; probe++) |
105 | if (rinfo[probe].diff <= rinfo[new_sorted].diff && | 106 | if (rinfo[probe].diff <= rinfo[new_sorted].diff && |
106 | rate_supported(sta, mode, rinfo[probe].index)) | 107 | rate_supported(sta, band, rinfo[probe].index)) |
107 | tmp = probe; | 108 | tmp = probe; |
108 | } | 109 | } |
109 | 110 | ||
110 | /* Fit the rate found to the nearest supported rate. */ | 111 | /* Fit the rate found to the nearest supported rate. */ |
111 | do { | 112 | do { |
112 | if (rate_supported(sta, mode, rinfo[tmp].index)) { | 113 | if (rate_supported(sta, band, rinfo[tmp].index)) { |
113 | sta->txrate = rinfo[tmp].index; | 114 | sta->txrate_idx = rinfo[tmp].index; |
114 | break; | 115 | break; |
115 | } | 116 | } |
116 | if (adj < 0) | 117 | if (adj < 0) |
@@ -122,7 +123,7 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
122 | #ifdef CONFIG_MAC80211_DEBUGFS | 123 | #ifdef CONFIG_MAC80211_DEBUGFS |
123 | rate_control_pid_event_rate_change( | 124 | rate_control_pid_event_rate_change( |
124 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, | 125 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, |
125 | cur, mode->rates[cur].rate); | 126 | sta->txrate_idx, sband->bitrates[sta->txrate_idx].bitrate); |
126 | #endif | 127 | #endif |
127 | } | 128 | } |
128 | 129 | ||
@@ -147,9 +148,12 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
147 | struct ieee80211_local *local, | 148 | struct ieee80211_local *local, |
148 | struct sta_info *sta) | 149 | struct sta_info *sta) |
149 | { | 150 | { |
151 | #ifdef CONFIG_MAC80211_MESH | ||
152 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
153 | #endif | ||
150 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; | 154 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; |
151 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; | 155 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; |
152 | struct ieee80211_hw_mode *mode; | 156 | struct ieee80211_supported_band *sband; |
153 | u32 pf; | 157 | u32 pf; |
154 | s32 err_avg; | 158 | s32 err_avg; |
155 | u32 err_prop; | 159 | u32 err_prop; |
@@ -158,7 +162,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
158 | int adj, i, j, tmp; | 162 | int adj, i, j, tmp; |
159 | unsigned long period; | 163 | unsigned long period; |
160 | 164 | ||
161 | mode = local->oper_hw_mode; | 165 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
162 | spinfo = sta->rate_ctrl_priv; | 166 | spinfo = sta->rate_ctrl_priv; |
163 | 167 | ||
164 | /* In case nothing happened during the previous control interval, turn | 168 | /* In case nothing happened during the previous control interval, turn |
@@ -177,25 +181,32 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
177 | pf = spinfo->last_pf; | 181 | pf = spinfo->last_pf; |
178 | else { | 182 | else { |
179 | pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; | 183 | pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; |
184 | #ifdef CONFIG_MAC80211_MESH | ||
185 | if (pf == 100 && | ||
186 | sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | ||
187 | mesh_plink_broken(sta); | ||
188 | #endif | ||
180 | pf <<= RC_PID_ARITH_SHIFT; | 189 | pf <<= RC_PID_ARITH_SHIFT; |
190 | sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) | ||
191 | >> RC_PID_ARITH_SHIFT; | ||
181 | } | 192 | } |
182 | 193 | ||
183 | spinfo->tx_num_xmit = 0; | 194 | spinfo->tx_num_xmit = 0; |
184 | spinfo->tx_num_failed = 0; | 195 | spinfo->tx_num_failed = 0; |
185 | 196 | ||
186 | /* If we just switched rate, update the rate behaviour info. */ | 197 | /* If we just switched rate, update the rate behaviour info. */ |
187 | if (pinfo->oldrate != sta->txrate) { | 198 | if (pinfo->oldrate != sta->txrate_idx) { |
188 | 199 | ||
189 | i = rinfo[pinfo->oldrate].rev_index; | 200 | i = rinfo[pinfo->oldrate].rev_index; |
190 | j = rinfo[sta->txrate].rev_index; | 201 | j = rinfo[sta->txrate_idx].rev_index; |
191 | 202 | ||
192 | tmp = (pf - spinfo->last_pf); | 203 | tmp = (pf - spinfo->last_pf); |
193 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); | 204 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); |
194 | 205 | ||
195 | rinfo[j].diff = rinfo[i].diff + tmp; | 206 | rinfo[j].diff = rinfo[i].diff + tmp; |
196 | pinfo->oldrate = sta->txrate; | 207 | pinfo->oldrate = sta->txrate_idx; |
197 | } | 208 | } |
198 | rate_control_pid_normalize(pinfo, mode->num_rates); | 209 | rate_control_pid_normalize(pinfo, sband->n_bitrates); |
199 | 210 | ||
200 | /* Compute the proportional, integral and derivative errors. */ | 211 | /* Compute the proportional, integral and derivative errors. */ |
201 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; | 212 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; |
@@ -236,23 +247,27 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
236 | struct sta_info *sta; | 247 | struct sta_info *sta; |
237 | struct rc_pid_sta_info *spinfo; | 248 | struct rc_pid_sta_info *spinfo; |
238 | unsigned long period; | 249 | unsigned long period; |
250 | struct ieee80211_supported_band *sband; | ||
251 | |||
252 | rcu_read_lock(); | ||
239 | 253 | ||
240 | sta = sta_info_get(local, hdr->addr1); | 254 | sta = sta_info_get(local, hdr->addr1); |
255 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
241 | 256 | ||
242 | if (!sta) | 257 | if (!sta) |
243 | return; | 258 | goto unlock; |
244 | 259 | ||
245 | /* Don't update the state if we're not controlling the rate. */ | 260 | /* Don't update the state if we're not controlling the rate. */ |
246 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 261 | sdata = sta->sdata; |
247 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 262 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { |
248 | sta->txrate = sdata->bss->max_ratectrl_rateidx; | 263 | sta->txrate_idx = sdata->bss->max_ratectrl_rateidx; |
249 | return; | 264 | goto unlock; |
250 | } | 265 | } |
251 | 266 | ||
252 | /* Ignore all frames that were sent with a different rate than the rate | 267 | /* Ignore all frames that were sent with a different rate than the rate |
253 | * we currently advise mac80211 to use. */ | 268 | * we currently advise mac80211 to use. */ |
254 | if (status->control.rate != &local->oper_hw_mode->rates[sta->txrate]) | 269 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) |
255 | goto ignore; | 270 | goto unlock; |
256 | 271 | ||
257 | spinfo = sta->rate_ctrl_priv; | 272 | spinfo = sta->rate_ctrl_priv; |
258 | spinfo->tx_num_xmit++; | 273 | spinfo->tx_num_xmit++; |
@@ -277,9 +292,6 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
277 | sta->tx_num_consecutive_failures++; | 292 | sta->tx_num_consecutive_failures++; |
278 | sta->tx_num_mpdu_fail++; | 293 | sta->tx_num_mpdu_fail++; |
279 | } else { | 294 | } else { |
280 | sta->last_ack_rssi[0] = sta->last_ack_rssi[1]; | ||
281 | sta->last_ack_rssi[1] = sta->last_ack_rssi[2]; | ||
282 | sta->last_ack_rssi[2] = status->ack_signal; | ||
283 | sta->tx_num_consecutive_failures = 0; | 295 | sta->tx_num_consecutive_failures = 0; |
284 | sta->tx_num_mpdu_ok++; | 296 | sta->tx_num_mpdu_ok++; |
285 | } | 297 | } |
@@ -293,12 +305,12 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
293 | if (time_after(jiffies, spinfo->last_sample + period)) | 305 | if (time_after(jiffies, spinfo->last_sample + period)) |
294 | rate_control_pid_sample(pinfo, local, sta); | 306 | rate_control_pid_sample(pinfo, local, sta); |
295 | 307 | ||
296 | ignore: | 308 | unlock: |
297 | sta_info_put(sta); | 309 | rcu_read_unlock(); |
298 | } | 310 | } |
299 | 311 | ||
300 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | 312 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, |
301 | struct ieee80211_hw_mode *mode, | 313 | struct ieee80211_supported_band *sband, |
302 | struct sk_buff *skb, | 314 | struct sk_buff *skb, |
303 | struct rate_selection *sel) | 315 | struct rate_selection *sel) |
304 | { | 316 | { |
@@ -309,6 +321,8 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
309 | int rateidx; | 321 | int rateidx; |
310 | u16 fc; | 322 | u16 fc; |
311 | 323 | ||
324 | rcu_read_lock(); | ||
325 | |||
312 | sta = sta_info_get(local, hdr->addr1); | 326 | sta = sta_info_get(local, hdr->addr1); |
313 | 327 | ||
314 | /* Send management frames and broadcast/multicast data using lowest | 328 | /* Send management frames and broadcast/multicast data using lowest |
@@ -316,32 +330,31 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
316 | fc = le16_to_cpu(hdr->frame_control); | 330 | fc = le16_to_cpu(hdr->frame_control); |
317 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
318 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 332 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
319 | sel->rate = rate_lowest(local, mode, sta); | 333 | sel->rate = rate_lowest(local, sband, sta); |
320 | if (sta) | 334 | rcu_read_unlock(); |
321 | sta_info_put(sta); | ||
322 | return; | 335 | return; |
323 | } | 336 | } |
324 | 337 | ||
325 | /* If a forced rate is in effect, select it. */ | 338 | /* If a forced rate is in effect, select it. */ |
326 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 339 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
327 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 340 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) |
328 | sta->txrate = sdata->bss->force_unicast_rateidx; | 341 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; |
329 | 342 | ||
330 | rateidx = sta->txrate; | 343 | rateidx = sta->txrate_idx; |
331 | 344 | ||
332 | if (rateidx >= mode->num_rates) | 345 | if (rateidx >= sband->n_bitrates) |
333 | rateidx = mode->num_rates - 1; | 346 | rateidx = sband->n_bitrates - 1; |
334 | 347 | ||
335 | sta->last_txrate = rateidx; | 348 | sta->last_txrate_idx = rateidx; |
336 | 349 | ||
337 | sta_info_put(sta); | 350 | rcu_read_unlock(); |
338 | 351 | ||
339 | sel->rate = &mode->rates[rateidx]; | 352 | sel->rate = &sband->bitrates[rateidx]; |
340 | 353 | ||
341 | #ifdef CONFIG_MAC80211_DEBUGFS | 354 | #ifdef CONFIG_MAC80211_DEBUGFS |
342 | rate_control_pid_event_tx_rate( | 355 | rate_control_pid_event_tx_rate( |
343 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, | 356 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, |
344 | rateidx, mode->rates[rateidx].rate); | 357 | rateidx, sband->bitrates[rateidx].bitrate); |
345 | #endif | 358 | #endif |
346 | } | 359 | } |
347 | 360 | ||
@@ -353,28 +366,33 @@ static void rate_control_pid_rate_init(void *priv, void *priv_sta, | |||
353 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 366 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
354 | * Until that method is implemented, we will use the lowest supported | 367 | * Until that method is implemented, we will use the lowest supported |
355 | * rate as a workaround. */ | 368 | * rate as a workaround. */ |
356 | sta->txrate = rate_lowest_index(local, local->oper_hw_mode, sta); | 369 | struct ieee80211_supported_band *sband; |
370 | |||
371 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
372 | sta->txrate_idx = rate_lowest_index(local, sband, sta); | ||
373 | sta->fail_avg = 0; | ||
357 | } | 374 | } |
358 | 375 | ||
359 | static void *rate_control_pid_alloc(struct ieee80211_local *local) | 376 | static void *rate_control_pid_alloc(struct ieee80211_local *local) |
360 | { | 377 | { |
361 | struct rc_pid_info *pinfo; | 378 | struct rc_pid_info *pinfo; |
362 | struct rc_pid_rateinfo *rinfo; | 379 | struct rc_pid_rateinfo *rinfo; |
363 | struct ieee80211_hw_mode *mode; | 380 | struct ieee80211_supported_band *sband; |
364 | int i, j, tmp; | 381 | int i, j, tmp; |
365 | bool s; | 382 | bool s; |
366 | #ifdef CONFIG_MAC80211_DEBUGFS | 383 | #ifdef CONFIG_MAC80211_DEBUGFS |
367 | struct rc_pid_debugfs_entries *de; | 384 | struct rc_pid_debugfs_entries *de; |
368 | #endif | 385 | #endif |
369 | 386 | ||
387 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
388 | |||
370 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 389 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
371 | if (!pinfo) | 390 | if (!pinfo) |
372 | return NULL; | 391 | return NULL; |
373 | 392 | ||
374 | /* We can safely assume that oper_hw_mode won't change unless we get | 393 | /* We can safely assume that sband won't change unless we get |
375 | * reinitialized. */ | 394 | * reinitialized. */ |
376 | mode = local->oper_hw_mode; | 395 | rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC); |
377 | rinfo = kmalloc(sizeof(*rinfo) * mode->num_rates, GFP_ATOMIC); | ||
378 | if (!rinfo) { | 396 | if (!rinfo) { |
379 | kfree(pinfo); | 397 | kfree(pinfo); |
380 | return NULL; | 398 | return NULL; |
@@ -383,7 +401,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
383 | /* Sort the rates. This is optimized for the most common case (i.e. | 401 | /* Sort the rates. This is optimized for the most common case (i.e. |
384 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | 402 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed |
385 | * mapping too. */ | 403 | * mapping too. */ |
386 | for (i = 0; i < mode->num_rates; i++) { | 404 | for (i = 0; i < sband->n_bitrates; i++) { |
387 | rinfo[i].index = i; | 405 | rinfo[i].index = i; |
388 | rinfo[i].rev_index = i; | 406 | rinfo[i].rev_index = i; |
389 | if (pinfo->fast_start) | 407 | if (pinfo->fast_start) |
@@ -391,11 +409,11 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
391 | else | 409 | else |
392 | rinfo[i].diff = i * pinfo->norm_offset; | 410 | rinfo[i].diff = i * pinfo->norm_offset; |
393 | } | 411 | } |
394 | for (i = 1; i < mode->num_rates; i++) { | 412 | for (i = 1; i < sband->n_bitrates; i++) { |
395 | s = 0; | 413 | s = 0; |
396 | for (j = 0; j < mode->num_rates - i; j++) | 414 | for (j = 0; j < sband->n_bitrates - i; j++) |
397 | if (unlikely(mode->rates[rinfo[j].index].rate > | 415 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > |
398 | mode->rates[rinfo[j + 1].index].rate)) { | 416 | sband->bitrates[rinfo[j + 1].index].bitrate)) { |
399 | tmp = rinfo[j].index; | 417 | tmp = rinfo[j].index; |
400 | rinfo[j].index = rinfo[j + 1].index; | 418 | rinfo[j].index = rinfo[j + 1].index; |
401 | rinfo[j + 1].index = tmp; | 419 | rinfo[j + 1].index = tmp; |