Merge tag 'iwlwifi-next-for-kalle-2022-03-10' of git://git.kernel.org/pub/scm/linux...
authorKalle Valo <kvalo@kernel.org>
Thu, 10 Mar 2022 16:46:32 +0000 (18:46 +0200)
committerKalle Valo <kvalo@kernel.org>
Thu, 10 Mar 2022 16:46:32 +0000 (18:46 +0200)
iwlwifi patches for v5.18

* Mostly debugging infra changes;
* Some more work on the Bz family of devices;
* Bump the FW API twice;
* Some other small fixes, clean-ups and improvements.

19 files changed:
MAINTAINERS
drivers/bcma/driver_gpio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/efuse.c
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac.h
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/reg.h
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852ae.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c [new file with mode: 0644]
drivers/net/wireless/realtek/rtw89/rtw8852c.h [new file with mode: 0644]
drivers/net/wireless/realtek/rtw89/rtw8852ce.c [new file with mode: 0644]
drivers/net/wireless/st/cw1200/queue.c

index 25eb3097baae87225e6930d8b2966b70f387b2e9..59e973c5f5d56463260b7e7e24c964635b5f9472 100644 (file)
@@ -3817,9 +3817,6 @@ BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
 M:     Arend van Spriel <aspriel@gmail.com>
 M:     Franky Lin <franky.lin@broadcom.com>
 M:     Hante Meuleman <hante.meuleman@broadcom.com>
-M:     Chi-hsien Lin <chi-hsien.lin@infineon.com>
-M:     Wright Feng <wright.feng@infineon.com>
-M:     Chung-hsien Hsu <chung-hsien.hsu@infineon.com>
 L:     linux-wireless@vger.kernel.org
 L:     brcm80211-dev-list.pdl@broadcom.com
 L:     SHA-cyfmac-dev-list@infineon.com
@@ -12152,6 +12149,7 @@ R:      Shayne Chen <shayne.chen@mediatek.com>
 R:     Sean Wang <sean.wang@mediatek.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
+F:     Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
 F:     drivers/net/wireless/mediatek/mt76/
 
 MEDIATEK MT7601U WIRELESS LAN DRIVER
index 8a1e4705bc873d303b6b859056d9c06f298d75b8..1e74ec1c7f231426b4b1dbf40f8f50657d93e236 100644 (file)
@@ -181,7 +181,6 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
        chip->set               = bcma_gpio_set_value;
        chip->direction_input   = bcma_gpio_direction_input;
        chip->direction_output  = bcma_gpio_direction_output;
-       chip->owner             = THIS_MODULE;
        chip->parent            = bus->dev;
 #if IS_BUILTIN(CONFIG_OF)
        chip->of_node           = cc->core->dev.of_node;
index b2fb9fcacdc92566109318d3c915e93c9055389c..f0ad1e23f3c8049f86e72744281c9f983f2f722b 100644 (file)
@@ -4623,7 +4623,7 @@ exit:
 
 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
 {
-       s32 pktflags[] = {
+       static const s32 pktflags[] = {
                BRCMF_VNDR_IE_PRBREQ_FLAG,
                BRCMF_VNDR_IE_PRBRSP_FLAG,
                BRCMF_VNDR_IE_BEACON_FLAG
index 04735da11168a797c3f516bc9b49a16a2e181093..da54e51badd3a76d8e2d61fb339182b1e5d464d9 100644 (file)
@@ -396,36 +396,6 @@ void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
        }
 }
 
-static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
-{
-       u32 u4b_tmp;
-       u8 delay = 5;
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-
-       rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
-       rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
-       rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
-       u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
-       while (u4b_tmp != 0 && delay > 0) {
-               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
-               rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
-               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
-               u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
-               delay--;
-       }
-       if (delay == 0) {
-               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
-               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
-               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
-               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
-               rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
-                       "Switch RF timeout !!!\n");
-               return;
-       }
-       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
-       rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
-}
-
 static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                            enum rf_pwrstate rfpwr_state)
 {
@@ -519,7 +489,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
                                jiffies_to_msecs(jiffies -
                                                 ppsc->last_awake_jiffies));
                        ppsc->last_sleep_jiffies = jiffies;
-                       _rtl92ce_phy_set_rf_sleep(hw);
+                       _rtl92c_phy_set_rf_sleep(hw);
                        break;
                }
        default:
index a93555b0a2bfb3e6b814520849871519fb6e262b..bcefc968576e0f68215cdfa1896590343cddd220 100644 (file)
@@ -2732,10 +2732,11 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
 
 static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        u8 cv;
 
        cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK);
-       if (cv <= CHIP_CBV) {
+       if (chip->chip_id == RTL8852A && cv <= CHIP_CBV) {
                if (rtw89_read32(rtwdev, R_AX_GPIO0_7_FUNC_SEL) == RTW89_R32_DEAD)
                        cv = CHIP_CAV;
                else
index d203e4c5727d2a4e267e64aadf3602dc418a456a..483cf45fbcc9980ef5794e0709a2216c9e4086b9 100644 (file)
@@ -13,6 +13,7 @@
 #include <net/mac80211.h>
 
 struct rtw89_dev;
+struct rtw89_pci_info;
 
 extern const struct ieee80211_ops rtw89_ops;
 
@@ -2065,6 +2066,8 @@ struct rtw89_chip_ops {
        void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en);
        void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev,
                                       s16 pw_ofst, enum rtw89_mac_idx mac_idx);
+       int (*pwr_on_func)(struct rtw89_dev *rtwdev);
+       int (*pwr_off_func)(struct rtw89_dev *rtwdev);
 
        void (*btc_set_rfe)(struct rtw89_dev *rtwdev);
        void (*btc_init_cfg)(struct rtw89_dev *rtwdev);
@@ -2185,6 +2188,7 @@ struct rtw89_ple_quota {
        u16 bb_rpt;
        u16 wd_rel;
        u16 cpu_io;
+       u16 tx_rpt;
 };
 
 struct rtw89_dle_mem {
@@ -2234,6 +2238,21 @@ struct rtw89_txpwr_table {
                     const struct rtw89_txpwr_table *tbl);
 };
 
+struct rtw89_page_regs {
+       u32 hci_fc_ctrl;
+       u32 ch_page_ctrl;
+       u32 ach_page_ctrl;
+       u32 ach_page_info;
+       u32 pub_page_info3;
+       u32 pub_page_ctrl1;
+       u32 pub_page_ctrl2;
+       u32 pub_page_info1;
+       u32 pub_page_info2;
+       u32 wp_page_ctrl1;
+       u32 wp_page_ctrl2;
+       u32 wp_page_info1;
+};
+
 struct rtw89_chip_info {
        enum rtw89_core_chip_id chip_id;
        const struct rtw89_chip_ops *ops;
@@ -2257,6 +2276,8 @@ struct rtw89_chip_info {
        u32 physical_efuse_size;
        u32 logical_efuse_size;
        u32 limit_efuse_size;
+       u32 dav_phy_efuse_size;
+       u32 dav_log_efuse_size;
        u32 phycap_addr;
        u32 phycap_size;
 
@@ -2304,10 +2325,22 @@ struct rtw89_chip_info {
        u8 rf_para_dlink_num;
        const struct rtw89_btc_rf_trx_para *rf_para_dlink;
        u8 ps_mode_supported;
+
+       u32 hci_func_en_addr;
+       u32 h2c_ctrl_reg;
+       const u32 *h2c_regs;
+       u32 c2h_ctrl_reg;
+       const u32 *c2h_regs;
+       const struct rtw89_page_regs *page_regs;
+};
+
+union rtw89_bus_info {
+       const struct rtw89_pci_info *pci;
 };
 
 struct rtw89_driver_info {
        const struct rtw89_chip_info *chip;
+       union rtw89_bus_info bus;
 };
 
 enum rtw89_hcifc_mode {
@@ -2633,18 +2666,22 @@ struct rtw89_cfo_tracking_info {
 
 /* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */
 #define TSSI_TRIM_CH_GROUP_NUM 8
+#define TSSI_TRIM_CH_GROUP_NUM_6G 16
 
 #define TSSI_CCK_CH_GROUP_NUM 6
 #define TSSI_MCS_2G_CH_GROUP_NUM 5
 #define TSSI_MCS_5G_CH_GROUP_NUM 14
+#define TSSI_MCS_6G_CH_GROUP_NUM 32
 #define TSSI_MCS_CH_GROUP_NUM \
        (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM)
 
 struct rtw89_tssi_info {
        u8 thermal[RF_PATH_MAX];
        s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM];
+       s8 tssi_trim_6g[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM_6G];
        s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM];
        s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM];
+       s8 tssi_6g_mcs[RF_PATH_MAX][TSSI_MCS_6G_CH_GROUP_NUM];
        s8 extra_ofst[RF_PATH_MAX];
        bool tssi_tracking_check[RF_PATH_MAX];
        u8 default_txagc_offset[RF_PATH_MAX];
@@ -2858,6 +2895,7 @@ struct rtw89_dev {
        bool dbcc_en;
        struct rtw89_hw_scan_info scan_info;
        const struct rtw89_chip_info *chip;
+       const struct rtw89_pci_info *pci_info;
        struct rtw89_hal hal;
        struct rtw89_mac_info mac;
        struct rtw89_fw_info fw;
index c0b80f3da56c2cd5e760f0aef661911babcc5957..7bd4f8558e03b624b5f4da10c13c441e705e4f6c 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "debug.h"
 #include "efuse.h"
+#include "mac.h"
 #include "reg.h"
 
 enum rtw89_efuse_bank {
@@ -16,6 +17,9 @@ static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
 {
        u8 val;
 
+       if (rtwdev->chip->chip_id != RTL8852A)
+               return 0;
+
        val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1,
                                B_AX_EF_CELL_SEL_MASK);
        if (bank == val)
@@ -32,14 +36,61 @@ static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
        return -EBUSY;
 }
 
-static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
-                                        u32 dump_addr, u32 dump_size)
+static void rtw89_enable_otp_burst_mode(struct rtw89_dev *rtwdev, bool en)
+{
+       if (en)
+               rtw89_write32_set(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST);
+       else
+               rtw89_write32_clr(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST);
+}
+
+static void rtw89_enable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev)
+{
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       struct rtw89_hal *hal = &rtwdev->hal;
+
+       if (chip_id == RTL8852A)
+               return;
+
+       rtw89_write8_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+       rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
+
+       fsleep(1000);
+
+       rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
+       rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
+       if (chip_id == RTL8852B && hal->cv == CHIP_CAV)
+               rtw89_enable_otp_burst_mode(rtwdev, true);
+}
+
+static void rtw89_disable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev)
+{
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       struct rtw89_hal *hal = &rtwdev->hal;
+
+       if (chip_id == RTL8852A)
+               return;
+
+       if (chip_id == RTL8852B && hal->cv == CHIP_CAV)
+               rtw89_enable_otp_burst_mode(rtwdev, false);
+
+       rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
+       rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
+
+       fsleep(1000);
+
+       rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
+       rtw89_write8_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+}
+
+static int rtw89_dump_physical_efuse_map_ddv(struct rtw89_dev *rtwdev, u8 *map,
+                                            u32 dump_addr, u32 dump_size)
 {
        u32 efuse_ctl;
        u32 addr;
        int ret;
 
-       rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI);
+       rtw89_enable_efuse_pwr_cut_ddv(rtwdev);
 
        for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
                efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK);
