athrate-sample.c revision 1.4.2.2 1 1.4.2.2 skrll /*-
2 1.4.2.2 skrll * Copyright (c) 2005 John Bicket
3 1.4.2.2 skrll * All rights reserved.
4 1.4.2.2 skrll *
5 1.4.2.2 skrll * Redistribution and use in source and binary forms, with or without
6 1.4.2.2 skrll * modification, are permitted provided that the following conditions
7 1.4.2.2 skrll * are met:
8 1.4.2.2 skrll * 1. Redistributions of source code must retain the above copyright
9 1.4.2.2 skrll * notice, this list of conditions and the following disclaimer,
10 1.4.2.2 skrll * without modification.
11 1.4.2.2 skrll * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 1.4.2.2 skrll * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 1.4.2.2 skrll * redistribution must be conditioned upon including a substantially
14 1.4.2.2 skrll * similar Disclaimer requirement for further binary redistribution.
15 1.4.2.2 skrll * 3. Neither the names of the above-listed copyright holders nor the names
16 1.4.2.2 skrll * of any contributors may be used to endorse or promote products derived
17 1.4.2.2 skrll * from this software without specific prior written permission.
18 1.4.2.2 skrll *
19 1.4.2.2 skrll * Alternatively, this software may be distributed under the terms of the
20 1.4.2.2 skrll * GNU General Public License ("GPL") version 2 as published by the Free
21 1.4.2.2 skrll * Software Foundation.
22 1.4.2.2 skrll *
23 1.4.2.2 skrll * NO WARRANTY
24 1.4.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 1.4.2.2 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 1.4.2.2 skrll * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27 1.4.2.2 skrll * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28 1.4.2.2 skrll * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29 1.4.2.2 skrll * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 1.4.2.2 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 1.4.2.2 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32 1.4.2.2 skrll * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 1.4.2.2 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 1.4.2.2 skrll * THE POSSIBILITY OF SUCH DAMAGES.
35 1.4.2.2 skrll */
36 1.4.2.2 skrll
37 1.4.2.2 skrll #include <sys/cdefs.h>
38 1.4.2.2 skrll #ifdef __FreeBSD__
39 1.4.2.2 skrll __FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.c,v 1.8 2005/04/02 18:56:50 sam Exp $");
40 1.4.2.2 skrll #endif
41 1.4.2.2 skrll #ifdef __NetBSD__
42 1.4.2.2 skrll __KERNEL_RCSID(0, "$NetBSD: athrate-sample.c,v 1.4.2.2 2005/11/10 14:04:14 skrll Exp $");
43 1.4.2.2 skrll #endif
44 1.4.2.2 skrll
45 1.4.2.2 skrll
46 1.4.2.2 skrll /*
47 1.4.2.2 skrll * John Bicket's SampleRate control algorithm.
48 1.4.2.2 skrll */
49 1.4.2.2 skrll #include "opt_inet.h"
50 1.4.2.2 skrll
51 1.4.2.2 skrll #include <sys/param.h>
52 1.4.2.2 skrll #include <sys/systm.h>
53 1.4.2.2 skrll #include <sys/sysctl.h>
54 1.4.2.2 skrll #include <sys/kernel.h>
55 1.4.2.2 skrll #include <sys/lock.h>
56 1.4.2.2 skrll #include <sys/errno.h>
57 1.4.2.2 skrll #include <sys/device.h>
58 1.4.2.2 skrll
59 1.4.2.2 skrll #include <machine/bus.h>
60 1.4.2.2 skrll
61 1.4.2.2 skrll #include <sys/socket.h>
62 1.4.2.2 skrll
63 1.4.2.2 skrll #include <net/if.h>
64 1.4.2.2 skrll #include <net/if_media.h>
65 1.4.2.2 skrll #include <net/if_arp.h>
66 1.4.2.2 skrll #include <net/if_ether.h> /* XXX for ether_sprintf */
67 1.4.2.2 skrll
68 1.4.2.2 skrll #include <net80211/ieee80211_var.h>
69 1.4.2.2 skrll
70 1.4.2.2 skrll #include <net/bpf.h>
71 1.4.2.2 skrll
72 1.4.2.2 skrll #ifdef INET
73 1.4.2.2 skrll #include <netinet/in.h>
74 1.4.2.2 skrll #endif
75 1.4.2.2 skrll
76 1.4.2.2 skrll #include <dev/ic/athvar.h>
77 1.4.2.2 skrll #include <dev/ic/athrate-sample.h>
78 1.4.2.2 skrll #include <contrib/dev/ic/athhal_desc.h>
79 1.4.2.2 skrll
80 1.4.2.2 skrll #define SAMPLE_DEBUG
81 1.4.2.2 skrll #ifdef SAMPLE_DEBUG
82 1.4.2.2 skrll enum {
83 1.4.2.2 skrll ATH_DEBUG_RATE = 0x00000010, /* rate control */
84 1.4.2.2 skrll };
85 1.4.2.2 skrll #define DPRINTF(sc, _fmt, ...) do { \
86 1.4.2.2 skrll if (sc->sc_debug & ATH_DEBUG_RATE) \
87 1.4.2.2 skrll printf(_fmt, __VA_ARGS__); \
88 1.4.2.2 skrll } while (0)
89 1.4.2.2 skrll #else
90 1.4.2.2 skrll #define DPRINTF(sc, _fmt, ...)
91 1.4.2.2 skrll #endif
92 1.4.2.2 skrll
93 1.4.2.2 skrll /*
94 1.4.2.2 skrll * This file is an implementation of the SampleRate algorithm
95 1.4.2.2 skrll * in "Bit-rate Selection in Wireless Networks"
96 1.4.2.2 skrll * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps)
97 1.4.2.2 skrll *
98 1.4.2.2 skrll * SampleRate chooses the bit-rate it predicts will provide the most
99 1.4.2.2 skrll * throughput based on estimates of the expected per-packet
100 1.4.2.2 skrll * transmission time for each bit-rate. SampleRate periodically sends
101 1.4.2.2 skrll * packets at bit-rates other than the current one to estimate when
102 1.4.2.2 skrll * another bit-rate will provide better performance. SampleRate
103 1.4.2.2 skrll * switches to another bit-rate when its estimated per-packet
104 1.4.2.2 skrll * transmission time becomes smaller than the current bit-rate's.
105 1.4.2.2 skrll * SampleRate reduces the number of bit-rates it must sample by
106 1.4.2.2 skrll * eliminating those that could not perform better than the one
107 1.4.2.2 skrll * currently being used. SampleRate also stops probing at a bit-rate
108 1.4.2.2 skrll * if it experiences several successive losses.
109 1.4.2.2 skrll *
110 1.4.2.2 skrll * The difference between the algorithm in the thesis and the one in this
111 1.4.2.2 skrll * file is that the one in this file uses a ewma instead of a window.
112 1.4.2.2 skrll *
113 1.4.2.2 skrll */
114 1.4.2.2 skrll
115 1.4.2.2 skrll #define STALE_FAILURE_TIMEOUT_MS 10000
116 1.4.2.2 skrll
117 1.4.2.2 skrll static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
118 1.4.2.2 skrll
119 1.4.2.2 skrll static __inline int size_to_bin(int size)
120 1.4.2.2 skrll {
121 1.4.2.2 skrll int x = 0;
122 1.4.2.2 skrll for (x = 0; x < NUM_PACKET_SIZE_BINS; x++) {
123 1.4.2.2 skrll if (size <= packet_size_bins[x]) {
124 1.4.2.2 skrll return x;
125 1.4.2.2 skrll }
126 1.4.2.2 skrll }
127 1.4.2.2 skrll return NUM_PACKET_SIZE_BINS-1;
128 1.4.2.2 skrll }
129 1.4.2.2 skrll static __inline int bin_to_size(int index) {
130 1.4.2.2 skrll return packet_size_bins[index];
131 1.4.2.2 skrll }
132 1.4.2.2 skrll
133 1.4.2.2 skrll static __inline int rate_to_ndx(struct sample_node *sn, int rate) {
134 1.4.2.2 skrll int x = 0;
135 1.4.2.2 skrll for (x = 0; x < sn->num_rates; x++) {
136 1.4.2.2 skrll if (sn->rates[x].rate == rate) {
137 1.4.2.2 skrll return x;
138 1.4.2.2 skrll }
139 1.4.2.2 skrll }
140 1.4.2.2 skrll return -1;
141 1.4.2.2 skrll }
142 1.4.2.2 skrll
143 1.4.2.2 skrll /*
144 1.4.2.2 skrll * Setup rate codes for management/control frames. We force
145 1.4.2.2 skrll * all such frames to the lowest rate.
146 1.4.2.2 skrll */
147 1.4.2.2 skrll static void
148 1.4.2.2 skrll ath_rate_setmgtrates(struct ath_softc *sc, struct ath_node *an)
149 1.4.2.2 skrll {
150 1.4.2.2 skrll const HAL_RATE_TABLE *rt = sc->sc_currates;
151 1.4.2.2 skrll
152 1.4.2.2 skrll /* setup rates for management frames */
153 1.4.2.2 skrll /* XXX management/control frames always go at lowest speed */
154 1.4.2.2 skrll an->an_tx_mgtrate = rt->info[0].rateCode;
155 1.4.2.2 skrll an->an_tx_mgtratesp = an->an_tx_mgtrate
156 1.4.2.2 skrll | rt->info[0].shortPreamble;
157 1.4.2.2 skrll }
158 1.4.2.2 skrll
159 1.4.2.2 skrll void
160 1.4.2.2 skrll ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
161 1.4.2.2 skrll {
162 1.4.2.2 skrll DPRINTF(sc, "%s:\n", __func__);
163 1.4.2.2 skrll /* NB: assumed to be zero'd by caller */
164 1.4.2.2 skrll ath_rate_setmgtrates(sc, an);
165 1.4.2.2 skrll }
166 1.4.2.2 skrll
167 1.4.2.2 skrll void
168 1.4.2.2 skrll ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
169 1.4.2.2 skrll {
170 1.4.2.2 skrll DPRINTF(sc, "%s:\n", __func__);
171 1.4.2.2 skrll }
172 1.4.2.2 skrll
173 1.4.2.2 skrll
174 1.4.2.2 skrll /*
175 1.4.2.2 skrll * returns the ndx with the lowest average_tx_time,
176 1.4.2.2 skrll * or -1 if all the average_tx_times are 0.
177 1.4.2.2 skrll */
178 1.4.2.2 skrll static __inline int best_rate_ndx(struct sample_node *sn, int size_bin,
179 1.4.2.2 skrll int require_acked_before)
180 1.4.2.2 skrll {
181 1.4.2.2 skrll int x = 0;
182 1.4.2.2 skrll int best_ndx = 0;
183 1.4.2.2 skrll int best_rate_tt = 0;
184 1.4.2.2 skrll for (x = 0; x < sn->num_rates; x++) {
185 1.4.2.2 skrll int tt = sn->stats[size_bin][x].average_tx_time;
186 1.4.2.2 skrll if (tt <= 0 || (require_acked_before &&
187 1.4.2.2 skrll !sn->stats[size_bin][x].packets_acked)) {
188 1.4.2.2 skrll continue;
189 1.4.2.2 skrll }
190 1.4.2.2 skrll if (!best_rate_tt || best_rate_tt > tt) {
191 1.4.2.2 skrll best_rate_tt = tt;
192 1.4.2.2 skrll best_ndx = x;
193 1.4.2.2 skrll }
194 1.4.2.2 skrll }
195 1.4.2.2 skrll return (best_rate_tt) ? best_ndx : -1;
196 1.4.2.2 skrll }
197 1.4.2.2 skrll
198 1.4.2.2 skrll /*
199 1.4.2.2 skrll * pick a ndx s.t. the perfect_tx_time
200 1.4.2.2 skrll * is less than the best bit-rate's average_tx_time
201 1.4.2.2 skrll * and the ndx has not had four successive failures.
202 1.4.2.2 skrll */
203 1.4.2.2 skrll static __inline int pick_sample_ndx(struct sample_node *sn, int size_bin)
204 1.4.2.2 skrll {
205 1.4.2.2 skrll int x = 0;
206 1.4.2.2 skrll int current_ndx = 0;
207 1.4.2.2 skrll unsigned current_tt = 0;
208 1.4.2.2 skrll
209 1.4.2.2 skrll current_ndx = sn->current_rate[size_bin];
210 1.4.2.2 skrll if (current_ndx < 0) {
211 1.4.2.2 skrll /* no successes yet, send at the lowest bit-rate */
212 1.4.2.2 skrll return 0;
213 1.4.2.2 skrll }
214 1.4.2.2 skrll
215 1.4.2.2 skrll current_tt = sn->stats[size_bin][current_ndx].average_tx_time;
216 1.4.2.2 skrll
217 1.4.2.2 skrll for (x = 0; x < sn->num_rates; x++) {
218 1.4.2.2 skrll int ndx = (sn->last_sample_ndx[size_bin] + 1 + x) % sn->num_rates;
219 1.4.2.2 skrll /*
220 1.4.2.2 skrll * clear any stale stuff out.
221 1.4.2.2 skrll */
222 1.4.2.2 skrll if (ticks - sn->stats[size_bin][ndx].last_tx > ((hz * STALE_FAILURE_TIMEOUT_MS)/1000)) {
223 1.4.2.2 skrll sn->stats[size_bin][ndx].average_tx_time = sn->stats[size_bin][ndx].perfect_tx_time;
224 1.4.2.2 skrll sn->stats[size_bin][ndx].successive_failures = 0;
225 1.4.2.2 skrll sn->stats[size_bin][ndx].tries = 0;
226 1.4.2.2 skrll sn->stats[size_bin][ndx].total_packets = 0;
227 1.4.2.2 skrll sn->stats[size_bin][ndx].packets_acked = 0;
228 1.4.2.2 skrll }
229 1.4.2.2 skrll
230 1.4.2.2 skrll if (ndx != current_ndx &&
231 1.4.2.2 skrll sn->stats[size_bin][ndx].perfect_tx_time < current_tt &&
232 1.4.2.2 skrll sn->stats[size_bin][ndx].successive_failures < 4) {
233 1.4.2.2 skrll sn->last_sample_ndx[size_bin] = ndx;
234 1.4.2.2 skrll return ndx;
235 1.4.2.2 skrll }
236 1.4.2.2 skrll }
237 1.4.2.2 skrll return current_ndx;
238 1.4.2.2 skrll }
239 1.4.2.2 skrll
240 1.4.2.2 skrll void
241 1.4.2.2 skrll ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
242 1.4.2.2 skrll int shortPreamble, size_t frameLen,
243 1.4.2.2 skrll u_int8_t *rix, int *try0, u_int8_t *txrate)
244 1.4.2.2 skrll {
245 1.4.2.2 skrll struct sample_node *sn = ATH_NODE_SAMPLE(an);
246 1.4.2.2 skrll struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
247 1.4.2.2 skrll struct ieee80211com *ic = &sc->sc_ic;
248 1.4.2.2 skrll int ndx, size_bin, mrr, best_ndx;
249 1.4.2.2 skrll unsigned average_tx_time;
250 1.4.2.2 skrll
251 1.4.2.2 skrll mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) &&
252 1.4.2.2 skrll !(frameLen > ic->ic_rtsthreshold);
253 1.4.2.2 skrll size_bin = size_to_bin(frameLen);
254 1.4.2.2 skrll best_ndx = best_rate_ndx(sn, size_bin, !mrr);
255 1.4.2.2 skrll
256 1.4.2.2 skrll if (best_ndx >= 0) {
257 1.4.2.2 skrll average_tx_time = sn->stats[size_bin][best_ndx].average_tx_time;
258 1.4.2.2 skrll } else {
259 1.4.2.2 skrll average_tx_time = 0;
260 1.4.2.2 skrll }
261 1.4.2.2 skrll if (sn->static_rate_ndx != -1) {
262 1.4.2.2 skrll ndx = sn->static_rate_ndx;
263 1.4.2.2 skrll *try0 = ATH_TXMAXTRY;
264 1.4.2.2 skrll } else {
265 1.4.2.2 skrll ndx = 0;
266 1.4.2.2 skrll *try0 = mrr ? 2 : ATH_TXMAXTRY;
267 1.4.2.2 skrll
268 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d mrr %d packets_sent %d best_ndx %d "
269 1.4.2.2 skrll "sample tt %d packets since %d\n"
270 1.4.2.2 skrll , __func__, ether_sprintf(an->an_node.ni_macaddr)
271 1.4.2.2 skrll , packet_size_bins[size_bin]
272 1.4.2.2 skrll , mrr
273 1.4.2.2 skrll , sn->packets_sent[size_bin]
274 1.4.2.2 skrll , best_ndx
275 1.4.2.2 skrll , sn->sample_tt[size_bin]
276 1.4.2.2 skrll , sn->packets_since_sample[size_bin]
277 1.4.2.2 skrll );
278 1.4.2.2 skrll if (!sn->packets_sent[size_bin]) {
279 1.4.2.2 skrll /* no packets sent */
280 1.4.2.2 skrll if (best_ndx == -1) {
281 1.4.2.2 skrll ndx = sn->num_rates - 1;
282 1.4.2.2 skrll if (sc->sc_curmode != IEEE80211_MODE_11B) {
283 1.4.2.2 skrll for (; ndx >= 0 && sn->rates[ndx].rate > 72; ndx--)
284 1.4.2.2 skrll ;
285 1.4.2.2 skrll
286 1.4.2.2 skrll }
287 1.4.2.2 skrll } else {
288 1.4.2.2 skrll ndx = best_ndx;
289 1.4.2.2 skrll }
290 1.4.2.2 skrll } else if (best_ndx == -1) {
291 1.4.2.2 skrll /* no packet has succeeded yet */
292 1.4.2.2 skrll if (mrr) {
293 1.4.2.2 skrll /*
294 1.4.2.2 skrll * no packet has succeeded, try the
295 1.4.2.2 skrll * highest bitrate that hasn't failed
296 1.4.2.2 skrll */
297 1.4.2.2 skrll for (ndx = sn->num_rates-1; ndx >= 0; ndx--) {
298 1.4.2.2 skrll if (sn->stats[size_bin][ndx].successive_failures == 0) {
299 1.4.2.2 skrll break;
300 1.4.2.2 skrll }
301 1.4.2.2 skrll }
302 1.4.2.2 skrll } else {
303 1.4.2.2 skrll ndx = sn->num_rates - 1;
304 1.4.2.2 skrll if (sc->sc_curmode != IEEE80211_MODE_11B) {
305 1.4.2.2 skrll for (; ndx >= 0 && sn->rates[ndx].rate > 72; ndx--)
306 1.4.2.2 skrll ;
307 1.4.2.2 skrll
308 1.4.2.2 skrll }
309 1.4.2.2 skrll }
310 1.4.2.2 skrll } else if (sn->sample_tt[size_bin] < (sn->packets_since_sample[size_bin]*ssc->ath_sample_rate/100) * average_tx_time &&
311 1.4.2.2 skrll sn->packets_since_sample[size_bin] > 15) {
312 1.4.2.2 skrll /*
313 1.4.2.2 skrll * we want to limit the time measuring the performance
314 1.4.2.2 skrll * of other bit-rates to ath_sample_rate% of the
315 1.4.2.2 skrll * total transmission time.
316 1.4.2.2 skrll */
317 1.4.2.2 skrll ndx = pick_sample_ndx(sn, size_bin);
318 1.4.2.2 skrll if (ndx != sn->current_rate[size_bin]) {
319 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d last sample tt %d sampling %d packets since %d\n",
320 1.4.2.2 skrll __func__,
321 1.4.2.2 skrll ether_sprintf(an->an_node.ni_macaddr),
322 1.4.2.2 skrll packet_size_bins[size_bin],
323 1.4.2.2 skrll sn->sample_tt[size_bin],
324 1.4.2.2 skrll sn->rates[ndx].rate,
325 1.4.2.2 skrll sn->packets_since_sample[size_bin]);
326 1.4.2.2 skrll sn->current_sample_ndx[size_bin] = ndx;
327 1.4.2.2 skrll } else {
328 1.4.2.2 skrll sn->current_sample_ndx[size_bin] = -1;
329 1.4.2.2 skrll }
330 1.4.2.2 skrll sn->packets_since_sample[size_bin] = 0;
331 1.4.2.2 skrll
332 1.4.2.2 skrll } else {
333 1.4.2.2 skrll sn->packets_since_sample[size_bin]++;
334 1.4.2.2 skrll /*
335 1.4.2.2 skrll * don't switch bit-rates every packet. only
336 1.4.2.2 skrll * switch during the first few packets we send
337 1.4.2.2 skrll * or after 100 packets, or if the current
338 1.4.2.2 skrll * bit-rate begins to perform twice as bad as
339 1.4.2.2 skrll * another one.
340 1.4.2.2 skrll */
341 1.4.2.2 skrll if (sn->packets_sent[size_bin] < 20 ||
342 1.4.2.2 skrll ticks - ((hz*2000)/1000) > sn->jiffies_since_switch[size_bin] ||
343 1.4.2.2 skrll average_tx_time * 2 < sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time ) {
344 1.4.2.2 skrll if (sn->packets_sent[size_bin] > 20) {
345 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mmr %d\n",
346 1.4.2.2 skrll __func__,
347 1.4.2.2 skrll ether_sprintf(an->an_node.ni_macaddr),
348 1.4.2.2 skrll packet_size_bins[size_bin],
349 1.4.2.2 skrll sn->rates[sn->current_rate[size_bin]].rate,
350 1.4.2.2 skrll sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time,
351 1.4.2.2 skrll sn->stats[size_bin][sn->current_rate[size_bin]].perfect_tx_time,
352 1.4.2.2 skrll sn->rates[best_ndx].rate,
353 1.4.2.2 skrll sn->stats[size_bin][best_ndx].average_tx_time,
354 1.4.2.2 skrll sn->stats[size_bin][best_ndx].perfect_tx_time,
355 1.4.2.2 skrll sn->packets_since_switch[size_bin],
356 1.4.2.2 skrll mrr);
357 1.4.2.2 skrll }
358 1.4.2.2 skrll sn->packets_since_switch[size_bin] = 0;
359 1.4.2.2 skrll sn->current_rate[size_bin] = best_ndx;
360 1.4.2.2 skrll sn->jiffies_since_switch[size_bin] = ticks;
361 1.4.2.2 skrll }
362 1.4.2.2 skrll ndx = sn->current_rate[size_bin];
363 1.4.2.2 skrll sn->packets_since_switch[size_bin]++;
364 1.4.2.2 skrll }
365 1.4.2.2 skrll
366 1.4.2.2 skrll }
367 1.4.2.2 skrll
368 1.4.2.2 skrll if (ndx < 0) {
369 1.4.2.2 skrll ndx = 0;
370 1.4.2.2 skrll }
371 1.4.2.2 skrll *rix = sn->rates[ndx].rix;
372 1.4.2.2 skrll if (shortPreamble) {
373 1.4.2.2 skrll *txrate = sn->rates[ndx].shortPreambleRateCode;
374 1.4.2.2 skrll } else {
375 1.4.2.2 skrll *txrate = sn->rates[ndx].rateCode;
376 1.4.2.2 skrll }
377 1.4.2.2 skrll sn->packets_sent[size_bin]++;
378 1.4.2.2 skrll an->an_node.ni_txrate = ndx;
379 1.4.2.2 skrll }
380 1.4.2.2 skrll
381 1.4.2.2 skrll void
382 1.4.2.2 skrll ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
383 1.4.2.2 skrll struct ath_desc *ds, int shortPreamble, u_int8_t rix)
384 1.4.2.2 skrll {
385 1.4.2.2 skrll struct sample_node *sn = ATH_NODE_SAMPLE(an);
386 1.4.2.2 skrll int rateCode = -1;
387 1.4.2.2 skrll int frame_size, size_bin, best_ndx, ndx;
388 1.4.2.2 skrll
389 1.4.2.2 skrll frame_size = ds->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */
390 1.4.2.2 skrll KASSERT(frame_size != 0, ("no frame size"));
391 1.4.2.2 skrll size_bin = size_to_bin(frame_size);
392 1.4.2.2 skrll best_ndx = best_rate_ndx(sn, size_bin, 0);
393 1.4.2.2 skrll
394 1.4.2.2 skrll if (best_ndx == -1 || !sn->stats[size_bin][best_ndx].packets_acked) {
395 1.4.2.2 skrll /*
396 1.4.2.2 skrll * no packet has succeeded, so also try at the
397 1.4.2.2 skrll * lowest bitate.
398 1.4.2.2 skrll */
399 1.4.2.2 skrll ndx = 0;
400 1.4.2.2 skrll } else {
401 1.4.2.2 skrll /*
402 1.4.2.2 skrll * we're trying a different bit-rate, and it could be lossy,
403 1.4.2.2 skrll * so if it fails try at the best bit-rate.
404 1.4.2.2 skrll */
405 1.4.2.2 skrll ndx = best_ndx;
406 1.4.2.2 skrll }
407 1.4.2.2 skrll KASSERT(0 <= ndx && ndx < IEEE80211_RATE_MAXSIZE,
408 1.4.2.2 skrll ("invalid ndx %d", ndx));
409 1.4.2.2 skrll if (shortPreamble) {
410 1.4.2.2 skrll rateCode = sn->rates[ndx].shortPreambleRateCode;
411 1.4.2.2 skrll } else {
412 1.4.2.2 skrll rateCode = sn->rates[ndx].rateCode;
413 1.4.2.2 skrll }
414 1.4.2.2 skrll ath_hal_setupxtxdesc(sc->sc_ah, ds
415 1.4.2.2 skrll , rateCode, 3 /* series 1 */
416 1.4.2.2 skrll , sn->rates[0].rateCode, 3 /* series 2 */
417 1.4.2.2 skrll , 0, 0 /* series 3 */
418 1.4.2.2 skrll );
419 1.4.2.2 skrll }
420 1.4.2.2 skrll
421 1.4.2.2 skrll static void
422 1.4.2.2 skrll update_stats(struct ath_softc *sc, struct ath_node *an,
423 1.4.2.2 skrll int frame_size,
424 1.4.2.2 skrll int ndx0, int tries0,
425 1.4.2.2 skrll int ndx1, int tries1,
426 1.4.2.2 skrll int ndx2, int tries2,
427 1.4.2.2 skrll int ndx3, int tries3,
428 1.4.2.2 skrll int short_tries, int tries, int status)
429 1.4.2.2 skrll {
430 1.4.2.2 skrll struct sample_node *sn = ATH_NODE_SAMPLE(an);
431 1.4.2.2 skrll struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
432 1.4.2.2 skrll int tt = 0;
433 1.4.2.2 skrll int tries_so_far = 0;
434 1.4.2.2 skrll int size_bin = 0;
435 1.4.2.2 skrll int size = 0;
436 1.4.2.2 skrll int rate = 0;
437 1.4.2.2 skrll
438 1.4.2.2 skrll size_bin = size_to_bin(frame_size);
439 1.4.2.2 skrll size = bin_to_size(size_bin);
440 1.4.2.2 skrll rate = sn->rates[ndx0].rate;
441 1.4.2.2 skrll
442 1.4.2.2 skrll tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx0].rix,
443 1.4.2.2 skrll short_tries-1,
444 1.4.2.2 skrll MIN(tries0, tries) - 1);
445 1.4.2.2 skrll tries_so_far += tries0;
446 1.4.2.2 skrll if (tries1 && tries0 < tries) {
447 1.4.2.2 skrll tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx1].rix,
448 1.4.2.2 skrll short_tries-1,
449 1.4.2.2 skrll MIN(tries1 + tries_so_far, tries) - tries_so_far - 1);
450 1.4.2.2 skrll }
451 1.4.2.2 skrll tries_so_far += tries1;
452 1.4.2.2 skrll
453 1.4.2.2 skrll if (tries2 && tries0 + tries1 < tries) {
454 1.4.2.2 skrll tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx2].rix,
455 1.4.2.2 skrll short_tries-1,
456 1.4.2.2 skrll MIN(tries2 + tries_so_far, tries) - tries_so_far - 1);
457 1.4.2.2 skrll }
458 1.4.2.2 skrll
459 1.4.2.2 skrll tries_so_far += tries2;
460 1.4.2.2 skrll
461 1.4.2.2 skrll if (tries3 && tries0 + tries1 + tries2 < tries) {
462 1.4.2.2 skrll tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx3].rix,
463 1.4.2.2 skrll short_tries-1,
464 1.4.2.2 skrll MIN(tries3 + tries_so_far, tries) - tries_so_far - 1);
465 1.4.2.2 skrll }
466 1.4.2.2 skrll #ifdef SAMPLE_DEBUG
467 1.4.2.2 skrll if (short_tries + tries > 3 || status) {
468 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d rate %d ndx %d tries (%d/%d) tries0 %d tt %d avg_tt %d perfect_tt %d status %d\n",
469 1.4.2.2 skrll __func__, ether_sprintf(an->an_node.ni_macaddr),
470 1.4.2.2 skrll size,
471 1.4.2.2 skrll rate, ndx0, short_tries, tries, tries0, tt,
472 1.4.2.2 skrll sn->stats[size_bin][ndx0].average_tx_time,
473 1.4.2.2 skrll sn->stats[size_bin][ndx0].perfect_tx_time,
474 1.4.2.2 skrll status);
475 1.4.2.2 skrll }
476 1.4.2.2 skrll #endif /* SAMPLE_DEBUG */
477 1.4.2.2 skrll if (sn->stats[size_bin][ndx0].total_packets < (100 / (100 - ssc->ath_smoothing_rate))) {
478 1.4.2.2 skrll /* just average the first few packets */
479 1.4.2.2 skrll int avg_tx = sn->stats[size_bin][ndx0].average_tx_time;
480 1.4.2.2 skrll int packets = sn->stats[size_bin][ndx0].total_packets;
481 1.4.2.2 skrll sn->stats[size_bin][ndx0].average_tx_time = (tt+(avg_tx*packets))/(packets+1);
482 1.4.2.2 skrll } else {
483 1.4.2.2 skrll /* use a ewma */
484 1.4.2.2 skrll sn->stats[size_bin][ndx0].average_tx_time =
485 1.4.2.2 skrll ((sn->stats[size_bin][ndx0].average_tx_time * ssc->ath_smoothing_rate) +
486 1.4.2.2 skrll (tt * (100 - ssc->ath_smoothing_rate))) / 100;
487 1.4.2.2 skrll }
488 1.4.2.2 skrll
489 1.4.2.2 skrll if (status) {
490 1.4.2.2 skrll /*
491 1.4.2.2 skrll * this packet failed - count this as a failure
492 1.4.2.2 skrll * for larger packets also, since we assume
493 1.4.2.2 skrll * if a small packet fails at a lower bit-rate
494 1.4.2.2 skrll * then a larger one will also.
495 1.4.2.2 skrll */
496 1.4.2.2 skrll int y;
497 1.4.2.2 skrll for (y = size_bin; y < NUM_PACKET_SIZE_BINS; y++) {
498 1.4.2.2 skrll sn->stats[y][ndx0].successive_failures++;
499 1.4.2.2 skrll sn->stats[y][ndx0].last_tx = ticks;
500 1.4.2.2 skrll }
501 1.4.2.2 skrll } else {
502 1.4.2.2 skrll sn->stats[size_bin][ndx0].packets_acked++;
503 1.4.2.2 skrll sn->stats[size_bin][ndx0].successive_failures = 0;
504 1.4.2.2 skrll }
505 1.4.2.2 skrll sn->stats[size_bin][ndx0].tries += tries;
506 1.4.2.2 skrll sn->stats[size_bin][ndx0].last_tx = ticks;
507 1.4.2.2 skrll sn->stats[size_bin][ndx0].total_packets++;
508 1.4.2.2 skrll
509 1.4.2.2 skrll
510 1.4.2.2 skrll if (ndx0 == sn->current_sample_ndx[size_bin]) {
511 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d) status %d\n",
512 1.4.2.2 skrll __func__, ether_sprintf(an->an_node.ni_macaddr),
513 1.4.2.2 skrll size, rate, short_tries, tries, tt,
514 1.4.2.2 skrll sn->stats[size_bin][ndx0].average_tx_time,
515 1.4.2.2 skrll sn->stats[size_bin][ndx0].perfect_tx_time,
516 1.4.2.2 skrll status);
517 1.4.2.2 skrll sn->sample_tt[size_bin] = tt;
518 1.4.2.2 skrll sn->current_sample_ndx[size_bin] = -1;
519 1.4.2.2 skrll }
520 1.4.2.2 skrll }
521 1.4.2.2 skrll
522 1.4.2.2 skrll void
523 1.4.2.2 skrll ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
524 1.4.2.2 skrll const struct ath_desc *ds, const struct ath_desc *ds0)
525 1.4.2.2 skrll {
526 1.4.2.2 skrll struct sample_node *sn = ATH_NODE_SAMPLE(an);
527 1.4.2.2 skrll const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0;
528 1.4.2.2 skrll int final_rate, short_tries, long_tries, frame_size;
529 1.4.2.2 skrll int ndx = -1;
530 1.4.2.2 skrll
531 1.4.2.2 skrll final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate;
532 1.4.2.2 skrll short_tries = ds->ds_txstat.ts_shortretry + 1;
533 1.4.2.2 skrll long_tries = ds->ds_txstat.ts_longretry + 1;
534 1.4.2.2 skrll frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */
535 1.4.2.2 skrll if (frame_size == 0) /* NB: should not happen */
536 1.4.2.2 skrll frame_size = 1500;
537 1.4.2.2 skrll
538 1.4.2.2 skrll if (sn->num_rates <= 0) {
539 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d "
540 1.4.2.2 skrll "no rates yet\n",
541 1.4.2.2 skrll __func__, ether_sprintf(an->an_node.ni_macaddr),
542 1.4.2.2 skrll bin_to_size(size_to_bin(frame_size)),
543 1.4.2.2 skrll ds->ds_txstat.ts_status,
544 1.4.2.2 skrll short_tries, long_tries);
545 1.4.2.2 skrll return;
546 1.4.2.2 skrll }
547 1.4.2.2 skrll
548 1.4.2.2 skrll if (sc->sc_mrretry && ds->ds_txstat.ts_status) {
549 1.4.2.2 skrll /* this packet failed */
550 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d rate/try %d/%d %d/%d %d/%d %d/%d status %s retries (%d/%d)\n",
551 1.4.2.2 skrll __func__,
552 1.4.2.2 skrll ether_sprintf(an->an_node.ni_macaddr),
553 1.4.2.2 skrll bin_to_size(size_to_bin(frame_size)),
554 1.4.2.2 skrll sc->sc_hwmap[ads->xmit_rate0].ieeerate,
555 1.4.2.2 skrll ads->xmit_tries0,
556 1.4.2.2 skrll sc->sc_hwmap[ads->xmit_rate1].ieeerate,
557 1.4.2.2 skrll ads->xmit_tries1,
558 1.4.2.2 skrll sc->sc_hwmap[ads->xmit_rate2].ieeerate,
559 1.4.2.2 skrll ads->xmit_tries2,
560 1.4.2.2 skrll sc->sc_hwmap[ads->xmit_rate3].ieeerate,
561 1.4.2.2 skrll ads->xmit_tries3,
562 1.4.2.2 skrll ds->ds_txstat.ts_status ? "FAIL" : "OK",
563 1.4.2.2 skrll short_tries,
564 1.4.2.2 skrll long_tries);
565 1.4.2.2 skrll }
566 1.4.2.2 skrll
567 1.4.2.2 skrll if (!(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) {
568 1.4.2.2 skrll /* only one rate was used */
569 1.4.2.2 skrll ndx = rate_to_ndx(sn, final_rate);
570 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n",
571 1.4.2.2 skrll __func__, ether_sprintf(an->an_node.ni_macaddr),
572 1.4.2.2 skrll bin_to_size(size_to_bin(frame_size)),
573 1.4.2.2 skrll ds->ds_txstat.ts_status,
574 1.4.2.2 skrll ndx, short_tries, long_tries);
575 1.4.2.2 skrll if (ndx >= 0 && ndx < sn->num_rates) {
576 1.4.2.2 skrll update_stats(sc, an, frame_size,
577 1.4.2.2 skrll ndx, long_tries,
578 1.4.2.2 skrll 0, 0,
579 1.4.2.2 skrll 0, 0,
580 1.4.2.2 skrll 0, 0,
581 1.4.2.2 skrll short_tries, long_tries, ds->ds_txstat.ts_status);
582 1.4.2.2 skrll }
583 1.4.2.2 skrll } else {
584 1.4.2.2 skrll int rate0, tries0, ndx0;
585 1.4.2.2 skrll int rate1, tries1, ndx1;
586 1.4.2.2 skrll int rate2, tries2, ndx2;
587 1.4.2.2 skrll int rate3, tries3, ndx3;
588 1.4.2.2 skrll int finalTSIdx = ads->final_ts_index;
589 1.4.2.2 skrll
590 1.4.2.2 skrll /*
591 1.4.2.2 skrll * Process intermediate rates that failed.
592 1.4.2.2 skrll */
593 1.4.2.2 skrll
594 1.4.2.2 skrll rate0 = sc->sc_hwmap[ads->xmit_rate0].ieeerate;
595 1.4.2.2 skrll tries0 = ads->xmit_tries0;
596 1.4.2.2 skrll ndx0 = rate_to_ndx(sn, rate0);
597 1.4.2.2 skrll
598 1.4.2.2 skrll rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate;
599 1.4.2.2 skrll tries1 = ads->xmit_tries1;
600 1.4.2.2 skrll ndx1 = rate_to_ndx(sn, rate1);
601 1.4.2.2 skrll
602 1.4.2.2 skrll rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate;
603 1.4.2.2 skrll tries2 = ads->xmit_tries2;
604 1.4.2.2 skrll ndx2 = rate_to_ndx(sn, rate2);
605 1.4.2.2 skrll
606 1.4.2.2 skrll rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate;
607 1.4.2.2 skrll tries3 = ads->xmit_tries3;
608 1.4.2.2 skrll ndx3 = rate_to_ndx(sn, rate3);
609 1.4.2.2 skrll
610 1.4.2.2 skrll #if 1
611 1.4.2.2 skrll DPRINTF(sc, "%s: %s size %d finaltsidx %d tries %d status %d rate/try %d/%d %d/%d %d/%d %d/%d\n",
612 1.4.2.2 skrll __func__, ether_sprintf(an->an_node.ni_macaddr),
613 1.4.2.2 skrll bin_to_size(size_to_bin(frame_size)),
614 1.4.2.2 skrll finalTSIdx,
615 1.4.2.2 skrll long_tries,
616 1.4.2.2 skrll ds->ds_txstat.ts_status,
617 1.4.2.2 skrll rate0, tries0,
618 1.4.2.2 skrll rate1, tries1,
619 1.4.2.2 skrll rate2, tries2,
620 1.4.2.2 skrll rate3, tries3);
621 1.4.2.2 skrll #endif
622 1.4.2.2 skrll
623 1.4.2.2 skrll if (tries0) {
624 1.4.2.2 skrll update_stats(sc, an, frame_size,
625 1.4.2.2 skrll ndx0, tries0,
626 1.4.2.2 skrll ndx1, tries1,
627 1.4.2.2 skrll ndx2, tries2,
628 1.4.2.2 skrll ndx3, tries3,
629 1.4.2.2 skrll short_tries, ds->ds_txstat.ts_longretry + 1,
630 1.4.2.2 skrll ds->ds_txstat.ts_status);
631 1.4.2.2 skrll }
632 1.4.2.2 skrll
633 1.4.2.2 skrll if (tries1 && finalTSIdx > 0) {
634 1.4.2.2 skrll update_stats(sc, an, frame_size,
635 1.4.2.2 skrll ndx1, tries1,
636 1.4.2.2 skrll ndx2, tries2,
637 1.4.2.2 skrll ndx3, tries3,
638 1.4.2.2 skrll 0, 0,
639 1.4.2.2 skrll short_tries, ds->ds_txstat.ts_longretry + 1 - tries0,
640 1.4.2.2 skrll ds->ds_txstat.ts_status);
641 1.4.2.2 skrll }
642 1.4.2.2 skrll
643 1.4.2.2 skrll if (tries2 && finalTSIdx > 1) {
644 1.4.2.2 skrll update_stats(sc, an, frame_size,
645 1.4.2.2 skrll ndx2, tries2,
646 1.4.2.2 skrll ndx3, tries3,
647 1.4.2.2 skrll 0, 0,
648 1.4.2.2 skrll 0, 0,
649 1.4.2.2 skrll short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1,
650 1.4.2.2 skrll ds->ds_txstat.ts_status);
651 1.4.2.2 skrll }
652 1.4.2.2 skrll
653 1.4.2.2 skrll if (tries3 && finalTSIdx > 2) {
654 1.4.2.2 skrll update_stats(sc, an, frame_size,
655 1.4.2.2 skrll ndx3, tries3,
656 1.4.2.2 skrll 0, 0,
657 1.4.2.2 skrll 0, 0,
658 1.4.2.2 skrll 0, 0,
659 1.4.2.2 skrll short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2,
660 1.4.2.2 skrll ds->ds_txstat.ts_status);
661 1.4.2.2 skrll }
662 1.4.2.2 skrll }
663 1.4.2.2 skrll }
664 1.4.2.2 skrll
665 1.4.2.2 skrll void
666 1.4.2.2 skrll ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
667 1.4.2.2 skrll {
668 1.4.2.2 skrll DPRINTF(sc, "%s: %s isnew %d\n", __func__,
669 1.4.2.2 skrll ether_sprintf(an->an_node.ni_macaddr), isnew);
670 1.4.2.2 skrll if (isnew)
671 1.4.2.2 skrll ath_rate_ctl_reset(sc, &an->an_node);
672 1.4.2.2 skrll }
673 1.4.2.2 skrll
674 1.4.2.2 skrll /*
675 1.4.2.2 skrll * Initialize the tables for a node.
676 1.4.2.2 skrll */
677 1.4.2.2 skrll static void
678 1.4.2.2 skrll ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
679 1.4.2.2 skrll {
680 1.4.2.2 skrll #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
681 1.4.2.2 skrll struct ieee80211com *ic = &sc->sc_ic;
682 1.4.2.2 skrll struct ath_node *an = ATH_NODE(ni);
683 1.4.2.2 skrll struct sample_node *sn = ATH_NODE_SAMPLE(an);
684 1.4.2.2 skrll const HAL_RATE_TABLE *rt = sc->sc_currates;
685 1.4.2.2 skrll int x, y, srate;
686 1.4.2.2 skrll
687 1.4.2.2 skrll KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
688 1.4.2.2 skrll sn->static_rate_ndx = -1;
689 1.4.2.2 skrll if (ic->ic_fixed_rate != -1) {
690 1.4.2.2 skrll /*
691 1.4.2.2 skrll * A fixed rate is to be used; ic_fixed_rate is an
692 1.4.2.2 skrll * index into the supported rate set. Convert this
693 1.4.2.2 skrll * to the index into the negotiated rate set for
694 1.4.2.2 skrll * the node. We know the rate is there because the
695 1.4.2.2 skrll * rate set is checked when the station associates.
696 1.4.2.2 skrll */
697 1.4.2.2 skrll const struct ieee80211_rateset *rs =
698 1.4.2.2 skrll &ic->ic_sup_rates[ic->ic_curmode];
699 1.4.2.2 skrll int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
700 1.4.2.2 skrll /* NB: the rate set is assumed sorted */
701 1.4.2.2 skrll srate = ni->ni_rates.rs_nrates - 1;
702 1.4.2.2 skrll for (; srate >= 0 && RATE(srate) != r; srate--)
703 1.4.2.2 skrll ;
704 1.4.2.2 skrll KASSERT(srate >= 0,
705 1.4.2.2 skrll ("fixed rate %d not in rate set", ic->ic_fixed_rate));
706 1.4.2.2 skrll sn->static_rate_ndx = srate;
707 1.4.2.2 skrll }
708 1.4.2.2 skrll
709 1.4.2.2 skrll DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr));
710 1.4.2.2 skrll
711 1.4.2.2 skrll sn->num_rates = ni->ni_rates.rs_nrates;
712 1.4.2.2 skrll for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
713 1.4.2.2 skrll sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
714 1.4.2.2 skrll sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
715 1.4.2.2 skrll sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;
716 1.4.2.2 skrll sn->rates[x].shortPreambleRateCode =
717 1.4.2.2 skrll rt->info[sn->rates[x].rix].rateCode |
718 1.4.2.2 skrll rt->info[sn->rates[x].rix].shortPreamble;
719 1.4.2.2 skrll
720 1.4.2.2 skrll DPRINTF(sc, " %d/%d", sn->rates[x].rate,
721 1.4.2.2 skrll calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix,
722 1.4.2.2 skrll 0,0));
723 1.4.2.2 skrll }
724 1.4.2.2 skrll DPRINTF(sc, "%s\n", "");
725 1.4.2.2 skrll
726 1.4.2.2 skrll /* set the visible bit-rate to the lowest one available */
727 1.4.2.2 skrll ni->ni_txrate = 0;
728 1.4.2.2 skrll sn->num_rates = ni->ni_rates.rs_nrates;
729 1.4.2.2 skrll
730 1.4.2.2 skrll for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
731 1.4.2.2 skrll int size = bin_to_size(y);
732 1.4.2.2 skrll sn->packets_sent[y] = 0;
733 1.4.2.2 skrll sn->current_sample_ndx[y] = -1;
734 1.4.2.2 skrll sn->last_sample_ndx[y] = 0;
735 1.4.2.2 skrll
736 1.4.2.2 skrll for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
737 1.4.2.2 skrll sn->stats[y][x].successive_failures = 0;
738 1.4.2.2 skrll sn->stats[y][x].tries = 0;
739 1.4.2.2 skrll sn->stats[y][x].total_packets = 0;
740 1.4.2.2 skrll sn->stats[y][x].packets_acked = 0;
741 1.4.2.2 skrll sn->stats[y][x].last_tx = 0;
742 1.4.2.2 skrll
743 1.4.2.2 skrll sn->stats[y][x].perfect_tx_time =
744 1.4.2.2 skrll calc_usecs_unicast_packet(sc, size,
745 1.4.2.2 skrll sn->rates[x].rix,
746 1.4.2.2 skrll 0, 0);
747 1.4.2.2 skrll sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time;
748 1.4.2.2 skrll }
749 1.4.2.2 skrll }
750 1.4.2.2 skrll #undef RATE
751 1.4.2.2 skrll }
752 1.4.2.2 skrll
753 1.4.2.2 skrll static void
754 1.4.2.2 skrll rate_cb(void *arg, struct ieee80211_node *ni)
755 1.4.2.2 skrll {
756 1.4.2.2 skrll struct ath_softc *sc = arg;
757 1.4.2.2 skrll
758 1.4.2.2 skrll ath_rate_newassoc(sc, ATH_NODE(ni), 1);
759 1.4.2.2 skrll }
760 1.4.2.2 skrll
761 1.4.2.2 skrll /*
762 1.4.2.2 skrll * Reset the rate control state for each 802.11 state transition.
763 1.4.2.2 skrll */
764 1.4.2.2 skrll void
765 1.4.2.2 skrll ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
766 1.4.2.2 skrll {
767 1.4.2.2 skrll struct ieee80211com *ic = &sc->sc_ic;
768 1.4.2.2 skrll
769 1.4.2.2 skrll if (state == IEEE80211_S_RUN) {
770 1.4.2.2 skrll if (ic->ic_opmode != IEEE80211_M_STA) {
771 1.4.2.2 skrll /*
772 1.4.2.2 skrll * Sync rates for associated stations and neighbors.
773 1.4.2.2 skrll */
774 1.4.2.2 skrll ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc);
775 1.4.2.2 skrll }
776 1.4.2.2 skrll ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1);
777 1.4.2.2 skrll }
778 1.4.2.2 skrll }
779 1.4.2.2 skrll
780 1.4.2.2 skrll static void
781 1.4.2.2 skrll ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *osc)
782 1.4.2.2 skrll {
783 1.4.2.2 skrll int rc;
784 1.4.2.2 skrll struct sysctllog **log = &sc->sc_sysctllog;
785 1.4.2.2 skrll const struct sysctlnode *cnode, *rnode;
786 1.4.2.2 skrll
787 1.4.2.2 skrll if ((rnode = ath_sysctl_instance(sc->sc_dev.dv_xname, log)) == NULL)
788 1.4.2.2 skrll return;
789 1.4.2.2 skrll
790 1.4.2.2 skrll /* XXX bounds check [0..100] */
791 1.4.2.2 skrll if ((rc = SYSCTL_PFX_INT(osc->ath_, CTLFLAG_READWRITE, smoothing_rate,
792 1.4.2.2 skrll "rate control: retry threshold to credit rate raise (%%)")) != 0)
793 1.4.2.2 skrll goto err;
794 1.4.2.2 skrll
795 1.4.2.2 skrll /* XXX bounds check [2..100] */
796 1.4.2.2 skrll if ((rc = SYSCTL_PFX_INT(osc->ath_, CTLFLAG_READWRITE, sample_rate,
797 1.4.2.2 skrll "rate control: # good periods before raising rate")) != 0)
798 1.4.2.2 skrll goto err;
799 1.4.2.2 skrll
800 1.4.2.2 skrll return;
801 1.4.2.2 skrll err:
802 1.4.2.2 skrll printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
803 1.4.2.2 skrll }
804 1.4.2.2 skrll
805 1.4.2.2 skrll struct ath_ratectrl *
806 1.4.2.2 skrll ath_rate_attach(struct ath_softc *sc)
807 1.4.2.2 skrll {
808 1.4.2.2 skrll struct sample_softc *osc;
809 1.4.2.2 skrll
810 1.4.2.2 skrll DPRINTF(sc, "%s:\n", __func__);
811 1.4.2.2 skrll osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
812 1.4.2.2 skrll if (osc == NULL)
813 1.4.2.2 skrll return NULL;
814 1.4.2.2 skrll osc->arc.arc_space = sizeof(struct sample_node);
815 1.4.2.2 skrll osc->ath_smoothing_rate = 95; /* ewma percentage (out of 100) */
816 1.4.2.2 skrll osc->ath_sample_rate = 10; /* send a different bit-rate 1/X packets */
817 1.4.2.2 skrll ath_rate_sysctlattach(sc, osc);
818 1.4.2.2 skrll return &osc->arc;
819 1.4.2.2 skrll }
820 1.4.2.2 skrll
821 1.4.2.2 skrll void
822 1.4.2.2 skrll ath_rate_detach(struct ath_ratectrl *arc)
823 1.4.2.2 skrll {
824 1.4.2.2 skrll struct sample_softc *osc = (struct sample_softc *) arc;
825 1.4.2.2 skrll
826 1.4.2.2 skrll free(osc, M_DEVBUF);
827 1.4.2.2 skrll }
828