DF-4881 / fix.diff
Fix DF-4881: onoe caches HW rate codes into index-typed fields. Cache the rate-table indices alongside the codes (onoe.h) and populate ath_rc_series.rix with indices and .ratecode with codes (onoe.c), instead of storing codes in both. Without this, every downstream rt->info[rc[i].rix] deref (if_ath_tx.c:1073/1133/1298, if_ath_tx_ht.c:588) is a wrong-entry access, OOB on 11n HALs (HT codes 0x80-0x8f vs HAL_RATE_TABLE.info[64]), and the correct series-0 index set by the caller at if_ath_tx.c:1392 is clobbered. --- a/sys/dev/netif/ath/ath_rate/onoe/onoe.h +++ b/sys/dev/netif/ath/ath_rate/onoe/onoe.h @@ -63,9 +63,13 @@ struct onoe_node { u_int8_t on_tx_rix0; /* series 0 rate index */ u_int8_t on_tx_try0; /* series 0 try count */ u_int8_t on_tx_rate0; /* series 0 h/w rate */ + u_int8_t on_tx_rix1; /* series 1 rate index */ u_int8_t on_tx_rate1; /* series 1 h/w rate */ + u_int8_t on_tx_rix2; /* series 2 rate index */ u_int8_t on_tx_rate2; /* series 2 h/w rate */ + u_int8_t on_tx_rix3; /* series 3 rate index */ u_int8_t on_tx_rate3; /* series 3 h/w rate */ u_int8_t on_tx_rate0sp; /* series 0 short preamble h/w rate */ u_int8_t on_tx_rate1sp; /* series 1 short preamble h/w rate */ --- a/sys/dev/netif/ath/ath_rate/onoe/onoe.c +++ b/sys/dev/netif/ath/ath_rate/onoe/onoe.c @@ -141,12 +141,14 @@ ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an, struct onoe_node *on = ATH_NODE_ONOE(an); rc[0].flags = rc[1].flags = rc[2].flags = rc[3].flags = 0; - rc[0].rix = on->on_tx_rate0; - rc[1].rix = on->on_tx_rate1; - rc[2].rix = on->on_tx_rate2; - rc[3].rix = on->on_tx_rate3; + /* .rix is a rate-table INDEX (if_athrate.h); codes go to .ratecode */ + rc[0].rix = on->on_tx_rix0; + rc[1].rix = on->on_tx_rix1; + rc[2].rix = on->on_tx_rix2; + rc[3].rix = on->on_tx_rix3; + rc[0].ratecode = on->on_tx_rate0; + rc[1].ratecode = on->on_tx_rate1; + rc[2].ratecode = on->on_tx_rate2; + rc[3].ratecode = on->on_tx_rate3; rc[0].tries = on->on_tx_try0; rc[1].tries = 2; @@ -234,21 +236,27 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) on->on_tx_try0 = 1 + 3; /* 4 tries at rate 0 */ if (--rate >= 0) { rix = sc->sc_rixmap[ ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; + on->on_tx_rix1 = rix; on->on_tx_rate1 = rt->info[rix].rateCode; on->on_tx_rate1sp = on->on_tx_rate1 | rt->info[rix].shortPreamble; } else { + on->on_tx_rix1 = 0; on->on_tx_rate1 = on->on_tx_rate1sp = 0; } if (--rate >= 0) { rix = sc->sc_rixmap[ ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL]; + on->on_tx_rix2 = rix; on->on_tx_rate2 = rt->info[rix].rateCode; on->on_tx_rate2sp = on->on_tx_rate2 | rt->info[rix].shortPreamble; } else { + on->on_tx_rix2 = 0; on->on_tx_rate2 = on->on_tx_rate2sp = 0; } if (rate > 0) { /* NB: only do this if we didn't already do it above */ + on->on_tx_rix3 = 0; on->on_tx_rate3 = rt->info[0].rateCode; on->on_tx_rate3sp = on->on_tx_rate3 | rt->info[0].shortPreamble; } else { + on->on_tx_rix3 = 0; on->on_tx_rate3 = on->on_tx_rate3sp = 0; } } else { on->on_tx_try0 = ATH_TXMAXTRY; /* max tries at rate 0 */ + on->on_tx_rix1 = on->on_tx_rix2 = on->on_tx_rix3 = 0; on->on_tx_rate1 = on->on_tx_rate1sp = 0; on->on_tx_rate2 = on->on_tx_rate2sp = 0; on->on_tx_rate3 = on->on_tx_rate3sp = 0; |