@@ -54,6 +105,74 @@ static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
                *map++ = (u8)(efuse_ctl & 0xff);
        }
 
+       rtw89_disable_efuse_pwr_cut_ddv(rtwdev);
+
+       return 0;
+}
+
+static int rtw89_dump_physical_efuse_map_dav(struct rtw89_dev *rtwdev, u8 *map,
+                                            u32 dump_addr, u32 dump_size)
+{
+       u32 addr;
+       u8 val8;
+       int err;
+       int ret;
+
+       for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
+               ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK);
+               if (ret)
+                       return ret;
+               ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR,
+                                             addr & 0xff, XTAL_SI_LOW_ADDR_MASK);
+               if (ret)
+                       return ret;
+               ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8,
+                                             XTAL_SI_HIGH_ADDR_MASK);
+               if (ret)
+                       return ret;
+               ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0,
+                                             XTAL_SI_MODE_SEL_MASK);
+               if (ret)
+                       return ret;
+
+               ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err,
+                                              !err && (val8 & XTAL_SI_RDY),
+                                              1, 10000, false,
+                                              rtwdev, XTAL_SI_CTRL, &val8);
+               if (ret) {
+                       rtw89_warn(rtwdev, "failed to read dav efuse\n");
+                       return ret;
+               }
+
+               ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8);
+               if (ret)
+                       return ret;
+               *map++ = val8;
+       }
+
+       return 0;
+}
+
+static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
+                                        u32 dump_addr, u32 dump_size, bool dav)
+{
+       int ret;
+
+       if (!map || dump_size == 0)
+               return 0;
+
+       rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI);
+
+       if (dav) {
+               ret = rtw89_dump_physical_efuse_map_dav(rtwdev, map, dump_addr, dump_size);
+               if (ret)
+                       return ret;
+       } else {
+               ret = rtw89_dump_physical_efuse_map_ddv(rtwdev, map, dump_addr, dump_size);
+               if (ret)
+                       return ret;
+       }
+
        return 0;
 }
 
@@ -78,6 +197,9 @@ static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map,
        u8 word_en;
        int i;
 
+       if (!phy_map)
+               return 0;
+
        while (phy_idx < physical_size - sec_ctrl_size) {
                hdr1 = phy_map[phy_idx];
                hdr2 = phy_map[phy_idx + 1];
@@ -109,8 +231,13 @@ int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev)
 {
        u32 phy_size = rtwdev->chip->physical_efuse_size;
        u32 log_size = rtwdev->chip->logical_efuse_size;
+       u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size;
+       u32 dav_log_size = rtwdev->chip->dav_log_efuse_size;
+       u32 full_log_size = log_size + dav_log_size;
        u8 *phy_map = NULL;
        u8 *log_map = NULL;
+       u8 *dav_phy_map = NULL;
+       u8 *dav_log_map = NULL;
        int ret;
 
        if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS)
@@ -119,27 +246,41 @@ int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev)
                rtw89_warn(rtwdev, "failed to check efuse autoload\n");
 
        phy_map = kmalloc(phy_size, GFP_KERNEL);
-       log_map = kmalloc(log_size, GFP_KERNEL);
+       log_map = kmalloc(full_log_size, GFP_KERNEL);
+       if (dav_phy_size && dav_log_size) {
+               dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL);
+               dav_log_map = log_map + log_size;
+       }
 
-       if (!phy_map || !log_map) {
+       if (!phy_map || !log_map || (dav_phy_size && !dav_phy_map)) {
                ret = -ENOMEM;
                goto out_free;
        }
 
-       ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size);
+       ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size, false);
        if (ret) {
                rtw89_warn(rtwdev, "failed to dump efuse physical map\n");
                goto out_free;
        }
+       ret = rtw89_dump_physical_efuse_map(rtwdev, dav_phy_map, 0, dav_phy_size, true);
+       if (ret) {
+               rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n");
+               goto out_free;
+       }
 
-       memset(log_map, 0xff, log_size);
+       memset(log_map, 0xff, full_log_size);
        ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map);
        if (ret) {
                rtw89_warn(rtwdev, "failed to dump efuse logical map\n");
                goto out_free;
        }
+       ret = rtw89_dump_logical_efuse_map(rtwdev, dav_phy_map, dav_log_map);
+       if (ret) {
+               rtw89_warn(rtwdev, "failed to dump efuse dav logical map\n");
+               goto out_free;
+       }
 
-       rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, log_size);
+       rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, full_log_size);
 
        ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map);
        if (ret) {
@@ -148,6 +289,7 @@ int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev)
        }
 
 out_free:
+       kfree(dav_phy_map);
        kfree(log_map);
        kfree(phy_map);
 
@@ -169,7 +311,7 @@ int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev)
                return -ENOMEM;
 
        ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map,
-                                           phycap_addr, phycap_size);
+                                           phycap_addr, phycap_size, false);
        if (ret) {
                rtw89_warn(rtwdev, "failed to dump phycap map\n");
                goto out_free;
index 97224483f6188b89e28c8824eeba5e30a3dee65e..2fe091cc12c0e4797751391450c4ff90b3ee3950 100644 (file)
@@ -1832,15 +1832,13 @@ void rtw89_fw_c2h_work(struct work_struct *work)
 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
                                  struct rtw89_mac_h2c_info *info)
 {
-       static const u32 h2c_reg[RTW89_H2CREG_MAX] = {
-               R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1,
-               R_AX_H2CREG_DATA2, R_AX_H2CREG_DATA3
-       };
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const u32 *h2c_reg = chip->h2c_regs;
        u8 i, val, len;
        int ret;
 
        ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false,
-                               rtwdev, R_AX_H2CREG_CTRL);
+                               rtwdev, chip->h2c_ctrl_reg);
        if (ret) {
                rtw89_warn(rtwdev, "FW does not process h2c registers\n");
                return ret;
@@ -1854,7 +1852,7 @@ static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
        for (i = 0; i < RTW89_H2CREG_MAX; i++)
                rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]);
 
-       rtw89_write8(rtwdev, R_AX_H2CREG_CTRL, B_AX_H2CREG_TRIGGER);
+       rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER);
 
        return 0;
 }
@@ -1862,10 +1860,8 @@ static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
 static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
                                 struct rtw89_mac_c2h_info *info)
 {
-       static const u32 c2h_reg[RTW89_C2HREG_MAX] = {
-               R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1,
-               R_AX_C2HREG_DATA2, R_AX_C2HREG_DATA3
-       };
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const u32 *c2h_reg = chip->c2h_regs;
        u32 ret;
        u8 i, val;
 
@@ -1873,7 +1869,7 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
 
        ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
                                       RTW89_C2H_TIMEOUT, false, rtwdev,
-                                      R_AX_C2HREG_CTRL);
+                                      chip->c2h_ctrl_reg);
        if (ret) {
                rtw89_warn(rtwdev, "c2h reg timeout\n");
                return ret;
@@ -1882,7 +1878,7 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
        for (i = 0; i < RTW89_C2HREG_MAX; i++)
                info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]);
 
-       rtw89_write8(rtwdev, R_AX_C2HREG_CTRL, 0);
+       rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0);
 
        info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg);
        info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) -
index 9a91b408cd28e68c80b2f9ff177c27ee057a377d..8fbdfd983cc53dae65667d0616b77ce3a0a6f1a2 100644 (file)
@@ -569,6 +569,8 @@ static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev)
 
 static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
        int ret = 0;
@@ -588,13 +590,15 @@ static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch)
        val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) |
              u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) |
              (cfg[ch].grp ? B_AX_GRP : 0);
-       rtw89_write32(rtwdev, R_AX_ACH0_PAGE_CTRL + ch * 4, val);
+       rtw89_write32(rtwdev, regs->ach_page_ctrl + ch * 4, val);
 
        return 0;
 }
 
 static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        struct rtw89_hfc_ch_info *info = param->ch_info;
        const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
@@ -608,7 +612,7 @@ static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch)
        if (ch > RTW89_DMA_H2C)
                return -EINVAL;
 
-       val = rtw89_read32(rtwdev, R_AX_ACH0_PAGE_INFO + ch * 4);
+       val = rtw89_read32(rtwdev, regs->ach_page_info + ch * 4);
        info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK);
        if (ch < RTW89_DMA_H2C)
                info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK);
@@ -620,6 +624,8 @@ static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch)
 
 static int hfc_pub_ctrl(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg;
        u32 val;
        int ret;
@@ -634,16 +640,18 @@ static int hfc_pub_ctrl(struct rtw89_dev *rtwdev)
 
        val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) |
              u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK);
-       rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL1, val);
+       rtw89_write32(rtwdev, regs->pub_page_ctrl1, val);
 
        val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK);
-       rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL2, val);
+       rtw89_write32(rtwdev, regs->wp_page_ctrl2, val);
 
        return 0;
 }
 
 static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
        struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
@@ -655,20 +663,20 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
        if (ret)
                return ret;
 
-       val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO1);
+       val = rtw89_read32(rtwdev, regs->pub_page_info1);
        info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK);
        info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK);
-       val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO3);
+       val = rtw89_read32(rtwdev, regs->pub_page_info3);
        info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK);
        info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK);
        info->pub_aval =
-               u32_get_bits(rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO2),
+               u32_get_bits(rtw89_read32(rtwdev, regs->pub_page_info2),
                             B_AX_PUB_AVAL_PG_MASK);
        info->wp_aval =
-               u32_get_bits(rtw89_read32(rtwdev, R_AX_WP_PAGE_INFO1),
+               u32_get_bits(rtw89_read32(rtwdev, regs->wp_page_info1),
                             B_AX_WP_AVAL_PG_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL);
+       val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
        param->en = val & B_AX_HCI_FC_EN ? 1 : 0;
        param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0;
        param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK);
@@ -681,21 +689,21 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
        prec_cfg->wp_ch811_full_cond =
                u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_CH_PAGE_CTRL);
+       val = rtw89_read32(rtwdev, regs->ch_page_ctrl);
        prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK);
        prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL2);
+       val = rtw89_read32(rtwdev, regs->pub_page_ctrl2);
        pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL1);
+       val = rtw89_read32(rtwdev, regs->wp_page_ctrl1);
        prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK);
        prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL2);
