The branch stable/15 has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0272ecf586255991f94f80378c4a3384e83fccc5

commit 0272ecf586255991f94f80378c4a3384e83fccc5
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2025-10-17 20:22:54 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2025-10-27 00:18:21 +0000

    rtw88: update Realtek's rtw88 driver
    
    This version is based on
    git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
    e5f0a698b34ed76002dc5cff3804a61c80233a7a ( tag: v6.17 ).
    
    (cherry picked from commit eb15fdb1b72de02e7a4c454f7eeeb1cee5cb83df)
---
 sys/contrib/dev/rtw88/Makefile         |     9 +
 sys/contrib/dev/rtw88/coex.c           |    24 +-
 sys/contrib/dev/rtw88/debug.c          |    57 +-
 sys/contrib/dev/rtw88/fw.c             |    31 +-
 sys/contrib/dev/rtw88/fw.h             |     1 +
 sys/contrib/dev/rtw88/hci.h            |     8 +
 sys/contrib/dev/rtw88/mac.c            |    50 +-
 sys/contrib/dev/rtw88/mac.h            |     3 +
 sys/contrib/dev/rtw88/mac80211.c       |    11 +-
 sys/contrib/dev/rtw88/main.c           |   118 +-
 sys/contrib/dev/rtw88/main.h           |    65 +-
 sys/contrib/dev/rtw88/pci.c            |    55 +-
 sys/contrib/dev/rtw88/pci.h            |     1 +
 sys/contrib/dev/rtw88/phy.c            |   215 +-
 sys/contrib/dev/rtw88/phy.h            |    20 +-
 sys/contrib/dev/rtw88/reg.h            |    69 +-
 sys/contrib/dev/rtw88/rtw8703b.c       |    64 +-
 sys/contrib/dev/rtw88/rtw8723cs.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8723d.c       |     8 +-
 sys/contrib/dev/rtw88/rtw8723de.c      |     3 +-
 sys/contrib/dev/rtw88/rtw8723ds.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8723du.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8723x.c       |    68 +-
 sys/contrib/dev/rtw88/rtw8723x.h       |     6 +
 sys/contrib/dev/rtw88/rtw8812a.c       |     5 +-
 sys/contrib/dev/rtw88/rtw8812au.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8814a.c       |  2281 +++
 sys/contrib/dev/rtw88/rtw8814a.h       |    62 +
 sys/contrib/dev/rtw88/rtw8814a_table.c | 23930 +++++++++++++++++++++++++++++++
 sys/contrib/dev/rtw88/rtw8814a_table.h |    40 +
 sys/contrib/dev/rtw88/rtw8814ae.c      |    34 +
 sys/contrib/dev/rtw88/rtw8814au.c      |    54 +
 sys/contrib/dev/rtw88/rtw8821a.c       |     5 +-
 sys/contrib/dev/rtw88/rtw8821au.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8821c.c       |    21 +-
 sys/contrib/dev/rtw88/rtw8821ce.c      |     3 +-
 sys/contrib/dev/rtw88/rtw8821cs.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8821cu.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8822b.c       |    22 +-
 sys/contrib/dev/rtw88/rtw8822be.c      |     3 +-
 sys/contrib/dev/rtw88/rtw8822bs.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8822bu.c      |     8 +-
 sys/contrib/dev/rtw88/rtw8822c.c       |    11 +-
 sys/contrib/dev/rtw88/rtw8822ce.c      |     3 +-
 sys/contrib/dev/rtw88/rtw8822cs.c      |     2 +-
 sys/contrib/dev/rtw88/rtw8822cu.c      |     2 +-
 sys/contrib/dev/rtw88/rtw88xxa.c       |     2 +-
 sys/contrib/dev/rtw88/rx.c             |     6 +
 sys/contrib/dev/rtw88/sar.c            |     2 +-
 sys/contrib/dev/rtw88/sdio.c           |    37 +-
 sys/contrib/dev/rtw88/tx.c             |     3 +-
 sys/contrib/dev/rtw88/usb.c            |    65 +-
 sys/contrib/dev/rtw88/util.c           |     3 +-
 sys/modules/rtw88/Makefile             |     5 +-
 54 files changed, 27180 insertions(+), 331 deletions(-)

diff --git a/sys/contrib/dev/rtw88/Makefile b/sys/contrib/dev/rtw88/Makefile
index 0cbbb366e393..0b3da05a2938 100644
--- a/sys/contrib/dev/rtw88/Makefile
+++ b/sys/contrib/dev/rtw88/Makefile
@@ -94,6 +94,15 @@ rtw88_8821au-objs            := rtw8821au.o
 obj-$(CONFIG_RTW88_8812AU)     += rtw88_8812au.o
 rtw88_8812au-objs              := rtw8812au.o
 
