aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r--net/mac80211/rc80211_pid_algo.c92
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. */
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, 70static 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