+       val = rtw89_read32(rtwdev, regs->wp_page_ctrl2);
        pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK);
 
-       val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL1);
+       val = rtw89_read32(rtwdev, regs->pub_page_ctrl1);
        pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK);
        pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK);
 
@@ -708,20 +716,24 @@ static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
 
 static void hfc_h2c_cfg(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
        u32 val;
 
        val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
-       rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val);
+       rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
 
-       rtw89_write32_mask(rtwdev, R_AX_HCI_FC_CTRL,
+       rtw89_write32_mask(rtwdev, regs->hci_fc_ctrl,
                           B_AX_HCI_FC_CH12_FULL_COND_MASK,
                           prec_cfg->h2c_full_cond);
 }
 
 static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
        const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
@@ -729,18 +741,18 @@ static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
 
        val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) |
              u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
-       rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val);
+       rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
 
        val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK);
-       rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL2, val);
+       rtw89_write32(rtwdev, regs->pub_page_ctrl2, val);
 
        val = u32_encode_bits(prec_cfg->wp_ch07_prec,
                              B_AX_PREC_PAGE_WP_CH07_MASK) |
              u32_encode_bits(prec_cfg->wp_ch811_prec,
                              B_AX_PREC_PAGE_WP_CH811_MASK);
-       rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL1, val);
+       rtw89_write32(rtwdev, regs->wp_page_ctrl1, val);
 
-       val = u32_replace_bits(rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL),
+       val = u32_replace_bits(rtw89_read32(rtwdev, regs->hci_fc_ctrl),
                               param->mode, B_AX_HCI_FC_MODE_MASK);
        val = u32_replace_bits(val, prec_cfg->ch011_full_cond,
                               B_AX_HCI_FC_WD_FULL_COND_MASK);
@@ -750,21 +762,23 @@ static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
                               B_AX_HCI_FC_WP_CH07_FULL_COND_MASK);
        val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond,
                               B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
-       rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val);
+       rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
 }
 
 static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       const struct rtw89_page_regs *regs = chip->page_regs;
        struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
        u32 val;
 
-       val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL);
+       val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
        param->en = en;
        param->h2c_en = h2c_en;
        val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN);
        val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) :
                         (val & ~B_AX_HCI_FC_CH12_EN);
-       rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val);
+       rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
 }
 
 static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
@@ -1022,14 +1036,18 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
 #define PWR_ACT 1
        const struct rtw89_chip_info *chip = rtwdev->chip;
        const struct rtw89_pwr_cfg * const *cfg_seq;
+       int (*cfg_func)(struct rtw89_dev *rtwdev);
        struct rtw89_hal *hal = &rtwdev->hal;
        int ret;
        u8 val;
 
-       if (on)
+       if (on) {
                cfg_seq = chip->pwr_on_seq;
-       else
+               cfg_func = chip->ops->pwr_on_func;
+       } else {
                cfg_seq = chip->pwr_off_seq;
+               cfg_func = chip->ops->pwr_off_func;
+       }
 
        if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
                __rtw89_leave_ps_mode(rtwdev);
@@ -1040,7 +1058,7 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
                return -EBUSY;
        }
 
-       ret = rtw89_mac_pwr_seq(rtwdev, cfg_seq);
+       ret = cfg_func ? cfg_func(rtwdev) : rtw89_mac_pwr_seq(rtwdev, cfg_seq);
        if (ret)
                return ret;
 
@@ -1165,6 +1183,18 @@ const struct rtw89_dle_size rtw89_wde_size4 = {
 };
 EXPORT_SYMBOL(rtw89_wde_size4);
 
+/* 8852C DLFW */
+const struct rtw89_dle_size rtw89_wde_size18 = {
+       RTW89_WDE_PG_64, 0, 2048,
+};
+EXPORT_SYMBOL(rtw89_wde_size18);
+
+/* 8852C PCIE SCC */
+const struct rtw89_dle_size rtw89_wde_size19 = {
+       RTW89_WDE_PG_64, 3328, 0,
+};
+EXPORT_SYMBOL(rtw89_wde_size19);
+
 /* PCIE */
 const struct rtw89_dle_size rtw89_ple_size0 = {
        RTW89_PLE_PG_128, 1520, 16,
@@ -1177,6 +1207,18 @@ const struct rtw89_dle_size rtw89_ple_size4 = {
 };
 EXPORT_SYMBOL(rtw89_ple_size4);
 
+/* 8852C DLFW */
+const struct rtw89_dle_size rtw89_ple_size18 = {
+       RTW89_PLE_PG_128, 2544, 16,
+};
+EXPORT_SYMBOL(rtw89_ple_size18);
+
+/* 8852C PCIE SCC */
+const struct rtw89_dle_size rtw89_ple_size19 = {
+       RTW89_PLE_PG_128, 1904, 16,
+};
+EXPORT_SYMBOL(rtw89_ple_size19);
+
 /* PCIE 64 */
 const struct rtw89_wde_quota rtw89_wde_qt0 = {
        3792, 196, 0, 107,
@@ -1189,6 +1231,18 @@ const struct rtw89_wde_quota rtw89_wde_qt4 = {
 };
 EXPORT_SYMBOL(rtw89_wde_qt4);
 
+/* 8852C DLFW */
+const struct rtw89_wde_quota rtw89_wde_qt17 = {
+       0, 0, 0,  0,
+};
+EXPORT_SYMBOL(rtw89_wde_qt17);
+
+/* 8852C PCIE SCC */
+const struct rtw89_wde_quota rtw89_wde_qt18 = {
+       3228, 60, 0, 40,
+};
+EXPORT_SYMBOL(rtw89_wde_qt18);
+
 /* PCIE SCC */
 const struct rtw89_ple_quota rtw89_ple_qt4 = {
        264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,
@@ -1207,6 +1261,30 @@ const struct rtw89_ple_quota rtw89_ple_qt13 = {
 };
 EXPORT_SYMBOL(rtw89_ple_qt13);
 
+/* DLFW 52C */
+const struct rtw89_ple_quota rtw89_ple_qt44 = {
+       0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+EXPORT_SYMBOL(rtw89_ple_qt44);
+
+/* DLFW 52C */
+const struct rtw89_ple_quota rtw89_ple_qt45 = {
+       0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+EXPORT_SYMBOL(rtw89_ple_qt45);
+
+/* 8852C PCIE SCC */
+const struct rtw89_ple_quota rtw89_ple_qt46 = {
+       525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,
+};
+EXPORT_SYMBOL(rtw89_ple_qt46);
+
+/* 8852C PCIE SCC */
+const struct rtw89_ple_quota rtw89_ple_qt47 = {
+       525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,
+};
+EXPORT_SYMBOL(rtw89_ple_qt47);
+
 static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
                                                   enum rtw89_qta_mode mode)
 {
@@ -1361,6 +1439,8 @@ static void ple_quota_cfg(struct rtw89_dev *rtwdev,
        SET_QUOTA(bb_rpt, PLE, 8);
        SET_QUOTA(wd_rel, PLE, 9);
        SET_QUOTA(cpu_io, PLE, 10);
+       if (rtwdev->chip->chip_id == RTL8852C)
+               SET_QUOTA(tx_rpt, PLE, 11);
 }
 
 #undef SET_QUOTA
@@ -2615,7 +2695,9 @@ static int rtw89_mac_fw_dl_pre_init(struct rtw89_dev *rtwdev)
 
 static void rtw89_mac_hci_func_en(struct rtw89_dev *rtwdev)
 {
-       rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN,
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       rtw89_write32_set(rtwdev, chip->hci_func_en_addr,
                          B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN);
 }
 
@@ -3968,3 +4050,51 @@ int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
 
        return 0;
 }
+
+int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
+{
+       u32 val32;
+       int ret;
+
+       val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, val) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, mask) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_WRITE) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
+       rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
+
+       ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
+                               50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
+       if (ret) {
+               rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n",
+                          offset, val, mask);
+               return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(rtw89_mac_write_xtal_si);
+
+int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
+{
+       u32 val32;
+       int ret;
+
+       val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, 0x00) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, 0x00) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_READ) |
+               FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
+       rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
+
+       ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
+                               50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
+       if (ret) {
+               rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset);
+               return ret;
+       }
+
+       *val = rtw89_read8(rtwdev, R_AX_WLAN_XTAL_SI_CTRL + 1);
+
+       return 0;
+}
index 5c7a9d784265a6d3b4e699106bf21f8a2506cf06..2f707c817fa797b299b4f8584c1ba01ad27c2239 100644 (file)
@@ -675,13 +675,23 @@ enum mac_ax_err_info {
 extern const struct rtw89_hfc_prec_cfg rtw89_hfc_preccfg_pcie;
 extern const struct rtw89_dle_size rtw89_wde_size0;
 extern const struct rtw89_dle_size rtw89_wde_size4;
+extern const struct rtw89_dle_size rtw89_wde_size18;
+extern const struct rtw89_dle_size rtw89_wde_size19;
 extern const struct rtw89_dle_size rtw89_ple_size0;
 extern const struct rtw89_dle_size rtw89_ple_size4;
+extern const struct rtw89_dle_size rtw89_ple_size18;
+extern const struct rtw89_dle_size rtw89_ple_size19;
 extern const struct rtw89_wde_quota rtw89_wde_qt0;
 extern const struct rtw89_wde_quota rtw89_wde_qt4;
+extern const struct rtw89_wde_quota rtw89_wde_qt17;
+extern const struct rtw89_wde_quota rtw89_wde_qt18;
 extern const struct rtw89_ple_quota rtw89_ple_qt4;
 extern const struct rtw89_ple_quota rtw89_ple_qt5;
 extern const struct rtw89_ple_quota rtw89_ple_qt13;
+extern const struct rtw89_ple_quota rtw89_ple_qt44;
+extern const struct rtw89_ple_quota rtw89_ple_qt45;
+extern const struct rtw89_ple_quota rtw89_ple_qt46;
+extern const struct rtw89_ple_quota rtw89_ple_qt47;
 
 static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band)
 {
@@ -872,4 +882,42 @@ int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
 int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
                                 struct rtw89_sta *rtwsta, u8 *tx_retry);
 
