git: 745a85824748 - main - rtwn: update rtwn_get_rates() to separate out the CCK/OFDM and HT rates
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 18 Dec 2024 23:49:03 UTC
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=745a85824748e06b9b2ca4e9639ba13bbf9c08ca commit 745a85824748e06b9b2ca4e9639ba13bbf9c08ca Author: Adrian Chadd <adrian@FreeBSD.org> AuthorDate: 2024-12-08 20:22:04 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2024-12-18 23:48:10 +0000 rtwn: update rtwn_get_rates() to separate out the CCK/OFDM and HT rates The 32 bit bitmap is enough for CCK/OFDM rates and MCS0..15, but won't work for > MCS15, nor VHT rates. So, break out the legacy rates and HT rates. * break the rates and htrates out * document which calls are looking up basic rates and which care about the rates themselves * ensure the rate bitmap passed into the rate control firmware call (which isn't enabled yet!) is capped at 28 bits so they don't set the mode field. Differential Revision: https://reviews.freebsd.org/D47993 Reviewed by: bz, imp --- sys/dev/rtwn/if_rtwn.c | 3 ++- sys/dev/rtwn/if_rtwn_rx.c | 30 ++++++++++++++++++++++-------- sys/dev/rtwn/if_rtwn_rx.h | 3 ++- sys/dev/rtwn/rtl8192c/r92c_fw.c | 15 +++++++++++---- sys/dev/rtwn/rtl8812a/r12a_chan.c | 3 ++- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c index fdf44467680b..be01ececf307 100644 --- a/sys/dev/rtwn/if_rtwn.c +++ b/sys/dev/rtwn/if_rtwn.c @@ -1213,7 +1213,8 @@ rtwn_calc_basicrates(struct rtwn_softc *sc) continue; ni = ieee80211_ref_node(vap->iv_bss); - rtwn_get_rates(sc, &ni->ni_rates, NULL, &rates, NULL, 1); + /* Only fetches basic rates; no need to add HT/VHT here */ + rtwn_get_rates(sc, &ni->ni_rates, NULL, &rates, NULL, NULL, 1); basicrates |= rates; ieee80211_free_node(ni); } diff --git a/sys/dev/rtwn/if_rtwn_rx.c b/sys/dev/rtwn/if_rtwn_rx.c index 58cd53b01e63..977c1d17a08a 100644 --- a/sys/dev/rtwn/if_rtwn_rx.c +++ b/sys/dev/rtwn/if_rtwn_rx.c @@ -52,12 +52,24 @@ #include <dev/rtwn/rtl8192c/r92c_reg.h> +/* + * Get the driver rate set for the current operating rateset(s). + * + * rates_p is set to a mask of 11abg ridx values (not HW rate values.) + * htrates_p is set to a mask of 11n ridx values (not HW rate values), + * starting at MCS0 == bit 0. + * + * maxrate_p is set to the ridx value. + * + * If basic_rates is 1 then only the 11abg basic rate logic will + * be applied; HT/VHT will be ignored. + */ void rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs, const struct ieee80211_htrateset *rs_ht, uint32_t *rates_p, - int *maxrate_p, int basic_rates) + uint32_t *htrates_p, int *maxrate_p, int basic_rates) { - uint32_t rates; + uint32_t rates = 0, htrates = 0; uint8_t ridx; int i, maxrate; @@ -65,7 +77,7 @@ rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs, rates = 0; maxrate = 0; - /* This is for 11bg */ + /* This is for 11abg */ for (i = 0; i < rs->rs_nrates; i++) { /* Convert 802.11 rate to HW rate index. */ ridx = rate2ridx(IEEE80211_RV(rs->rs_rates[i])); @@ -82,15 +94,15 @@ rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs, /* If we're doing 11n, enable 11n rates */ if (rs_ht != NULL && !basic_rates) { for (i = 0; i < rs_ht->rs_nrates; i++) { + /* Only do up to 2-stream rates for now */ if ((rs_ht->rs_rates[i] & 0x7f) > 0xf) continue; - /* 11n rates start at index 12 */ - ridx = RTWN_RIDX_HT_MCS((rs_ht->rs_rates[i]) & 0xf); - rates |= (1 << ridx); + ridx = rs_ht->rs_rates[i] & 0xf; + htrates |= (1 << ridx); /* Guard against the rate table being oddly ordered */ - if (ridx > maxrate) - maxrate = ridx; + if (RTWN_RIDX_HT_MCS(ridx) > maxrate) + maxrate = RTWN_RIDX_HT_MCS(ridx); } } @@ -99,6 +111,8 @@ rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs, if (rates_p != NULL) *rates_p = rates; + if (htrates_p != NULL) + *htrates_p = htrates; if (maxrate_p != NULL) *maxrate_p = maxrate; } diff --git a/sys/dev/rtwn/if_rtwn_rx.h b/sys/dev/rtwn/if_rtwn_rx.h index 73bdf0d7a0de..3108f1d4cde4 100644 --- a/sys/dev/rtwn/if_rtwn_rx.h +++ b/sys/dev/rtwn/if_rtwn_rx.h @@ -20,7 +20,8 @@ #define RTWN_NOISE_FLOOR -95 void rtwn_get_rates(struct rtwn_softc *, const struct ieee80211_rateset *, - const struct ieee80211_htrateset *, uint32_t *, int *, int); + const struct ieee80211_htrateset *, uint32_t *, uint32_t *, + int *, int); void rtwn_set_basicrates(struct rtwn_softc *, uint32_t); struct ieee80211_node * rtwn_rx_common(struct rtwn_softc *, struct mbuf *, void *); diff --git a/sys/dev/rtwn/rtl8192c/r92c_fw.c b/sys/dev/rtwn/rtl8192c/r92c_fw.c index 426dfd0e6d3f..1ca37df7d0f4 100644 --- a/sys/dev/rtwn/rtl8192c/r92c_fw.c +++ b/sys/dev/rtwn/rtl8192c/r92c_fw.c @@ -196,7 +196,7 @@ r92c_init_ra(struct rtwn_softc *sc, int macid) { struct ieee80211_htrateset *rs_ht; struct ieee80211_node *ni; - uint32_t rates; + uint32_t rates, htrates; int maxrate; RTWN_NT_LOCK(sc); @@ -212,13 +212,20 @@ r92c_init_ra(struct rtwn_softc *sc, int macid) rs_ht = &ni->ni_htrates; else rs_ht = NULL; - /* XXX MACID_BC */ - rtwn_get_rates(sc, &ni->ni_rates, rs_ht, &rates, &maxrate, 0); + /* + * Note: this pushes the rate bitmap and maxrate into the + * firmware; and for this chipset 2-stream 11n support is enough. + */ + rtwn_get_rates(sc, &ni->ni_rates, rs_ht, &rates, &htrates, &maxrate, 0); RTWN_NT_UNLOCK(sc); #ifndef RTWN_WITHOUT_UCODE if (sc->sc_ratectl == RTWN_RATECTL_FW) { - r92c_send_ra_cmd(sc, macid, rates, maxrate); + uint32_t fw_rates; + /* Add HT rates after normal rates; limit to MCS0..15 */ + fw_rates = rates | + ((htrates & 0xffff) << RTWN_RIDX_HT_MCS_SHIFT); + r92c_send_ra_cmd(sc, macid, fw_rates, maxrate); } #endif diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c b/sys/dev/rtwn/rtl8812a/r12a_chan.c index d71e0a8177fd..f900d1ef7b2d 100644 --- a/sys/dev/rtwn/rtl8812a/r12a_chan.c +++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c @@ -452,8 +452,9 @@ r12a_set_band(struct rtwn_softc *sc, struct ieee80211_channel *c) !(rtwn_read_1(sc, R12A_CCK_CHECK) & R12A_CCK_CHECK_5GHZ)) return; + /* Note: this only fetches the basic rates, not the full rateset */ rtwn_get_rates(sc, ieee80211_get_suprates(ic, c), NULL, &basicrates, - NULL, 1); + NULL, NULL, 1); if (IEEE80211_IS_CHAN_2GHZ(c)) { rtwn_r12a_set_band_2ghz(sc, basicrates); swing = rs->tx_bbswing_2g;