aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2024-12-08 20:22:04 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2024-12-18 23:48:10 +0000
commit745a85824748e06b9b2ca4e9639ba13bbf9c08ca (patch)
tree701cdbde34b03b37118666c43c460c27940fffb2
parent638fcd53db7d538bf2cf229458c9b954c44a576c (diff)
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
-rw-r--r--sys/dev/rtwn/if_rtwn.c3
-rw-r--r--sys/dev/rtwn/if_rtwn_rx.c30
-rw-r--r--sys/dev/rtwn/if_rtwn_rx.h3
-rw-r--r--sys/dev/rtwn/rtl8192c/r92c_fw.c15
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_chan.c3
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;