+enum rtw89_mac_xtal_si_offset {
+       XTAL_SI_XTAL_SC_XI = 0x04,
+       XTAL_SI_XTAL_SC_XO = 0x05,
+       XTAL_SI_PWR_CUT = 0x10,
+#define XTAL_SI_SMALL_PWR_CUT  BIT(0)
+#define XTAL_SI_BIG_PWR_CUT    BIT(1)
+       XTAL_SI_XTAL_XMD_2 = 0x24,
+#define XTAL_SI_LDO_LPS                GENMASK(6, 4)
+       XTAL_SI_XTAL_XMD_4 = 0x26,
+#define XTAL_SI_LPS_CAP                GENMASK(3, 0)
+       XTAL_SI_CV = 0x41,
+       XTAL_SI_LOW_ADDR = 0x62,
+#define XTAL_SI_LOW_ADDR_MASK  GENMASK(7, 0)
+       XTAL_SI_CTRL = 0x63,
+#define XTAL_SI_MODE_SEL_MASK  GENMASK(7, 6)
+#define XTAL_SI_RDY            BIT(5)
+#define XTAL_SI_HIGH_ADDR_MASK GENMASK(2, 0)
+       XTAL_SI_READ_VAL = 0x7A,
+       XTAL_SI_WL_RFC_S0 = 0x80,
+#define XTAL_SI_RF00           BIT(0)
+       XTAL_SI_WL_RFC_S1 = 0x81,
+#define XTAL_SI_RF10           BIT(0)
+       XTAL_SI_ANAPAR_WL = 0x90,
+#define XTAL_SI_SRAM2RFC       BIT(7)
+#define XTAL_SI_GND_SHDN_WL    BIT(6)
+#define XTAL_SI_SHDN_WL                BIT(5)
+#define XTAL_SI_RFC2RF         BIT(4)
+#define XTAL_SI_OFF_EI         BIT(3)
+#define XTAL_SI_OFF_WEI                BIT(2)
+#define XTAL_SI_PON_EI         BIT(1)
+#define XTAL_SI_PON_WEI                BIT(0)
+       XTAL_SI_SRAM_CTRL = 0xA1,
+#define FULL_BIT_MASK          GENMASK(7, 0)
+};
+
+int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask);
+int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val);
+
 #endif