+obj-$(CONFIG_RTW88_8814A)      += rtw88_8814a.o
+rtw88_8814a-objs               := rtw8814a.o rtw8814a_table.o
+
+obj-$(CONFIG_RTW88_8814AE)     += rtw88_8814ae.o
+rtw88_8814ae-objs              := rtw8814ae.o
+
+obj-$(CONFIG_RTW88_8814AU)     += rtw88_8814au.o
+rtw88_8814au-objs              := rtw8814au.o
+
 obj-$(CONFIG_RTW88_PCI)                += rtw88_pci.o
 rtw88_pci-objs                 := pci.o
 
diff --git a/sys/contrib/dev/rtw88/coex.c b/sys/contrib/dev/rtw88/coex.c
index c929db1e53ca..b4dc6ff2c175 100644
--- a/sys/contrib/dev/rtw88/coex.c
+++ b/sys/contrib/dev/rtw88/coex.c
@@ -309,7 +309,7 @@ static void rtw_coex_tdma_timer_base(struct rtw_dev 
*rtwdev, u8 type)
 {
        struct rtw_coex *coex = &rtwdev->coex;
        struct rtw_coex_stat *coex_stat = &coex->stat;
-       u8 para[2] = {0};
+       u8 para[6] = {};
        u8 times;
        u16 tbtt_interval = coex_stat->wl_beacon_interval;
 
@@ -1501,28 +1501,28 @@ static u8 rtw_coex_algorithm(struct rtw_dev *rtwdev)
                algorithm = COEX_ALGO_HFP;
                break;
        case           BPM_HID:
-       case BPM_HFP + BPM_HID:
+       case BPM_HFP | BPM_HID:
                algorithm = COEX_ALGO_HID;
                break;
-       case BPM_HFP           + BPM_A2DP:
-       case           BPM_HID + BPM_A2DP:
-       case BPM_HFP + BPM_HID + BPM_A2DP:
+       case BPM_HFP           | BPM_A2DP:
+       case           BPM_HID | BPM_A2DP:
+       case BPM_HFP | BPM_HID | BPM_A2DP:
                algorithm = COEX_ALGO_A2DP_HID;
                break;
-       case BPM_HFP                      + BPM_PAN:
-       case           BPM_HID            + BPM_PAN:
-       case BPM_HFP + BPM_HID            + BPM_PAN:
+       case BPM_HFP                      | BPM_PAN:
+       case           BPM_HID            | BPM_PAN:
+       case BPM_HFP | BPM_HID            | BPM_PAN:
                algorithm = COEX_ALGO_PAN_HID;
                break;
-       case BPM_HFP           + BPM_A2DP + BPM_PAN:
-       case           BPM_HID + BPM_A2DP + BPM_PAN:
-       case BPM_HFP + BPM_HID + BPM_A2DP + BPM_PAN:
+       case BPM_HFP           | BPM_A2DP | BPM_PAN:
+       case           BPM_HID | BPM_A2DP | BPM_PAN:
+       case BPM_HFP | BPM_HID | BPM_A2DP | BPM_PAN:
                algorithm = COEX_ALGO_A2DP_PAN_HID;
                break;
        case                                BPM_PAN:
                algorithm = COEX_ALGO_PAN;
                break;
-       case                     BPM_A2DP + BPM_PAN:
+       case                     BPM_A2DP | BPM_PAN:
                algorithm = COEX_ALGO_A2DP_PAN;
                break;
        case                     BPM_A2DP:
diff --git a/sys/contrib/dev/rtw88/debug.c b/sys/contrib/dev/rtw88/debug.c
index f0ee8e62da3b..53742a3220f2 100644
--- a/sys/contrib/dev/rtw88/debug.c
+++ b/sys/contrib/dev/rtw88/debug.c
@@ -654,10 +654,10 @@ static void rtw_print_rate(struct seq_file *m, u8 rate)
        case DESC_RATE6M...DESC_RATE54M:
                rtw_print_ofdm_rate_txt(m, rate);
                break;
-       case DESC_RATEMCS0...DESC_RATEMCS15:
+       case DESC_RATEMCS0...DESC_RATEMCS31:
                rtw_print_ht_rate_txt(m, rate);
                break;
-       case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9:
+       case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT4SS_MCS9:
                rtw_print_vht_rate_txt(m, rate);
                break;
        default:
@@ -692,9 +692,11 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, 
void *v)
 {
        struct rtw_debugfs_priv *debugfs_priv = m->private;
        struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+       struct rtw_power_params pwr_param = {0};
        struct rtw_hal *hal = &rtwdev->hal;
+       u8 nss = rtwdev->efuse.hw_cap.nss;
        u8 path, rate, bw, ch, regd;
-       struct rtw_power_params pwr_param = {0};
+       u8 max_ht_rate, max_rate;
 
        mutex_lock(&rtwdev->mutex);
        bw = hal->current_band_width;
@@ -707,19 +709,23 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, 
void *v)
        seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n",
                   "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem");
 
+       max_ht_rate = DESC_RATEMCS0 + nss * 8 - 1;
+
+       if (rtwdev->chip->vht_supported)
+               max_rate = DESC_RATEVHT1SS_MCS0 + nss * 10 - 1;
+       else
+               max_rate = max_ht_rate;
+
        mutex_lock(&hal->tx_power_mutex);
