diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/core.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/core.h | 38 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/efuse.c | 160 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/fw.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac.c | 184 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac.h | 48 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/pci.c | 200 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/pci.h | 76 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/reg.h | 121 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852a.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852c.c | 479 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852c.h | 76 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/st/cw1200/queue.c | 3 |
17 files changed, 1353 insertions, 175 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index b2fb9fcacdc9..f0ad1e23f3c8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -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 diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c index 04735da11168..da54e51badd3 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c @@ -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: diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index a93555b0a2bf..bcefc968576e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -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 diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index d203e4c5727d..483cf45fbcc9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -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; diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c index c0b80f3da56c..7bd4f8558e03 100644 --- a/drivers/net/wireless/realtek/rtw89/efuse.c +++ b/drivers/net/wireless/realtek/rtw89/efuse.c @@ -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; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 97224483f618..2fe091cc12c0 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -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) - diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 9a91b408cd28..8fbdfd983cc5 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -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 = ¶m->pub_cfg; struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->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 = ¶m->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 = ¶m->pub_cfg; const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->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; +} diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 5c7a9d784265..2f707c817fa7 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -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 diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 6481085b958e..e79bfc335b44 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -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) { diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 7f1ee1544688..b84acd0d0582 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -130,6 +130,10 @@ #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) @@ -163,6 +167,36 @@ #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 @@ -180,6 +214,10 @@ #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 @@ -194,6 +232,19 @@ #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; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 62dca0888d88..ec5e70b86600 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -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) @@ -41,6 +61,17 @@ #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) @@ -72,11 +103,16 @@ #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) @@ -89,11 +125,20 @@ #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 @@ -131,6 +176,21 @@ #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) @@ -139,6 +199,11 @@ #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) @@ -163,6 +228,58 @@ #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 @@ -208,7 +325,10 @@ #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) @@ -445,6 +565,7 @@ #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) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index a222e11de6ac..c429eeae1b56 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -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); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c index de93280e0f69..48459aba441d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c @@ -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 index 000000000000..35a9f40af3c9 --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -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 index 000000000000..d0594716040b --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h @@ -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 index 000000000000..e71370585b4d --- /dev/null +++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c @@ -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"); diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c index 12952b1c29df..e06da4b3b0d4 100644 --- a/drivers/net/wireless/st/cw1200/queue.c +++ b/drivers/net/wireless/st/cw1200/queue.c @@ -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]; |