41 42/* 43 * AMRR rate control. See: 44 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html 45 * "IEEE 802.11 Rate Adaptation: A Practical Approach" by 46 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti 47 */ 48#include "opt_inet.h" 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/sysctl.h> 53#include <sys/module.h> 54#include <sys/kernel.h> 55#include <sys/lock.h> 56#include <sys/mutex.h> 57#include <sys/errno.h> 58 59#include <machine/bus.h> 60#include <machine/resource.h> 61#include <sys/bus.h> 62 63#include <sys/socket.h> 64 65#include <net/if.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/amrr/amrr.h> 81#include <contrib/dev/ath/ah_desc.h> 82 83#define AMRR_DEBUG 84#ifdef AMRR_DEBUG 85#define DPRINTF(sc, _fmt, ...) do { \ 86 if (sc->sc_debug & 0x10) \ 87 printf(_fmt, __VA_ARGS__); \ 88} while (0) 89#else 90#define DPRINTF(sc, _fmt, ...) 91#endif 92 93static int ath_rateinterval = 1000; /* rate ctl interval (ms) */ 94static int ath_rate_max_success_threshold = 10; 95static int ath_rate_min_success_threshold = 1; 96 97static void ath_ratectl(void *); 98static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, 99 int rate); 100static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); 101static void ath_rate_ctl(void *, struct ieee80211_node *); 102 103void 104ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) 105{ 106 /* NB: assumed to be zero'd by caller */ 107 ath_rate_update(sc, &an->an_node, 0); 108} 109 110void 111ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) 112{ 113} 114 115void 116ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, 117 HAL_BOOL shortPreamble, size_t frameLen, 118 u_int8_t *rix, int *try0, u_int8_t *txrate) 119{ 120 struct amrr_node *amn = ATH_NODE_AMRR(an); 121 122 *rix = amn->amn_tx_rix0; 123 *try0 = amn->amn_tx_try0; 124 if (shortPreamble) 125 *txrate = amn->amn_tx_rate0sp; 126 else 127 *txrate = amn->amn_tx_rate0; 128} 129 130void 131ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an, 132 struct ath_desc *ds, HAL_BOOL shortPreamble, u_int8_t rix) 133{ 134 struct amrr_node *amn = ATH_NODE_AMRR(an); 135 136 ath_hal_setupxtxdesc(sc->sc_ah, ds 137 , amn->amn_tx_rate1sp, amn->amn_tx_try1 /* series 1 */ 138 , amn->amn_tx_rate2sp, amn->amn_tx_try2 /* series 2 */ 139 , amn->amn_tx_rate3sp, amn->amn_tx_try3 /* series 3 */ 140 ); 141} 142 143void 144ath_rate_tx_complete(struct ath_softc *sc, 145 struct ath_node *an, const struct ath_desc *ds) 146{ 147 struct amrr_node *amn = ATH_NODE_AMRR(an); 148 int sr = ds->ds_txstat.ts_shortretry; 149 int lr = ds->ds_txstat.ts_longretry; 150 int retry_count = sr + lr; 151 152 amn->amn_tx_try0_cnt++; 153 if (retry_count == 1) { 154 amn->amn_tx_try1_cnt++; 155 } else if (retry_count == 2) { 156 amn->amn_tx_try1_cnt++; 157 amn->amn_tx_try2_cnt++; 158 } else if (retry_count == 3) { 159 amn->amn_tx_try1_cnt++; 160 amn->amn_tx_try2_cnt++; 161 amn->amn_tx_try3_cnt++; 162 } else if (retry_count > 3) { 163 amn->amn_tx_try1_cnt++; 164 amn->amn_tx_try2_cnt++; 165 amn->amn_tx_try3_cnt++; 166 amn->amn_tx_failure_cnt++; 167 } 168} 169 170void 171ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) 172{ 173 if (isnew) 174 ath_rate_ctl_start(sc, &an->an_node); 175} 176 177static void 178node_reset (struct amrr_node *amn) 179{ 180 amn->amn_tx_try0_cnt = 0; 181 amn->amn_tx_try1_cnt = 0; 182 amn->amn_tx_try2_cnt = 0; 183 amn->amn_tx_try3_cnt = 0; 184 amn->amn_tx_failure_cnt = 0; 185 amn->amn_success = 0; 186 amn->amn_recovery = 0; 187 amn->amn_success_threshold = ath_rate_min_success_threshold; 188} 189 190 191/** 192 * The code below assumes that we are dealing with hardware multi rate retry 193 * I have no idea what will happen if you try to use this module with another 194 * type of hardware. Your machine might catch fire or it might work with 195 * horrible performance... 196 */ 197static void 198ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) 199{ 200 struct ath_node *an = ATH_NODE(ni); 201 struct amrr_node *amn = ATH_NODE_AMRR(an); 202 const HAL_RATE_TABLE *rt = sc->sc_currates; 203 u_int8_t rix; 204 205 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); 206 207 DPRINTF(sc, "%s: set xmit rate for %s to %dM\n", 208 __func__, ether_sprintf(ni->ni_macaddr), 209 ni->ni_rates.rs_nrates > 0 ? 210 (ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0); 211 212 ni->ni_txrate = rate; 213 /* XXX management/control frames always go at the lowest speed */ 214 an->an_tx_mgtrate = rt->info[0].rateCode; 215 an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble; 216 /* 217 * Before associating a node has no rate set setup 218 * so we can't calculate any transmit codes to use. 219 * This is ok since we should never be sending anything 220 * but management frames and those always go at the 221 * lowest hardware rate. 222 */ 223 if (ni->ni_rates.rs_nrates > 0) { 224 amn->amn_tx_rix0 = sc->sc_rixmap[ 225 ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL]; 226 amn->amn_tx_rate0 = rt->info[amn->amn_tx_rix0].rateCode; 227 amn->amn_tx_rate0sp = amn->amn_tx_rate0 | 228 rt->info[amn->amn_tx_rix0].shortPreamble; 229 if (sc->sc_mrretry) { 230 amn->amn_tx_try0 = 1; 231 amn->amn_tx_try1 = 1; 232 amn->amn_tx_try2 = 1; 233 amn->amn_tx_try3 = 1; 234 if (--rate >= 0) { 235 rix = sc->sc_rixmap[ 236 ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; 237 amn->amn_tx_rate1 = rt->info[rix].rateCode; 238 amn->amn_tx_rate1sp = amn->amn_tx_rate1 | 239 rt->info[rix].shortPreamble; 240 } else { 241 amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0; 242 } 243 if (--rate >= 0) { 244 rix = sc->sc_rixmap[ 245 ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; 246 amn->amn_tx_rate2 = rt->info[rix].rateCode; 247 amn->amn_tx_rate2sp = amn->amn_tx_rate2 | 248 rt->info[rix].shortPreamble; 249 } else { 250 amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0; 251 } 252 if (rate > 0) { 253 /* NB: only do this if we didn't already do it above */ 254 amn->amn_tx_rate3 = rt->info[0].rateCode; 255 amn->amn_tx_rate3sp = 256 an->an_tx_mgtrate | rt->info[0].shortPreamble; 257 } else { 258 amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0; 259 } 260 } else { 261 amn->amn_tx_try0 = ATH_TXMAXTRY; 262 /* theorically, these statements are useless because 263 * the code which uses them tests for an_tx_try0 == ATH_TXMAXTRY 264 */ 265 amn->amn_tx_try1 = 0; 266 amn->amn_tx_try2 = 0; 267 amn->amn_tx_try3 = 0; 268 amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0; 269 amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0; 270 amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0; 271 } 272 } 273 node_reset (amn); 274} 275 276/* 277 * Set the starting transmit rate for a node. 278 */ 279static void 280ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) 281{ 282#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) 283 struct ieee80211com *ic = &sc->sc_ic; 284 int srate; 285 286 KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); 287 if (ic->ic_fixed_rate == -1) { 288 /* 289 * No fixed rate is requested. For 11b start with 290 * the highest negotiated rate; otherwise, for 11g 291 * and 11a, we start "in the middle" at 24Mb or 36Mb. 292 */ 293 srate = ni->ni_rates.rs_nrates - 1; 294 if (sc->sc_curmode != IEEE80211_MODE_11B) { 295 /* 296 * Scan the negotiated rate set to find the 297 * closest rate. 298 */ 299 /* NB: the rate set is assumed sorted */ 300 for (; srate >= 0 && RATE(srate) > 72; srate--) 301 ; 302 KASSERT(srate >= 0, ("bogus rate set")); 303 } 304 } else { 305 /* 306 * A fixed rate is to be used; ic_fixed_rate is an 307 * index into the supported rate set. Convert this 308 * to the index into the negotiated rate set for 309 * the node. We know the rate is there because the 310 * rate set is checked when the station associates. 311 */ 312 const struct ieee80211_rateset *rs = 313 &ic->ic_sup_rates[ic->ic_curmode]; 314 int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 315 /* NB: the rate set is assumed sorted */ 316 srate = ni->ni_rates.rs_nrates - 1; 317 for (; srate >= 0 && RATE(srate) != r; srate--) 318 ; 319 KASSERT(srate >= 0, 320 ("fixed rate %d not in rate set", ic->ic_fixed_rate)); 321 } 322 ath_rate_update(sc, ni, srate); 323#undef RATE 324} 325 326static void 327ath_rate_cb(void *arg, struct ieee80211_node *ni) 328{ 329 ath_rate_update(ni->ni_ic->ic_ifp->if_softc, ni, (int)(uintptr_t) arg); 330} 331 332/* 333 * Reset the rate control state for each 802.11 state transition. 334 */ 335void 336ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) 337{ 338 struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; 339 struct ieee80211com *ic = &sc->sc_ic; 340 struct ieee80211_node *ni; 341 342 if (state == IEEE80211_S_INIT) { 343 callout_stop(&asc->timer); 344 return; 345 } 346 if (ic->ic_opmode == IEEE80211_M_STA) { 347 /* 348 * Reset local xmit state; this is really only 349 * meaningful when operating in station mode. 350 */ 351 ni = ic->ic_bss; 352 if (state == IEEE80211_S_RUN) { 353 ath_rate_ctl_start(sc, ni); 354 } else { 355 ath_rate_update(sc, ni, 0); 356 } 357 } else { 358 /* 359 * When operating as a station the node table holds 360 * the AP's that were discovered during scanning. 361 * For any other operating mode we want to reset the 362 * tx rate state of each node. 363 */ 364 if (ic->ic_sta != NULL) 365 ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0); 366 ath_rate_update(sc, ic->ic_bss, 0); 367 } 368 if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) { 369 int interval; 370 /* 371 * Start the background rate control thread if we 372 * are not configured to use a fixed xmit rate. 373 */ 374 interval = ath_rateinterval; 375 if (ic->ic_opmode == IEEE80211_M_STA) 376 interval /= 2; 377 callout_reset(&asc->timer, (interval * hz) / 1000, 378 ath_ratectl, &sc->sc_if); 379 } 380} 381 382/* 383 * Examine and potentially adjust the transmit rate. 384 */ 385static void 386ath_rate_ctl(void *arg, struct ieee80211_node *ni) 387{ 388 struct ath_softc *sc = arg; 389 struct amrr_node *amn = ATH_NODE_AMRR(ATH_NODE (ni)); 390 int old_rate; 391 392#define is_success(amn) \ 393(amn->amn_tx_try1_cnt < (amn->amn_tx_try0_cnt/10)) 394#define is_enough(amn) \ 395(amn->amn_tx_try0_cnt > 10) 396#define is_failure(amn) \ 397(amn->amn_tx_try1_cnt > (amn->amn_tx_try0_cnt/3)) 398#define is_max_rate(ni) \ 399((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates) 400#define is_min_rate(ni) \ 401(ni->ni_txrate == 0) 402 403 old_rate = ni->ni_txrate; 404 405 DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n", 406 amn->amn_tx_try0_cnt, 407 amn->amn_tx_try1_cnt, 408 amn->amn_tx_try2_cnt, 409 amn->amn_tx_try3_cnt, 410 amn->amn_success_threshold); 411 if (is_success (amn) && is_enough (amn)) { 412 amn->amn_success++; 413 if (amn->amn_success == amn->amn_success_threshold && 414 !is_max_rate (ni)) { 415 amn->amn_recovery = 1; 416 amn->amn_success = 0; 417 ni->ni_txrate++; 418 DPRINTF (sc, "increase rate to %d\n", ni->ni_txrate); 419 } else { 420 amn->amn_recovery = 0; 421 } 422 } else if (is_failure (amn)) { 423 amn->amn_success = 0; 424 if (!is_min_rate (ni)) { 425 if (amn->amn_recovery) { 426 /* recovery failure. */ 427 amn->amn_success_threshold *= 2; 428 amn->amn_success_threshold = min (amn->amn_success_threshold, 429 (u_int)ath_rate_max_success_threshold); 430 DPRINTF (sc, "decrease rate recovery thr: %d\n", amn->amn_success_threshold); 431 } else { 432 /* simple failure. */ 433 amn->amn_success_threshold = ath_rate_min_success_threshold; 434 DPRINTF (sc, "decrease rate normal thr: %d\n", amn->amn_success_threshold); 435 } 436 amn->amn_recovery = 0; 437 ni->ni_txrate--; 438 } else { 439 amn->amn_recovery = 0; 440 } 441 442 } 443 if (is_enough (amn) || old_rate != ni->ni_txrate) { 444 /* reset counters. */ 445 amn->amn_tx_try0_cnt = 0; 446 amn->amn_tx_try1_cnt = 0; 447 amn->amn_tx_try2_cnt = 0; 448 amn->amn_tx_try3_cnt = 0; 449 amn->amn_tx_failure_cnt = 0; 450 } 451 if (old_rate != ni->ni_txrate) { 452 ath_rate_update(sc, ni, ni->ni_txrate); 453 } 454} 455 456static void 457ath_ratectl(void *arg) 458{ 459 struct ifnet *ifp = arg; 460 struct ath_softc *sc = ifp->if_softc; 461 struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; 462 struct ieee80211com *ic = &sc->sc_ic; 463 int interval; 464 465 if (ifp->if_flags & IFF_RUNNING) { 466 sc->sc_stats.ast_rate_calls++; 467 468 if (ic->ic_opmode == IEEE80211_M_STA) 469 ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */ 470 else if (ic->ic_sta != NULL) 471 ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc); 472 } 473 interval = ath_rateinterval; 474 if (ic->ic_opmode == IEEE80211_M_STA) 475 interval /= 2; 476 callout_reset(&asc->timer, (interval * hz) / 1000, 477 ath_ratectl, &sc->sc_if); 478} 479 480static void 481ath_rate_sysctlattach(struct ath_softc *sc) 482{ 483 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 484 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 485 486 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 487 "rate_interval", CTLFLAG_RW, &ath_rateinterval, 0, 488 "rate control: operation interval (ms)"); 489 /* XXX bounds check values */ 490 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 491 "max_sucess_threshold", CTLFLAG_RW, 492 &ath_rate_max_success_threshold, 0, ""); 493 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 494 "min_sucess_threshold", CTLFLAG_RW, 495 &ath_rate_min_success_threshold, 0, ""); 496} 497 498struct ath_ratectrl * 499ath_rate_attach(struct ath_softc *sc) 500{ 501 struct amrr_softc *asc; 502 503 asc = malloc(sizeof(struct amrr_softc), M_DEVBUF, M_NOWAIT|M_ZERO); 504 if (asc == NULL) 505 return NULL; 506 asc->arc.arc_space = sizeof(struct amrr_node); 507 callout_init(&asc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0); 508 ath_rate_sysctlattach(sc); 509 510 return &asc->arc; 511} 512 513void 514ath_rate_detach(struct ath_ratectrl *arc) 515{ 516 struct amrr_softc *asc = (struct amrr_softc *) arc; 517 518 callout_drain(&asc->timer); 519 free(asc, M_DEVBUF); 520} 521 522/* 523 * Module glue. 524 */ 525static int 526amrr_modevent(module_t mod, int type, void *unused) 527{ 528 switch (type) { 529 case MOD_LOAD: 530 if (bootverbose) 531 printf("ath_rate: <AMRR rate control algorithm> version 0.1\n"); 532 return 0; 533 case MOD_UNLOAD: 534 return 0; 535 } 536 return EINVAL; 537} 538 539static moduledata_t amrr_mod = { 540 "ath_rate", 541 amrr_modevent, 542 0 543}; 544DECLARE_MODULE(ath_rate, amrr_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 545MODULE_VERSION(ath_rate, 1); 546MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
| 41 42/* 43 * AMRR rate control. See: 44 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html 45 * "IEEE 802.11 Rate Adaptation: A Practical Approach" by 46 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti 47 */ 48#include "opt_inet.h" 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/sysctl.h> 53#include <sys/module.h> 54#include <sys/kernel.h> 55#include <sys/lock.h> 56#include <sys/mutex.h> 57#include <sys/errno.h> 58 59#include <machine/bus.h> 60#include <machine/resource.h> 61#include <sys/bus.h> 62 63#include <sys/socket.h> 64 65#include <net/if.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/amrr/amrr.h> 81#include <contrib/dev/ath/ah_desc.h> 82 83#define AMRR_DEBUG 84#ifdef AMRR_DEBUG 85#define DPRINTF(sc, _fmt, ...) do { \ 86 if (sc->sc_debug & 0x10) \ 87 printf(_fmt, __VA_ARGS__); \ 88} while (0) 89#else 90#define DPRINTF(sc, _fmt, ...) 91#endif 92 93static int ath_rateinterval = 1000; /* rate ctl interval (ms) */ 94static int ath_rate_max_success_threshold = 10; 95static int ath_rate_min_success_threshold = 1; 96 97static void ath_ratectl(void *); 98static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, 99 int rate); 100static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); 101static void ath_rate_ctl(void *, struct ieee80211_node *); 102 103void 104ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) 105{ 106 /* NB: assumed to be zero'd by caller */ 107 ath_rate_update(sc, &an->an_node, 0); 108} 109 110void 111ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) 112{ 113} 114 115void 116ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, 117 HAL_BOOL shortPreamble, size_t frameLen, 118 u_int8_t *rix, int *try0, u_int8_t *txrate) 119{ 120 struct amrr_node *amn = ATH_NODE_AMRR(an); 121 122 *rix = amn->amn_tx_rix0; 123 *try0 = amn->amn_tx_try0; 124 if (shortPreamble) 125 *txrate = amn->amn_tx_rate0sp; 126 else 127 *txrate = amn->amn_tx_rate0; 128} 129 130void 131ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an, 132 struct ath_desc *ds, HAL_BOOL shortPreamble, u_int8_t rix) 133{ 134 struct amrr_node *amn = ATH_NODE_AMRR(an); 135 136 ath_hal_setupxtxdesc(sc->sc_ah, ds 137 , amn->amn_tx_rate1sp, amn->amn_tx_try1 /* series 1 */ 138 , amn->amn_tx_rate2sp, amn->amn_tx_try2 /* series 2 */ 139 , amn->amn_tx_rate3sp, amn->amn_tx_try3 /* series 3 */ 140 ); 141} 142 143void 144ath_rate_tx_complete(struct ath_softc *sc, 145 struct ath_node *an, const struct ath_desc *ds) 146{ 147 struct amrr_node *amn = ATH_NODE_AMRR(an); 148 int sr = ds->ds_txstat.ts_shortretry; 149 int lr = ds->ds_txstat.ts_longretry; 150 int retry_count = sr + lr; 151 152 amn->amn_tx_try0_cnt++; 153 if (retry_count == 1) { 154 amn->amn_tx_try1_cnt++; 155 } else if (retry_count == 2) { 156 amn->amn_tx_try1_cnt++; 157 amn->amn_tx_try2_cnt++; 158 } else if (retry_count == 3) { 159 amn->amn_tx_try1_cnt++; 160 amn->amn_tx_try2_cnt++; 161 amn->amn_tx_try3_cnt++; 162 } else if (retry_count > 3) { 163 amn->amn_tx_try1_cnt++; 164 amn->amn_tx_try2_cnt++; 165 amn->amn_tx_try3_cnt++; 166 amn->amn_tx_failure_cnt++; 167 } 168} 169 170void 171ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) 172{ 173 if (isnew) 174 ath_rate_ctl_start(sc, &an->an_node); 175} 176 177static void 178node_reset (struct amrr_node *amn) 179{ 180 amn->amn_tx_try0_cnt = 0; 181 amn->amn_tx_try1_cnt = 0; 182 amn->amn_tx_try2_cnt = 0; 183 amn->amn_tx_try3_cnt = 0; 184 amn->amn_tx_failure_cnt = 0; 185 amn->amn_success = 0; 186 amn->amn_recovery = 0; 187 amn->amn_success_threshold = ath_rate_min_success_threshold; 188} 189 190 191/** 192 * The code below assumes that we are dealing with hardware multi rate retry 193 * I have no idea what will happen if you try to use this module with another 194 * type of hardware. Your machine might catch fire or it might work with 195 * horrible performance... 196 */ 197static void 198ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) 199{ 200 struct ath_node *an = ATH_NODE(ni); 201 struct amrr_node *amn = ATH_NODE_AMRR(an); 202 const HAL_RATE_TABLE *rt = sc->sc_currates; 203 u_int8_t rix; 204 205 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); 206 207 DPRINTF(sc, "%s: set xmit rate for %s to %dM\n", 208 __func__, ether_sprintf(ni->ni_macaddr), 209 ni->ni_rates.rs_nrates > 0 ? 210 (ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0); 211 212 ni->ni_txrate = rate; 213 /* XXX management/control frames always go at the lowest speed */ 214 an->an_tx_mgtrate = rt->info[0].rateCode; 215 an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble; 216 /* 217 * Before associating a node has no rate set setup 218 * so we can't calculate any transmit codes to use. 219 * This is ok since we should never be sending anything 220 * but management frames and those always go at the 221 * lowest hardware rate. 222 */ 223 if (ni->ni_rates.rs_nrates > 0) { 224 amn->amn_tx_rix0 = sc->sc_rixmap[ 225 ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL]; 226 amn->amn_tx_rate0 = rt->info[amn->amn_tx_rix0].rateCode; 227 amn->amn_tx_rate0sp = amn->amn_tx_rate0 | 228 rt->info[amn->amn_tx_rix0].shortPreamble; 229 if (sc->sc_mrretry) { 230 amn->amn_tx_try0 = 1; 231 amn->amn_tx_try1 = 1; 232 amn->amn_tx_try2 = 1; 233 amn->amn_tx_try3 = 1; 234 if (--rate >= 0) { 235 rix = sc->sc_rixmap[ 236 ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; 237 amn->amn_tx_rate1 = rt->info[rix].rateCode; 238 amn->amn_tx_rate1sp = amn->amn_tx_rate1 | 239 rt->info[rix].shortPreamble; 240 } else { 241 amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0; 242 } 243 if (--rate >= 0) { 244 rix = sc->sc_rixmap[ 245 ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; 246 amn->amn_tx_rate2 = rt->info[rix].rateCode; 247 amn->amn_tx_rate2sp = amn->amn_tx_rate2 | 248 rt->info[rix].shortPreamble; 249 } else { 250 amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0; 251 } 252 if (rate > 0) { 253 /* NB: only do this if we didn't already do it above */ 254 amn->amn_tx_rate3 = rt->info[0].rateCode; 255 amn->amn_tx_rate3sp = 256 an->an_tx_mgtrate | rt->info[0].shortPreamble; 257 } else { 258 amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0; 259 } 260 } else { 261 amn->amn_tx_try0 = ATH_TXMAXTRY; 262 /* theorically, these statements are useless because 263 * the code which uses them tests for an_tx_try0 == ATH_TXMAXTRY 264 */ 265 amn->amn_tx_try1 = 0; 266 amn->amn_tx_try2 = 0; 267 amn->amn_tx_try3 = 0; 268 amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0; 269 amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0; 270 amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0; 271 } 272 } 273 node_reset (amn); 274} 275 276/* 277 * Set the starting transmit rate for a node. 278 */ 279static void 280ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) 281{ 282#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) 283 struct ieee80211com *ic = &sc->sc_ic; 284 int srate; 285 286 KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); 287 if (ic->ic_fixed_rate == -1) { 288 /* 289 * No fixed rate is requested. For 11b start with 290 * the highest negotiated rate; otherwise, for 11g 291 * and 11a, we start "in the middle" at 24Mb or 36Mb. 292 */ 293 srate = ni->ni_rates.rs_nrates - 1; 294 if (sc->sc_curmode != IEEE80211_MODE_11B) { 295 /* 296 * Scan the negotiated rate set to find the 297 * closest rate. 298 */ 299 /* NB: the rate set is assumed sorted */ 300 for (; srate >= 0 && RATE(srate) > 72; srate--) 301 ; 302 KASSERT(srate >= 0, ("bogus rate set")); 303 } 304 } else { 305 /* 306 * A fixed rate is to be used; ic_fixed_rate is an 307 * index into the supported rate set. Convert this 308 * to the index into the negotiated rate set for 309 * the node. We know the rate is there because the 310 * rate set is checked when the station associates. 311 */ 312 const struct ieee80211_rateset *rs = 313 &ic->ic_sup_rates[ic->ic_curmode]; 314 int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 315 /* NB: the rate set is assumed sorted */ 316 srate = ni->ni_rates.rs_nrates - 1; 317 for (; srate >= 0 && RATE(srate) != r; srate--) 318 ; 319 KASSERT(srate >= 0, 320 ("fixed rate %d not in rate set", ic->ic_fixed_rate)); 321 } 322 ath_rate_update(sc, ni, srate); 323#undef RATE 324} 325 326static void 327ath_rate_cb(void *arg, struct ieee80211_node *ni) 328{ 329 ath_rate_update(ni->ni_ic->ic_ifp->if_softc, ni, (int)(uintptr_t) arg); 330} 331 332/* 333 * Reset the rate control state for each 802.11 state transition. 334 */ 335void 336ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) 337{ 338 struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; 339 struct ieee80211com *ic = &sc->sc_ic; 340 struct ieee80211_node *ni; 341 342 if (state == IEEE80211_S_INIT) { 343 callout_stop(&asc->timer); 344 return; 345 } 346 if (ic->ic_opmode == IEEE80211_M_STA) { 347 /* 348 * Reset local xmit state; this is really only 349 * meaningful when operating in station mode. 350 */ 351 ni = ic->ic_bss; 352 if (state == IEEE80211_S_RUN) { 353 ath_rate_ctl_start(sc, ni); 354 } else { 355 ath_rate_update(sc, ni, 0); 356 } 357 } else { 358 /* 359 * When operating as a station the node table holds 360 * the AP's that were discovered during scanning. 361 * For any other operating mode we want to reset the 362 * tx rate state of each node. 363 */ 364 if (ic->ic_sta != NULL) 365 ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0); 366 ath_rate_update(sc, ic->ic_bss, 0); 367 } 368 if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) { 369 int interval; 370 /* 371 * Start the background rate control thread if we 372 * are not configured to use a fixed xmit rate. 373 */ 374 interval = ath_rateinterval; 375 if (ic->ic_opmode == IEEE80211_M_STA) 376 interval /= 2; 377 callout_reset(&asc->timer, (interval * hz) / 1000, 378 ath_ratectl, &sc->sc_if); 379 } 380} 381 382/* 383 * Examine and potentially adjust the transmit rate. 384 */ 385static void 386ath_rate_ctl(void *arg, struct ieee80211_node *ni) 387{ 388 struct ath_softc *sc = arg; 389 struct amrr_node *amn = ATH_NODE_AMRR(ATH_NODE (ni)); 390 int old_rate; 391 392#define is_success(amn) \ 393(amn->amn_tx_try1_cnt < (amn->amn_tx_try0_cnt/10)) 394#define is_enough(amn) \ 395(amn->amn_tx_try0_cnt > 10) 396#define is_failure(amn) \ 397(amn->amn_tx_try1_cnt > (amn->amn_tx_try0_cnt/3)) 398#define is_max_rate(ni) \ 399((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates) 400#define is_min_rate(ni) \ 401(ni->ni_txrate == 0) 402 403 old_rate = ni->ni_txrate; 404 405 DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n", 406 amn->amn_tx_try0_cnt, 407 amn->amn_tx_try1_cnt, 408 amn->amn_tx_try2_cnt, 409 amn->amn_tx_try3_cnt, 410 amn->amn_success_threshold); 411 if (is_success (amn) && is_enough (amn)) { 412 amn->amn_success++; 413 if (amn->amn_success == amn->amn_success_threshold && 414 !is_max_rate (ni)) { 415 amn->amn_recovery = 1; 416 amn->amn_success = 0; 417 ni->ni_txrate++; 418 DPRINTF (sc, "increase rate to %d\n", ni->ni_txrate); 419 } else { 420 amn->amn_recovery = 0; 421 } 422 } else if (is_failure (amn)) { 423 amn->amn_success = 0; 424 if (!is_min_rate (ni)) { 425 if (amn->amn_recovery) { 426 /* recovery failure. */ 427 amn->amn_success_threshold *= 2; 428 amn->amn_success_threshold = min (amn->amn_success_threshold, 429 (u_int)ath_rate_max_success_threshold); 430 DPRINTF (sc, "decrease rate recovery thr: %d\n", amn->amn_success_threshold); 431 } else { 432 /* simple failure. */ 433 amn->amn_success_threshold = ath_rate_min_success_threshold; 434 DPRINTF (sc, "decrease rate normal thr: %d\n", amn->amn_success_threshold); 435 } 436 amn->amn_recovery = 0; 437 ni->ni_txrate--; 438 } else { 439 amn->amn_recovery = 0; 440 } 441 442 } 443 if (is_enough (amn) || old_rate != ni->ni_txrate) { 444 /* reset counters. */ 445 amn->amn_tx_try0_cnt = 0; 446 amn->amn_tx_try1_cnt = 0; 447 amn->amn_tx_try2_cnt = 0; 448 amn->amn_tx_try3_cnt = 0; 449 amn->amn_tx_failure_cnt = 0; 450 } 451 if (old_rate != ni->ni_txrate) { 452 ath_rate_update(sc, ni, ni->ni_txrate); 453 } 454} 455 456static void 457ath_ratectl(void *arg) 458{ 459 struct ifnet *ifp = arg; 460 struct ath_softc *sc = ifp->if_softc; 461 struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; 462 struct ieee80211com *ic = &sc->sc_ic; 463 int interval; 464 465 if (ifp->if_flags & IFF_RUNNING) { 466 sc->sc_stats.ast_rate_calls++; 467 468 if (ic->ic_opmode == IEEE80211_M_STA) 469 ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */ 470 else if (ic->ic_sta != NULL) 471 ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc); 472 } 473 interval = ath_rateinterval; 474 if (ic->ic_opmode == IEEE80211_M_STA) 475 interval /= 2; 476 callout_reset(&asc->timer, (interval * hz) / 1000, 477 ath_ratectl, &sc->sc_if); 478} 479 480static void 481ath_rate_sysctlattach(struct ath_softc *sc) 482{ 483 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 484 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 485 486 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 487 "rate_interval", CTLFLAG_RW, &ath_rateinterval, 0, 488 "rate control: operation interval (ms)"); 489 /* XXX bounds check values */ 490 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 491 "max_sucess_threshold", CTLFLAG_RW, 492 &ath_rate_max_success_threshold, 0, ""); 493 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 494 "min_sucess_threshold", CTLFLAG_RW, 495 &ath_rate_min_success_threshold, 0, ""); 496} 497 498struct ath_ratectrl * 499ath_rate_attach(struct ath_softc *sc) 500{ 501 struct amrr_softc *asc; 502 503 asc = malloc(sizeof(struct amrr_softc), M_DEVBUF, M_NOWAIT|M_ZERO); 504 if (asc == NULL) 505 return NULL; 506 asc->arc.arc_space = sizeof(struct amrr_node); 507 callout_init(&asc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0); 508 ath_rate_sysctlattach(sc); 509 510 return &asc->arc; 511} 512 513void 514ath_rate_detach(struct ath_ratectrl *arc) 515{ 516 struct amrr_softc *asc = (struct amrr_softc *) arc; 517 518 callout_drain(&asc->timer); 519 free(asc, M_DEVBUF); 520} 521 522/* 523 * Module glue. 524 */ 525static int 526amrr_modevent(module_t mod, int type, void *unused) 527{ 528 switch (type) { 529 case MOD_LOAD: 530 if (bootverbose) 531 printf("ath_rate: <AMRR rate control algorithm> version 0.1\n"); 532 return 0; 533 case MOD_UNLOAD: 534 return 0; 535 } 536 return EINVAL; 537} 538 539static moduledata_t amrr_mod = { 540 "ath_rate", 541 amrr_modevent, 542 0 543}; 544DECLARE_MODULE(ath_rate, amrr_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 545MODULE_VERSION(ath_rate, 1); 546MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
|