-       for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
+       for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
                /* there is no CCK rates used in 5G */
                if (hal->current_band_type == RTW_BAND_5G)
                        rate = DESC_RATE6M;
                else
                        rate = DESC_RATE1M;
 
-               /* now, not support vht 3ss and vht 4ss*/
-               for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) {
-                       /* now, not support ht 3ss and ht 4ss*/
-                       if (rate > DESC_RATEMCS15 &&
-                           rate < DESC_RATEVHT1SS_MCS0)
+               for (; rate <= max_rate; rate++) {
+                       if (rate > max_ht_rate && rate <= DESC_RATEMCS31)
                                continue;
 
                        rtw_get_tx_power_params(rtwdev, path, rate, bw,
@@ -849,20 +855,28 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, 
void *v)
                           last_cnt->num_qry_pkt[rate_id + 9]);
        }
 
-       seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n",
+       seq_printf(m, "[RSSI(dBm)] = {%d, %d, %d, %d}\n",
                   dm_info->rssi[RF_PATH_A] - 100,
-                  dm_info->rssi[RF_PATH_B] - 100);
-       seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n",
+                  dm_info->rssi[RF_PATH_B] - 100,
+                  dm_info->rssi[RF_PATH_C] - 100,
+                  dm_info->rssi[RF_PATH_D] - 100);
+       seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d, -%d, -%d}\n",
                   dm_info->rx_evm_dbm[RF_PATH_A],
-                  dm_info->rx_evm_dbm[RF_PATH_B]);
-       seq_printf(m, "[Rx SNR] = {%d, %d}\n",
+                  dm_info->rx_evm_dbm[RF_PATH_B],
+                  dm_info->rx_evm_dbm[RF_PATH_C],
+                  dm_info->rx_evm_dbm[RF_PATH_D]);
+       seq_printf(m, "[Rx SNR] = {%d, %d, %d, %d}\n",
                   dm_info->rx_snr[RF_PATH_A],
-                  dm_info->rx_snr[RF_PATH_B]);
-       seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n",
+                  dm_info->rx_snr[RF_PATH_B],
+                  dm_info->rx_snr[RF_PATH_C],
+                  dm_info->rx_snr[RF_PATH_D]);
+       seq_printf(m, "[CFO_tail(KHz)] = {%d, %d, %d, %d}\n",
                   dm_info->cfo_tail[RF_PATH_A],
-                  dm_info->cfo_tail[RF_PATH_B]);
+                  dm_info->cfo_tail[RF_PATH_B],
+                  dm_info->cfo_tail[RF_PATH_C],
+                  dm_info->cfo_tail[RF_PATH_D]);
 
-       if (dm_info->curr_rx_rate >= DESC_RATE11M) {
+       if (dm_info->curr_rx_rate >= DESC_RATE6M) {
                seq_puts(m, "[Rx Average Status]:\n");
                seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n",
                           (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]),
@@ -875,6 +889,13 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, 
void *v)
                           (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]),
                           (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]),
                           (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B]));
+               seq_printf(m, " * 3SS, EVM: {-%d, -%d, -%d}, SNR: {%d, %d, 
%d}\n",
+                          (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_A]),
+                          (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_B]),
+                          (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_C]),
+                          (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_A]),
+                          (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_B]),
+                          (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_C]));
        }
 
        seq_puts(m, "[Rx Counter]:\n");
diff --git a/sys/contrib/dev/rtw88/fw.c b/sys/contrib/dev/rtw88/fw.c
index ae5af6bc3e92..5ce4a6bcffb6 100644
--- a/sys/contrib/dev/rtw88/fw.c
+++ b/sys/contrib/dev/rtw88/fw.c
@@ -521,7 +521,7 @@ rtw_fw_send_general_info(struct rtw_dev *rtwdev)
        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
        u16 total_size = H2C_PKT_HDR_SIZE + 4;
 
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return;
 
        rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO);
@@ -544,7 +544,7 @@ rtw_fw_send_phydm_info(struct rtw_dev *rtwdev)
        u16 total_size = H2C_PKT_HDR_SIZE + 8;
        u8 fw_rf_type = 0;
 
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return;
 
        if (hal->rf_type == RF_1T1R)
@@ -735,6 +735,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si,
 {
        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
        bool disable_pt = true;
+       u32 mask_hi;
 
        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
 
@@ -755,6 +756,20 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si,
        si->init_ra_lv = 0;
 
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+
+       if (rtwdev->chip->id != RTW_CHIP_TYPE_8814A)
+               return;
+
+       SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI);
+
+       mask_hi = si->ra_mask >> 32;
+
+       SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff));
+       SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8);
+       SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16);
+       SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24);
+
+       rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
 void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool 
