aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
authorStefano Brivio <stefano.brivio@polimi.it>2008-01-29 14:29:16 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:33 -0500
commitb7c50de92e1b54fa4a9a2ee436b16ead3ee31767 (patch)
tree6e387e37c2a58aba0a8db9ffb92dcd33aba8a76b /net/mac80211/rc80211_pid_algo.c
parent238814fd9a9624e3076c47ef0c003101927c7818 (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.c93
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. */
72static 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
100static void rate_control_pid_adjust_rate(struct ieee80211_local *local, 71static 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