The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=745a85824748e06b9b2ca4e9639ba13bbf9c08ca

commit 745a85824748e06b9b2ca4e9639ba13bbf9c08ca
Author:     Adrian Chadd <adr...@freebsd.org>
AuthorDate: 2024-12-08 20:22:04 +0000
Commit:     Adrian Chadd <adr...@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;

Reply via email to