connect)
@@ -1451,7 +1466,7 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
 int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
                                u8 *buf, u32 size)
 {
-       u8 bckp[2];
+       u8 bckp[3];
        u8 val;
        u16 rsvd_pg_head;
        u32 bcn_valid_addr;
@@ -1463,7 +1478,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, 
u16 pg_addr,
        if (!size)
                return -EINVAL;
 
-       if (rtw_chip_wcpu_11n(rtwdev)) {
+       bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL);
+
+       if (rtw_chip_wcpu_8051(rtwdev)) {
                rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID);
        } else {
                pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
@@ -1476,6 +1493,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, 
u16 pg_addr,
        val |= BIT_ENSWBCN >> 8;
        rtw_write8(rtwdev, REG_CR + 1, val);
 
+       rtw_write8(rtwdev, REG_BCN_CTRL,
+                  (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT);
+
        if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {
                val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
                bckp[1] = val;
@@ -1489,7 +1509,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, 
u16 pg_addr,
                goto restore;
        }
 
-       if (rtw_chip_wcpu_11n(rtwdev)) {
+       if (rtw_chip_wcpu_8051(rtwdev)) {
                bcn_valid_addr = REG_DWBCN0_CTRL;
                bcn_valid_mask = BIT_BCN_VALID;
        } else {
@@ -1506,6 +1526,7 @@ restore:
        rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
        rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
                    rsvd_pg_head | BIT_BCN_VALID_V1);
+       rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]);
        if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
                rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
        rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
diff --git a/sys/contrib/dev/rtw88/fw.h b/sys/contrib/dev/rtw88/fw.h
index 404de1b0c407..48ad9ceab6ea 100644
--- a/sys/contrib/dev/rtw88/fw.h
+++ b/sys/contrib/dev/rtw88/fw.h
@@ -557,6 +557,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 
sub_id)
 #define H2C_CMD_DEFAULT_PORT           0x2c
 #define H2C_CMD_RA_INFO                        0x40
 #define H2C_CMD_RSSI_MONITOR           0x42
+#define H2C_CMD_RA_INFO_HI             0x46
 #define H2C_CMD_BCN_FILTER_OFFLOAD_P0  0x56
 #define H2C_CMD_BCN_FILTER_OFFLOAD_P1  0x57
 #define H2C_CMD_WL_PHY_INFO            0x58
diff --git a/sys/contrib/dev/rtw88/hci.h b/sys/contrib/dev/rtw88/hci.h
index 96aeda26014e..d4bee9c3ecfe 100644
--- a/sys/contrib/dev/rtw88/hci.h
+++ b/sys/contrib/dev/rtw88/hci.h
@@ -19,6 +19,8 @@ struct rtw_hci_ops {
        void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
        void (*interface_cfg)(struct rtw_dev *rtwdev);
        void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable);
+       void (*write_firmware_page)(struct rtw_dev *rtwdev, u32 page,
+                                   const u8 *data, u32 size);
 
        int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
        int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
@@ -79,6 +81,12 @@ static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev 
*rtwdev, bool enable)
                rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable);
 }
 
+static inline void rtw_hci_write_firmware_page(struct rtw_dev *rtwdev, u32 
page,
+                                              const u8 *data, u32 size)
+{
+       rtwdev->hci.ops->write_firmware_page(rtwdev, page, data, size);
+}
+
 static inline int
 rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
 {
diff --git a/sys/contrib/dev/rtw88/mac.c b/sys/contrib/dev/rtw88/mac.c
index cae9cca6dca3..eaa928bab240 100644
--- a/sys/contrib/dev/rtw88/mac.c
+++ b/sys/contrib/dev/rtw88/mac.c
@@ -41,7 +41,7 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, 
u8 bw,
        }
        rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);
 
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return;
 
        value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
@@ -67,7 +67,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
 
        rtw_write8(rtwdev, REG_RSV_CTRL, 0);
 
-       if (rtw_chip_wcpu_11n(rtwdev)) {
+       if (rtw_chip_wcpu_8051(rtwdev)) {
                if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO)
                        rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL);
                else
@@ -278,7 +278,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, 
bool pwr_on)
        bool cur_pwr;
        int ret;
 
-       if (rtw_chip_wcpu_11ac(rtwdev)) {
+       if (rtw_chip_wcpu_3081(rtwdev)) {
                rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
 
                /* Check FW still exist or not */
@@ -291,6 +291,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, 
bool pwr_on)
        if (rtw_read8(rtwdev, REG_CR) == 0xea)
                cur_pwr = false;
        else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB &&
+                chip->id != RTW_CHIP_TYPE_8814A &&
                 (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0)))
                cur_pwr = false;
        else
