Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ath/ath_rate/sample/sample.c
39565 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2005 John Bicket
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer,
12
* without modification.
13
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
14
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15
* redistribution must be conditioned upon including a substantially
16
* similar Disclaimer requirement for further binary redistribution.
17
* 3. Neither the names of the above-listed copyright holders nor the names
18
* of any contributors may be used to endorse or promote products derived
19
* from this software without specific prior written permission.
20
*
21
* Alternatively, this software may be distributed under the terms of the
22
* GNU General Public License ("GPL") version 2 as published by the Free
23
* Software Foundation.
24
*
25
* NO WARRANTY
26
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
29
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
31
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36
* THE POSSIBILITY OF SUCH DAMAGES.
37
*
38
*/
39
40
#include <sys/cdefs.h>
41
/*
42
* John Bicket's SampleRate control algorithm.
43
*/
44
#include "opt_ath.h"
45
#include "opt_inet.h"
46
#include "opt_wlan.h"
47
#include "opt_ah.h"
48
49
#include <sys/param.h>
50
#include <sys/systm.h>
51
#include <sys/sysctl.h>
52
#include <sys/kernel.h>
53
#include <sys/lock.h>
54
#include <sys/malloc.h>
55
#include <sys/mutex.h>
56
#include <sys/errno.h>
57
58
#include <machine/bus.h>
59
#include <machine/resource.h>
60
#include <sys/bus.h>
61
62
#include <sys/socket.h>
63
64
#include <net/if.h>
65
#include <net/if_var.h>
66
#include <net/if_media.h>
67
#include <net/if_arp.h>
68
#include <net/ethernet.h> /* XXX for ether_sprintf */
69
70
#include <net80211/ieee80211_var.h>
71
72
#include <net/bpf.h>
73
74
#ifdef INET
75
#include <netinet/in.h>
76
#include <netinet/if_ether.h>
77
#endif
78
79
#include <dev/ath/if_athvar.h>
80
#include <dev/ath/ath_rate/sample/sample.h>
81
#include <dev/ath/ath_hal/ah_desc.h>
82
#include <dev/ath/ath_rate/sample/tx_schedules.h>
83
84
/*
85
* This file is an implementation of the SampleRate algorithm
86
* in "Bit-rate Selection in Wireless Networks"
87
* (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps)
88
*
89
* SampleRate chooses the bit-rate it predicts will provide the most
90
* throughput based on estimates of the expected per-packet
91
* transmission time for each bit-rate. SampleRate periodically sends
92
* packets at bit-rates other than the current one to estimate when
93
* another bit-rate will provide better performance. SampleRate
94
* switches to another bit-rate when its estimated per-packet
95
* transmission time becomes smaller than the current bit-rate's.
96
* SampleRate reduces the number of bit-rates it must sample by
97
* eliminating those that could not perform better than the one
98
* currently being used. SampleRate also stops probing at a bit-rate
99
* if it experiences several successive losses.
100
*
101
* The difference between the algorithm in the thesis and the one in this
102
* file is that the one in this file uses a ewma instead of a window.
103
*
104
* Also, this implementation tracks the average transmission time for
105
* a few different packet sizes independently for each link.
106
*/
107
108
/* XXX TODO: move this into ath_hal/net80211 so it can be shared */
109
110
#define MCS_HT20 0
111
#define MCS_HT20_SGI 1
112
#define MCS_HT40 2
113
#define MCS_HT40_SGI 3
114
115
/*
116
* This is currently a copy/paste from the 11n tx code.
117
*
118
* It's used to determine the maximum frame length allowed for the
119
* given rate. For now this ignores SGI/LGI and will assume long-GI.
120
* This only matters for lower rates that can't fill a full 64k A-MPDU.
121
*
122
* (But it's also important because right now rate control doesn't set
123
* flags like SGI/LGI, STBC, LDPC, TX power, etc.)
124
*
125
* When selecting a set of rates the rate control code will iterate
126
* over the HT20/HT40 max frame length and tell the caller the maximum
127
* length (@ LGI.) It will also choose a bucket that's the minimum
128
* of this value and the provided aggregate length. That way the
129
* rate selection will closely match what the eventual formed aggregate
130
* will be rather than "not at all".
131
*/
132
133
static int ath_rate_sample_max_4ms_framelen[4][32] = {
134
[MCS_HT20] = {
135
3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172,
136
6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280,
137
9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532,
138
12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532,
139
},
140
[MCS_HT20_SGI] = {
141
3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744,
142
7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532,
143
10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532,
144
14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532,
145
},
146
[MCS_HT40] = {
147
6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532,
148
13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532,
149
20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532,
150
26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532,
151
},
152
[MCS_HT40_SGI] = {
153
7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532,
154
14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532,
155
22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532,
156
29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532,
157
}
158
};
159
160
/*
161
* Given the (potentially MRR) transmit schedule, calculate the maximum
162
* allowed packet size for forming aggregates based on the lowest
163
* MCS rate in the transmit schedule.
164
*
165
* Returns -1 if it's a legacy rate or no MRR.
166
*
167
* XXX TODO: this needs to be limited by the RTS/CTS AR5416 8KB bug limit!
168
* (by checking rts/cts flags and applying sc_rts_aggr_limit)
169
*
170
* XXX TODO: apply per-node max-ampdu size and driver ampdu size limits too.
171
*/
172
static int
173
ath_rate_sample_find_min_pktlength(struct ath_softc *sc,
174
struct ath_node *an, uint8_t rix0, int is_aggr)
175
{
176
#define MCS_IDX(ix) (rt->info[ix].dot11Rate)
177
const HAL_RATE_TABLE *rt = sc->sc_currates;
178
struct sample_node *sn = ATH_NODE_SAMPLE(an);
179
const struct txschedule *sched = &sn->sched[rix0];
180
int max_pkt_length = 65530; // ATH_AGGR_MAXSIZE
181
// Note: this may not be true in all cases; need to check?
182
int is_ht40 = (an->an_node.ni_chw == NET80211_STA_RX_BW_40);
183
// Note: not great, but good enough..
184
int idx = is_ht40 ? MCS_HT40 : MCS_HT20;
185
186
if (rt->info[rix0].phy != IEEE80211_T_HT) {
187
return -1;
188
}
189
190
if (! sc->sc_mrretry) {
191
return -1;
192
}
193
194
KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
195
rix0, sched->r0));
196
197
/*
198
* Update based on sched->r{0,1,2,3} if sched->t{0,1,2,3}
199
* is not zero.
200
*
201
* Note: assuming all four PHYs are HT!
202
*
203
* XXX TODO: right now I hardcode here and in getxtxrates() that
204
* rates 2 and 3 in the tx schedule are ignored. This is important
205
* for forming larger aggregates because right now (a) the tx schedule
206
* per rate is fixed, and (b) reliable packet transmission at those
207
* higher rates kinda needs a lower MCS rate in there somewhere.
208
* However, this means we can only form shorter aggregates.
209
* If we've negotiated aggregation then we can actually just
210
* rely on software retransmit rather than having things fall
211
* back to like MCS0/1 in hardware, and rate control will hopefully
212
* do the right thing.
213
*
214
* Once the whole rate schedule is passed into ath_rate_findrate(),
215
* the ath_rc_series is populated ,the fixed tx schedule stuff
216
* is removed AND getxtxrates() is removed then we can remove this
217
* check as it can just NOT populate t2/t3. It also means
218
* probing can actually use rix0 for probeing and rix1 for the
219
* current best rate..
220
*/
221
if (sched->t0 != 0) {
222
max_pkt_length = MIN(max_pkt_length,
223
ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r0)]);
224
}
225
if (sched->t1 != 0) {
226
max_pkt_length = MIN(max_pkt_length,
227
ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]);
228
}
229
if (sched->t2 != 0 && (! is_aggr)) {
230
max_pkt_length = MIN(max_pkt_length,
231
ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]);
232
}
233
if (sched->t3 != 0 && (! is_aggr)) {
234
max_pkt_length = MIN(max_pkt_length,
235
ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]);
236
}
237
238
return max_pkt_length;
239
#undef MCS
240
}
241
242
static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
243
244
static __inline int
245
size_to_bin(int size)
246
{
247
#if NUM_PACKET_SIZE_BINS > 1
248
if (size <= packet_size_bins[0])
249
return 0;
250
#endif
251
#if NUM_PACKET_SIZE_BINS > 2
252
if (size <= packet_size_bins[1])
253
return 1;
254
#endif
255
#if NUM_PACKET_SIZE_BINS > 3
256
if (size <= packet_size_bins[2])
257
return 2;
258
#endif
259
#if NUM_PACKET_SIZE_BINS > 4
260
if (size <= packet_size_bins[3])
261
return 3;
262
#endif
263
#if NUM_PACKET_SIZE_BINS > 5
264
if (size <= packet_size_bins[4])
265
return 4;
266
#endif
267
#if NUM_PACKET_SIZE_BINS > 6
268
if (size <= packet_size_bins[5])
269
return 5;
270
#endif
271
#if NUM_PACKET_SIZE_BINS > 7
272
if (size <= packet_size_bins[6])
273
return 6;
274
#endif
275
#if NUM_PACKET_SIZE_BINS > 8
276
#error "add support for more packet sizes"
277
#endif
278
return NUM_PACKET_SIZE_BINS-1;
279
}
280
281
void
282
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
283
{
284
/* NB: assumed to be zero'd by caller */
285
}
286
287
void
288
ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
289
{
290
}
291
292
static int
293
dot11rate(const HAL_RATE_TABLE *rt, int rix)
294
{
295
if (rix < 0)
296
return -1;
297
return rt->info[rix].phy == IEEE80211_T_HT ?
298
rt->info[rix].dot11Rate : (rt->info[rix].dot11Rate & IEEE80211_RATE_VAL) / 2;
299
}
300
301
static const char *
302
dot11rate_label(const HAL_RATE_TABLE *rt, int rix)
303
{
304
if (rix < 0)
305
return "";
306
return rt->info[rix].phy == IEEE80211_T_HT ? "MCS" : "Mb ";
307
}
308
309
/*
310
* Return the rix with the lowest average_tx_time,
311
* or -1 if all the average_tx_times are 0.
312
*/
313
static __inline int
314
pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
315
int size_bin, int require_acked_before)
316
{
317
struct sample_node *sn = ATH_NODE_SAMPLE(an);
318
int best_rate_rix, best_rate_tt, best_rate_pct;
319
uint64_t mask;
320
int rix, tt, pct;
321
322
best_rate_rix = 0;
323
best_rate_tt = 0;
324
best_rate_pct = 0;
325
for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
326
if ((mask & 1) == 0) /* not a supported rate */
327
continue;
328
329
/* Don't pick a non-HT rate for a HT node */
330
if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
331
(rt->info[rix].phy != IEEE80211_T_HT)) {
332
continue;
333
}
334
335
tt = sn->stats[size_bin][rix].average_tx_time;
336
if (tt <= 0 ||
337
(require_acked_before &&
338
!sn->stats[size_bin][rix].packets_acked))
339
continue;
340
341
/* Calculate percentage if possible */
342
if (sn->stats[size_bin][rix].total_packets > 0) {
343
pct = sn->stats[size_bin][rix].ewma_pct;
344
} else {
345
pct = -1; /* No percent yet to compare against! */
346
}
347
348
/* don't use a bit-rate that has been failing */
349
if (sn->stats[size_bin][rix].successive_failures > 3)
350
continue;
351
352
/*
353
* For HT, Don't use a bit rate that is more
354
* lossy than the best. Give a bit of leeway.
355
*
356
* Don't consider best rates that we haven't seen
357
* packets for yet; let sampling start inflence that.
358
*/
359
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
360
if (pct == -1)
361
continue;
362
#if 0
363
IEEE80211_NOTE(an->an_node.ni_vap,
364
IEEE80211_MSG_RATECTL,
365
&an->an_node,
366
"%s: size %d comparing best rate 0x%x pkts/ewma/tt (%ju/%d/%d) "
367
"to 0x%x pkts/ewma/tt (%ju/%d/%d)",
368
__func__,
369
bin_to_size(size_bin),
370
rt->info[best_rate_rix].dot11Rate,
371
sn->stats[size_bin][best_rate_rix].total_packets,
372
best_rate_pct,
373
best_rate_tt,
374
rt->info[rix].dot11Rate,
375
sn->stats[size_bin][rix].total_packets,
376
pct,
377
tt);
378
#endif
379
if (best_rate_pct > (pct + 50))
380
continue;
381
}
382
/*
383
* For non-MCS rates, use the current average txtime for
384
* comparison.
385
*/
386
if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
387
if (best_rate_tt == 0 || tt <= best_rate_tt) {
388
best_rate_tt = tt;
389
best_rate_rix = rix;
390
best_rate_pct = pct;
391
}
392
}
393
394
/*
395
* Since 2 and 3 stream rates have slightly higher TX times,
396
* allow a little bit of leeway. This should later
397
* be abstracted out and properly handled.
398
*/
399
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
400
if (best_rate_tt == 0 ||
401
((tt * 9) <= (best_rate_tt * 10))) {
402
best_rate_tt = tt;
403
best_rate_rix = rix;
404
best_rate_pct = pct;
405
}
406
}
407
}
408
return (best_rate_tt ? best_rate_rix : -1);
409
}
410
411
/*
412
* Pick a good "random" bit-rate to sample other than the current one.
413
*/
414
static __inline int
415
pick_sample_rate(struct sample_softc *ssc , struct ath_node *an,
416
const HAL_RATE_TABLE *rt, int size_bin)
417
{
418
#define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
419
#define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
420
struct sample_node *sn = ATH_NODE_SAMPLE(an);
421
int current_rix, rix;
422
unsigned current_tt;
423
uint64_t mask;
424
425
current_rix = sn->current_rix[size_bin];
426
if (current_rix < 0) {
427
/* no successes yet, send at the lowest bit-rate */
428
/* XXX TODO should return MCS0 if HT */
429
return 0;
430
}
431
432
current_tt = sn->stats[size_bin][current_rix].average_tx_time;
433
434
rix = sn->last_sample_rix[size_bin]+1; /* next sample rate */
435
mask = sn->ratemask &~ ((uint64_t) 1<<current_rix);/* don't sample current rate */
436
while (mask != 0) {
437
if ((mask & ((uint64_t) 1<<rix)) == 0) { /* not a supported rate */
438
nextrate:
439
if (++rix >= rt->rateCount)
440
rix = 0;
441
continue;
442
}
443
444
/*
445
* The following code stops trying to sample
446
* non-MCS rates when speaking to an MCS node.
447
* However, at least for CCK rates in 2.4GHz mode,
448
* the non-MCS rates MAY actually provide better
449
* PER at the very far edge of reception.
450
*
451
* However! Until ath_rate_form_aggr() grows
452
* some logic to not form aggregates if the
453
* selected rate is non-MCS, this won't work.
454
*
455
* So don't disable this code until you've taught
456
* ath_rate_form_aggr() to drop out if any of
457
* the selected rates are non-MCS.
458
*/
459
#if 1
460
/* if the node is HT and the rate isn't HT, don't bother sample */
461
if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
462
(rt->info[rix].phy != IEEE80211_T_HT)) {
463
mask &= ~((uint64_t) 1<<rix);
464
goto nextrate;
465
}
466
#endif
467
468
/* this bit-rate is always worse than the current one */
469
if (sn->stats[size_bin][rix].perfect_tx_time > current_tt) {
470
mask &= ~((uint64_t) 1<<rix);
471
goto nextrate;
472
}
473
474
/* rarely sample bit-rates that fail a lot */
475
if (sn->stats[size_bin][rix].successive_failures > ssc->max_successive_failures &&
476
ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout) {
477
mask &= ~((uint64_t) 1<<rix);
478
goto nextrate;
479
}
480
481
/*
482
* For HT, only sample a few rates on either side of the
483
* current rix; there's quite likely a lot of them.
484
*
485
* This is limited to testing rate indexes on either side of
486
* this MCS, but for all spatial streams.
487
*
488
* Otherwise we'll (a) never really sample higher MCS
489
* rates if we're stuck low, and we'll make weird moves
490
* like sample MCS8 if we're using MCS7.
491
*/
492
if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
493
uint8_t current_mcs, rix_mcs;
494
495
current_mcs = MCS(current_rix) & 0x7;
496
rix_mcs = MCS(rix) & 0x7;
497
498
if (rix_mcs < (current_mcs - 2) ||
499
rix_mcs > (current_mcs + 2)) {
500
mask &= ~((uint64_t) 1<<rix);
501
goto nextrate;
502
}
503
}
504
505
/* Don't sample more than 2 rates higher for rates > 11M for non-HT rates */
506
if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
507
if (DOT11RATE(rix) > 2*11 && rix > current_rix + 2) {
508
mask &= ~((uint64_t) 1<<rix);
509
goto nextrate;
510
}
511
}
512
513
sn->last_sample_rix[size_bin] = rix;
514
return rix;
515
}
516
return current_rix;
517
#undef DOT11RATE
518
#undef MCS
519
}
520
521
static int
522
ath_rate_get_static_rix(struct ath_softc *sc, const struct ieee80211_node *ni)
523
{
524
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
525
#define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
526
#define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
527
const struct ieee80211_txparam *tp = ni->ni_txparms;
528
int srate;
529
530
/* Check MCS rates */
531
for (srate = ni->ni_htrates.rs_nrates - 1; srate >= 0; srate--) {
532
if (MCS(srate) == tp->ucastrate)
533
return sc->sc_rixmap[tp->ucastrate];
534
}
535
536
/* Check legacy rates */
537
for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--) {
538
if (RATE(srate) == tp->ucastrate)
539
return sc->sc_rixmap[tp->ucastrate];
540
}
541
return -1;
542
#undef RATE
543
#undef DOT11RATE
544
#undef MCS
545
}
546
547
static void
548
ath_rate_update_static_rix(struct ath_softc *sc, struct ieee80211_node *ni)
549
{
550
struct ath_node *an = ATH_NODE(ni);
551
const struct ieee80211_txparam *tp = ni->ni_txparms;
552
struct sample_node *sn = ATH_NODE_SAMPLE(an);
553
554
if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
555
/*
556
* A fixed rate is to be used; ucastrate is the IEEE code
557
* for this rate (sans basic bit). Check this against the
558
* negotiated rate set for the node. Note the fixed rate
559
* may not be available for various reasons so we only
560
* setup the static rate index if the lookup is successful.
561
*/
562
sn->static_rix = ath_rate_get_static_rix(sc, ni);
563
} else {
564
sn->static_rix = -1;
565
}
566
}
567
568
/*
569
* Pick a non-HT rate to begin using.
570
*/
571
static int
572
ath_rate_pick_seed_rate_legacy(struct ath_softc *sc, struct ath_node *an,
573
int frameLen)
574
{
575
#define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
576
#define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
577
#define RATE(ix) (DOT11RATE(ix) / 2)
578
int rix = -1;
579
const HAL_RATE_TABLE *rt = sc->sc_currates;
580
struct sample_node *sn = ATH_NODE_SAMPLE(an);
581
const int size_bin = size_to_bin(frameLen);
582
583
/* no packet has been sent successfully yet */
584
for (rix = rt->rateCount-1; rix > 0; rix--) {
585
if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
586
continue;
587
588
/* Skip HT rates */
589
if (rt->info[rix].phy == IEEE80211_T_HT)
590
continue;
591
592
/*
593
* Pick the highest rate <= 36 Mbps
594
* that hasn't failed.
595
*/
596
if (DOT11RATE(rix) <= 72 &&
597
sn->stats[size_bin][rix].successive_failures == 0) {
598
break;
599
}
600
}
601
return rix;
602
#undef RATE
603
#undef MCS
604
#undef DOT11RATE
605
}
606
607
/*
608
* Pick a HT rate to begin using.
609
*
610
* Don't use any non-HT rates; only consider HT rates.
611
*/
612
static int
613
ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struct ath_node *an,
614
int frameLen)
615
{
616
#define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
617
#define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
618
#define RATE(ix) (DOT11RATE(ix) / 2)
619
int rix = -1, ht_rix = -1;
620
const HAL_RATE_TABLE *rt = sc->sc_currates;
621
struct sample_node *sn = ATH_NODE_SAMPLE(an);
622
const int size_bin = size_to_bin(frameLen);
623
624
/* no packet has been sent successfully yet */
625
for (rix = rt->rateCount-1; rix > 0; rix--) {
626
/* Skip rates we can't use */
627
if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
628
continue;
629
630
/* Keep a copy of the last seen HT rate index */
631
if (rt->info[rix].phy == IEEE80211_T_HT)
632
ht_rix = rix;
633
634
/* Skip non-HT rates */
635
if (rt->info[rix].phy != IEEE80211_T_HT)
636
continue;
637
638
/*
639
* Pick a medium-speed rate at 1 spatial stream
640
* which has not seen any failures.
641
* Higher rates may fail; we'll try them later.
642
*/
643
if (((MCS(rix)& 0x7f) <= 4) &&
644
sn->stats[size_bin][rix].successive_failures == 0) {
645
break;
646
}
647
}
648
649
/*
650
* If all the MCS rates have successive failures, rix should be
651
* > 0; otherwise use the lowest MCS rix (hopefully MCS 0.)
652
*/
653
return MAX(rix, ht_rix);
654
#undef RATE
655
#undef MCS
656
#undef DOT11RATE
657
}
658
659
void
660
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
661
int shortPreamble, size_t frameLen, int tid,
662
int is_aggr, u_int8_t *rix0, int *try0,
663
u_int8_t *txrate, int *maxdur, int *maxpktlen)
664
{
665
#define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
666
#define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
667
#define RATE(ix) (DOT11RATE(ix) / 2)
668
struct sample_node *sn = ATH_NODE_SAMPLE(an);
669
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
670
struct ieee80211com *ic = &sc->sc_ic;
671
const HAL_RATE_TABLE *rt = sc->sc_currates;
672
int size_bin = size_to_bin(frameLen);
673
int rix, mrr, best_rix, change_rates;
674
unsigned average_tx_time;
675
int max_pkt_len;
676
677
ath_rate_update_static_rix(sc, &an->an_node);
678
679
/* For now don't take TID, is_aggr into account */
680
/* Also for now don't calculate a max duration; that'll come later */
681
*maxdur = -1;
682
683
/*
684
* For now just set it to the frame length; we'll optimise it later.
685
*/
686
*maxpktlen = frameLen;
687
688
if (sn->currates != sc->sc_currates) {
689
device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",
690
__func__);
691
rix = 0;
692
*try0 = ATH_TXMAXTRY;
693
goto done;
694
}
695
696
if (sn->static_rix != -1) {
697
rix = sn->static_rix;
698
*try0 = ATH_TXMAXTRY;
699
700
/*
701
* Ensure we limit max packet length here too!
702
*/
703
max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an,
704
sn->static_rix,
705
is_aggr);
706
if (max_pkt_len > 0) {
707
*maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
708
size_bin = size_to_bin(frameLen);
709
}
710
goto done;
711
}
712
713
mrr = sc->sc_mrretry;
714
/* XXX check HT protmode too */
715
/* XXX turn into a cap; 11n MACs support MRR+RTSCTS */
716
if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
717
mrr = 0;
718
719
best_rix = pick_best_rate(an, rt, size_bin, !mrr);
720
721
/*
722
* At this point we've chosen the best rix, so now we
723
* need to potentially update our maximum packet length
724
* and size_bin if we're doing 11n rates.
725
*/
726
max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an, best_rix,
727
is_aggr);
728
if (max_pkt_len > 0) {
729
#if 0
730
device_printf(sc->sc_dev,
731
"Limiting maxpktlen from %d to %d bytes\n",
732
(int) frameLen, max_pkt_len);
733
#endif
734
*maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
735
size_bin = size_to_bin(frameLen);
736
}
737
738
if (best_rix >= 0) {
739
average_tx_time = sn->stats[size_bin][best_rix].average_tx_time;
740
} else {
741
average_tx_time = 0;
742
}
743
744
/*
745
* Limit the time measuring the performance of other tx
746
* rates to sample_rate% of the total transmission time.
747
*/
748
if (sn->sample_tt[size_bin] <
749
average_tx_time *
750
(sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) {
751
rix = pick_sample_rate(ssc, an, rt, size_bin);
752
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
753
&an->an_node, "att %d sample_tt %d size %u "
754
"sample rate %d %s current rate %d %s",
755
average_tx_time,
756
sn->sample_tt[size_bin],
757
bin_to_size(size_bin),
758
dot11rate(rt, rix),
759
dot11rate_label(rt, rix),
760
dot11rate(rt, sn->current_rix[size_bin]),
761
dot11rate_label(rt, sn->current_rix[size_bin]));
762
if (rix != sn->current_rix[size_bin]) {
763
sn->current_sample_rix[size_bin] = rix;
764
} else {
765
sn->current_sample_rix[size_bin] = -1;
766
}
767
sn->packets_since_sample[size_bin] = 0;
768
} else {
769
change_rates = 0;
770
if (!sn->packets_sent[size_bin] || best_rix == -1) {
771
/* no packet has been sent successfully yet */
772
change_rates = 1;
773
if (an->an_node.ni_flags & IEEE80211_NODE_HT)
774
best_rix =
775
ath_rate_pick_seed_rate_ht(sc, an, frameLen);
776
else
777
best_rix =
778
ath_rate_pick_seed_rate_legacy(sc, an, frameLen);
779
} else if (sn->packets_sent[size_bin] < 20) {
780
/* let the bit-rate switch quickly during the first few packets */
781
IEEE80211_NOTE(an->an_node.ni_vap,
782
IEEE80211_MSG_RATECTL, &an->an_node,
783
"%s: switching quickly..", __func__);
784
change_rates = 1;
785
} else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) {
786
/* min_switch seconds have gone by */
787
IEEE80211_NOTE(an->an_node.ni_vap,
788
IEEE80211_MSG_RATECTL, &an->an_node,
789
"%s: min_switch %d > ticks_since_switch %d..",
790
__func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]);
791
change_rates = 1;
792
} else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) &&
793
(2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) {
794
/* the current bit-rate is twice as slow as the best one */
795
IEEE80211_NOTE(an->an_node.ni_vap,
796
IEEE80211_MSG_RATECTL, &an->an_node,
797
"%s: 2x att (= %d) < cur_rix att %d",
798
__func__,
799
2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time);
800
change_rates = 1;
801
} else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) {
802
int cur_rix = sn->current_rix[size_bin];
803
int cur_att = sn->stats[size_bin][cur_rix].average_tx_time;
804
/*
805
* If the node is HT, it if the rate isn't the
806
* same and the average tx time is within 10%
807
* of the current rate. It can fail a little.
808
*
809
* This is likely not optimal!
810
*/
811
#if 0
812
printf("cur rix/att %x/%d, best rix/att %x/%d\n",
813
MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time);
814
#endif
815
if ((best_rix != cur_rix) &&
816
(average_tx_time * 9) <= (cur_att * 10)) {
817
IEEE80211_NOTE(an->an_node.ni_vap,
818
IEEE80211_MSG_RATECTL, &an->an_node,
819
"%s: HT: size %d best_rix 0x%x > "
820
" cur_rix 0x%x, average_tx_time %d,"
821
" cur_att %d",
822
__func__, bin_to_size(size_bin),
823
MCS(best_rix), MCS(cur_rix),
824
average_tx_time, cur_att);
825
change_rates = 1;
826
}
827
}
828
829
sn->packets_since_sample[size_bin]++;
830
831
if (change_rates) {
832
if (best_rix != sn->current_rix[size_bin]) {
833
IEEE80211_NOTE(an->an_node.ni_vap,
834
IEEE80211_MSG_RATECTL,
835
&an->an_node,
836
"%s: size %d switch rate %d %s (%d/%d) EWMA %d -> %d %s (%d/%d) EWMA %d after %d packets mrr %d",
837
__func__,
838
bin_to_size(size_bin),
839
dot11rate(rt, sn->current_rix[size_bin]),
840
dot11rate_label(rt, sn->current_rix[size_bin]),
841
sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time,
842
sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time,
843
sn->stats[size_bin][sn->current_rix[size_bin]].ewma_pct,
844
dot11rate(rt, best_rix),
845
dot11rate_label(rt, best_rix),
846
sn->stats[size_bin][best_rix].average_tx_time,
847
sn->stats[size_bin][best_rix].perfect_tx_time,
848
sn->stats[size_bin][best_rix].ewma_pct,
849
sn->packets_since_switch[size_bin],
850
mrr);
851
}
852
sn->packets_since_switch[size_bin] = 0;
853
sn->current_rix[size_bin] = best_rix;
854
sn->ticks_since_switch[size_bin] = ticks;
855
/*
856
* Set the visible txrate for this node.
857
*/
858
if (rt->info[best_rix].phy == IEEE80211_T_HT)
859
ieee80211_node_set_txrate_ht_mcsrate(
860
&an->an_node,
861
MCS(best_rix) & IEEE80211_RATE_VAL);
862
else
863
ieee80211_node_set_txrate_dot11rate(
864
&an->an_node,
865
DOT11RATE(best_rix));
866
}
867
rix = sn->current_rix[size_bin];
868
sn->packets_since_switch[size_bin]++;
869
}
870
*try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY;
871
done:
872
873
/*
874
* This bug totally sucks and should be fixed.
875
*
876
* For now though, let's not panic, so we can start to figure
877
* out how to better reproduce it.
878
*/
879
if (rix < 0 || rix >= rt->rateCount) {
880
printf("%s: ERROR: rix %d out of bounds (rateCount=%d)\n",
881
__func__,
882
rix,
883
rt->rateCount);
884
rix = 0; /* XXX just default for now */
885
}
886
KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix));
887
888
*rix0 = rix;
889
*txrate = rt->info[rix].rateCode
890
| (shortPreamble ? rt->info[rix].shortPreamble : 0);
891
sn->packets_sent[size_bin]++;
892
893
#undef DOT11RATE
894
#undef MCS
895
#undef RATE
896
}
897
898
/*
899
* Get the TX rates. Don't fiddle with short preamble flags for them;
900
* the caller can do that.
901
*/
902
void
903
ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
904
uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
905
{
906
struct sample_node *sn = ATH_NODE_SAMPLE(an);
907
const struct txschedule *sched = &sn->sched[rix0];
908
909
KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
910
rix0, sched->r0));
911
912
rc[0].flags = rc[1].flags = rc[2].flags = rc[3].flags = 0;
913
914
rc[0].rix = sched->r0;
915
rc[1].rix = sched->r1;
916
rc[2].rix = sched->r2;
917
rc[3].rix = sched->r3;
918
919
rc[0].tries = sched->t0;
920
rc[1].tries = sched->t1;
921
922
if (is_aggr) {
923
rc[2].tries = rc[3].tries = 0;
924
} else {
925
rc[2].tries = sched->t2;
926
rc[3].tries = sched->t3;
927
}
928
}
929
930
void
931
ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
932
struct ath_desc *ds, int shortPreamble, u_int8_t rix)
933
{
934
struct sample_node *sn = ATH_NODE_SAMPLE(an);
935
const struct txschedule *sched = &sn->sched[rix];
936
const HAL_RATE_TABLE *rt = sc->sc_currates;
937
uint8_t rix1, s1code, rix2, s2code, rix3, s3code;
938
939
/* XXX precalculate short preamble tables */
940
rix1 = sched->r1;
941
s1code = rt->info[rix1].rateCode
942
| (shortPreamble ? rt->info[rix1].shortPreamble : 0);
943
rix2 = sched->r2;
944
s2code = rt->info[rix2].rateCode
945
| (shortPreamble ? rt->info[rix2].shortPreamble : 0);
946
rix3 = sched->r3;
947
s3code = rt->info[rix3].rateCode
948
| (shortPreamble ? rt->info[rix3].shortPreamble : 0);
949
ath_hal_setupxtxdesc(sc->sc_ah, ds,
950
s1code, sched->t1, /* series 1 */
951
s2code, sched->t2, /* series 2 */
952
s3code, sched->t3); /* series 3 */
953
}
954
955
/*
956
* Update the current statistics.
957
*
958
* Note that status is for the FINAL transmit status, not this
959
* particular attempt. So, check if tries > tries0 and if so
960
* assume this status failed.
961
*
962
* This is important because some failures are due to both
963
* short AND long retries; if the final issue was a short
964
* retry failure then we still want to account for the
965
* bad long retry attempts.
966
*/
967
static void
968
update_stats(struct ath_softc *sc, struct ath_node *an,
969
int frame_size,
970
int rix0, int tries0,
971
int short_tries, int tries, int status,
972
int nframes, int nbad)
973
{
974
struct sample_node *sn = ATH_NODE_SAMPLE(an);
975
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
976
#ifdef IEEE80211_DEBUG
977
const HAL_RATE_TABLE *rt = sc->sc_currates;
978
#endif
979
const int size_bin = size_to_bin(frame_size);
980
const int size = bin_to_size(size_bin);
981
int tt;
982
int is_ht40 = (an->an_node.ni_chw == NET80211_STA_RX_BW_40);
983
int pct;
984
985
if (!IS_RATE_DEFINED(sn, rix0))
986
return;
987
988
/*
989
* Treat long retries as us exceeding retries, even
990
* if the eventual attempt at some other MRR schedule
991
* succeeded.
992
*/
993
if (tries > tries0) {
994
status = HAL_TXERR_XRETRY;
995
}
996
997
/*
998
* If status is FAIL then we treat all frames as bad.
999
* This better accurately tracks EWMA and average TX time
1000
* because even if the eventual transmission succeeded,
1001
* transmission at this rate did not.
1002
*/
1003
if (status != 0)
1004
nbad = nframes;
1005
1006
/*
1007
* Ignore short tries count as contributing to failure.
1008
* Right now there's no way to know if it's part of any
1009
* given rate attempt, and outside of the RTS/CTS management
1010
* rate, it doesn't /really/ help.
1011
*/
1012
tt = calc_usecs_unicast_packet(sc, size, rix0,
1013
0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40);
1014
1015
if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) {
1016
/* just average the first few packets */
1017
int avg_tx = sn->stats[size_bin][rix0].average_tx_time;
1018
int packets = sn->stats[size_bin][rix0].total_packets;
1019
sn->stats[size_bin][rix0].average_tx_time = (tt+(avg_tx*packets))/(packets+nframes);
1020
} else {
1021
/* use a ewma */
1022
sn->stats[size_bin][rix0].average_tx_time =
1023
((sn->stats[size_bin][rix0].average_tx_time * ssc->smoothing_rate) +
1024
(tt * (100 - ssc->smoothing_rate))) / 100;
1025
}
1026
1027
if (nframes == nbad) {
1028
sn->stats[size_bin][rix0].successive_failures += nbad;
1029
} else {
1030
sn->stats[size_bin][rix0].packets_acked += (nframes - nbad);
1031
sn->stats[size_bin][rix0].successive_failures = 0;
1032
}
1033
sn->stats[size_bin][rix0].tries += tries;
1034
sn->stats[size_bin][rix0].last_tx = ticks;
1035
sn->stats[size_bin][rix0].total_packets += nframes;
1036
1037
/* update EWMA for this rix */
1038
1039
/* Calculate percentage based on current rate */
1040
if (nframes == 0)
1041
nframes = nbad = 1;
1042
pct = ((nframes - nbad) * 1000) / nframes;
1043
1044
if (sn->stats[size_bin][rix0].total_packets <
1045
ssc->smoothing_minpackets) {
1046
/* just average the first few packets */
1047
int a_pct = (sn->stats[size_bin][rix0].packets_acked * 1000) /
1048
(sn->stats[size_bin][rix0].total_packets);
1049
sn->stats[size_bin][rix0].ewma_pct = a_pct;
1050
} else {
1051
/* use a ewma */
1052
sn->stats[size_bin][rix0].ewma_pct =
1053
((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) +
1054
(pct * (100 - ssc->smoothing_rate))) / 100;
1055
}
1056
1057
/*
1058
* Only update the sample time for the initial sample rix.
1059
* We've updated the statistics on each of the other retries
1060
* fine, but we should only update the sample_tt with what
1061
* was actually sampled.
1062
*
1063
* However, to aide in debugging, log all the failures for
1064
* each of the buckets
1065
*/
1066
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1067
&an->an_node,
1068
"%s: size %d %s %s rate %d %s tries (%d/%d) tt %d "
1069
"avg_tt (%d/%d) nfrm %d nbad %d",
1070
__func__,
1071
size,
1072
status ? "FAIL" : "OK",
1073
rix0 == sn->current_sample_rix[size_bin] ? "sample" : "mrr",
1074
dot11rate(rt, rix0),
1075
dot11rate_label(rt, rix0),
1076
short_tries, tries, tt,
1077
sn->stats[size_bin][rix0].average_tx_time,
1078
sn->stats[size_bin][rix0].perfect_tx_time,
1079
nframes, nbad);
1080
1081
if (rix0 == sn->current_sample_rix[size_bin]) {
1082
sn->sample_tt[size_bin] = tt;
1083
sn->current_sample_rix[size_bin] = -1;
1084
}
1085
}
1086
1087
static void
1088
badrate(struct ath_softc *sc, int series, int hwrate, int tries, int status)
1089
{
1090
1091
device_printf(sc->sc_dev,
1092
"bad series%d hwrate 0x%x, tries %u ts_status 0x%x\n",
1093
series, hwrate, tries, status);
1094
}
1095
1096
void
1097
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
1098
const struct ath_rc_series *rc, const struct ath_tx_status *ts,
1099
int frame_size, int rc_framesize, int nframes, int nbad)
1100
{
1101
struct ieee80211com *ic = &sc->sc_ic;
1102
struct sample_node *sn = ATH_NODE_SAMPLE(an);
1103
int final_rix, short_tries, long_tries;
1104
const HAL_RATE_TABLE *rt = sc->sc_currates;
1105
int status = ts->ts_status;
1106
int mrr;
1107
1108
final_rix = rt->rateCodeToIndex[ts->ts_rate];
1109
short_tries = ts->ts_shortretry;
1110
long_tries = ts->ts_longretry + 1;
1111
1112
if (nframes == 0) {
1113
device_printf(sc->sc_dev, "%s: nframes=0?\n", __func__);
1114
return;
1115
}
1116
1117
if (frame_size == 0) /* NB: should not happen */
1118
frame_size = 1500;
1119
if (rc_framesize == 0) /* NB: should not happen */
1120
rc_framesize = 1500;
1121
1122
/*
1123
* There are still some places where what rate control set as
1124
* a limit but the hardware decided, for some reason, to transmit
1125
* at a smaller size that fell into a different bucket.
1126
*
1127
* The eternal question here is - which size_bin should it go in?
1128
* The one that was requested, or the one that was transmitted?
1129
*
1130
* Here's the problem - if we use the one that was transmitted,
1131
* we may continue to hit corner cases where we make a rate
1132
* selection using a higher bin but only update the smaller bin;
1133
* thus never really "adapting".
1134
*
1135
* If however we update the larger bin, we're not accurately
1136
* representing the channel state at that frame/aggregate size.
1137
* However if we keep hitting the larger request but completing
1138
* a smaller size, we at least updates based on what the
1139
* request was /for/.
1140
*
1141
* I'm going to err on the side of caution and choose the
1142
* latter.
1143
*/
1144
if (size_to_bin(frame_size) != size_to_bin(rc_framesize)) {
1145
#if 0
1146
device_printf(sc->sc_dev,
1147
"%s: completed but frame size buckets mismatch "
1148
"(completed %d tx'ed %d)\n",
1149
__func__, frame_size, rc_framesize);
1150
#endif
1151
frame_size = rc_framesize;
1152
}
1153
1154
if (sn->ratemask == 0) {
1155
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1156
&an->an_node,
1157
"%s: size %d %s rate/try %d/%d no rates yet",
1158
__func__,
1159
bin_to_size(size_to_bin(frame_size)),
1160
status ? "FAIL" : "OK",
1161
short_tries, long_tries);
1162
return;
1163
}
1164
mrr = sc->sc_mrretry;
1165
/* XXX check HT protmode too */
1166
if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
1167
mrr = 0;
1168
1169
if (!mrr || ts->ts_finaltsi == 0) {
1170
if (!IS_RATE_DEFINED(sn, final_rix)) {
1171
device_printf(sc->sc_dev,
1172
"%s: ts_rate=%d ts_finaltsi=%d, final_rix=%d\n",
1173
__func__, ts->ts_rate, ts->ts_finaltsi, final_rix);
1174
badrate(sc, 0, ts->ts_rate, long_tries, status);
1175
return;
1176
}
1177
/*
1178
* Only one rate was used; optimize work.
1179
*/
1180
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1181
&an->an_node, "%s: size %d (%d bytes) %s rate/short/long %d %s/%d/%d nframes/nbad [%d/%d]",
1182
__func__,
1183
bin_to_size(size_to_bin(frame_size)),
1184
frame_size,
1185
status ? "FAIL" : "OK",
1186
dot11rate(rt, final_rix), dot11rate_label(rt, final_rix),
1187
short_tries, long_tries, nframes, nbad);
1188
update_stats(sc, an, frame_size,
1189
final_rix, long_tries,
1190
short_tries, long_tries, status,
1191
nframes, nbad);
1192
1193
} else {
1194
int finalTSIdx = ts->ts_finaltsi;
1195
int i;
1196
1197
/*
1198
* Process intermediate rates that failed.
1199
*/
1200
1201
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1202
&an->an_node,
1203
"%s: size %d (%d bytes) finaltsidx %d short %d long %d %s rate/try [%d %s/%d %d %s/%d %d %s/%d %d %s/%d] nframes/nbad [%d/%d]",
1204
__func__,
1205
bin_to_size(size_to_bin(frame_size)),
1206
frame_size,
1207
finalTSIdx,
1208
short_tries,
1209
long_tries,
1210
status ? "FAIL" : "OK",
1211
dot11rate(rt, rc[0].rix),
1212
dot11rate_label(rt, rc[0].rix), rc[0].tries,
1213
dot11rate(rt, rc[1].rix),
1214
dot11rate_label(rt, rc[1].rix), rc[1].tries,
1215
dot11rate(rt, rc[2].rix),
1216
dot11rate_label(rt, rc[2].rix), rc[2].tries,
1217
dot11rate(rt, rc[3].rix),
1218
dot11rate_label(rt, rc[3].rix), rc[3].tries,
1219
nframes, nbad);
1220
1221
for (i = 0; i < 4; i++) {
1222
if (rc[i].tries && !IS_RATE_DEFINED(sn, rc[i].rix))
1223
badrate(sc, 0, rc[i].ratecode, rc[i].tries,
1224
status);
1225
}
1226
1227
/*
1228
* This used to not penalise other tries because loss
1229
* can be bursty, but it's then not accurately keeping
1230
* the avg TX time and EWMA updated.
1231
*/
1232
if (rc[0].tries) {
1233
update_stats(sc, an, frame_size,
1234
rc[0].rix, rc[0].tries,
1235
short_tries, long_tries,
1236
status,
1237
nframes, nbad);
1238
long_tries -= rc[0].tries;
1239
}
1240
1241
if (rc[1].tries && finalTSIdx > 0) {
1242
update_stats(sc, an, frame_size,
1243
rc[1].rix, rc[1].tries,
1244
short_tries, long_tries,
1245
status,
1246
nframes, nbad);
1247
long_tries -= rc[1].tries;
1248
}
1249
1250
if (rc[2].tries && finalTSIdx > 1) {
1251
update_stats(sc, an, frame_size,
1252
rc[2].rix, rc[2].tries,
1253
short_tries, long_tries,
1254
status,
1255
nframes, nbad);
1256
long_tries -= rc[2].tries;
1257
}
1258
1259
if (rc[3].tries && finalTSIdx > 2) {
1260
update_stats(sc, an, frame_size,
1261
rc[3].rix, rc[3].tries,
1262
short_tries, long_tries,
1263
status,
1264
nframes, nbad);
1265
}
1266
}
1267
}
1268
1269
void
1270
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
1271
{
1272
if (isnew)
1273
ath_rate_ctl_reset(sc, &an->an_node);
1274
}
1275
1276
void
1277
ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi)
1278
{
1279
}
1280
1281
static const struct txschedule *mrr_schedules[IEEE80211_MODE_MAX+2] = {
1282
NULL, /* IEEE80211_MODE_AUTO */
1283
series_11a, /* IEEE80211_MODE_11A */
1284
series_11g, /* IEEE80211_MODE_11B */
1285
series_11g, /* IEEE80211_MODE_11G */
1286
NULL, /* IEEE80211_MODE_FH */
1287
series_11a, /* IEEE80211_MODE_TURBO_A */
1288
series_11g, /* IEEE80211_MODE_TURBO_G */
1289
series_11a, /* IEEE80211_MODE_STURBO_A */
1290
series_11na, /* IEEE80211_MODE_11NA */
1291
series_11ng, /* IEEE80211_MODE_11NG */
1292
series_half, /* IEEE80211_MODE_HALF */
1293
series_quarter, /* IEEE80211_MODE_QUARTER */
1294
};
1295
1296
/*
1297
* Initialize the tables for a node.
1298
*/
1299
static void
1300
ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
1301
{
1302
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
1303
#define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
1304
#define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
1305
struct ath_node *an = ATH_NODE(ni);
1306
struct sample_node *sn = ATH_NODE_SAMPLE(an);
1307
const HAL_RATE_TABLE *rt = sc->sc_currates;
1308
int x, y, rix;
1309
1310
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
1311
1312
KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2,
1313
("curmode %u", sc->sc_curmode));
1314
1315
sn->sched = mrr_schedules[sc->sc_curmode];
1316
KASSERT(sn->sched != NULL,
1317
("no mrr schedule for mode %u", sc->sc_curmode));
1318
1319
sn->static_rix = -1;
1320
ath_rate_update_static_rix(sc, ni);
1321
1322
sn->currates = sc->sc_currates;
1323
1324
/*
1325
* Construct a bitmask of usable rates. This has all
1326
* negotiated rates minus those marked by the hal as
1327
* to be ignored for doing rate control.
1328
*/
1329
sn->ratemask = 0;
1330
/* MCS rates */
1331
if (ni->ni_flags & IEEE80211_NODE_HT) {
1332
for (x = 0; x < ni->ni_htrates.rs_nrates; x++) {
1333
rix = sc->sc_rixmap[MCS(x)];
1334
if (rix == 0xff)
1335
continue;
1336
/* skip rates marked broken by hal */
1337
if (!rt->info[rix].valid)
1338
continue;
1339
KASSERT(rix < SAMPLE_MAXRATES,
1340
("mcs %u has rix %d", MCS(x), rix));
1341
sn->ratemask |= (uint64_t) 1<<rix;
1342
}
1343
}
1344
1345
/* Legacy rates */
1346
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
1347
rix = sc->sc_rixmap[RATE(x)];
1348
if (rix == 0xff)
1349
continue;
1350
/* skip rates marked broken by hal */
1351
if (!rt->info[rix].valid)
1352
continue;
1353
KASSERT(rix < SAMPLE_MAXRATES,
1354
("rate %u has rix %d", RATE(x), rix));
1355
sn->ratemask |= (uint64_t) 1<<rix;
1356
}
1357
#ifdef IEEE80211_DEBUG
1358
if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) {
1359
uint64_t mask;
1360
1361
ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt",
1362
ni->ni_macaddr, ":", __func__);
1363
for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
1364
if ((mask & 1) == 0)
1365
continue;
1366
printf(" %d %s/%d", dot11rate(rt, rix), dot11rate_label(rt, rix),
1367
calc_usecs_unicast_packet(sc, 1600, rix, 0,0,
1368
(ni->ni_chw == NET80211_STA_RX_BW_40)));
1369
}
1370
printf("\n");
1371
}
1372
#endif
1373
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
1374
int size = bin_to_size(y);
1375
uint64_t mask;
1376
1377
sn->packets_sent[y] = 0;
1378
sn->current_sample_rix[y] = -1;
1379
sn->last_sample_rix[y] = 0;
1380
/* XXX start with first valid rate */
1381
sn->current_rix[y] = ffs(sn->ratemask)-1;
1382
1383
/*
1384
* Initialize the statistics buckets; these are
1385
* indexed by the rate code index.
1386
*/
1387
for (rix = 0, mask = sn->ratemask; mask != 0; rix++, mask >>= 1) {
1388
if ((mask & 1) == 0) /* not a valid rate */
1389
continue;
1390
sn->stats[y][rix].successive_failures = 0;
1391
sn->stats[y][rix].tries = 0;
1392
sn->stats[y][rix].total_packets = 0;
1393
sn->stats[y][rix].packets_acked = 0;
1394
sn->stats[y][rix].last_tx = 0;
1395
sn->stats[y][rix].ewma_pct = 0;
1396
1397
sn->stats[y][rix].perfect_tx_time =
1398
calc_usecs_unicast_packet(sc, size, rix, 0, 0,
1399
(ni->ni_chw == NET80211_STA_RX_BW_40));
1400
sn->stats[y][rix].average_tx_time =
1401
sn->stats[y][rix].perfect_tx_time;
1402
}
1403
}
1404
#if 0
1405
/* XXX 0, num_rates-1 are wrong */
1406
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
1407
"%s: %d rates %d%sMbps (%dus)- %d%sMbps (%dus)", __func__,
1408
sn->num_rates,
1409
DOT11RATE(0)/2, DOT11RATE(0) % 1 ? ".5" : "",
1410
sn->stats[1][0].perfect_tx_time,
1411
DOT11RATE(sn->num_rates-1)/2, DOT11RATE(sn->num_rates-1) % 1 ? ".5" : "",
1412
sn->stats[1][sn->num_rates-1].perfect_tx_time
1413
);
1414
#endif
1415
/* set the visible bit-rate */
1416
if (sn->static_rix != -1)
1417
ieee80211_node_set_txrate_dot11rate(ni,
1418
DOT11RATE(sn->static_rix));
1419
else
1420
ieee80211_node_set_txrate_dot11rate(ni, RATE(0));
1421
#undef RATE
1422
#undef DOT11RATE
1423
}
1424
1425
/*
1426
* Fetch the statistics for the given node.
1427
*
1428
* The ieee80211 node must be referenced and unlocked, however the ath_node
1429
* must be locked.
1430
*
1431
* The main difference here is that we convert the rate indexes
1432
* to 802.11 rates, or the userland output won't make much sense
1433
* as it has no access to the rix table.
1434
*/
1435
int
1436
ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an,
1437
struct ath_rateioctl *rs)
1438
{
1439
struct sample_node *sn = ATH_NODE_SAMPLE(an);
1440
const HAL_RATE_TABLE *rt = sc->sc_currates;
1441
struct ath_rateioctl_tlv av;
1442
struct ath_rateioctl_rt *tv;
1443
int error, y;
1444
int o = 0;
1445
1446
ATH_NODE_LOCK_ASSERT(an);
1447
1448
error = 0;
1449
1450
/*
1451
* Ensure there's enough space for the statistics.
1452
*/
1453
if (rs->len <
1454
sizeof(struct ath_rateioctl_tlv) +
1455
sizeof(struct ath_rateioctl_rt) +
1456
sizeof(struct ath_rateioctl_tlv) +
1457
sizeof(struct sample_node)) {
1458
device_printf(sc->sc_dev, "%s: len=%d, too short\n",
1459
__func__,
1460
rs->len);
1461
return (EINVAL);
1462
}
1463
1464
/*
1465
* Take a temporary copy of the sample node state so we can
1466
* modify it before we copy it.
1467
*/
1468
tv = malloc(sizeof(struct ath_rateioctl_rt), M_TEMP,
1469
M_NOWAIT | M_ZERO);
1470
if (tv == NULL) {
1471
return (ENOMEM);
1472
}
1473
1474
/*
1475
* Populate the rate table mapping TLV.
1476
*/
1477
tv->nentries = rt->rateCount;
1478
for (y = 0; y < rt->rateCount; y++) {
1479
tv->ratecode[y] = rt->info[y].dot11Rate & IEEE80211_RATE_VAL;
1480
if (rt->info[y].phy == IEEE80211_T_HT)
1481
tv->ratecode[y] |= IEEE80211_RATE_MCS;
1482
}
1483
1484
o = 0;
1485
/*
1486
* First TLV - rate code mapping
1487
*/
1488
av.tlv_id = ATH_RATE_TLV_RATETABLE;
1489
av.tlv_len = sizeof(struct ath_rateioctl_rt);
1490
error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
1491
if (error != 0)
1492
goto out;
1493
o += sizeof(struct ath_rateioctl_tlv);
1494
error = copyout(tv, rs->buf + o, sizeof(struct ath_rateioctl_rt));
1495
if (error != 0)
1496
goto out;
1497
o += sizeof(struct ath_rateioctl_rt);
1498
1499
/*
1500
* Second TLV - sample node statistics
1501
*/
1502
av.tlv_id = ATH_RATE_TLV_SAMPLENODE;
1503
av.tlv_len = sizeof(struct sample_node);
1504
error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
1505
if (error != 0)
1506
goto out;
1507
o += sizeof(struct ath_rateioctl_tlv);
1508
1509
/*
1510
* Copy the statistics over to the provided buffer.
1511
*/
1512
error = copyout(sn, rs->buf + o, sizeof(struct sample_node));
1513
if (error != 0)
1514
goto out;
1515
o += sizeof(struct sample_node);
1516
1517
out:
1518
free(tv, M_TEMP);
1519
return (error);
1520
}
1521
1522
static void
1523
sample_stats(void *arg, struct ieee80211_node *ni)
1524
{
1525
struct ath_softc *sc = arg;
1526
const HAL_RATE_TABLE *rt = sc->sc_currates;
1527
struct sample_node *sn = ATH_NODE_SAMPLE(ATH_NODE(ni));
1528
uint64_t mask;
1529
int rix, y;
1530
1531
printf("\n[%s] refcnt %d static_rix (%d %s) ratemask 0x%jx\n",
1532
ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni),
1533
dot11rate(rt, sn->static_rix),
1534
dot11rate_label(rt, sn->static_rix),
1535
(uintmax_t)sn->ratemask);
1536
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
1537
printf("[%4u] cur rix %d (%d %s) since switch: packets %d ticks %u\n",
1538
bin_to_size(y), sn->current_rix[y],
1539
dot11rate(rt, sn->current_rix[y]),
1540
dot11rate_label(rt, sn->current_rix[y]),
1541
sn->packets_since_switch[y], sn->ticks_since_switch[y]);
1542
printf("[%4u] last sample (%d %s) cur sample (%d %s) packets sent %d\n",
1543
bin_to_size(y),
1544
dot11rate(rt, sn->last_sample_rix[y]),
1545
dot11rate_label(rt, sn->last_sample_rix[y]),
1546
dot11rate(rt, sn->current_sample_rix[y]),
1547
dot11rate_label(rt, sn->current_sample_rix[y]),
1548
sn->packets_sent[y]);
1549
printf("[%4u] packets since sample %d sample tt %u\n",
1550
bin_to_size(y), sn->packets_since_sample[y],
1551
sn->sample_tt[y]);
1552
}
1553
for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
1554
if ((mask & 1) == 0)
1555
continue;
1556
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
1557
if (sn->stats[y][rix].total_packets == 0)
1558
continue;
1559
printf("[%2u %s:%4u] %8ju:%-8ju (%3d%%) (EWMA %3d.%1d%%) T %8ju F %4d avg %5u last %u\n",
1560
dot11rate(rt, rix), dot11rate_label(rt, rix),
1561
bin_to_size(y),
1562
(uintmax_t) sn->stats[y][rix].total_packets,
1563
(uintmax_t) sn->stats[y][rix].packets_acked,
1564
(int) ((sn->stats[y][rix].packets_acked * 100ULL) /
1565
sn->stats[y][rix].total_packets),
1566
sn->stats[y][rix].ewma_pct / 10,
1567
sn->stats[y][rix].ewma_pct % 10,
1568
(uintmax_t) sn->stats[y][rix].tries,
1569
sn->stats[y][rix].successive_failures,
1570
sn->stats[y][rix].average_tx_time,
1571
ticks - sn->stats[y][rix].last_tx);
1572
}
1573
}
1574
}
1575
1576
static int
1577
ath_rate_sysctl_stats(SYSCTL_HANDLER_ARGS)
1578
{
1579
struct ath_softc *sc = arg1;
1580
struct ieee80211com *ic = &sc->sc_ic;
1581
int error, v;
1582
1583
v = 0;
1584
error = sysctl_handle_int(oidp, &v, 0, req);
1585
if (error || !req->newptr)
1586
return error;
1587
ieee80211_iterate_nodes(&ic->ic_sta, sample_stats, sc);
1588
return 0;
1589
}
1590
1591
static int
1592
ath_rate_sysctl_smoothing_rate(SYSCTL_HANDLER_ARGS)
1593
{
1594
struct sample_softc *ssc = arg1;
1595
int rate, error;
1596
1597
rate = ssc->smoothing_rate;
1598
error = sysctl_handle_int(oidp, &rate, 0, req);
1599
if (error || !req->newptr)
1600
return error;
1601
if (!(0 <= rate && rate < 100))
1602
return EINVAL;
1603
ssc->smoothing_rate = rate;
1604
ssc->smoothing_minpackets = 100 / (100 - rate);
1605
return 0;
1606
}
1607
1608
static int
1609
ath_rate_sysctl_sample_rate(SYSCTL_HANDLER_ARGS)
1610
{
1611
struct sample_softc *ssc = arg1;
1612
int rate, error;
1613
1614
rate = ssc->sample_rate;
1615
error = sysctl_handle_int(oidp, &rate, 0, req);
1616
if (error || !req->newptr)
1617
return error;
1618
if (!(2 <= rate && rate <= 100))
1619
return EINVAL;
1620
ssc->sample_rate = rate;
1621
return 0;
1622
}
1623
1624
static void
1625
ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *ssc)
1626
{
1627
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
1628
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
1629
1630
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1631
"smoothing_rate", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1632
ssc, 0, ath_rate_sysctl_smoothing_rate, "I",
1633
"sample: smoothing rate for avg tx time (%%)");
1634
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1635
"sample_rate", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1636
ssc, 0, ath_rate_sysctl_sample_rate, "I",
1637
"sample: percent air time devoted to sampling new rates (%%)");
1638
/* XXX max_successive_failures, stale_failure_timeout, min_switch */
1639
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1640
"sample_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1641
sc, 0, ath_rate_sysctl_stats, "I", "sample: print statistics");
1642
}
1643
1644
struct ath_ratectrl *
1645
ath_rate_attach(struct ath_softc *sc)
1646
{
1647
struct sample_softc *ssc;
1648
1649
ssc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
1650
if (ssc == NULL)
1651
return NULL;
1652
ssc->arc.arc_space = sizeof(struct sample_node);
1653
ssc->smoothing_rate = 75; /* ewma percentage ([0..99]) */
1654
ssc->smoothing_minpackets = 100 / (100 - ssc->smoothing_rate);
1655
ssc->sample_rate = 10; /* %time to try diff tx rates */
1656
ssc->max_successive_failures = 3; /* threshold for rate sampling*/
1657
ssc->stale_failure_timeout = 10 * hz; /* 10 seconds */
1658
ssc->min_switch = hz; /* 1 second */
1659
ath_rate_sysctlattach(sc, ssc);
1660
return &ssc->arc;
1661
}
1662
1663
void
1664
ath_rate_detach(struct ath_ratectrl *arc)
1665
{
1666
struct sample_softc *ssc = (struct sample_softc *) arc;
1667
1668
free(ssc, M_DEVBUF);
1669
}
1670
1671