index 6481085b958e77627b0ade971fe81cf3fb3f8097..e79bfc335b446b2f82f6c2416b8b8a13238077ef 100644 (file)
@@ -62,7 +62,7 @@ static u32 rtw89_pci_txbd_recalc(struct rtw89_dev *rtwdev,
                                 struct rtw89_pci_tx_ring *tx_ring)
 {
        struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring;
-       u32 addr_idx = bd_ring->addr_idx;
+       u32 addr_idx = bd_ring->addr.idx;
        u32 cnt, idx;
 
        idx = rtw89_read32(rtwdev, addr_idx);
@@ -121,7 +121,7 @@ static u32 rtw89_pci_rxbd_recalc(struct rtw89_dev *rtwdev,
                                 struct rtw89_pci_rx_ring *rx_ring)
 {
        struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring;
-       u32 addr_idx = bd_ring->addr_idx;
+       u32 addr_idx = bd_ring->addr.idx;
        u32 cnt, idx;
 
        idx = rtw89_read32(rtwdev, addr_idx);
@@ -304,7 +304,7 @@ static void rtw89_pci_rxbd_deliver(struct rtw89_dev *rtwdev,
                cnt -= rx_cnt;
        }
 
-       rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp);
+       rtw89_write16(rtwdev, bd_ring->addr.idx, bd_ring->wp);
 }
 
 static int rtw89_pci_poll_rxq_dma(struct rtw89_dev *rtwdev,
@@ -555,7 +555,7 @@ static void rtw89_pci_release_tx(struct rtw89_dev *rtwdev,
                cnt -= release_cnt;
        }
 
-       rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp);
+       rtw89_write16(rtwdev, bd_ring->addr.idx, bd_ring->wp);
 }
 
 static int rtw89_pci_poll_rpq_dma(struct rtw89_dev *rtwdev,
@@ -598,7 +598,7 @@ static void rtw89_pci_isr_rxd_unavail(struct rtw89_dev *rtwdev,
                rx_ring = &rtwpci->rx_rings[i];
                bd_ring = &rx_ring->bd_ring;
 
-               reg_idx = rtw89_read32(rtwdev, bd_ring->addr_idx);
+               reg_idx = rtw89_read32(rtwdev, bd_ring->addr.idx);
                hw_idx = FIELD_GET(TXBD_HW_IDX_MASK, reg_idx);
                host_idx = FIELD_GET(TXBD_HOST_IDX_MASK, reg_idx);
                hw_idx_next = (hw_idx + 1) % bd_ring->len;
@@ -697,71 +697,110 @@ exit:
        return irqret;
 }
 
-#define case_TXCHADDRS(txch) \
-       case RTW89_TXCH_##txch: \
-               *addr_num = R_AX_##txch##_TXBD_NUM; \
-               *addr_idx = R_AX_##txch##_TXBD_IDX; \
-               *addr_bdram = R_AX_##txch##_BDRAM_CTRL; \
-               *addr_desa_l = R_AX_##txch##_TXBD_DESA_L; \
-               *addr_desa_h = R_AX_##txch##_TXBD_DESA_H; \
-               break
-
-static int rtw89_pci_get_txch_addrs(enum rtw89_tx_channel txch,
-                                   u32 *addr_num,
-                                   u32 *addr_idx,
-                                   u32 *addr_bdram,
-                                   u32 *addr_desa_l,
-                                   u32 *addr_desa_h)
-{
-       switch (txch) {
-       case_TXCHADDRS(ACH0);
-       case_TXCHADDRS(ACH1);
-       case_TXCHADDRS(ACH2);
-       case_TXCHADDRS(ACH3);
-       case_TXCHADDRS(ACH4);
-       case_TXCHADDRS(ACH5);
-       case_TXCHADDRS(ACH6);
-       case_TXCHADDRS(ACH7);
-       case_TXCHADDRS(CH8);
-       case_TXCHADDRS(CH9);
-       case_TXCHADDRS(CH10);
-       case_TXCHADDRS(CH11);
-       case_TXCHADDRS(CH12);
-       default:
+#define DEF_TXCHADDRS_TYPE1(info, txch, v...) \
+       [RTW89_TXCH_##txch] = { \
+               .num = R_AX_##txch##_TXBD_NUM ##v, \
+               .idx = R_AX_##txch##_TXBD_IDX ##v, \
+               .bdram = R_AX_##txch##_BDRAM_CTRL ##v, \
+               .desa_l = R_AX_##txch##_TXBD_DESA_L ##v, \
+               .desa_h = R_AX_##txch##_TXBD_DESA_H ##v, \
+       }
+
+#define DEF_TXCHADDRS(info, txch, v...) \
+       [RTW89_TXCH_##txch] = { \
+               .num = R_AX_##txch##_TXBD_NUM, \
+               .idx = R_AX_##txch##_TXBD_IDX, \
+               .bdram = R_AX_##txch##_BDRAM_CTRL ##v, \
+               .desa_l = R_AX_##txch##_TXBD_DESA_L ##v, \
+               .desa_h = R_AX_##txch##_TXBD_DESA_H ##v, \
+       }
+
+#define DEF_RXCHADDRS(info, rxch, v...) \
+       [RTW89_RXCH_##rxch] = { \
+               .num = R_AX_##rxch##_RXBD_NUM ##v, \
+               .idx = R_AX_##rxch##_RXBD_IDX ##v, \
+               .desa_l = R_AX_##rxch##_RXBD_DESA_L ##v, \
+               .desa_h = R_AX_##rxch##_RXBD_DESA_H ##v, \
+       }
+
+const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set = {
+       .tx = {
+               DEF_TXCHADDRS(info, ACH0),
+               DEF_TXCHADDRS(info, ACH1),
+               DEF_TXCHADDRS(info, ACH2),
+               DEF_TXCHADDRS(info, ACH3),
+               DEF_TXCHADDRS(info, ACH4),
+               DEF_TXCHADDRS(info, ACH5),
+               DEF_TXCHADDRS(info, ACH6),
+               DEF_TXCHADDRS(info, ACH7),
+               DEF_TXCHADDRS(info, CH8),
+               DEF_TXCHADDRS(info, CH9),
+               DEF_TXCHADDRS_TYPE1(info, CH10),
+               DEF_TXCHADDRS_TYPE1(info, CH11),
+               DEF_TXCHADDRS(info, CH12),
+       },
+       .rx = {
+               DEF_RXCHADDRS(info, RXQ),
+               DEF_RXCHADDRS(info, RPQ),
+       },
+};
+EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set);
+
+const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1 = {
+       .tx = {
+               DEF_TXCHADDRS(info, ACH0, _V1),
+               DEF_TXCHADDRS(info, ACH1, _V1),
+               DEF_TXCHADDRS(info, ACH2, _V1),
+               DEF_TXCHADDRS(info, ACH3, _V1),
+               DEF_TXCHADDRS(info, ACH4, _V1),
+               DEF_TXCHADDRS(info, ACH5, _V1),
+               DEF_TXCHADDRS(info, ACH6, _V1),
+               DEF_TXCHADDRS(info, ACH7, _V1),
+               DEF_TXCHADDRS(info, CH8, _V1),
+               DEF_TXCHADDRS(info, CH9, _V1),
+               DEF_TXCHADDRS_TYPE1(info, CH10, _V1),
+               DEF_TXCHADDRS_TYPE1(info, CH11, _V1),
+               DEF_TXCHADDRS(info, CH12, _V1),
+       },
+       .rx = {
+               DEF_RXCHADDRS(info, RXQ, _V1),
+               DEF_RXCHADDRS(info, RPQ, _V1),
+       },
+};
+EXPORT_SYMBOL(rtw89_pci_ch_dma_addr_set_v1);
+
+#undef DEF_TXCHADDRS_TYPE1
+#undef DEF_TXCHADDRS
+#undef DEF_RXCHADDRS
+
+static int rtw89_pci_get_txch_addrs(struct rtw89_dev *rtwdev,
+                                   enum rtw89_tx_channel txch,
+                                   const struct rtw89_pci_ch_dma_addr **addr)
+{
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+
+       if (txch >= RTW89_TXCH_NUM)
                return -EINVAL;
-       }
+
+       *addr = &info->dma_addr_set->tx[txch];
 
        return 0;
 }
 
-#undef case_TXCHADDRS
-
-#define case_RXCHADDRS(rxch) \
-       case RTW89_RXCH_##rxch: \
-               *addr_num = R_AX_##rxch##_RXBD_NUM; \
-               *addr_idx = R_AX_##rxch##_RXBD_IDX; \
-               *addr_desa_l = R_AX_##rxch##_RXBD_DESA_L; \
-               *addr_desa_h = R_AX_##rxch##_RXBD_DESA_H; \
-               break
-
-static int rtw89_pci_get_rxch_addrs(enum rtw89_rx_channel rxch,
-                                   u32 *addr_num,
-                                   u32 *addr_idx,
-                                   u32 *addr_desa_l,
-                                   u32 *addr_desa_h)
+static int rtw89_pci_get_rxch_addrs(struct rtw89_dev *rtwdev,
+                                   enum rtw89_rx_channel rxch,
+                                   const struct rtw89_pci_ch_dma_addr **addr)
 {
-       switch (rxch) {
-       case_RXCHADDRS(RXQ);
-       case_RXCHADDRS(RPQ);
-       default:
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+
+       if (rxch >= RTW89_RXCH_NUM)
                return -EINVAL;
-       }
+
+       *addr = &info->dma_addr_set->rx[rxch];
 
        return 0;
 }
 
-#undef case_RXCHADDRS
-
 static u32 rtw89_pci_get_avail_txbd_num(struct rtw89_pci_tx_ring *ring)
 {
        struct rtw89_pci_dma_ring *bd_ring = &ring->bd_ring;
@@ -837,7 +876,7 @@ static void __rtw89_pci_tx_kick_off(struct rtw89_dev *rtwdev, struct rtw89_pci_t
        struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring;
        u32 host_idx, addr;
 
-       addr = bd_ring->addr_idx;
+       addr = bd_ring->addr.idx;
        host_idx = bd_ring->wp;
        rtw89_write16(rtwdev, addr, host_idx);
 }
@@ -879,7 +918,7 @@ static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop)
         * just use for loop with udelay here.
         */
        for (i = 0; i < 60; i++) {
-               cur_idx = rtw89_read32(rtwdev, bd_ring->addr_idx);
+               cur_idx = rtw89_read32(rtwdev, bd_ring->addr.idx);
                cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx);
                if (cur_rp == bd_ring->wp)
                        return;
@@ -1140,9 +1179,9 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
                tx_ring = &rtwpci->tx_rings[i];
                bd_ring = &tx_ring->bd_ring;
                bd_ram = &bd_ram_table[i];
-               addr_num = bd_ring->addr_num;
-               addr_bdram = bd_ring->addr_bdram;
-               addr_desa_l = bd_ring->addr_desa_l;
+               addr_num = bd_ring->addr.num;
+               addr_bdram = bd_ring->addr.bdram;
+               addr_desa_l = bd_ring->addr.desa_l;
                bd_ring->wp = 0;
                bd_ring->rp = 0;
 
@@ -1158,8 +1197,8 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
        for (i = 0; i < RTW89_RXCH_NUM; i++) {
                rx_ring = &rtwpci->rx_rings[i];
                bd_ring = &rx_ring->bd_ring;
-               addr_num = bd_ring->addr_num;
-               addr_desa_l = bd_ring->addr_desa_l;
+               addr_num = bd_ring->addr.num;
+               addr_desa_l = bd_ring->addr.desa_l;
                bd_ring->wp = 0;
                bd_ring->rp = 0;
                rx_ring->diliver_skb = NULL;
@@ -2188,14 +2227,10 @@ static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev,
                                   u32 desc_size, u32 len,
                                   enum rtw89_tx_channel txch)
 {
+       const struct rtw89_pci_ch_dma_addr *txch_addr;
        int ring_sz = desc_size * len;
        u8 *head;
        dma_addr_t dma;
-       u32 addr_num;
-       u32 addr_idx;
-       u32 addr_bdram;
-       u32 addr_desa_l;
-       u32 addr_desa_h;
        int ret;
 
        ret = rtw89_pci_alloc_tx_wd_ring(rtwdev, pdev, tx_ring, txch);
@@ -2204,8 +2239,7 @@ static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev,
                goto err;
        }
 
-       ret = rtw89_pci_get_txch_addrs(txch, &addr_num, &addr_idx, &addr_bdram,
-                                      &addr_desa_l, &addr_desa_h);
+       ret = rtw89_pci_get_txch_addrs(rtwdev, txch, &txch_addr);
        if (ret) {
                rtw89_err(rtwdev, "failed to get address of txch %d", txch);
                goto err_free_wd_ring;
@@ -2222,11 +2256,7 @@ static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev,
        tx_ring->bd_ring.dma = dma;
        tx_ring->bd_ring.len = len;
        tx_ring->bd_ring.desc_size = desc_size;
-       tx_ring->bd_ring.addr_num = addr_num;
-       tx_ring->bd_ring.addr_idx = addr_idx;
-       tx_ring->bd_ring.addr_bdram = addr_bdram;
-       tx_ring->bd_ring.addr_desa_l = addr_desa_l;
-       tx_ring->bd_ring.addr_desa_h = addr_desa_h;
+       tx_ring->bd_ring.addr = *txch_addr;
        tx_ring->bd_ring.wp = 0;
        tx_ring->bd_ring.rp = 0;
        tx_ring->txch = txch;
@@ -2278,20 +2308,16 @@ static int rtw89_pci_alloc_rx_ring(struct rtw89_dev *rtwdev,
                                   struct rtw89_pci_rx_ring *rx_ring,
                                   u32 desc_size, u32 len, u32 rxch)
 {
+       const struct rtw89_pci_ch_dma_addr *rxch_addr;
        struct sk_buff *skb;
        u8 *head;
        dma_addr_t dma;
-       u32 addr_num;
-       u32 addr_idx;
-       u32 addr_desa_l;
-       u32 addr_desa_h;
        int ring_sz = desc_size * len;
        int buf_sz = RTW89_PCI_RX_BUF_SIZE;
        int i, allocated;
        int ret;
 
-       ret = rtw89_pci_get_rxch_addrs(rxch, &addr_num, &addr_idx,
-                                      &addr_desa_l, &addr_desa_h);
+       ret = rtw89_pci_get_rxch_addrs(rtwdev, rxch, &rxch_addr);
        if (ret) {
                rtw89_err(rtwdev, "failed to get address of rxch %d", rxch);
                return ret;
@@ -2307,10 +2333,7 @@ static int rtw89_pci_alloc_rx_ring(struct rtw89_dev *rtwdev,
        rx_ring->bd_ring.dma = dma;
        rx_ring->bd_ring.len = len;
        rx_ring->bd_ring.desc_size = desc_size;
-       rx_ring->bd_ring.addr_num = addr_num;
-       rx_ring->bd_ring.addr_idx = addr_idx;
-       rx_ring->bd_ring.addr_desa_l = addr_desa_l;
-       rx_ring->bd_ring.addr_desa_h = addr_desa_h;
+       rx_ring->bd_ring.addr = *rxch_addr;
        rx_ring->bd_ring.wp = 0;
        rx_ring->bd_ring.rp = 0;
        rx_ring->buf_sz = buf_sz;
@@ -2937,6 +2960,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        info = (const struct rtw89_driver_info *)id->driver_data;
        rtwdev->chip = info->chip;
+       rtwdev->pci_info = info->bus.pci;
 
        ret = rtw89_core_init(rtwdev);
        if (ret) {
index 7f1ee1544688df97ae634af59290104b2b0e978f..b84acd0d0582ac5f25c35307916e4f2f0abe5335 100644 (file)
 #define R_AX_CH10_TXBD_IDX     0x137C /* Management Queue band 1 */
 #define R_AX_CH11_TXBD_IDX     0x1380 /* HI Queue band 1 */
 #define R_AX_CH12_TXBD_IDX     0x1080 /* FWCMD Queue */
+#define R_AX_CH10_TXBD_IDX_V1  0x11D0
+#define R_AX_CH11_TXBD_IDX_V1  0x11D4
+#define R_AX_RXQ_RXBD_IDX_V1   0x1218
+#define R_AX_RPQ_RXBD_IDX_V1   0x121C
 #define TXBD_HW_IDX_MASK       GENMASK(27, 16)
 #define TXBD_HOST_IDX_MASK     GENMASK(11, 0)
 
 #define R_AX_RXQ_RXBD_DESA_H   0x1104
 #define R_AX_RPQ_RXBD_DESA_L   0x1108
 #define R_AX_RPQ_RXBD_DESA_H   0x110C
+#define R_AX_RXQ_RXBD_DESA_L_V1 0x1220
+#define R_AX_RXQ_RXBD_DESA_H_V1 0x1224
+#define R_AX_RPQ_RXBD_DESA_L_V1 0x1228
+#define R_AX_RPQ_RXBD_DESA_H_V1 0x122C
+#define R_AX_ACH0_TXBD_DESA_L_V1 0x1230
+#define R_AX_ACH0_TXBD_DESA_H_V1 0x1234
+#define R_AX_ACH1_TXBD_DESA_L_V1 0x1238
+#define R_AX_ACH1_TXBD_DESA_H_V1 0x123C
+#define R_AX_ACH2_TXBD_DESA_L_V1 0x1240
+#define R_AX_ACH2_TXBD_DESA_H_V1 0x1244
+#define R_AX_ACH3_TXBD_DESA_L_V1 0x1248
+#define R_AX_ACH3_TXBD_DESA_H_V1 0x124C
+#define R_AX_ACH4_TXBD_DESA_L_V1 0x1250
+#define R_AX_ACH4_TXBD_DESA_H_V1 0x1254
+#define R_AX_ACH5_TXBD_DESA_L_V1 0x1258
+#define R_AX_ACH5_TXBD_DESA_H_V1 0x125C
+#define R_AX_ACH6_TXBD_DESA_L_V1 0x1260
+#define R_AX_ACH6_TXBD_DESA_H_V1 0x1264
+#define R_AX_ACH7_TXBD_DESA_L_V1 0x1268
+#define R_AX_ACH7_TXBD_DESA_H_V1 0x126C
+#define R_AX_CH8_TXBD_DESA_L_V1 0x1270
+#define R_AX_CH8_TXBD_DESA_H_V1 0x1274
+#define R_AX_CH9_TXBD_DESA_L_V1 0x1278
+#define R_AX_CH9_TXBD_DESA_H_V1 0x127C
+#define R_AX_CH12_TXBD_DESA_L_V1 0x1280
+#define R_AX_CH12_TXBD_DESA_H_V1 0x1284
+#define R_AX_CH10_TXBD_DESA_L_V1 0x1458
+#define R_AX_CH10_TXBD_DESA_H_V1 0x145C
+#define R_AX_CH11_TXBD_DESA_L_V1 0x1460
+#define R_AX_CH11_TXBD_DESA_H_V1 0x1464
 #define B_AX_DESC_NUM_MSK              GENMASK(11, 0)
 
 #define R_AX_RXQ_RXBD_NUM      0x1020
 #define R_AX_CH10_TXBD_NUM     0x1338
 #define R_AX_CH11_TXBD_NUM     0x133A
 #define R_AX_CH12_TXBD_NUM     0x1038
+#define R_AX_RXQ_RXBD_NUM_V1   0x1210
+#define R_AX_RPQ_RXBD_NUM_V1   0x1212
+#define R_AX_CH10_TXBD_NUM_V1  0x1438
+#define R_AX_CH11_TXBD_NUM_V1  0x143A
 
 #define R_AX_ACH0_BDRAM_CTRL   0x1200
 #define R_AX_ACH1_BDRAM_CTRL   0x1204
 #define R_AX_CH10_BDRAM_CTRL   0x1320
 #define R_AX_CH11_BDRAM_CTRL   0x1324
 #define R_AX_CH12_BDRAM_CTRL   0x1228
+#define R_AX_ACH0_BDRAM_CTRL_V1 0x1300
+#define R_AX_ACH1_BDRAM_CTRL_V1 0x1304
+#define R_AX_ACH2_BDRAM_CTRL_V1 0x1308
+#define R_AX_ACH3_BDRAM_CTRL_V1 0x130C
+#define R_AX_ACH4_BDRAM_CTRL_V1 0x1310
+#define R_AX_ACH5_BDRAM_CTRL_V1 0x1314
+#define R_AX_ACH6_BDRAM_CTRL_V1 0x1318
+#define R_AX_ACH7_BDRAM_CTRL_V1 0x131C
+#define R_AX_CH8_BDRAM_CTRL_V1 0x1320
+#define R_AX_CH9_BDRAM_CTRL_V1 0x1324
+#define R_AX_CH12_BDRAM_CTRL_V1 0x1328
+#define R_AX_CH10_BDRAM_CTRL_V1 0x1420
+#define R_AX_CH11_BDRAM_CTRL_V1 0x1424
 #define BDRAM_SIDX_MASK                GENMASK(7, 0)
 #define BDRAM_MAX_MASK         GENMASK(15, 8)
 #define BDRAM_MIN_MASK         GENMASK(23, 16)
@@ -382,6 +433,23 @@ enum rtw89_pcie_clkdly_hw {
        PCIE_CLKDLY_HW_200US = 0x5,
 };
 
+struct rtw89_pci_ch_dma_addr {
+       u32 num;
+       u32 idx;
+       u32 bdram;
+       u32 desa_l;
+       u32 desa_h;
+};
+
+struct rtw89_pci_ch_dma_addr_set {
+       struct rtw89_pci_ch_dma_addr tx[RTW89_TXCH_NUM];
+       struct rtw89_pci_ch_dma_addr rx[RTW89_RXCH_NUM];
+};
+
+struct rtw89_pci_info {
+       const struct rtw89_pci_ch_dma_addr_set *dma_addr_set;
+};
+
 struct rtw89_pci_bd_ram {
        u8 start_idx;
        u8 max_num;
@@ -469,11 +537,7 @@ struct rtw89_pci_dma_ring {
        u8 desc_size;
        dma_addr_t dma;
 
-       u32 addr_num;
-       u32 addr_idx;
-       u32 addr_bdram;
-       u32 addr_desa_l;
-       u32 addr_desa_h;
+       struct rtw89_pci_ch_dma_addr addr;
 
        u32 len;
        u32 wp; /* host idx */
@@ -626,6 +690,8 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
 }
 
 extern const struct dev_pm_ops rtw89_pm_ops;
+extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
+extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
 
 struct pci_device_id;
 
index 62dca0888d88ddc46e3d3fc5fa761ad56d0f68c1..ec5e70b866009e0083bb92e4280d6d88d4968d4e 100644 (file)
@@ -8,16 +8,36 @@
 #define R_AX_SYS_WL_EFUSE_CTRL 0x000A
 #define B_AX_AUTOLOAD_SUS BIT(5)
 
+#define R_AX_SYS_ISO_CTRL 0x0000
+#define B_AX_PWC_EV2EF_MASK GENMASK(15, 14)
+#define B_AX_PWC_EV2EF_B15 BIT(15)
+#define B_AX_PWC_EV2EF_B14 BIT(14)
+#define B_AX_ISO_EB2CORE BIT(8)
+
 #define R_AX_SYS_FUNC_EN 0x0002
 #define B_AX_FEN_BB_GLB_RSTN BIT(1)
 #define B_AX_FEN_BBRSTB BIT(0)
 
 #define R_AX_SYS_PW_CTRL 0x0004
+#define B_AX_XTAL_OFF_A_DIE BIT(22)
+#define B_AX_DIS_WLBT_PDNSUSEN_SOPC BIT(18)
+#define B_AX_RDY_SYSPWR BIT(17)
+#define B_AX_EN_WLON BIT(16)
+#define B_AX_APDM_HPDN BIT(15)
 #define B_AX_PSUS_OFF_CAPC_EN BIT(14)
+#define B_AX_AFSM_PCIE_SUS_EN BIT(12)
+#define B_AX_AFSM_WLSUS_EN BIT(11)
+#define B_AX_APFM_SWLPS BIT(10)
+#define B_AX_APFM_OFFMAC BIT(9)
+#define B_AX_APFN_ONMAC BIT(8)
 
 #define R_AX_SYS_CLK_CTRL 0x0008
 #define B_AX_CPU_CLK_EN BIT(14)
 
+#define R_AX_SYS_ADIE_PAD_PWR_CTRL 0x0018
+#define B_AX_SYM_PADPDN_WL_PTA_1P3 BIT(6)
+#define B_AX_SYM_PADPDN_WL_RFC_1P3 BIT(5)
+
 #define R_AX_RSV_CTRL 0x001C
 #define B_AX_R_DIS_PRST BIT(6)
 #define B_AX_WLOCK_1C_BIT6 BIT(5)
 #define B_AX_EF_ADDR_MASK GENMASK(26, 16)
 #define B_AX_EF_DATA_MASK GENMASK(15, 0)
 
+#define R_AX_EFUSE_CTRL_1_V1 0x0038
+#define B_AX_EF_ENT BIT(31)
+#define B_AX_EF_BURST BIT(19)
+#define B_AX_EF_TEST_SEL_MASK GENMASK(18, 16)
+#define B_AX_EF_TROW_EN BIT(15)
+#define B_AX_EF_ERR_FLAG BIT(14)
+#define B_AX_EF_DSB_EN BIT(11)
+#define B_AX_PCIE_CALIB_EN_V1 BIT(12)
+#define B_AX_WDT_WAKE_PCIE_EN BIT(10)
+#define B_AX_WDT_WAKE_USB_EN BIT(9)
+
 #define R_AX_GPIO_MUXCFG 0x0040
 #define B_AX_BOOT_MODE BIT(19)
 #define B_AX_WL_EECS_EXT_32K_SEL BIT(18)
 #define R_AX_SYS_SDIO_CTRL 0x0070
 #define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15)
 #define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14)
+#define B_AX_PCIE_CALIB_EN_V1 BIT(12)
 #define B_AX_PCIE_AUXCLK_GATE BIT(11)
 #define B_AX_LTE_MUX_CTRL_PATH BIT(26)
 
 #define R_AX_PLATFORM_ENABLE 0x0088
 #define B_AX_WCPU_EN BIT(1)
+#define B_AX_PLATFORM_EN BIT(0)
+
+#define R_AX_WLLPS_CTRL 0x0090
+#define B_AX_DIS_WLBT_LPSEN_LOPC BIT(1)
 
 #define R_AX_SCOREBOARD  0x00AC
 #define B_AX_TOGGLE BIT(31)
 #define R_AX_DBG_PORT_SEL 0x00C0
 #define B_AX_DEBUG_ST_MASK GENMASK(31, 0)
 
+#define R_AX_PMC_DBG_CTRL2 0x00CC
+#define B_AX_SYSON_DIS_PMCR_AX_WRMSK BIT(2)
+
 #define R_AX_SYS_CFG1 0x00F0
 #define B_AX_CHIP_VER_MASK GENMASK(15, 12)
 
 #define R_AX_SYS_STATUS1 0x00F4
 #define B_AX_SEL_0XC0_MASK GENMASK(17, 16)
+#define B_AX_PAD_HCI_SEL_V2_MASK GENMASK(5, 3)
+#define MAC_AX_HCI_SEL_SDIO_UART 0
+#define MAC_AX_HCI_SEL_MULTI_USB 1
+#define MAC_AX_HCI_SEL_PCIE_UART 2
+#define MAC_AX_HCI_SEL_PCIE_USB 3
+#define MAC_AX_HCI_SEL_MULTI_SDIO 4
 
 #define R_AX_HALT_H2C_CTRL 0x0160
 #define R_AX_HALT_H2C 0x0168
 #define R_AX_UDM2 0x01F8
 #define R_AX_UDM3 0x01FC
 
+#define R_AX_LDO_AON_CTRL0 0x0218
+#define B_AX_PD_REGU_L BIT(16)
+
+#define R_AX_WLAN_XTAL_SI_CTRL 0x0270
+#define B_AX_WL_XTAL_SI_CMD_POLL BIT(31)
+#define B_AX_BT_XTAL_SI_ERR_FLAG BIT(30)
+#define B_AX_WL_XTAL_GNT BIT(29)
+#define B_AX_BT_XTAL_GNT BIT(28)
+#define B_AX_WL_XTAL_SI_MODE_MASK GENMASK(25, 24)
+#define XTAL_SI_NORMAL_WRITE 0x00
+#define XTAL_SI_NORMAL_READ 0x01
+#define B_AX_WL_XTAL_SI_BITMASK_MASK GENMASK(23, 16)
+#define B_AX_WL_XTAL_SI_DATA_MASK GENMASK(15, 8)
+#define B_AX_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0)
+
 #define R_AX_XTAL_ON_CTRL0 0x0280
 #define B_AX_XTAL_SC_LPS BIT(31)
 #define B_AX_XTAL_SC_XO_MASK GENMASK(23, 17)
 
 #define R_AX_GPIO0_7_FUNC_SEL 0x02D0
 
+#define R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN 0x02E4
+#define B_AX_LED1_PULL_LOW_EN BIT(18)
+#define B_AX_EESK_PULL_LOW_EN BIT(17)
+#define B_AX_EECS_PULL_LOW_EN BIT(16)
+
 #define R_AX_WLRF_CTRL 0x02F0
 #define B_AX_WLRF1_CTRL_7 BIT(15)
 #define B_AX_WLRF1_CTRL_1 BIT(9)
 #define B_AX_ASFF_FULL_NO_STK BIT(1)
 #define B_AX_EN_STUCK_DBG BIT(0)
 
+#define R_AX_HCI_FC_CTRL_V1 0x1700
+#define R_AX_CH_PAGE_CTRL_V1 0x1704
+
+#define R_AX_ACH0_PAGE_CTRL_V1 0x1710
+#define R_AX_ACH1_PAGE_CTRL_V1 0x1714
+#define R_AX_ACH2_PAGE_CTRL_V1 0x1718
+#define R_AX_ACH3_PAGE_CTRL_V1 0x171C
+#define R_AX_ACH4_PAGE_CTRL_V1 0x1720
+#define R_AX_ACH5_PAGE_CTRL_V1 0x1724
+#define R_AX_ACH6_PAGE_CTRL_V1 0x1728
+#define R_AX_ACH7_PAGE_CTRL_V1 0x172C
+#define R_AX_CH8_PAGE_CTRL_V1 0x1730
+#define R_AX_CH9_PAGE_CTRL_V1 0x1734
+#define R_AX_CH10_PAGE_CTRL_V1 0x1738
+#define R_AX_CH11_PAGE_CTRL_V1 0x173C
+
+#define R_AX_ACH0_PAGE_INFO_V1 0x1750
+#define R_AX_ACH1_PAGE_INFO_V1 0x1754
+#define R_AX_ACH2_PAGE_INFO_V1 0x1758
+#define R_AX_ACH3_PAGE_INFO_V1 0x175C
+#define R_AX_ACH4_PAGE_INFO_V1 0x1760
+#define R_AX_ACH5_PAGE_INFO_V1 0x1764
+#define R_AX_ACH6_PAGE_INFO_V1 0x1768
+#define R_AX_ACH7_PAGE_INFO_V1 0x176C
+#define R_AX_CH8_PAGE_INFO_V1 0x1770
+#define R_AX_CH9_PAGE_INFO_V1 0x1774
+#define R_AX_CH10_PAGE_INFO_V1 0x1778
+#define R_AX_CH11_PAGE_INFO_V1 0x177C
+#define R_AX_CH12_PAGE_INFO_V1 0x1780
+
+#define R_AX_PUB_PAGE_INFO3_V1 0x178C
+#define R_AX_PUB_PAGE_CTRL1_V1 0x1790
+#define R_AX_PUB_PAGE_CTRL2_V1 0x1794
+#define R_AX_PUB_PAGE_INFO1_V1 0x1798
+#define R_AX_PUB_PAGE_INFO2_V1 0x179C
+#define R_AX_WP_PAGE_CTRL1_V1 0x17A0
+#define R_AX_WP_PAGE_CTRL2_V1 0x17A4
+#define R_AX_WP_PAGE_INFO1_V1 0x17A8
+
+#define R_AX_H2CREG_DATA0_V1 0x7140
+#define R_AX_H2CREG_DATA1_V1 0x7144
+#define R_AX_H2CREG_DATA2_V1 0x7148
+#define R_AX_H2CREG_DATA3_V1 0x714C
+#define R_AX_C2HREG_DATA0_V1 0x7150
+#define R_AX_C2HREG_DATA1_V1 0x7154
+#define R_AX_C2HREG_DATA2_V1 0x7158
+#define R_AX_C2HREG_DATA3_V1 0x715C
+#define R_AX_H2CREG_CTRL_V1 0x7160
+#define R_AX_C2HREG_CTRL_V1 0x7164
+
+#define R_AX_HCI_FUNC_EN_V1 0x7880
+
 #define R_AX_PHYREG_SET 0x8040
 #define PHYREG_SET_ALL_CYCLE 0x8
 
 #define B_AX_PKT_IN_EN BIT(20)
 #define B_AX_DLE_CPUIO_EN BIT(19)
 #define B_AX_DISPATCHER_EN BIT(18)
+#define B_AX_BBRPT_EN BIT(17)
 #define B_AX_MAC_SEC_EN BIT(16)
+#define B_AX_MAC_UN_EN BIT(15)
+#define B_AX_H_AXIDMA_EN BIT(14)
 
 #define R_AX_DMAC_CLK_EN 0x8404
 #define B_AX_WD_RLS_CLK_EN BIT(27)
 #define R_AX_PLE_QTA8_CFG 0x9060
 #define R_AX_PLE_QTA9_CFG 0x9064
 #define R_AX_PLE_QTA10_CFG 0x9068
+#define R_AX_PLE_QTA11_CFG 0x906C
 
 #define R_AX_PLE_INI_STATUS 0x9100
 #define B_AX_PLE_Q_MGN_INI_RDY BIT(1)
index a222e11de6acfb4cee1d6a776e190579c0c7a5a9..c429eeae1b56712d91a718f4ff384c1eb28effee 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include "coex.h"
+#include "fw.h"
 #include "mac.h"
 #include "phy.h"
 #include "reg.h"
@@ -376,6 +377,31 @@ static const struct rtw89_pwr_cfg * const pwr_off_seq_8852a[] = {
        rtw8852a_pwroff, NULL
 };
 
+static const u32 rtw8852a_h2c_regs[RTW89_H2CREG_MAX] = {
+       R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1,  R_AX_H2CREG_DATA2,
+       R_AX_H2CREG_DATA3
+};
+
+static const u32 rtw8852a_c2h_regs[RTW89_C2HREG_MAX] = {
+       R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2,
+       R_AX_C2HREG_DATA3
+};
+
+static const struct rtw89_page_regs rtw8852a_page_regs = {
+       .hci_fc_ctrl    = R_AX_HCI_FC_CTRL,
+       .ch_page_ctrl   = R_AX_CH_PAGE_CTRL,
+       .ach_page_ctrl  = R_AX_ACH0_PAGE_CTRL,
+       .ach_page_info  = R_AX_ACH0_PAGE_INFO,
+       .pub_page_info3 = R_AX_PUB_PAGE_INFO3,
+       .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1,
+       .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2,
+       .pub_page_info1 = R_AX_PUB_PAGE_INFO1,
+       .pub_page_info2 = R_AX_PUB_PAGE_INFO2,
+       .wp_page_ctrl1  = R_AX_WP_PAGE_CTRL1,
+       .wp_page_ctrl2  = R_AX_WP_PAGE_CTRL2,
+       .wp_page_info1  = R_AX_WP_PAGE_INFO1,
+};
+
 static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse,
                                    struct rtw8852a_efuse *map)
 {
@@ -1987,6 +2013,8 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
        .query_ppdu             = rtw8852a_query_ppdu,
        .bb_ctrl_btc_preagc     = rtw8852a_bb_ctrl_btc_preagc,
        .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset,
+       .pwr_on_func            = NULL,
+       .pwr_off_func           = NULL,
 
        .btc_set_rfe            = rtw8852a_btc_set_rfe,
        .btc_init_cfg           = rtw8852a_btc_init_cfg,
@@ -2035,6 +2063,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .physical_efuse_size    = 1216,
        .logical_efuse_size     = 1536,
        .limit_efuse_size       = 1152,
+       .dav_phy_efuse_size     = 0,
+       .dav_log_efuse_size     = 0,
        .phycap_addr            = 0x580,
        .phycap_size            = 128,
        .para_ver               = 0x05050864,
@@ -2055,6 +2085,12 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .ps_mode_supported      = BIT(RTW89_PS_MODE_RFOFF) |
                                  BIT(RTW89_PS_MODE_CLK_GATED) |
                                  BIT(RTW89_PS_MODE_PWR_GATED),
+       .hci_func_en_addr       = R_AX_HCI_FUNC_EN,
+       .h2c_ctrl_reg           = R_AX_H2CREG_CTRL,
+       .h2c_regs               = rtw8852a_h2c_regs,
+       .c2h_ctrl_reg           = R_AX_C2HREG_CTRL,
+       .c2h_regs               = rtw8852a_c2h_regs,
+       .page_regs              = &rtw8852a_page_regs,
 };
 EXPORT_SYMBOL(rtw8852a_chip_info);
 
index de93280e0f697b82c30f26cbc3d469e9067da392..48459aba441df140b3f9b91365bce7337493fd6c 100644 (file)
@@ -8,8 +8,15 @@
 #include "pci.h"
 #include "rtw8852a.h"
 
+static const struct rtw89_pci_info rtw8852a_pci_info = {
+       .dma_addr_set           = &rtw89_pci_ch_dma_addr_set,
+};
+
 static const struct rtw89_driver_info rtw89_8852ae_info = {
        .chip = &rtw8852a_chip_info,
+       .bus = {
+               .pci = &rtw8852a_pci_info,
+       },
 };
 
 static const struct pci_device_id rtw89_8852ae_id_table[] = {
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
new file mode 100644 (file)
index 0000000..35a9f40
--- /dev/null
@@ -0,0 +1,479 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2019-2022  Realtek Corporation
+ */
+
+#include "debug.h"
+#include "fw.h"
+#include "mac.h"
+#include "reg.h"
+#include "rtw8852c.h"
+
+static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
+       [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_wde_size19, &rtw89_ple_size19,
+                          &rtw89_wde_qt18, &rtw89_wde_qt18, &rtw89_ple_qt46,
+                          &rtw89_ple_qt47},
+       [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_wde_size18,
+                           &rtw89_ple_size18, &rtw89_wde_qt17, &rtw89_wde_qt17,
+                           &rtw89_ple_qt44, &rtw89_ple_qt45},
+       [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
+                              NULL},
+};
+
+static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
+       R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
+       R_AX_H2CREG_DATA3_V1
+};
+
+static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
+       R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1,
+       R_AX_C2HREG_DATA3_V1
+};
+
+static const struct rtw89_page_regs rtw8852c_page_regs = {
+       .hci_fc_ctrl    = R_AX_HCI_FC_CTRL_V1,
+       .ch_page_ctrl   = R_AX_CH_PAGE_CTRL_V1,
+       .ach_page_ctrl  = R_AX_ACH0_PAGE_CTRL_V1,
+       .ach_page_info  = R_AX_ACH0_PAGE_INFO_V1,
+       .pub_page_info3 = R_AX_PUB_PAGE_INFO3_V1,
+       .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1_V1,
+       .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2_V1,
+       .pub_page_info1 = R_AX_PUB_PAGE_INFO1_V1,
+       .pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1,
+       .wp_page_ctrl1  = R_AX_WP_PAGE_CTRL1_V1,
+       .wp_page_ctrl2  = R_AX_WP_PAGE_CTRL2_V1,
+       .wp_page_info1  = R_AX_WP_PAGE_INFO1_V1,
+};
+
+static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
+{
+       u32 val32;
+       u32 ret;
+
+       val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
+       if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
+               rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
+
+       rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
+                                                   B_AX_AFSM_PCIE_SUS_EN);
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
+       rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
+
+       ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
+                               1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+       if (ret)
+               return ret;
+
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
+
+       ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
+                               1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+       if (ret)
+               return ret;
+
+       rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+       rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+       rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+       rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+
+       rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
+
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
+       rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
+       rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN |
+                                                 B_AX_R_SYM_WLCMAC1_P3_PC_EN |
+                                                 B_AX_R_SYM_WLCMAC1_P2_PC_EN |
+                                                 B_AX_R_SYM_WLCMAC1_P1_PC_EN |
+                                                 B_AX_R_SYM_WLCMAC1_PC_EN);
+       rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
+
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
+                                     XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
+       if (ret)
+               return ret;
+
+       rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
+
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
+                                     XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
+                                     XTAL_SI_OFF_WEI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
+                                     XTAL_SI_OFF_EI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
+                                     XTAL_SI_PON_WEI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
+                                     XTAL_SI_PON_EI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
+       if (ret)
+               return ret;
+
+       rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+       rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
+
+       fsleep(1000);
+
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
+       rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+       rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
+                         B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
+                         B_AX_LED1_PULL_LOW_EN);
+
+       rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
+                         B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
+                         B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
+                         B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
+                         B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
+                         B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
+                         B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN);
+
+       rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
+                         B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
+                         B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN |
+                         B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
+                         B_AX_TMAC_EN | B_AX_RMAC_EN);
+
+       return 0;
+}
+
+static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
+{
+       u32 val32;
+       u32 ret;
+
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
+                                     XTAL_SI_RFC2RF);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
+                                     XTAL_SI_SRAM2RFC);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI);
+       if (ret)
+               return ret;
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI);
+       if (ret)
+               return ret;
+
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+       rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
+                         B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
+
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL);
+       if (ret)
+               return ret;
+
+       rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
+
+       ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL);
+       if (ret)
+               return ret;
+
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
+
+       ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
+                               1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+       if (ret)
+               return ret;
+
+       rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
+       rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
+
+       return 0;
+}
+
+static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
+                                    struct rtw8852c_efuse *map)
+{
+       ether_addr_copy(efuse->addr, map->e.mac_addr);
+       efuse->rfe_type = map->rfe_type;
+       efuse->xtal_cap = map->xtal_k;
+}
+
+static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
+                                       struct rtw8852c_efuse *map)
+{
+       struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+       struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
+       u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
+       u8 i, j;
+
+       tssi->thermal[RF_PATH_A] = map->path_a_therm;
+       tssi->thermal[RF_PATH_B] = map->path_b_therm;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
+                      sizeof(ofst[i]->cck_tssi));
+
+               for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
+                       rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                                   "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
+                                   i, j, tssi->tssi_cck[i][j]);
+
+               memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
+                      sizeof(ofst[i]->bw40_tssi));
+               memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
+                      ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
+               memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
+                      sizeof(tssi->tssi_6g_mcs[i]));
+
+               for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
+                       rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                                   "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
+                                   i, j, tssi->tssi_mcs[i][j]);
+       }
+}
+
+static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map)
+{
+       struct rtw89_efuse *efuse = &rtwdev->efuse;
+       struct rtw8852c_efuse *map;
+
+       map = (struct rtw8852c_efuse *)log_map;
+
+       efuse->country_code[0] = map->country_code[0];
+       efuse->country_code[1] = map->country_code[1];
+       rtw8852c_efuse_parsing_tssi(rtwdev, map);
+
+       switch (rtwdev->hci.type) {
+       case RTW89_HCI_TYPE_PCIE:
+               rtw8852c_e_efuse_parsing(efuse, map);
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
+       rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
+
+       return 0;
+}
+
+static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+       struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+       static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
+       static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
+       u32 addr = rtwdev->chip->phycap_addr;
+       bool pg = false;
+       u32 ofst;
+       u8 i, j;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
+                       /* addrs are in decreasing order */
+                       ofst = tssi_trim_addr[i] - addr - j;
+                       tssi->tssi_trim[i][j] = phycap_map[ofst];
+
+                       if (phycap_map[ofst] != 0xff)
+                               pg = true;
+               }
+
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
+                       /* addrs are in decreasing order */
+                       ofst = tssi_trim_addr_6g[i] - addr - j;
+                       tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
+
+                       if (phycap_map[ofst] != 0xff)
+                               pg = true;
+               }
+       }
+
+       if (!pg) {
+               memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
+               memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
+               rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                           "[TSSI][TRIM] no PG, set all trim info to 0\n");
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++)
+               for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
+                       rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+                                   "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
+                                   i, j, tssi->tssi_trim[i][j],
+                                   tssi_trim_addr[i] - j);
+}
+
+static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
+                                                u8 *phycap_map)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
+       u32 addr = rtwdev->chip->phycap_addr;
+       u8 i;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
+                           i, info->thermal_trim[i]);
+
+               if (info->thermal_trim[i] != 0xff)
+                       info->pg_thermal_trim = true;
+       }
+}
+
+static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
+{
+#define __thm_setting(raw)                             \
+({                                                     \
+       u8 __v = (raw);                                 \
+       ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1);       \
+})
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       u8 i, val;
+
+       if (!info->pg_thermal_trim) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] no PG, do nothing\n");
+
+               return;
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               val = __thm_setting(info->thermal_trim[i]);
+               rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
+                           i, val);
+       }
+#undef __thm_setting
+}
+
+static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
+                                                u8 *phycap_map)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
+       u32 addr = rtwdev->chip->phycap_addr;
+       u8 i;
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
+                           i, info->pa_bias_trim[i]);
+
+               if (info->pa_bias_trim[i] != 0xff)
+                       info->pg_pa_bias_trim = true;
+       }
+}
+
+static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+       u8 pabias_2g, pabias_5g;
+       u8 i;
+
+       if (!info->pg_pa_bias_trim) {
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] no PG, do nothing\n");
+
+               return;
+       }
+
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
+               pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
+
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
+                           i, pabias_2g, pabias_5g);
+
+               rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
+               rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
+       }
+}
+
+static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+       rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
+       rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
+       rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
+
+       return 0;
+}
+
+static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
+{
+       rtw8852c_thermal_trim(rtwdev);
+       rtw8852c_pa_bias_trim(rtwdev);
+}
+
+static const struct rtw89_chip_ops rtw8852c_chip_ops = {
+       .read_efuse             = rtw8852c_read_efuse,
+       .read_phycap            = rtw8852c_read_phycap,
+       .power_trim             = rtw8852c_power_trim,
+       .pwr_on_func            = rtw8852c_pwr_on_func,
+       .pwr_off_func           = rtw8852c_pwr_off_func,
+};
+
+const struct rtw89_chip_info rtw8852c_chip_info = {
+       .chip_id                = RTL8852C,
+       .ops                    = &rtw8852c_chip_ops,
+       .fw_name                = "rtw89/rtw8852c_fw.bin",
+       .dle_mem                = rtw8852c_dle_mem_pcie,
+       .pwr_on_seq             = NULL,
+       .pwr_off_seq            = NULL,
+       .sec_ctrl_efuse_size    = 4,
+       .physical_efuse_size    = 1216,
+       .logical_efuse_size     = 2048,
+       .limit_efuse_size       = 1280,
+       .dav_phy_efuse_size     = 96,
+       .dav_log_efuse_size     = 16,
+       .phycap_addr            = 0x590,
+       .phycap_size            = 0x60,
+       .hci_func_en_addr       = R_AX_HCI_FUNC_EN_V1,
+       .h2c_ctrl_reg           = R_AX_H2CREG_CTRL_V1,
+       .h2c_regs               = rtw8852c_h2c_regs,
+       .c2h_ctrl_reg           = R_AX_C2HREG_CTRL_V1,
+       .c2h_regs               = rtw8852c_c2h_regs,
+       .page_regs              = &rtw8852c_page_regs,
+};
+EXPORT_SYMBOL(rtw8852c_chip_info);
+
+MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h
new file mode 100644 (file)
index 0000000..d059471
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2019-2022  Realtek Corporation
+ */
+
+#ifndef __RTW89_8852C_H__
+#define __RTW89_8852C_H__
+
+#include "core.h"
+
+#define RF_PATH_NUM_8852C 2
+
+struct rtw8852c_u_efuse {
+       u8 rsvd[0x38];
+       u8 mac_addr[ETH_ALEN];
+};
+
+struct rtw8852c_e_efuse {
+       u8 mac_addr[ETH_ALEN];
+};
+
+struct rtw8852c_tssi_offset {
+       u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
+       u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
+       u8 rsvd[7];
+       u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
+} __packed;
+
+struct rtw8852c_efuse {
+       u8 rsvd[0x210];
+       struct rtw8852c_tssi_offset path_a_tssi;
+       u8 rsvd1[10];
+       struct rtw8852c_tssi_offset path_b_tssi;
+       u8 rsvd2[94];
+       u8 channel_plan;
+       u8 xtal_k;
+       u8 rsvd3;
+       u8 iqk_lck;
+       u8 rsvd4[5];
+       u8 reg_setting:2;
+       u8 tx_diversity:1;
+       u8 rx_diversity:2;
+       u8 ac_mode:1;
+       u8 module_type:2;
+       u8 rsvd5;
+       u8 shared_ant:1;
+       u8 coex_type:3;
+       u8 ant_iso:1;
+       u8 radio_on_off:1;
+       u8 rsvd6:2;
+       u8 eeprom_version;
+       u8 customer_id;
+       u8 tx_bb_swing_2g;
+       u8 tx_bb_swing_5g;
+       u8 tx_cali_pwr_trk_mode;
+       u8 trx_path_selection;
+       u8 rfe_type;
+       u8 country_code[2];
+       u8 rsvd7[3];
+       u8 path_a_therm;
+       u8 path_b_therm;
+       u8 rsvd8[46];
+       u8 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM];
+       u8 rsvd9[10];
+       u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM];
+       u8 rsvd10[110];
+       u8 channel_plan_6g;
+       u8 rsvd11[71];
+       union {
+               struct rtw8852c_u_efuse u;
+               struct rtw8852c_e_efuse e;
+       };
+} __packed;
+
+extern const struct rtw89_chip_info rtw8852c_chip_info;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
new file mode 100644 (file)
index 0000000..e713705
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2020-2022  Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "pci.h"
+#include "reg.h"
+#include "rtw8852c.h"
+
+static const struct rtw89_pci_info rtw8852c_pci_info = {
+       .dma_addr_set           = &rtw89_pci_ch_dma_addr_set_v1,
+};
+
+static const struct rtw89_driver_info rtw89_8852ce_info = {
+       .chip = &rtw8852c_chip_info,
+       .bus = {
+               .pci = &rtw8852c_pci_info,
+       },
+};
+
+static const struct pci_device_id rtw89_8852ce_id_table[] = {
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xc852),
+               .driver_data = (kernel_ulong_t)&rtw89_8852ce_info,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(pci, rtw89_8852ce_id_table);
+
+static struct pci_driver rtw89_8852ce_driver = {
+       .name           = "rtw89_8852ce",
+       .id_table       = rtw89_8852ce_id_table,
+       .probe          = rtw89_pci_probe,
+       .remove         = rtw89_pci_remove,
+       .driver.pm      = &rtw89_pm_ops,
+};
+module_pci_driver(rtw89_8852ce_driver);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CE driver");
+MODULE_LICENSE("Dual BSD/GPL");
index 12952b1c29dfc82b5a118b754369e08196607f2d..e06da4b3b0d46051de9557a9dc29bfc8788f9b5c 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <net/mac80211.h>
 #include <linux/sched.h>
+#include <linux/jiffies.h>
 #include "queue.h"
 #include "cw1200.h"
 #include "debug.h"
@@ -94,7 +95,7 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue,
        bool wakeup_stats = false;
 
        list_for_each_entry_safe(item, tmp, &queue->queue, head) {
-               if (jiffies - item->queue_timestamp < queue->ttl)
+               if (time_is_after_jiffies(item->queue_timestamp + queue->ttl))
                        break;
                --queue->num_queued;
                --queue->link_map_cache[item->txpriv.link_id];