@@ -368,7 +369,7 @@ static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev 
*rtwdev)
 
 static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
 {
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return __rtw_mac_init_system_cfg_legacy(rtwdev);
 
        return __rtw_mac_init_system_cfg(rtwdev);
@@ -784,7 +785,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev,
        if (!check_firmware_size(data, size))
                return -EINVAL;
 
-       if (!ltecoex_read_reg(rtwdev, 0x38, &ltecoex_bckp))
+       if (rtwdev->chip->ltecoex_addr &&
+           !ltecoex_read_reg(rtwdev, 0x38, &ltecoex_bckp))
                return -EBUSY;
 
        wlan_cpu_enable(rtwdev, false);
@@ -802,7 +804,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev,
 
        wlan_cpu_enable(rtwdev, true);
 
-       if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) {
+       if (rtwdev->chip->ltecoex_addr &&
+           !ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) {
                ret = -EBUSY;
                goto dlfw_fail;
        }
@@ -853,8 +856,8 @@ fwdl_ready:
        }
 }
 
-static void
-write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size)
+void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page,
+                            const u8 *data, u32 size)
 {
        u32 val32;
        u32 block_nr;
@@ -884,6 +887,7 @@ write_firmware_page(struct rtw_dev *rtwdev, u32 page, const 
u8 *data, u32 size)
                rtw_write32(rtwdev, write_addr, le32_to_cpu(remain_data));
        }
 }
+EXPORT_SYMBOL(rtw_write_firmware_page);
 
 static int
 download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size)
@@ -901,11 +905,13 @@ download_firmware_legacy(struct rtw_dev *rtwdev, const u8 
*data, u32 size)
        rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT);
 
        for (page = 0; page < total_page; page++) {
-               write_firmware_page(rtwdev, page, data, DLFW_PAGE_SIZE_LEGACY);
+               rtw_hci_write_firmware_page(rtwdev, page, data,
+                                           DLFW_PAGE_SIZE_LEGACY);
                data += DLFW_PAGE_SIZE_LEGACY;
        }
        if (last_page_size)
-               write_firmware_page(rtwdev, page, data, last_page_size);
+               rtw_hci_write_firmware_page(rtwdev, page, data,
+                                           last_page_size);
 
        if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT, 1)) {
                rtw_err(rtwdev, "failed to check download firmware report\n");
@@ -975,7 +981,7 @@ out:
 static
 int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
 {
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return __rtw_download_firmware_legacy(rtwdev, fw);
 
        return __rtw_download_firmware(rtwdev, fw);
@@ -1116,7 +1122,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
 
        rtw_write8(rtwdev, REG_CR, 0);
        rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE);
-       if (rtw_chip_wcpu_11ac(rtwdev))
+       if (rtw_chip_wcpu_3081(rtwdev))
                rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
 
        if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
@@ -1139,7 +1145,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
        /* config rsvd page num */
        fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
        fifo->txff_pg_num = chip->txff_size / chip->page_size;
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
        else
                fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num +
@@ -1157,7 +1163,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
        fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num;
 
        cur_pg_addr = fifo->txff_pg_num;
-       if (rtw_chip_wcpu_11ac(rtwdev)) {
+       if (rtw_chip_wcpu_3081(rtwdev)) {
                cur_pg_addr -= csi_buf_pg_num;
                fifo->rsvd_csibuf_addr = cur_pg_addr;
                cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM;
@@ -1286,7 +1292,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev)
 
        pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
                   pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num);
        else
                return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num);
@@ -1302,7 +1308,7 @@ static int init_h2c(struct rtw_dev *rtwdev)
        u32 h2cq_free;
        u32 wp, rp;
 
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                return 0;
 
        h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT;
@@ -1369,7 +1375,7 @@ static int rtw_drv_info_cfg(struct rtw_dev *rtwdev)
        u8 value8;
 
        rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE);
-       if (rtw_chip_wcpu_11ac(rtwdev)) {
+       if (rtw_chip_wcpu_3081(rtwdev)) {
                value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1);
                value8 &= 0xF0;
                /* For rxdesc len = 0 issue */
@@ -1403,3 +1409,13 @@ int rtw_mac_init(struct rtw_dev *rtwdev)
 
        return 0;
 }
+
+int rtw_mac_postinit(struct rtw_dev *rtwdev)
+{
+       const struct rtw_chip_info *chip = rtwdev->chip;
+
+       if (!chip->ops->mac_postinit)
+               return 0;
+
+       return chip->ops->mac_postinit(rtwdev);
+}
diff --git a/sys/contrib/dev/rtw88/mac.h b/sys/contrib/dev/rtw88/mac.h
index 6905e2747372..b73af90ee1d7 100644
--- a/sys/contrib/dev/rtw88/mac.h
+++ b/sys/contrib/dev/rtw88/mac.h
@@ -34,8 +34,11 @@ int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
                       const struct rtw_pwr_seq_cmd * const *cmd_seq);
 int rtw_mac_power_on(struct rtw_dev *rtwdev);
 void rtw_mac_power_off(struct rtw_dev *rtwdev);
+void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page,
+                            const u8 *data, u32 size);
 int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
 int rtw_mac_init(struct rtw_dev *rtwdev);
+int rtw_mac_postinit(struct rtw_dev *rtwdev);
 void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
 int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev);
 int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);
