diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2008-01-29 14:29:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:33 -0500 |
commit | b7c50de92e1b54fa4a9a2ee436b16ead3ee31767 (patch) | |
tree | 6e387e37c2a58aba0a8db9ffb92dcd33aba8a76b /net/mac80211/rc80211_pid_algo.c | |
parent | 238814fd9a9624e3076c47ef0c003101927c7818 (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.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 93 |
1 files changed, 44 insertions, 49 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index c5a607ca8440..da8462bbd5f4 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 |
@@ -64,71 +64,66 @@ | |||
64 | */ | 64 | */ |
65 | 65 | ||
66 | 66 | ||
67 | /* Shift the adjustment so that we won't switch to a lower rate if it exhibited | 67 | /* Adjust the rate while ensuring that we won't switch to a lower rate if it |
68 | * a worse failed frames behaviour and we'll choose the highest rate whose | 68 | * exhibited a worse failed frames behaviour and we'll choose the highest rate |
69 | * 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 |
70 | * target. While at it, check that the adjustment is within the ranges. Then, | 70 | * target. While at it, check that the new rate is valid. */ |
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, | 71 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, |
101 | struct sta_info *sta, int adj, | 72 | struct sta_info *sta, int adj, |
102 | struct rc_pid_rateinfo *rinfo) | 73 | struct rc_pid_rateinfo *rinfo) |
103 | { | 74 | { |
104 | struct ieee80211_sub_if_data *sdata; | 75 | struct ieee80211_sub_if_data *sdata; |
105 | struct ieee80211_supported_band *sband; | 76 | struct ieee80211_supported_band *sband; |
106 | int newidx; | 77 | int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; |
107 | int maxrate; | 78 | int cur = sta->txrate_idx; |
108 | int back = (adj > 0) ? 1 : -1; | ||
109 | 79 | ||
110 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 80 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
111 | |||
112 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 81 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
113 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 82 | band = sband->band; |
83 | n_bitrates = sband->n_bitrates; | ||
114 | 84 | ||
115 | newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate_idx, | 85 | /* Map passed arguments to sorted values. */ |
116 | sband->n_bitrates); | 86 | cur_sorted = rinfo[cur].rev_index; |
87 | new_sorted = cur_sorted + adj; | ||
117 | 88 | ||
118 | while (newidx != sta->txrate_idx) { | 89 | /* Check limits. */ |
119 | if (rate_supported(sta, sband->band, newidx) && | 90 | if (new_sorted < 0) |
120 | (maxrate < 0 || newidx <= maxrate)) { | 91 | new_sorted = rinfo[0].rev_index; |
121 | sta->txrate_idx = newidx; | 92 | else if (new_sorted >= n_bitrates) |
122 | break; | 93 | new_sorted = rinfo[n_bitrates - 1].rev_index; |
123 | } | ||
124 | 94 | ||
125 | newidx += back; | 95 | tmp = new_sorted; |
96 | |||
97 | if (adj < 0) { | ||
98 | /* Ensure that the rate decrease isn't disadvantageous. */ | ||
99 | for (probe = cur_sorted; probe >= new_sorted; probe--) | ||
100 | if (rinfo[probe].diff <= rinfo[cur_sorted].diff && | ||
101 | rate_supported(sta, band, rinfo[probe].index)) | ||
102 | tmp = probe; | ||
103 | } else { | ||
104 | /* Look for rate increase with zero (or below) cost. */ | ||
105 | for (probe = new_sorted + 1; probe < n_bitrates; probe++) | ||
106 | if (rinfo[probe].diff <= rinfo[new_sorted].diff && | ||
107 | rate_supported(sta, band, rinfo[probe].index)) | ||
108 | tmp = probe; | ||
126 | } | 109 | } |
127 | 110 | ||
111 | /* Fit the rate found to the nearest supported rate. */ | ||
112 | do { | ||
113 | if (rate_supported(sta, band, rinfo[tmp].index)) { | ||
114 | sta->txrate_idx = rinfo[tmp].index; | ||
115 | break; | ||
116 | } | ||
117 | if (adj < 0) | ||
118 | tmp--; | ||
119 | else | ||
120 | tmp++; | ||
121 | } while (tmp < n_bitrates && tmp >= 0); | ||
122 | |||
128 | #ifdef CONFIG_MAC80211_DEBUGFS | 123 | #ifdef CONFIG_MAC80211_DEBUGFS |
129 | rate_control_pid_event_rate_change( | 124 | rate_control_pid_event_rate_change( |
130 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, | 125 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, |
131 | newidx, sband->bitrates[newidx].bitrate); | 126 | sta->txrate_idx, sband->bitrates[sta->txrate_idx].bitrate); |
132 | #endif | 127 | #endif |
133 | } | 128 | } |
134 | 129 | ||