diff options
| -rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index c339571632b2..3b77410588e7 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
| 3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
| 4 | * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de> | 4 | * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de> |
| 5 | * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it> | 5 | * Copyright 2007-2008, Stefano Brivio <stefano.brivio@polimi.it> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -63,72 +63,66 @@ | |||
| 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 | /* Shift the adjustment so that we won't switch to a lower rate if it exhibited | 67 | * exhibited a worse failed frames behaviour and we'll choose the highest rate |
| 68 | * a worse failed frames behaviour and we'll choose the highest rate whose | 68 | * whose failed frames behaviour is not worse than the one of the original rate |
| 69 | * failed frames behaviour is not worse than the one of the original rate | 69 | * target. While at it, check that the new rate is valid. */ |
| 70 | * target. While at it, check that the adjustment is within the ranges. Then, | ||
| 71 | * provide the new rate index. */ | ||
| 72 | static int rate_control_pid_shift_adjust(struct rc_pid_rateinfo *r, | ||
| 73 | int adj, int cur, int l) | ||
| 74 | { | ||
| 75 | int i, j, k, tmp; | ||
| 76 | |||
| 77 | j = r[cur].rev_index; | ||
| 78 | i = j + adj; | ||
| 79 | |||
| 80 | if (i < 0) | ||
| 81 | return r[0].index; | ||
| 82 | if (i >= l - 1) | ||
| 83 | return r[l - 1].index; | ||
| 84 | |||
| 85 | tmp = i; | ||
| 86 | |||
| 87 | if (adj < 0) { | ||
| 88 | for (k = j; k >= i; k--) | ||
| 89 | if (r[k].diff <= r[j].diff) | ||
| 90 | tmp = k; | ||
| 91 | } else { | ||
| 92 | for (k = i + 1; k + i < l; k++) | ||
| 93 | if (r[k].diff <= r[i].diff) | ||
| 94 | tmp = k; | ||
| 95 | } | ||
| 96 | |||
| 97 | return r[tmp].index; | ||
| 98 | } | ||
| 99 | |||
| 100 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | 70 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, |
| 101 | struct sta_info *sta, int adj, | 71 | struct sta_info *sta, int adj, |
| 102 | struct rc_pid_rateinfo *rinfo) | 72 | struct rc_pid_rateinfo *rinfo) |
| 103 | { | 73 | { |
| 104 | struct ieee80211_sub_if_data *sdata; | 74 | struct ieee80211_sub_if_data *sdata; |
| 105 | struct ieee80211_hw_mode *mode; | 75 | struct ieee80211_hw_mode *mode; |
| 106 | int newidx; | 76 | int cur_sorted, new_sorted, probe, tmp, n_bitrates; |
| 107 | int maxrate; | 77 | int cur = sta->txrate; |
| 108 | int back = (adj > 0) ? 1 : -1; | ||
| 109 | 78 | ||
| 110 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 79 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
| 111 | 80 | ||
| 112 | mode = local->oper_hw_mode; | 81 | mode = local->oper_hw_mode; |
| 113 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 82 | n_bitrates = mode->num_rates; |
| 114 | 83 | ||
| 115 | newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate, | 84 | /* Map passed arguments to sorted values. */ |
| 116 | mode->num_rates); | 85 | cur_sorted = rinfo[cur].rev_index; |
| 86 | new_sorted = cur_sorted + adj; | ||
| 117 | 87 | ||
| 118 | while (newidx != sta->txrate) { | 88 | /* Check limits. */ |
| 119 | if (rate_supported(sta, mode, newidx) && | 89 | if (new_sorted < 0) |
| 120 | (maxrate < 0 || newidx <= maxrate)) { | 90 | new_sorted = rinfo[0].rev_index; |
| 121 | sta->txrate = newidx; | 91 | else if (new_sorted >= n_bitrates) |
| 122 | break; | 92 | new_sorted = rinfo[n_bitrates - 1].rev_index; |
| 123 | } | ||
| 124 | 93 | ||
| 125 | newidx += back; | 94 | tmp = new_sorted; |
| 95 | |||
| 96 | if (adj < 0) { | ||
| 97 | /* Ensure that the rate decrease isn't disadvantageous. */ | ||
| 98 | for (probe = cur_sorted; probe >= new_sorted; probe--) | ||
| 99 | if (rinfo[probe].diff <= rinfo[cur_sorted].diff && | ||
| 100 | rate_supported(sta, mode, rinfo[probe].index)) | ||
| 101 | tmp = probe; | ||
| 102 | } else { | ||
| 103 | /* Look for rate increase with zero (or below) cost. */ | ||
| 104 | for (probe = new_sorted + 1; probe < n_bitrates; probe++) | ||
| 105 | if (rinfo[probe].diff <= rinfo[new_sorted].diff && | ||
| 106 | rate_supported(sta, mode, rinfo[probe].index)) | ||
| 107 | tmp = probe; | ||
| 126 | } | 108 | } |
| 127 | 109 | ||
| 110 | /* Fit the rate found to the nearest supported rate. */ | ||
| 111 | do { | ||
| 112 | if (rate_supported(sta, mode, rinfo[tmp].index)) { | ||
| 113 | sta->txrate = rinfo[tmp].index; | ||
| 114 | break; | ||
| 115 | } | ||
| 116 | if (adj < 0) | ||
| 117 | tmp--; | ||
| 118 | else | ||
| 119 | tmp++; | ||
| 120 | } while (tmp < n_bitrates && tmp >= 0); | ||
| 121 | |||
| 128 | #ifdef CONFIG_MAC80211_DEBUGFS | 122 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 129 | rate_control_pid_event_rate_change( | 123 | rate_control_pid_event_rate_change( |
| 130 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, | 124 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, |
| 131 | newidx, mode->rates[newidx].rate); | 125 | cur, mode->rates[cur].rate); |
| 132 | #endif | 126 | #endif |
| 133 | } | 127 | } |
| 134 | 128 | ||