diff --git a/sys/contrib/dev/rtw88/mac80211.c b/sys/contrib/dev/rtw88/mac80211.c
index 719052b7c6bb..8d84f1a3bc18 100644
--- a/sys/contrib/dev/rtw88/mac80211.c
+++ b/sys/contrib/dev/rtw88/mac80211.c
@@ -71,7 +71,7 @@ static void rtw_ops_stop(struct ieee80211_hw *hw, bool 
suspend)
        mutex_unlock(&rtwdev->mutex);
 }
 
-static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
+static int rtw_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
 {
        struct rtw_dev *rtwdev = hw->priv;
        int ret = 0;
@@ -411,6 +411,8 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw 
*hw,
                        if (rtw_bf_support)
                                rtw_bf_assoc(rtwdev, vif, conf);
 
+                       rtw_set_ampdu_factor(rtwdev, vif, conf);
+
                        rtw_fw_beacon_filter_config(rtwdev, true, vif);
                } else {
                        rtw_leave_lps(rtwdev);
@@ -721,7 +723,8 @@ static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
        mutex_unlock(&rtwdev->mutex);
 }
 
-static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,
+                                    u32 value)
 {
        struct rtw_dev *rtwdev = hw->priv;
 
@@ -810,6 +813,7 @@ static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
 }
 
 static int rtw_ops_set_antenna(struct ieee80211_hw *hw,
+                              int radio_idx,
                               u32 tx_antenna,
                               u32 rx_antenna)
 {
@@ -821,13 +825,14 @@ static int rtw_ops_set_antenna(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
 
        mutex_lock(&rtwdev->mutex);
-       ret = chip->ops->set_antenna(rtwdev, tx_antenna, rx_antenna);
+       ret = chip->ops->set_antenna(rtwdev, -1, tx_antenna, rx_antenna);
        mutex_unlock(&rtwdev->mutex);
 
        return ret;
 }
 
 static int rtw_ops_get_antenna(struct ieee80211_hw *hw,
+                              int radio_idx,
                               u32 *tx_antenna,
                               u32 *rx_antenna)
 {
diff --git a/sys/contrib/dev/rtw88/main.c b/sys/contrib/dev/rtw88/main.c
index 963b73f35350..d9e6e9477dfb 100644
--- a/sys/contrib/dev/rtw88/main.c
+++ b/sys/contrib/dev/rtw88/main.c
@@ -207,7 +207,7 @@ u16 rtw_desc_to_bitrate(u8 desc_rate)
        return rate.bitrate;
 }
 
-static struct ieee80211_supported_band rtw_band_2ghz = {
+static const struct ieee80211_supported_band rtw_band_2ghz = {
        .band = NL80211_BAND_2GHZ,
 
        .channels = rtw_channeltable_2g,
@@ -220,7 +220,7 @@ static struct ieee80211_supported_band rtw_band_2ghz = {
        .vht_cap = {0},
 };
 
-static struct ieee80211_supported_band rtw_band_5ghz = {
+static const struct ieee80211_supported_band rtw_band_5ghz = {
        .band = NL80211_BAND_5GHZ,
 
        .channels = rtw_channeltable_5g,
@@ -420,7 +420,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct 
ieee80211_sta *sta,
        struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
        int i;
 
-       if (vif->type == NL80211_IFTYPE_STATION) {
+       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
                si->mac_id = rtwvif->mac_id;
        } else {
                si->mac_id = rtw_acquire_macid(rtwdev);
@@ -462,7 +462,7 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct 
ieee80211_sta *sta,
 
        cancel_work_sync(&si->rc_work);
 
-       if (vif->type != NL80211_IFTYPE_STATION)
+       if (vif->type != NL80211_IFTYPE_STATION || sta->tdls)
                rtw_release_macid(rtwdev, si->mac_id);
        if (fw_exist)
                rtw_fw_media_status_report(rtwdev, si->mac_id, false);
@@ -717,6 +717,7 @@ void rtw_fw_recovery(struct rtw_dev *rtwdev)
        if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags))
                ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work);
 }
+EXPORT_SYMBOL(rtw_fw_recovery);
 
 static void __fw_recovery_work(struct rtw_dev *rtwdev)
 {
@@ -1315,7 +1316,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si,
                if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
                        ldpc_en = VHT_LDPC_EN;
        } else if (sta->deflink.ht_cap.ht_supported) {
-               ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) |
+               ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 36) |
+                          ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 28) |
+                          (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) |
                           (sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
                if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
                        stbc_en = HT_STBC_EN;
@@ -1325,6 +1328,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si,
 
        if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss)
                ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
+       else if (efuse->hw_cap.nss == 2)
+               ra_mask &= RA_MASK_VHT_RATES_2SS | RA_MASK_HT_RATES_2SS |
+                          RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
 
        if (hal->current_band_type == RTW_BAND_5G) {
                ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
@@ -1387,10 +1393,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si,
                break;
        }
 
