The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7722d5e214772be22ef20bee46afeed2e9f78858

commit 7722d5e214772be22ef20bee46afeed2e9f78858
Author:     Adrian Chadd <adr...@freebsd.org>
AuthorDate: 2024-12-04 05:58:05 +0000
Commit:     Adrian Chadd <adr...@freebsd.org>
CommitDate: 2024-12-14 02:17:27 +0000

    rtwn: add RTL8812/RTL8821 VHT80 channel programming, spur management
    
    * add VHT80 channel programming
    * add VHT80 spur management, sync with Linux rtw88
    
    Obtained from: Linux rtw88
    
    Differential Revision:  https://reviews.freebsd.org/D47901
---
 sys/dev/rtwn/rtl8812a/r12a_chan.c | 81 ++++++++++++++++++++++++++++++++++-----
 sys/dev/rtwn/rtl8812a/r12a_reg.h  |  4 ++
 2 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c 
b/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 789a14b0e1d6..749f0e09e831 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -374,12 +374,20 @@ r12a_fix_spur(struct rtwn_softc *sc, struct 
ieee80211_channel *c)
                } else {
                        rtwn_bb_setbits(sc, R12A_RFMOD, 0x400, 0x800);
 
-                       if (!IEEE80211_IS_CHAN_HT40(c) &&       /* 20 MHz */
+                       if ((IEEE80211_IS_CHAN_B(c) ||
+                           IEEE80211_IS_CHAN_ANYG(c) ||
+                           IEEE80211_IS_CHAN_HT20(c)) &&       /* 2GHz, 20 MHz 
*/
                            (chan == 13 || chan == 14)) {
                                rtwn_bb_setbits(sc, R12A_RFMOD, 0, 0x300);
                                rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK,
                                    0, 0x40000000);
-                       } else {        /* !80 Mhz */
+                       } else if (IEEE80211_IS_CHAN_HT40(c) ||
+                           IEEE80211_IS_CHAN_VHT40(c)) {
+                               /* XXX double check! */
+                               rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK,
+                                   0, 0x40000000);
+                       } else if (IEEE80211_IS_CHAN_VHT80(c)) {
+                               /* XXX double check! */
                                rtwn_bb_setbits(sc, R12A_RFMOD, 0x100, 0x200);
                                rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK,
                                    0x40000000, 0);
@@ -387,7 +395,9 @@ r12a_fix_spur(struct rtwn_softc *sc, struct 
ieee80211_channel *c)
                }
        } else {
                /* Set ADC clock to 160M to resolve 2480 MHz spur. */
-               if (!IEEE80211_IS_CHAN_HT40(c) &&       /* 20 MHz */
+               if ((IEEE80211_IS_CHAN_B(c) ||
+                   IEEE80211_IS_CHAN_ANYG(c) ||
+                   IEEE80211_IS_CHAN_HT20(c)) &&       /* 2GHz, 20 MHz */
                    (chan == 13 || chan == 14))
                        rtwn_bb_setbits(sc, R12A_RFMOD, 0, 0x300);
                else if (IEEE80211_IS_CHAN_2GHZ(c))
@@ -489,16 +499,67 @@ r12a_set_chan(struct rtwn_softc *sc, struct 
ieee80211_channel *c)
                rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW, 0xff, chan);
        }
 
