diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2008-03-02 05:33:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-04 18:36:35 -0500 |
commit | 1d60ab0574fae362b1cca0ef52181ef75fd46832 (patch) | |
tree | 0623fff0e79c97fa8862b5657a19363c0734cfb4 /net/mac80211 | |
parent | ec9b6add7d81f902f6094e71f595da4a362f3348 (diff) |
rc80211-pid: fix rate adjustment
Merge rate_control_pid_shift_adjust() to rate_control_pid_adjust_rate()
in order to make the learning algorithm aware of constraints on rates. Also
add some comments and rename variables.
This fixes a bug which prevented 802.11b/g non-AP STAs from working with
802.11b only AP STAs.
This patch was originally destined for 2.6.26, and is being backported
to fix a user reported problem in post-2.6.24 kernels.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-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 | ||