-       if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000)
-               tx_num = 2;
-       else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000)
-               tx_num = 2;
+       if (sta->deflink.vht_cap.vht_supported ||
+           sta->deflink.ht_cap.ht_supported)
+               tx_num = efuse->hw_cap.nss;
 
        rate_id = get_rate_id(wireless_set, bw_mode, tx_num);
 
@@ -1492,6 +1497,12 @@ int rtw_power_on(struct rtw_dev *rtwdev)
 
        chip->ops->phy_set_param(rtwdev);
 
+       ret = rtw_mac_postinit(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to configure mac in postinit\n");
+               goto err_off;
+       }
+
        ret = rtw_hci_start(rtwdev);
        if (ret) {
                rtw_err(rtwdev, "failed to start hci\n");
@@ -1646,6 +1657,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
 {
        const struct rtw_chip_info *chip = rtwdev->chip;
        struct rtw_efuse *efuse = &rtwdev->efuse;
+       int i;
 
        ht_cap->ht_supported = true;
        ht_cap->cap = 0;
@@ -1665,25 +1677,20 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
        ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
        ht_cap->ampdu_density = chip->ampdu_density;
        ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-       if (efuse->hw_cap.nss > 1) {
-               ht_cap->mcs.rx_mask[0] = 0xFF;
-               ht_cap->mcs.rx_mask[1] = 0xFF;
-               ht_cap->mcs.rx_mask[4] = 0x01;
-               ht_cap->mcs.rx_highest = cpu_to_le16(300);
-       } else {
-               ht_cap->mcs.rx_mask[0] = 0xFF;
-               ht_cap->mcs.rx_mask[1] = 0x00;
-               ht_cap->mcs.rx_mask[4] = 0x01;
-               ht_cap->mcs.rx_highest = cpu_to_le16(150);
-       }
+
+       for (i = 0; i < efuse->hw_cap.nss; i++)
+               ht_cap->mcs.rx_mask[i] = 0xFF;
+       ht_cap->mcs.rx_mask[4] = 0x01;
+       ht_cap->mcs.rx_highest = cpu_to_le16(150 * efuse->hw_cap.nss);
 }
 
 static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
                             struct ieee80211_sta_vht_cap *vht_cap)
 {
        struct rtw_efuse *efuse = &rtwdev->efuse;
-       u16 mcs_map;
+       u16 mcs_map = 0;
        __le16 highest;
+       int i;
 
        if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE &&
            efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT)
@@ -1706,21 +1713,15 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
        if (rtw_chip_has_rx_ldpc(rtwdev))
                vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
 
-       mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
-                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
-       if (efuse->hw_cap.nss > 1) {
-               highest = cpu_to_le16(780);
-               mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2;
-       } else {
-               highest = cpu_to_le16(390);
-               mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2;
+       for (i = 0; i < 8; i++) {
+               if (i < efuse->hw_cap.nss)
+                       mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
+               else
+                       mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
        }
 
+       highest = cpu_to_le16(390 * efuse->hw_cap.nss);
+
        vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
        vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
        vht_cap->vht_mcs.rx_highest = highest;
@@ -1872,7 +1873,7 @@ static void __update_firmware_info_legacy(struct rtw_dev 
*rtwdev,
 static void update_firmware_info(struct rtw_dev *rtwdev,
                                 struct rtw_fw_state *fw)
 {
-       if (rtw_chip_wcpu_11n(rtwdev))
+       if (rtw_chip_wcpu_8051(rtwdev))
                __update_firmware_info_legacy(rtwdev, fw);
        else
                __update_firmware_info(rtwdev, fw);
@@ -2329,7 +2330,6 @@ EXPORT_SYMBOL(rtw_core_deinit);
 
 int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 {
-       bool sta_mode_only = rtwdev->hci.type == RTW_HCI_TYPE_SDIO;
        struct rtw_hal *hal = &rtwdev->hal;
        int max_tx_headroom = 0;
        int ret;
@@ -2353,17 +2353,15 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct 
ieee80211_hw *hw)
        ieee80211_hw_set(hw, SUPPORTS_PS);
        ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
        ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
-       ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
+       if (rtwdev->chip->amsdu_in_ampdu)
+               ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
        ieee80211_hw_set(hw, HAS_RATE_CONTROL);
        ieee80211_hw_set(hw, TX_AMSDU);
        ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
 
-       if (sta_mode_only)
-               hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-       else
-               hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                            BIT(NL80211_IFTYPE_AP) |
-                                            BIT(NL80211_IFTYPE_ADHOC);
+       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                    BIT(NL80211_IFTYPE_AP) |
+                                    BIT(NL80211_IFTYPE_ADHOC);
        hw->wiphy->available_antennas_tx = hal->antenna_tx;
        hw->wiphy->available_antennas_rx = hal->antenna_rx;
 
@@ -2374,7 +2372,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct 
ieee80211_hw *hw)
        hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS;
        hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev);
 
-       if (!sta_mode_only && rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
+       if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
                hw->wiphy->iface_combinations = rtw_iface_combs;
                hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs);
        }