-#ifdef notyet
-       if (IEEE80211_IS_CHAN_HT80(c)) {        /* 80 MHz */
-               rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x80, 0x100);
+       if (IEEE80211_IS_CHAN_VHT80(c)) {       /* 80 MHz */
+               uint8_t ext20 = 0, ext40 = 0;
+               uint8_t txsc;
+               /* calculate ext20/ext40 */
+               if (c->ic_ieee > c->ic_vht_ch_freq1) {
+                       if (c->ic_ieee - c->ic_vht_ch_freq1 == 2) {
+                               ext20 = R12A_DATA_SEC_PRIM_UP_20;
+                               ext40 = R12A_DATA_SEC_PRIM_UP_40;
+                       } else {
+                               ext20 = R12A_DATA_SEC_PRIM_UPPER_20;
+                               ext40 = R12A_DATA_SEC_PRIM_UP_40;
+                       }
+               } else {
+                       if (c->ic_vht_ch_freq1 - c->ic_ieee == 2) {
+                               ext20 = R12A_DATA_SEC_PRIM_DOWN_20;
+                               ext40 = R12A_DATA_SEC_PRIM_DOWN_40;
+                       } else {
+                               ext20 = R12A_DATA_SEC_PRIM_LOWER_20;
+                               ext40 = R12A_DATA_SEC_PRIM_DOWN_40;
+                       }
+               }
+               /* Form txsc from sec20/sec40 config */
+               txsc = SM(R12A_DATA_SEC_TXSC_20M, ext20);
+               txsc |= SM(R12A_DATA_SEC_TXSC_40M, ext40);
+
+               rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x180, 0x100);
 
-               /* TODO */
+               /* DATA_SEC, for ext20/ext40 */
+               rtwn_write_1(sc, R12A_DATA_SEC, txsc);
+
+               /* ADCCLK */
+               rtwn_bb_setbits(sc, R12A_RFMOD, 0x003003c3, 0x00300202);
+
+               /* ADC160 - Set bit 30 */
+               rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK, 0, 0x40000000);
+
+               /* ADCCLK, ext20 */
+               /* discard high 4 bits */
+               val = rtwn_bb_read(sc, R12A_RFMOD);
+               val = RW(val, R12A_RFMOD_EXT_CHAN, ext20);
+               rtwn_bb_write(sc, R12A_RFMOD, val);
 
+               /* CCA2ND, ext20 */
+               val = rtwn_bb_read(sc, R12A_CCA_ON_SEC);
+               val = RW(val, R12A_CCA_ON_SEC_EXT_CHAN, ext20);
+               rtwn_bb_write(sc, R12A_CCA_ON_SEC, val);
+
+               /* PEAK_TH */
+               if (rtwn_read_1(sc, 0x837) & 0x04)
+                       val = 0x01400000;
+               else if (sc->nrxchains == 2 && sc->ntxchains == 2)
+                       val = 0x01800000;
+               else
+                       val = 0x01c00000;
+
+               rtwn_bb_setbits(sc, R12A_L1_PEAK_TH, 0x03c00000, val);
+               /* BWMASK */
                val = 0x0;
-       } else
-#endif
-       if (IEEE80211_IS_CHAN_HT40(c)) {        /* 40 MHz */
+
+       } else if (IEEE80211_IS_CHAN_HT40(c) ||
+           IEEE80211_IS_CHAN_VHT40(c)) {       /* 40 MHz */
                uint8_t ext_chan;
 
                if (IEEE80211_IS_CHAN_HT40U(c))
diff --git a/sys/dev/rtwn/rtl8812a/r12a_reg.h b/sys/dev/rtwn/rtl8812a/r12a_reg.h
index 4f5f6f28c11a..13867fb76973 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_reg.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_reg.h
@@ -45,6 +45,10 @@
 #define R12A_AMPDU_MAX_TIME            0x456
 #define R12A_AMPDU_MAX_LENGTH          R92C_AGGLEN_LMT
 #define R12A_DATA_SEC                  0x483
+#define R12A_DATA_SEC_TXSC_20M_M       0x0000000f
+#define R12A_DATA_SEC_TXSC_20M_S       0
+#define R12A_DATA_SEC_TXSC_40M_M       0x000000f0
+#define R12A_DATA_SEC_TXSC_40M_S       4
 #define R12A_ARFR_2G(i)                        (0x48c + (i) * 8)
 #define R12A_HT_SINGLE_AMPDU           0x4c7
 

Reply via email to