@@ -2558,6 +2556,38 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool 
enable)
        }
 }
 
+void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
+                         struct ieee80211_bss_conf *bss_conf)
+{
+       const struct rtw_chip_ops *ops = rtwdev->chip->ops;
+       struct ieee80211_sta *sta;
+       u8 factor = 0xff;
+
+       if (!ops->set_ampdu_factor)
+               return;
+
+       rcu_read_lock();
+
+       sta = ieee80211_find_sta(vif, bss_conf->bssid);
+       if (!sta) {
+               rcu_read_unlock();
+               rtw_warn(rtwdev, "%s: failed to find station %pM\n",
+                        __func__, bss_conf->bssid);
+               return;
+       }
+
+       if (sta->deflink.vht_cap.vht_supported)
+               factor = u32_get_bits(sta->deflink.vht_cap.cap,
+                                     
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
+       else if (sta->deflink.ht_cap.ht_supported)
+               factor = sta->deflink.ht_cap.ampdu_factor;
+
+       rcu_read_unlock();
+
+       if (factor != 0xff)
+               ops->set_ampdu_factor(rtwdev, factor);
+}
+
 MODULE_AUTHOR("Realtek Corporation");
 MODULE_DESCRIPTION("Realtek 802.11ac wireless core module");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sys/contrib/dev/rtw88/main.h b/sys/contrib/dev/rtw88/main.h
index 963863618523..d1e4f3e41ba1 100644
--- a/sys/contrib/dev/rtw88/main.h
+++ b/sys/contrib/dev/rtw88/main.h
@@ -70,7 +70,7 @@ enum rtw_hci_type {
 };
 
 struct rtw_hci {
-       struct rtw_hci_ops *ops;
+       const struct rtw_hci_ops *ops;
        enum rtw_hci_type type;
 
        u32 rpwm_addr;
@@ -175,9 +175,14 @@ enum rtw_rate_section {
        RTW_RATE_SECTION_HT_2S,
        RTW_RATE_SECTION_VHT_1S,
        RTW_RATE_SECTION_VHT_2S,
+       __RTW_RATE_SECTION_2SS_MAX = RTW_RATE_SECTION_VHT_2S,
+       RTW_RATE_SECTION_HT_3S,
+       RTW_RATE_SECTION_HT_4S,
+       RTW_RATE_SECTION_VHT_3S,
+       RTW_RATE_SECTION_VHT_4S,
 
        /* keep last */
-       RTW_RATE_SECTION_MAX,
+       RTW_RATE_SECTION_NUM,
 };
 
 enum rtw_wireless_set {
@@ -200,6 +205,7 @@ enum rtw_chip_type {
        RTW_CHIP_TYPE_8703B,
        RTW_CHIP_TYPE_8821A,
        RTW_CHIP_TYPE_8812A,
+       RTW_CHIP_TYPE_8814A,
 };
 
 enum rtw_tx_queue_type {
@@ -389,6 +395,9 @@ enum rtw_evm {
        RTW_EVM_1SS,
        RTW_EVM_2SS_A,
        RTW_EVM_2SS_B,
+       RTW_EVM_3SS_A,
+       RTW_EVM_3SS_B,
+       RTW_EVM_3SS_C,
        /* keep it last */
        RTW_EVM_NUM
 };
@@ -406,6 +415,10 @@ enum rtw_snr {
        RTW_SNR_2SS_B,
        RTW_SNR_2SS_C,
        RTW_SNR_2SS_D,
+       RTW_SNR_3SS_A,
+       RTW_SNR_3SS_B,
+       RTW_SNR_3SS_C,
+       RTW_SNR_3SS_D,
        /* keep it last */
        RTW_SNR_NUM
 };
@@ -831,7 +844,7 @@ struct rtw_vif {
 };
 
 struct rtw_regulatory {
-       char alpha2[2];
+       char alpha2[2] __nonstring;
        u8 txpwr_regd_2g;
        u8 txpwr_regd_5g;
 };
@@ -854,6 +867,7 @@ struct rtw_chip_ops {
        int (*power_on)(struct rtw_dev *rtwdev);
        void (*power_off)(struct rtw_dev *rtwdev);
        int (*mac_init)(struct rtw_dev *rtwdev);
+       int (*mac_postinit)(struct rtw_dev *rtwdev);
        int (*dump_fw_crash)(struct rtw_dev *rtwdev);
        void (*shutdown)(struct rtw_dev *rtwdev);
        int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map);
@@ -869,11 +883,12 @@ struct rtw_chip_ops {
        void (*set_tx_power_index)(struct rtw_dev *rtwdev);
        int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset,
                              u32 size);
-       int (*set_antenna)(struct rtw_dev *rtwdev,
+       int (*set_antenna)(struct rtw_dev *rtwdev, int radio_idx,
                           u32 antenna_tx,
                           u32 antenna_rx);
        void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
        void (*efuse_grant)(struct rtw_dev *rtwdev, bool enable);
*** 28602 LINES SKIPPED ***

Reply via email to