2022-03-07 14:04:45 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
|
|
/* Copyright(c) 2019-2022 Realtek Corporation
|
|
|
|
*/
|
|
|
|
|
2023-09-08 11:11:40 +08:00
|
|
|
#include "chan.h"
|
2022-04-08 08:13:49 +08:00
|
|
|
#include "coex.h"
|
2022-03-07 14:04:56 +08:00
|
|
|
#include "debug.h"
|
2022-03-07 14:04:52 +08:00
|
|
|
#include "fw.h"
|
2022-03-07 14:04:50 +08:00
|
|
|
#include "mac.h"
|
2022-03-17 13:55:35 +08:00
|
|
|
#include "phy.h"
|
2022-03-07 14:04:50 +08:00
|
|
|
#include "reg.h"
|
2022-03-07 14:04:45 +08:00
|
|
|
#include "rtw8852c.h"
|
2022-04-14 14:20:25 +08:00
|
|
|
#include "rtw8852c_rfk.h"
|
2022-04-14 14:20:15 +08:00
|
|
|
#include "rtw8852c_table.h"
|
2025-03-06 10:11:41 +08:00
|
|
|
#include "sar.h"
|
2022-04-14 14:20:25 +08:00
|
|
|
#include "util.h"
|
2022-03-07 14:04:45 +08:00
|
|
|
|
2025-04-16 16:12:38 +08:00
|
|
|
#define RTW8852C_FW_FORMAT_MAX 2
|
2023-03-20 21:06:06 +08:00
|
|
|
#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw"
|
|
|
|
#define RTW8852C_MODULE_FIRMWARE \
|
2024-08-05 17:00:24 +08:00
|
|
|
RTW8852C_FW_BASENAME "-" __stringify(RTW8852C_FW_FORMAT_MAX) ".bin"
|
2023-03-20 21:06:06 +08:00
|
|
|
|
2022-04-14 14:20:22 +08:00
|
|
|
static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = {
|
|
|
|
{13, 1614, grp_0}, /* ACH 0 */
|
|
|
|
{13, 1614, grp_0}, /* ACH 1 */
|
|
|
|
{13, 1614, grp_0}, /* ACH 2 */
|
|
|
|
{13, 1614, grp_0}, /* ACH 3 */
|
|
|
|
{13, 1614, grp_1}, /* ACH 4 */
|
|
|
|
{13, 1614, grp_1}, /* ACH 5 */
|
|
|
|
{13, 1614, grp_1}, /* ACH 6 */
|
|
|
|
{13, 1614, grp_1}, /* ACH 7 */
|
|
|
|
{13, 1614, grp_0}, /* B0MGQ */
|
|
|
|
{13, 1614, grp_0}, /* B0HIQ */
|
|
|
|
{13, 1614, grp_1}, /* B1MGQ */
|
|
|
|
{13, 1614, grp_1}, /* B1HIQ */
|
|
|
|
{40, 0, 0} /* FWCMDQ */
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_pcie = {
|
|
|
|
1614, /* Group 0 */
|
|
|
|
1614, /* Group 1 */
|
|
|
|
3228, /* Public Max */
|
|
|
|
0 /* WP threshold */
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = {
|
|
|
|
[RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_pcie, &rtw8852c_hfc_pubcfg_pcie,
|
|
|
|
&rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH},
|
|
|
|
[RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie,
|
|
|
|
RTW89_HCIFC_POH},
|
|
|
|
[RTW89_QTA_INVALID] = {NULL},
|
|
|
|
};
|
|
|
|
|
2022-03-07 14:04:54 +08:00
|
|
|
static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
|
2022-03-15 09:55:22 +08:00
|
|
|
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19,
|
|
|
|
&rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18,
|
|
|
|
&rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46,
|
|
|
|
&rtw89_mac_size.ple_qt47},
|
|
|
|
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18,
|
|
|
|
&rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17,
|
|
|
|
&rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44,
|
|
|
|
&rtw89_mac_size.ple_qt45},
|
2022-03-07 14:04:54 +08:00
|
|
|
[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
|
|
|
|
NULL},
|
|
|
|
};
|
|
|
|
|
2022-03-07 14:04:52 +08:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2024-06-20 13:58:20 +08:00
|
|
|
static const u32 rtw8852c_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
|
|
|
|
R_AX_C2HREG_DATA3_V1 + 3, R_AX_DBG_WOW,
|
|
|
|
};
|
|
|
|
|
2022-03-07 14:04:53 +08:00
|
|
|
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,
|
|
|
|
};
|
|
|
|
|
2022-03-17 13:55:32 +08:00
|
|
|
static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
|
|
|
|
R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
|
|
|
|
};
|
|
|
|
|
2022-04-08 08:13:42 +08:00
|
|
|
static const struct rtw89_imr_info rtw8852c_imr_info = {
|
|
|
|
.wdrls_imr_set = B_AX_WDRLS_IMR_SET_V1,
|
|
|
|
.wsec_imr_reg = R_AX_SEC_ERROR_FLAG_IMR,
|
|
|
|
.wsec_imr_set = B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR,
|
|
|
|
.mpdu_tx_imr_set = B_AX_MPDU_TX_IMR_SET_V1,
|
|
|
|
.mpdu_rx_imr_set = B_AX_MPDU_RX_IMR_SET_V1,
|
|
|
|
.sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET,
|
|
|
|
.txpktctl_imr_b0_reg = R_AX_TXPKTCTL_B0_ERRFLAG_IMR,
|
|
|
|
.txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR_V1,
|
|
|
|
.txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET_V1,
|
|
|
|
.txpktctl_imr_b1_reg = R_AX_TXPKTCTL_B1_ERRFLAG_IMR,
|
|
|
|
.txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR_V1,
|
|
|
|
.txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET_V1,
|
|
|
|
.wde_imr_clr = B_AX_WDE_IMR_CLR_V1,
|
|
|
|
.wde_imr_set = B_AX_WDE_IMR_SET_V1,
|
|
|
|
.ple_imr_clr = B_AX_PLE_IMR_CLR_V1,
|
|
|
|
.ple_imr_set = B_AX_PLE_IMR_SET_V1,
|
|
|
|
.host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR_V1,
|
|
|
|
.host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V1,
|
|
|
|
.cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR_V1,
|
|
|
|
.cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET_V1,
|
|
|
|
.other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR_V1,
|
|
|
|
.other_disp_imr_set = B_AX_OTHER_DISP_IMR_SET_V1,
|
2022-09-27 14:26:09 +08:00
|
|
|
.bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR,
|
2022-04-08 08:13:42 +08:00
|
|
|
.bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR,
|
|
|
|
.bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1,
|
|
|
|
.bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR,
|
2022-04-08 08:13:43 +08:00
|
|
|
.ptcl_imr_clr = B_AX_PTCL_IMR_CLR_V1,
|
|
|
|
.ptcl_imr_set = B_AX_PTCL_IMR_SET_V1,
|
|
|
|
.cdma_imr_0_reg = R_AX_RX_ERR_FLAG_IMR,
|
|
|
|
.cdma_imr_0_clr = B_AX_RX_ERR_IMR_CLR_V1,
|
|
|
|
.cdma_imr_0_set = B_AX_RX_ERR_IMR_SET_V1,
|
|
|
|
.cdma_imr_1_reg = R_AX_TX_ERR_FLAG_IMR,
|
|
|
|
.cdma_imr_1_clr = B_AX_TX_ERR_IMR_CLR_V1,
|
|
|
|
.cdma_imr_1_set = B_AX_TX_ERR_IMR_SET_V1,
|
|
|
|
.phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR_V1,
|
|
|
|
.phy_intf_imr_clr = B_AX_PHYINFO_IMR_CLR_V1,
|
|
|
|
.phy_intf_imr_set = B_AX_PHYINFO_IMR_SET_V1,
|
|
|
|
.rmac_imr_reg = R_AX_RX_ERR_IMR,
|
|
|
|
.rmac_imr_clr = B_AX_RMAC_IMR_CLR_V1,
|
|
|
|
.rmac_imr_set = B_AX_RMAC_IMR_SET_V1,
|
|
|
|
.tmac_imr_reg = R_AX_TRXPTCL_ERROR_INDICA_MASK,
|
|
|
|
.tmac_imr_clr = B_AX_TMAC_IMR_CLR_V1,
|
|
|
|
.tmac_imr_set = B_AX_TMAC_IMR_SET_V1,
|
2022-04-08 08:13:42 +08:00
|
|
|
};
|
|
|
|
|
2022-09-08 13:12:53 +08:00
|
|
|
static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = {
|
|
|
|
.ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0},
|
|
|
|
.rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2},
|
|
|
|
};
|
|
|
|
|
2024-07-24 13:26:24 +08:00
|
|
|
static const struct rtw89_rfkill_regs rtw8852c_rfkill_regs = {
|
|
|
|
.pinmux = {R_AX_GPIO8_15_FUNC_SEL,
|
|
|
|
B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
|
|
|
|
0xf},
|
|
|
|
.mode = {R_AX_GPIO_EXT_CTRL + 2,
|
|
|
|
(B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
|
|
|
|
0x0},
|
|
|
|
};
|
|
|
|
|
2022-09-08 13:12:49 +08:00
|
|
|
static const struct rtw89_dig_regs rtw8852c_dig_regs = {
|
|
|
|
.seg0_pd_reg = R_SEG0R_PD,
|
|
|
|
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
|
|
|
|
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
|
2023-08-22 20:58:22 +08:00
|
|
|
.bmode_pd_reg = R_BMODE_PDTH_EN_V1,
|
|
|
|
.bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
|
|
|
|
.bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
|
|
|
|
.bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
|
2022-09-08 13:12:49 +08:00
|
|
|
.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
|
|
|
|
.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
|
|
|
|
.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
|
|
|
|
.p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1},
|
|
|
|
.p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1},
|
|
|
|
.p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1},
|
|
|
|
.p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V1,
|
|
|
|
B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
|
|
|
|
.p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V1,
|
|
|
|
B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
|
|
|
|
.p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V1,
|
|
|
|
B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
|
|
|
|
.p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V1,
|
|
|
|
B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
|
|
|
|
};
|
|
|
|
|
2023-11-22 14:04:56 +08:00
|
|
|
static const struct rtw89_edcca_regs rtw8852c_edcca_regs = {
|
|
|
|
.edcca_level = R_SEG0R_EDCCA_LVL,
|
|
|
|
.edcca_mask = B_EDCCA_LVL_MSK0,
|
|
|
|
.edcca_p_mask = B_EDCCA_LVL_MSK1,
|
|
|
|
.ppdu_level = R_SEG0R_EDCCA_LVL,
|
|
|
|
.ppdu_mask = B_EDCCA_LVL_MSK3,
|
2025-01-17 15:28:27 +08:00
|
|
|
.p = {{
|
|
|
|
.rpt_a = R_EDCCA_RPT_A,
|
|
|
|
.rpt_b = R_EDCCA_RPT_B,
|
|
|
|
.rpt_sel = R_EDCCA_RPT_SEL,
|
|
|
|
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
|
|
|
|
}, {
|
|
|
|
.rpt_a = R_EDCCA_RPT_P1_A,
|
|
|
|
.rpt_b = R_EDCCA_RPT_P1_B,
|
|
|
|
.rpt_sel = R_EDCCA_RPT_SEL,
|
|
|
|
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
|
|
|
|
}},
|
2023-11-22 14:04:56 +08:00
|
|
|
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
|
|
|
|
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
|
|
|
|
};
|
|
|
|
|
2023-10-16 14:51:11 +08:00
|
|
|
static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
|
|
|
|
enum rtw89_phy_idx phy_idx);
|
|
|
|
|
2022-09-08 13:12:52 +08:00
|
|
|
static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
|
|
|
|
enum rtw89_mac_idx mac_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
2022-03-07 14:04:50 +08:00
|
|
|
static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
u32 val32;
|
2024-10-09 08:43:00 +08:00
|
|
|
int ret;
|
2022-03-07 14:04:50 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2024-04-26 14:12:00 +08:00
|
|
|
rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
|
|
|
|
B_AX_OCP_L1_MASK, 0x7);
|
|
|
|
|
2022-03-07 14:04:50 +08:00
|
|
|
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;
|
2024-04-26 14:12:00 +08:00
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0x10, XTAL_SI_LDO_LPS);
|
2022-03-07 14:04:50 +08:00
|
|
|
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);
|
|
|
|
|
2022-09-30 21:44:16 +08:00
|
|
|
rtw89_write32_mask(rtwdev, R_AX_LED1_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK,
|
|
|
|
PINMUX_EESK_FUNC_SEL_BT_LOG);
|
|
|
|
|
2022-03-07 14:04:50 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
u32 val32;
|
2024-10-09 08:43:00 +08:00
|
|
|
int ret;
|
2022-03-07 14:04:50 +08:00
|
|
|
|
|
|
|
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);
|
2024-04-26 14:11:59 +08:00
|
|
|
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
2022-03-07 14:04:50 +08:00
|
|
|
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;
|
|
|
|
|
2024-04-26 14:12:00 +08:00
|
|
|
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
|
2022-03-07 14:04:50 +08:00
|
|
|
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
|
2024-04-26 14:12:00 +08:00
|
|
|
rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ);
|
|
|
|
rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
|
|
|
|
B_AX_REG_ZCDC_H_MASK, 0x3);
|
2022-03-07 14:04:50 +08:00
|
|
|
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-03-07 14:04:57 +08:00
|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:21 +08:00
|
|
|
static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low)
|
|
|
|
{
|
|
|
|
if (high)
|
|
|
|
*high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), 3);
|
|
|
|
if (low)
|
|
|
|
*low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3);
|
|
|
|
|
|
|
|
return data != 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
|
|
|
|
struct rtw8852c_efuse *map)
|
|
|
|
{
|
|
|
|
struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
|
|
|
|
bool valid = false;
|
|
|
|
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_2g_cck,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_5g_low,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_5g_mid,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_5g_high,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]);
|
2023-11-17 10:40:27 +08:00
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_l0,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_l1,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_m0,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_m1,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_h0,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_h1,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_uh0,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0]);
|
|
|
|
valid |= _decode_efuse_gain(map->rx_gain_6g_uh1,
|
|
|
|
&gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1],
|
|
|
|
&gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1]);
|
2022-04-14 14:20:21 +08:00
|
|
|
|
|
|
|
gain->offset_valid = valid;
|
|
|
|
}
|
|
|
|
|
wifi: rtw89: mac: add to access efuse for WiFi 7 chips
MAC address, hardware type, calibration values and etc are stored in efuse,
so we read them at probe stage and use them as capabilities to register
hardware.
There are two physical efuse -- one is the main efuse for digital hardware
part, and the other is for analog part. Because they are very similar, we
only describe the main efuse below.
The main efuse is split into two regions -- one is for logic map, and the
other is for physical map. For both regions, we use the same method to read
data, but need additional parser to get logic map. To allow reading
operation, we need to convert power state to active, and turn to idle state
after reading.
For WiFi 7 chips, we introduce efuse blocks to define feature group easier,
and these blocks are discontinue. For example, RF block is from 0x1_0000 ~
0x1_0240, and the next block PCIE_SDIO is starting from 0x2_0000.
Comparing to old one used by WiFi 6 chips, there is only single one logic
map, it would be a little hard to add an new field to a group if we don't
reserve a room in advance.
The relationship between efuse, region and block is shown as below:
(logical map)
+------------+ +---------------+ +-----------------+
| main efuse | | region 1 | | block 0x1_0000~ |
| (digital) | |(to logcal map)| +-----------------+
| | | | => +-----------------+
| | => | | | block 0x2_0000~ |
| | | | +-----------------+
| | |---------------| :
| | | region 2 |
+------------+ +---------------+
+------------+ +-----------------+
| 2nd efuse | ======================> | block 0x7_0000~ |
| (analog) | +-----------------+
+------------+
The parser converting from raw data to logic map is to decode block page,
block page offset, and word_en bits. Each word_en bit indicates two
following bytes as data of logic map, so total four word_en bits can
represent eight bytes. Thus, block page offset is 8-byte alignment.
The layout of a tuple is shown as below
+--------+--------+--------+--------+--------+--------+
| fixed 3 byte header | | | |
| | | | |
| [19:17] block_page | | | ... |
| [16:4] block_page_offset| | | |
| [3:0] word_en | ^ | ^ | |
+----|---+--------+--------+---|----+----|---+--------+
| | |
+-------------------------+---------+
a word_en bit indicates two bytes as data
For example,
block_page = 0x3
block_page_offset = 0x80 (must 8-byte alignment)
word_en = 0x6 (b'0110; 0 means data is presented)
following 4 bytes = 34 56 78 90
Then,
0x3_0080 = 34 56
0x3_0086 = 78 90
A special block page is RTW89_EFUSE_BLOCK_ADIE (7) that uses different
but similar format, because its real efuse size is smaller than main efuse.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231117024029.113845-4-pkshih@realtek.com
2023-11-17 10:40:26 +08:00
|
|
|
static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
|
|
|
|
enum rtw89_efuse_block block)
|
2022-03-07 14:04:57 +08:00
|
|
|
{
|
|
|
|
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);
|
2022-04-14 14:20:21 +08:00
|
|
|
rtw8852c_efuse_parsing_gain_offset(rtwdev, map);
|
2022-03-07 14:04:57 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-03-07 14:04:56 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:24 +08:00
|
|
|
static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:24 +08:00
|
|
|
u8 mac_idx)
|
|
|
|
{
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
|
|
|
|
u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
|
|
|
|
u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
|
2022-04-14 14:20:24 +08:00
|
|
|
u8 txsc20 = 0, txsc40 = 0, txsc80 = 0;
|
|
|
|
u8 rf_mod_val = 0, chk_rate_mask = 0;
|
|
|
|
u32 txsc;
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
switch (chan->band_width) {
|
2022-04-14 14:20:24 +08:00
|
|
|
case RTW89_CHANNEL_WIDTH_160:
|
2022-08-09 18:49:41 +08:00
|
|
|
txsc80 = rtw89_phy_get_txsc(rtwdev, chan,
|
2022-04-14 14:20:24 +08:00
|
|
|
RTW89_CHANNEL_WIDTH_80);
|
|
|
|
fallthrough;
|
|
|
|
case RTW89_CHANNEL_WIDTH_80:
|
2022-08-09 18:49:41 +08:00
|
|
|
txsc40 = rtw89_phy_get_txsc(rtwdev, chan,
|
2022-04-14 14:20:24 +08:00
|
|
|
RTW89_CHANNEL_WIDTH_40);
|
|
|
|
fallthrough;
|
|
|
|
case RTW89_CHANNEL_WIDTH_40:
|
2022-08-09 18:49:41 +08:00
|
|
|
txsc20 = rtw89_phy_get_txsc(rtwdev, chan,
|
2022-04-14 14:20:24 +08:00
|
|
|
RTW89_CHANNEL_WIDTH_20);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
switch (chan->band_width) {
|
2022-04-14 14:20:24 +08:00
|
|
|
case RTW89_CHANNEL_WIDTH_160:
|
|
|
|
rf_mod_val = AX_WMAC_RFMOD_160M;
|
|
|
|
txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
|
|
|
|
FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) |
|
|
|
|
FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_80:
|
|
|
|
rf_mod_val = AX_WMAC_RFMOD_80M;
|
|
|
|
txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
|
|
|
|
FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_40:
|
|
|
|
rf_mod_val = AX_WMAC_RFMOD_40M;
|
|
|
|
txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_20:
|
|
|
|
default:
|
|
|
|
rf_mod_val = AX_WMAC_RFMOD_20M;
|
|
|
|
txsc = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val);
|
|
|
|
rtw89_write32(rtwdev, sub_carr, txsc);
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
switch (chan->band_type) {
|
2022-04-14 14:20:24 +08:00
|
|
|
case RTW89_BAND_2G:
|
|
|
|
chk_rate_mask = B_AX_BAND_MODE;
|
|
|
|
break;
|
|
|
|
case RTW89_BAND_5G:
|
|
|
|
case RTW89_BAND_6G:
|
|
|
|
chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6;
|
|
|
|
break;
|
|
|
|
default:
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
|
2022-04-14 14:20:24 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN |
|
|
|
|
B_AX_RTS_LIMIT_IN_OFDM6);
|
|
|
|
rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:25 +08:00
|
|
|
static const u32 rtw8852c_sco_barker_threshold[14] = {
|
|
|
|
0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6,
|
|
|
|
0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u32 rtw8852c_sco_cck_threshold[14] = {
|
|
|
|
0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db,
|
|
|
|
0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e
|
|
|
|
};
|
|
|
|
|
|
|
|
static int rtw8852c_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch,
|
|
|
|
u8 primary_ch, enum rtw89_bandwidth bw)
|
|
|
|
{
|
|
|
|
u8 ch_element;
|
|
|
|
|
|
|
|
if (bw == RTW89_CHANNEL_WIDTH_20) {
|
|
|
|
ch_element = central_ch - 1;
|
|
|
|
} else if (bw == RTW89_CHANNEL_WIDTH_40) {
|
|
|
|
if (primary_ch == 1)
|
|
|
|
ch_element = central_ch - 1 + 2;
|
|
|
|
else
|
|
|
|
ch_element = central_ch - 1 - 2;
|
|
|
|
} else {
|
|
|
|
rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_BK_FC0_INV_V1, B_BK_FC0_INV_MSK_V1,
|
|
|
|
rtw8852c_sco_barker_threshold[ch_element]);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CCK_FC0_INV_V1, B_CCK_FC0_INV_MSK_V1,
|
|
|
|
rtw8852c_sco_cck_threshold[ch_element]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:20 +08:00
|
|
|
struct rtw8852c_bb_gain {
|
|
|
|
u32 gain_g[BB_PATH_NUM_8852C];
|
|
|
|
u32 gain_a[BB_PATH_NUM_8852C];
|
|
|
|
u32 gain_mask;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw8852c_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
|
|
|
|
{ .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
|
|
|
|
.gain_mask = 0x00ff0000 },
|
|
|
|
{ .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
|
|
|
|
.gain_mask = 0xff000000 },
|
|
|
|
{ .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
|
|
|
|
.gain_mask = 0x000000ff },
|
|
|
|
{ .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
|
|
|
|
.gain_mask = 0x0000ff00 },
|
|
|
|
{ .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
|
|
|
|
.gain_mask = 0x00ff0000 },
|
|
|
|
{ .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
|
|
|
|
.gain_mask = 0xff000000 },
|
|
|
|
{ .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
|
|
|
|
.gain_mask = 0x000000ff },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw8852c_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
|
|
|
|
{ .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
|
|
|
|
.gain_mask = 0x00ff0000 },
|
|
|
|
{ .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
|
|
|
|
.gain_mask = 0xff000000 },
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw8852c_bb_gain_bypass {
|
|
|
|
u32 gain_g[BB_PATH_NUM_8852C];
|
|
|
|
u32 gain_a[BB_PATH_NUM_8852C];
|
|
|
|
u32 gain_mask_g;
|
|
|
|
u32 gain_mask_a;
|
|
|
|
};
|
|
|
|
|
|
|
|
static
|
|
|
|
const struct rtw8852c_bb_gain_bypass bb_gain_bypass_lna[LNA_GAIN_NUM] = {
|
|
|
|
{ .gain_g = {0x4BB8, 0x4C7C}, .gain_a = {0x4BB4, 0x4C78},
|
|
|
|
.gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
|
|
|
|
{ .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
|
|
|
|
.gain_mask_g = 0xff, .gain_mask_a = 0xff00},
|
|
|
|
{ .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
|
|
|
|
.gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
|
|
|
|
{ .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
|
|
|
|
.gain_mask_g = 0xff0000, .gain_mask_a = 0xff000000},
|
|
|
|
{ .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB8, 0x4C7C},
|
|
|
|
.gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
|
|
|
|
{ .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
|
|
|
|
.gain_mask_g = 0xff, .gain_mask_a = 0xff00},
|
|
|
|
{ .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
|
|
|
|
.gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw8852c_bb_gain_op1db {
|
|
|
|
struct {
|
|
|
|
u32 lna[BB_PATH_NUM_8852C];
|
|
|
|
u32 tia_lna[BB_PATH_NUM_8852C];
|
|
|
|
u32 mask;
|
|
|
|
} reg[LNA_GAIN_NUM];
|
|
|
|
u32 reg_tia0_lna6[BB_PATH_NUM_8852C];
|
|
|
|
u32 mask_tia0_lna6;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = {
|
|
|
|
.reg = {
|
|
|
|
{ .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
|
|
|
|
.mask = 0xff},
|
|
|
|
{ .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
|
|
|
|
.mask = 0xff00},
|
|
|
|
{ .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
|
|
|
|
.mask = 0xff0000},
|
|
|
|
{ .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
|
|
|
|
.mask = 0xff000000},
|
|
|
|
{ .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
|
|
|
|
.mask = 0xff},
|
|
|
|
{ .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
|
|
|
|
.mask = 0xff00},
|
|
|
|
{ .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
|
|
|
|
.mask = 0xff0000},
|
|
|
|
},
|
|
|
|
.reg_tia0_lna6 = {0x4674, 0x4758},
|
|
|
|
.mask_tia0_lna6 = 0xff000000,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev,
|
|
|
|
enum rtw89_subband subband,
|
|
|
|
enum rtw89_rf_path path)
|
|
|
|
{
|
2024-01-05 14:42:21 +08:00
|
|
|
const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
|
2022-10-05 16:32:11 +08:00
|
|
|
u8 gain_band = rtw89_subband_to_bb_gain_band(subband);
|
2022-04-14 14:20:20 +08:00
|
|
|
s32 val;
|
|
|
|
u32 reg;
|
|
|
|
u32 mask;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < LNA_GAIN_NUM; i++) {
|
|
|
|
if (subband == RTW89_CH_2G)
|
|
|
|
reg = bb_gain_lna[i].gain_g[path];
|
|
|
|
else
|
|
|
|
reg = bb_gain_lna[i].gain_a[path];
|
|
|
|
|
|
|
|
mask = bb_gain_lna[i].gain_mask;
|
|
|
|
val = gain->lna_gain[gain_band][path][i];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
|
|
|
|
if (subband == RTW89_CH_2G) {
|
|
|
|
reg = bb_gain_bypass_lna[i].gain_g[path];
|
|
|
|
mask = bb_gain_bypass_lna[i].gain_mask_g;
|
|
|
|
} else {
|
|
|
|
reg = bb_gain_bypass_lna[i].gain_a[path];
|
|
|
|
mask = bb_gain_bypass_lna[i].gain_mask_a;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = gain->lna_gain_bypass[gain_band][path][i];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
|
|
|
|
if (subband != RTW89_CH_2G) {
|
|
|
|
reg = bb_gain_op1db_a.reg[i].lna[path];
|
|
|
|
mask = bb_gain_op1db_a.reg[i].mask;
|
|
|
|
val = gain->lna_op1db[gain_band][path][i];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
|
|
|
|
reg = bb_gain_op1db_a.reg[i].tia_lna[path];
|
|
|
|
mask = bb_gain_op1db_a.reg[i].mask;
|
|
|
|
val = gain->tia_lna_op1db[gain_band][path][i];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (subband != RTW89_CH_2G) {
|
|
|
|
reg = bb_gain_op1db_a.reg_tia0_lna6[path];
|
|
|
|
mask = bb_gain_op1db_a.mask_tia0_lna6;
|
|
|
|
val = gain->tia_lna_op1db[gain_band][path][7];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < TIA_GAIN_NUM; i++) {
|
|
|
|
if (subband == RTW89_CH_2G)
|
|
|
|
reg = bb_gain_tia[i].gain_g[path];
|
|
|
|
else
|
|
|
|
reg = bb_gain_tia[i].gain_a[path];
|
|
|
|
|
|
|
|
mask = bb_gain_tia[i].gain_mask;
|
|
|
|
val = gain->tia_gain[gain_band][path][i];
|
|
|
|
rtw89_phy_write32_mask(rtwdev, reg, mask, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:21 +08:00
|
|
|
static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:21 +08:00
|
|
|
enum rtw89_phy_idx phy_idx,
|
|
|
|
enum rtw89_rf_path path)
|
|
|
|
{
|
|
|
|
static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
R_PATH1_G_TIA0_LNA6_OP1DB_V1};
|
|
|
|
static const u32 rpl_mask[2] = {B_RPL_PATHA_MASK, B_RPL_PATHB_MASK};
|
|
|
|
static const u32 rpl_tb_mask[2] = {B_RSSI_M_PATHA_MASK, B_RSSI_M_PATHB_MASK};
|
|
|
|
struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain;
|
|
|
|
enum rtw89_gain_offset gain_band;
|
|
|
|
s32 offset_q0, offset_base_q4;
|
|
|
|
s32 tmp = 0;
|
|
|
|
|
|
|
|
if (!efuse_gain->offset_valid)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (rtwdev->dbcc_en && path == RF_PATH_B)
|
|
|
|
phy_idx = RTW89_PHY_1;
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_type == RTW89_BAND_2G) {
|
2022-04-14 14:20:21 +08:00
|
|
|
offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK];
|
|
|
|
offset_base_q4 = efuse_gain->offset_base[phy_idx];
|
|
|
|
|
|
|
|
tmp = clamp_t(s32, (-offset_q0 << 3) + (offset_base_q4 >> 1),
|
|
|
|
S8_MIN >> 1, S8_MAX >> 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f);
|
|
|
|
}
|
|
|
|
|
2022-10-05 16:32:11 +08:00
|
|
|
gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type);
|
2022-04-14 14:20:21 +08:00
|
|
|
|
|
|
|
offset_q0 = -efuse_gain->offset[path][gain_band];
|
|
|
|
offset_base_q4 = efuse_gain->offset_base[phy_idx];
|
|
|
|
|
|
|
|
tmp = (offset_q0 << 2) + (offset_base_q4 >> 2);
|
|
|
|
tmp = clamp_t(s32, -tmp, S8_MIN, S8_MAX);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], B_PATH0_R_G_OFST_MASK, tmp & 0xff);
|
|
|
|
|
|
|
|
tmp = clamp_t(s32, offset_q0 << 4, S8_MIN, S8_MAX);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RPL_PATHAB, rpl_mask[path], tmp & 0xff, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, rpl_tb_mask[path], tmp & 0xff, phy_idx);
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:25 +08:00
|
|
|
static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
u8 sco;
|
2022-08-09 18:49:41 +08:00
|
|
|
u16 central_freq = chan->freq;
|
|
|
|
u8 central_ch = chan->channel;
|
|
|
|
u8 band = chan->band_type;
|
|
|
|
u8 subband = chan->subband_type;
|
2022-04-14 14:20:25 +08:00
|
|
|
bool is_2g = band == RTW89_BAND_2G;
|
|
|
|
u8 chan_idx;
|
|
|
|
|
|
|
|
if (!central_freq) {
|
|
|
|
rtw89_warn(rtwdev, "Invalid central_freq\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (phy_idx == RTW89_PHY_0) {
|
|
|
|
/* Path A */
|
|
|
|
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_A);
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_A);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
|
|
|
if (is_2g)
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
|
|
|
|
B_PATH0_BAND_SEL_MSK_V1, 1,
|
|
|
|
phy_idx);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
|
|
|
|
B_PATH0_BAND_SEL_MSK_V1, 0,
|
|
|
|
phy_idx);
|
|
|
|
/* Path B */
|
|
|
|
if (!rtwdev->dbcc_en) {
|
|
|
|
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
|
|
|
if (is_2g)
|
|
|
|
rtw89_phy_write32_idx(rtwdev,
|
|
|
|
R_PATH1_BAND_SEL_V1,
|
|
|
|
B_PATH1_BAND_SEL_MSK_V1,
|
|
|
|
1, phy_idx);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_idx(rtwdev,
|
|
|
|
R_PATH1_BAND_SEL_V1,
|
|
|
|
B_PATH1_BAND_SEL_MSK_V1,
|
|
|
|
0, phy_idx);
|
|
|
|
rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
|
|
|
|
} else {
|
|
|
|
if (is_2g)
|
|
|
|
rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
|
|
|
|
}
|
|
|
|
/* SCO compensate FC setting */
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
|
|
|
|
central_freq, phy_idx);
|
|
|
|
/* round_up((1/fc0)*pow(2,18)) */
|
|
|
|
sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco,
|
|
|
|
phy_idx);
|
|
|
|
} else {
|
|
|
|
/* Path B */
|
|
|
|
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
|
|
|
if (is_2g)
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
|
|
|
|
B_PATH1_BAND_SEL_MSK_V1,
|
|
|
|
1, phy_idx);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
|
|
|
|
B_PATH1_BAND_SEL_MSK_V1,
|
|
|
|
0, phy_idx);
|
|
|
|
/* SCO compensate FC setting */
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
|
|
|
|
central_freq, phy_idx);
|
|
|
|
/* round_up((1/fc0)*pow(2,18)) */
|
|
|
|
sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco,
|
|
|
|
phy_idx);
|
|
|
|
}
|
|
|
|
/* CCK parameters */
|
|
|
|
if (band == RTW89_BAND_2G) {
|
|
|
|
if (central_ch == 14) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
|
|
|
|
B_PCOEFF01_MSK_V1, 0x3b13ff);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
|
|
|
|
B_PCOEFF23_MSK_V1, 0x1c42de);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
|
|
|
|
B_PCOEFF45_MSK_V1, 0xfdb0ad);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
|
|
|
|
B_PCOEFF67_MSK_V1, 0xf60f6e);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
|
|
|
|
B_PCOEFF89_MSK_V1, 0xfd8f92);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
|
|
|
|
B_PCOEFFAB_MSK_V1, 0x2d011);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
|
|
|
|
B_PCOEFFCD_MSK_V1, 0x1c02c);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
|
|
|
|
B_PCOEFFEF_MSK_V1, 0xfff00a);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
|
|
|
|
B_PCOEFF01_MSK_V1, 0x3d23ff);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
|
|
|
|
B_PCOEFF23_MSK_V1, 0x29b354);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
|
|
|
|
B_PCOEFF45_MSK_V1, 0xfc1c8);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
|
|
|
|
B_PCOEFF67_MSK_V1, 0xfdb053);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
|
|
|
|
B_PCOEFF89_MSK_V1, 0xf86f9a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
|
|
|
|
B_PCOEFFAB_MSK_V1, 0xfaef92);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
|
|
|
|
B_PCOEFFCD_MSK_V1, 0xfe5fcc);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
|
|
|
|
B_PCOEFFEF_MSK_V1, 0xffdff5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-20 15:01:59 +08:00
|
|
|
chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path)
|
|
|
|
{
|
|
|
|
static const u32 adc_sel[2] = {0xC0EC, 0xC1EC};
|
|
|
|
static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
|
|
|
|
|
|
|
|
switch (bw) {
|
|
|
|
case RTW89_CHANNEL_WIDTH_5:
|
|
|
|
rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_10:
|
|
|
|
rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_20:
|
|
|
|
case RTW89_CHANNEL_WIDTH_40:
|
|
|
|
case RTW89_CHANNEL_WIDTH_80:
|
|
|
|
case RTW89_CHANNEL_WIDTH_160:
|
|
|
|
rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rtw89_warn(rtwdev, "Fail to set ADC\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_edcca_per20_bitmap_sifs(struct rtw89_dev *rtwdev, u8 bw,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
if (bw == RTW89_CHANNEL_WIDTH_20) {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0xff, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
u8 mod_sbw = 0;
|
|
|
|
|
|
|
|
switch (bw) {
|
|
|
|
case RTW89_CHANNEL_WIDTH_5:
|
|
|
|
case RTW89_CHANNEL_WIDTH_10:
|
|
|
|
case RTW89_CHANNEL_WIDTH_20:
|
|
|
|
if (bw == RTW89_CHANNEL_WIDTH_5)
|
|
|
|
mod_sbw = 0x1;
|
|
|
|
else if (bw == RTW89_CHANNEL_WIDTH_10)
|
|
|
|
mod_sbw = 0x2;
|
|
|
|
else if (bw == RTW89_CHANNEL_WIDTH_20)
|
|
|
|
mod_sbw = 0x0;
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW,
|
|
|
|
mod_sbw, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, 0x0,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
|
|
|
|
B_PATH0_BW_SEL_MSK_V1, 0xf);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
|
|
|
|
B_PATH1_BW_SEL_MSK_V1, 0xf);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_40:
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
|
|
|
|
pri_ch,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
|
|
|
|
B_PATH0_BW_SEL_MSK_V1, 0xf);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
|
|
|
|
B_PATH1_BW_SEL_MSK_V1, 0xf);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_80:
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
|
|
|
|
pri_ch,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
|
|
|
|
B_PATH0_BW_SEL_MSK_V1, 0xd);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
|
|
|
|
B_PATH1_BW_SEL_MSK_V1, 0xd);
|
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_160:
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x3,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
|
|
|
|
pri_ch,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH0_SAMPL_DLY_T_MSK_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
|
|
|
|
B_PATH1_SAMPL_DLY_T_MSK_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
|
|
|
|
B_PATH0_BW_SEL_MSK_V1, 0xb);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
|
|
|
|
B_PATH1_BW_SEL_MSK_V1, 0xb);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
|
|
|
|
pri_ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bw == RTW89_CHANNEL_WIDTH_40) {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
|
|
|
|
B_RX_BW40_2XFFT_EN_MSK_V1, 0x1, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 1, phy_idx);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
|
|
|
|
B_RX_BW40_2XFFT_EN_MSK_V1, 0x0, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 0, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (phy_idx == RTW89_PHY_0) {
|
|
|
|
rtw8852c_bw_setting(rtwdev, bw, RF_PATH_A);
|
|
|
|
if (!rtwdev->dbcc_en)
|
|
|
|
rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B);
|
|
|
|
} else {
|
|
|
|
rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B);
|
|
|
|
}
|
|
|
|
|
|
|
|
rtw8852c_edcca_per20_bitmap_sifs(rtwdev, bw, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan)
|
2022-04-14 14:20:25 +08:00
|
|
|
{
|
2022-08-09 18:49:41 +08:00
|
|
|
u8 center_chan = chan->channel;
|
|
|
|
u8 bw = chan->band_width;
|
2022-04-14 14:20:25 +08:00
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
switch (chan->band_type) {
|
2022-04-14 14:20:25 +08:00
|
|
|
case RTW89_BAND_2G:
|
|
|
|
if (bw == RTW89_CHANNEL_WIDTH_20) {
|
|
|
|
if (center_chan >= 5 && center_chan <= 8)
|
|
|
|
return 2440;
|
|
|
|
if (center_chan == 13)
|
|
|
|
return 2480;
|
|
|
|
} else if (bw == RTW89_CHANNEL_WIDTH_40) {
|
|
|
|
if (center_chan >= 3 && center_chan <= 10)
|
|
|
|
return 2440;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RTW89_BAND_5G:
|
|
|
|
if (center_chan == 151 || center_chan == 153 ||
|
|
|
|
center_chan == 155 || center_chan == 163)
|
|
|
|
return 5760;
|
|
|
|
break;
|
|
|
|
case RTW89_BAND_6G:
|
|
|
|
if (center_chan == 195 || center_chan == 197 ||
|
|
|
|
center_chan == 199 || center_chan == 207)
|
|
|
|
return 6920;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
|
|
|
|
#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
|
|
|
|
#define MAX_TONE_NUM 2048
|
|
|
|
|
|
|
|
static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
u32 spur_freq;
|
|
|
|
s32 freq_diff, csi_idx, csi_tone_idx;
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
spur_freq = rtw8852c_spur_freq(rtwdev, chan);
|
2022-04-14 14:20:25 +08:00
|
|
|
if (spur_freq == 0) {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 0, phy_idx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
freq_diff = (spur_freq - chan->freq) * 1000000;
|
2022-04-14 14:20:25 +08:00
|
|
|
csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
|
|
|
|
s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);
|
|
|
|
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, csi_tone_idx, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 1, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = {
|
|
|
|
[RF_PATH_A] = {
|
|
|
|
.notch1_idx = {0x4C14, 0xFF},
|
|
|
|
.notch1_frac_idx = {0x4C14, 0xC00},
|
|
|
|
.notch1_en = {0x4C14, 0x1000},
|
|
|
|
.notch2_idx = {0x4C20, 0xFF},
|
|
|
|
.notch2_frac_idx = {0x4C20, 0xC00},
|
|
|
|
.notch2_en = {0x4C20, 0x1000},
|
|
|
|
},
|
|
|
|
[RF_PATH_B] = {
|
|
|
|
.notch1_idx = {0x4CD8, 0xFF},
|
|
|
|
.notch1_frac_idx = {0x4CD8, 0xC00},
|
|
|
|
.notch1_en = {0x4CD8, 0x1000},
|
|
|
|
.notch2_idx = {0x4CE4, 0xFF},
|
|
|
|
.notch2_frac_idx = {0x4CE4, 0xC00},
|
|
|
|
.notch2_en = {0x4CE4, 0x1000},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_rf_path path)
|
|
|
|
{
|
|
|
|
const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path];
|
|
|
|
u32 spur_freq, fc;
|
|
|
|
s32 freq_diff;
|
|
|
|
s32 nbi_idx, nbi_tone_idx;
|
|
|
|
s32 nbi_frac_idx, nbi_frac_tone_idx;
|
|
|
|
bool notch2_chk = false;
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
spur_freq = rtw8852c_spur_freq(rtwdev, chan);
|
2022-04-14 14:20:25 +08:00
|
|
|
if (spur_freq == 0) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
fc = chan->freq;
|
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
|
2022-04-14 14:20:25 +08:00
|
|
|
fc = (spur_freq > fc) ? fc + 40 : fc - 40;
|
2022-08-09 18:49:41 +08:00
|
|
|
if ((fc > spur_freq &&
|
|
|
|
chan->channel < chan->primary_channel) ||
|
|
|
|
(fc < spur_freq &&
|
|
|
|
chan->channel > chan->primary_channel))
|
2022-04-14 14:20:25 +08:00
|
|
|
notch2_chk = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
freq_diff = (spur_freq - fc) * 1000000;
|
|
|
|
nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx);
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
|
2022-04-14 14:20:25 +08:00
|
|
|
s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
|
|
|
|
} else {
|
2022-08-09 18:49:41 +08:00
|
|
|
u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
|
|
|
|
128 : 256;
|
2022-04-14 14:20:25 +08:00
|
|
|
|
|
|
|
s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
|
|
|
|
}
|
|
|
|
nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr,
|
|
|
|
nbi->notch2_idx.mask, nbi_tone_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr,
|
|
|
|
nbi->notch2_frac_idx.mask, nbi_frac_tone_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr,
|
|
|
|
nbi->notch1_idx.mask, nbi_tone_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr,
|
|
|
|
nbi->notch1_frac_idx.mask, nbi_frac_tone_idx);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 20:02:12 +08:00
|
|
|
static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
u32 notch;
|
|
|
|
u32 notch2;
|
|
|
|
|
|
|
|
if (phy_idx == RTW89_PHY_0) {
|
|
|
|
notch = R_PATH0_NOTCH;
|
|
|
|
notch2 = R_PATH0_NOTCH2;
|
|
|
|
} else {
|
|
|
|
notch = R_PATH1_NOTCH;
|
|
|
|
notch2 = R_PATH1_NOTCH2;
|
|
|
|
}
|
|
|
|
|
|
|
|
rtw89_phy_write32_mask(rtwdev, notch,
|
|
|
|
B_PATH0_NOTCH_VAL | B_PATH0_NOTCH_EN, val);
|
|
|
|
rtw89_phy_write32_set(rtwdev, notch, B_PATH0_NOTCH_EN);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, notch2,
|
|
|
|
B_PATH0_NOTCH2_VAL | B_PATH0_NOTCH2_EN, val);
|
|
|
|
rtw89_phy_write32_set(rtwdev, notch2, B_PATH0_NOTCH2_EN);
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:25 +08:00
|
|
|
static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-05-06 20:02:12 +08:00
|
|
|
u8 pri_ch_idx,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_csi_tone_idx(rtwdev, chan, phy_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
|
|
|
if (phy_idx == RTW89_PHY_0) {
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
|
2022-05-06 20:02:12 +08:00
|
|
|
(pri_ch_idx == RTW89_SC_20_LOWER ||
|
|
|
|
pri_ch_idx == RTW89_SC_20_UP3X)) {
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_0);
|
|
|
|
if (!rtwdev->dbcc_en)
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
|
2022-08-09 18:49:41 +08:00
|
|
|
} else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
|
2022-05-06 20:02:12 +08:00
|
|
|
(pri_ch_idx == RTW89_SC_20_UPPER ||
|
|
|
|
pri_ch_idx == RTW89_SC_20_LOW3X)) {
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_0);
|
|
|
|
if (!rtwdev->dbcc_en)
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
|
|
|
|
} else {
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A);
|
2022-05-06 20:02:12 +08:00
|
|
|
if (!rtwdev->dbcc_en)
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_nbi_tone_idx(rtwdev, chan,
|
2022-05-06 20:02:12 +08:00
|
|
|
RF_PATH_B);
|
|
|
|
}
|
2022-04-14 14:20:25 +08:00
|
|
|
} else {
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
|
2022-05-06 20:02:12 +08:00
|
|
|
(pri_ch_idx == RTW89_SC_20_LOWER ||
|
|
|
|
pri_ch_idx == RTW89_SC_20_UP3X)) {
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
|
2022-08-09 18:49:41 +08:00
|
|
|
} else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
|
2022-05-06 20:02:12 +08:00
|
|
|
(pri_ch_idx == RTW89_SC_20_UPPER ||
|
|
|
|
pri_ch_idx == RTW89_SC_20_LOW3X)) {
|
|
|
|
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
|
|
|
|
} else {
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B);
|
2022-05-06 20:02:12 +08:00
|
|
|
}
|
2022-04-14 14:20:25 +08:00
|
|
|
}
|
2022-05-06 20:02:12 +08:00
|
|
|
|
|
|
|
if (pri_ch_idx == RTW89_SC_20_UP3X || pri_ch_idx == RTW89_SC_20_LOW3X)
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 0, phy_idx);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 1, phy_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
2023-04-06 15:28:41 +08:00
|
|
|
u8 pri_ch = chan->pri_ch_idx;
|
2022-04-14 14:20:25 +08:00
|
|
|
bool mask_5m_low;
|
|
|
|
bool mask_5m_en;
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
switch (chan->band_width) {
|
2022-04-14 14:20:25 +08:00
|
|
|
case RTW89_CHANNEL_WIDTH_40:
|
|
|
|
mask_5m_en = true;
|
2023-04-06 15:28:41 +08:00
|
|
|
mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
|
2022-04-14 14:20:25 +08:00
|
|
|
break;
|
|
|
|
case RTW89_CHANNEL_WIDTH_80:
|
2023-04-06 15:28:41 +08:00
|
|
|
mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
|
|
|
|
pri_ch == RTW89_SC_20_LOWEST;
|
|
|
|
mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
|
2022-04-14 14:20:25 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mask_5m_en = false;
|
|
|
|
mask_5m_low = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mask_5m_en) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x0);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT,
|
|
|
|
B_ASSIGN_SBD_OPT_EN, 0x0, phy_idx);
|
|
|
|
} else {
|
|
|
|
if (mask_5m_low) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x1);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x0);
|
|
|
|
}
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, 0x1, phy_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:19 +08:00
|
|
|
static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
/*HW SI reset*/
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
|
|
|
|
0x7);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
|
|
|
|
0x7);
|
|
|
|
|
|
|
|
udelay(1);
|
|
|
|
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
|
|
|
|
phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
|
|
|
|
phy_idx);
|
|
|
|
/*HW SI reset*/
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
|
|
|
|
0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
|
|
|
|
0x0);
|
|
|
|
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
|
|
|
|
phy_idx);
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:46 +08:00
|
|
|
static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
|
2022-04-14 14:20:19 +08:00
|
|
|
enum rtw89_phy_idx phy_idx, bool en)
|
|
|
|
{
|
|
|
|
if (en) {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
|
|
|
|
B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
|
|
|
|
B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
|
|
|
|
phy_idx);
|
2022-08-09 18:49:46 +08:00
|
|
|
if (band == RTW89_BAND_2G)
|
2022-04-14 14:20:19 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
|
|
|
|
B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
|
|
|
|
B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
|
|
|
|
fsleep(1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
|
|
|
|
phy_idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
rtw8852c_bb_reset_all(rtwdev, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
|
|
|
|
u8 tx_path_en, u8 trsw_tx,
|
|
|
|
u8 trsw_rx, u8 trsw, u8 trsw_b)
|
|
|
|
{
|
|
|
|
static const u32 path_cr_bases[] = {0x5868, 0x7868};
|
|
|
|
u32 mask_ofst = 16;
|
|
|
|
u32 cr;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
if (path >= ARRAY_SIZE(path_cr_bases))
|
|
|
|
return;
|
|
|
|
|
|
|
|
cr = path_cr_bases[path];
|
|
|
|
|
|
|
|
mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2;
|
|
|
|
val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b);
|
|
|
|
|
|
|
|
rtw89_phy_write32_mask(rtwdev, cr, (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
enum rtw8852c_rfe_src {
|
|
|
|
PAPE_RFM,
|
|
|
|
TRSW_RFM,
|
|
|
|
LNAON_RFM,
|
|
|
|
};
|
|
|
|
|
|
|
|
static
|
|
|
|
void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
|
|
|
|
enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl,
|
|
|
|
u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val)
|
|
|
|
{
|
|
|
|
static const u32 path_cr_bases[] = {0x5894, 0x7894};
|
|
|
|
static const u32 masks[] = {0, 8, 16};
|
|
|
|
u32 mask, mask_ofst;
|
|
|
|
u32 cr;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases))
|
|
|
|
return;
|
|
|
|
|
|
|
|
mask_ofst = masks[src];
|
|
|
|
cr = path_cr_bases[path];
|
|
|
|
|
|
|
|
val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) |
|
|
|
|
FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) |
|
|
|
|
FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) |
|
|
|
|
FIELD_PREP(B_P0_RFM_OUT, rfm_output_val);
|
|
|
|
mask = 0xff << mask_ofst;
|
|
|
|
|
|
|
|
rtw89_phy_write32_mask(rtwdev, cr, mask, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
static const u32 cr_bases[] = {0x5800, 0x7800};
|
|
|
|
u32 addr;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(cr_bases); i++) {
|
|
|
|
addr = cr_bases[i];
|
|
|
|
rtw89_phy_write32_set(rtwdev, (addr | 0x68), B_P0_TRSW_A);
|
|
|
|
rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_X);
|
|
|
|
rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_SO_A2);
|
|
|
|
rtw89_phy_write32(rtwdev, (addr | 0x80), 0x77777777);
|
|
|
|
rtw89_phy_write32(rtwdev, (addr | 0x84), 0x77777777);
|
|
|
|
}
|
|
|
|
|
|
|
|
rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff);
|
|
|
|
rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0);
|
|
|
|
rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0);
|
|
|
|
rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0);
|
|
|
|
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0);
|
|
|
|
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 0, 0, 1);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 0, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 0, 0, 1);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 1, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 0, 1, 0);
|
|
|
|
rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 1, 1, 0);
|
|
|
|
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, PAPE_RFM, 0, 0, 0, 0x0);
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, TRSW_RFM, 0, 0, 0, 0x4);
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, LNAON_RFM, 0, 0, 0, 0x8);
|
|
|
|
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, PAPE_RFM, 0, 0, 0, 0x0);
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, TRSW_RFM, 0, 0, 0, 0x4);
|
|
|
|
rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, LNAON_RFM, 0, 0, 0, 0x8);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
u32 addr;
|
|
|
|
|
|
|
|
for (addr = R_AX_PWR_MACID_LMT_TABLE0;
|
|
|
|
addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
|
|
|
|
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
2022-04-14 14:20:21 +08:00
|
|
|
struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
|
|
|
|
|
2022-04-14 14:20:19 +08:00
|
|
|
rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT,
|
|
|
|
B_DBCC_80P80_SEL_EVM_RPT_EN);
|
|
|
|
rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2,
|
|
|
|
B_DBCC_80P80_SEL_EVM_RPT2_EN);
|
|
|
|
|
|
|
|
rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0);
|
|
|
|
rtw8852c_bb_gpio_init(rtwdev);
|
2022-04-14 14:20:21 +08:00
|
|
|
|
|
|
|
/* read these registers after loading BB parameters */
|
|
|
|
gain->offset_base[RTW89_PHY_0] =
|
|
|
|
rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK);
|
|
|
|
gain->offset_base[RTW89_PHY_1] =
|
|
|
|
rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK);
|
2022-04-14 14:20:19 +08:00
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:25 +08:00
|
|
|
static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:41 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-14 14:20:25 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
2022-10-20 13:27:02 +08:00
|
|
|
static const u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
|
|
|
|
B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
|
2022-09-08 13:12:52 +08:00
|
|
|
struct rtw89_hal *hal = &rtwdev->hal;
|
2022-08-09 18:49:41 +08:00
|
|
|
bool cck_en = chan->band_type == RTW89_BAND_2G;
|
|
|
|
u8 pri_ch_idx = chan->pri_ch_idx;
|
2022-04-14 14:20:25 +08:00
|
|
|
u32 mask, reg;
|
2022-09-08 13:12:52 +08:00
|
|
|
u8 ntx_path;
|
2022-04-14 14:20:25 +08:00
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_type == RTW89_BAND_2G)
|
|
|
|
rtw8852c_ctrl_sco_cck(rtwdev, chan->channel,
|
|
|
|
chan->primary_channel,
|
|
|
|
chan->band_width);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_ctrl_ch(rtwdev, chan, phy_idx);
|
|
|
|
rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
if (cck_en) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
|
|
|
|
B_PD_ARBITER_OFF, 0x0, phy_idx);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
|
|
|
|
B_PD_ARBITER_OFF, 0x1, phy_idx);
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_spur_elimination(rtwdev, chan, pri_ch_idx, phy_idx);
|
2023-10-16 14:51:11 +08:00
|
|
|
rtw8852c_ctrl_btg_bt_rx(rtwdev, chan->band_type == RTW89_BAND_2G,
|
|
|
|
RTW89_PHY_0);
|
2022-08-09 18:49:41 +08:00
|
|
|
rtw8852c_5m_mask(rtwdev, chan, phy_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
|
2022-04-14 14:20:25 +08:00
|
|
|
rtwdev->hal.cv != CHIP_CAV) {
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ,
|
|
|
|
B_P80_AT_HIGH_FREQ, 0x0, phy_idx);
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
reg = rtw89_mac_reg_by_idx(rtwdev, R_P80_AT_HIGH_FREQ_BB_WRP, phy_idx);
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->primary_channel > chan->channel) {
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev,
|
|
|
|
R_P80_AT_HIGH_FREQ_RU_ALLOC,
|
|
|
|
ru_alloc_msk[phy_idx], 1);
|
|
|
|
rtw89_write32_mask(rtwdev, reg,
|
|
|
|
B_P80_AT_HIGH_FREQ_BB_WRP, 1);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev,
|
|
|
|
R_P80_AT_HIGH_FREQ_RU_ALLOC,
|
|
|
|
ru_alloc_msk[phy_idx], 0);
|
|
|
|
rtw89_write32_mask(rtwdev, reg,
|
|
|
|
B_P80_AT_HIGH_FREQ_BB_WRP, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:41 +08:00
|
|
|
if (chan->band_type == RTW89_BAND_6G &&
|
|
|
|
chan->band_width == RTW89_CHANNEL_WIDTH_160)
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
|
|
|
|
B_CDD_EVM_CHK_EN, 0, phy_idx);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
|
|
|
|
B_CDD_EVM_CHK_EN, 1, phy_idx);
|
|
|
|
|
|
|
|
if (!rtwdev->dbcc_en) {
|
|
|
|
mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
|
|
|
|
mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
|
|
|
|
} else {
|
|
|
|
if (phy_idx == RTW89_PHY_0) {
|
|
|
|
mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
|
|
|
|
} else {
|
|
|
|
mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-08 13:12:50 +08:00
|
|
|
if (chan->band_type == RTW89_BAND_6G)
|
|
|
|
rtw89_phy_write32_set(rtwdev, R_MUIC, B_MUIC_EN);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_clr(rtwdev, R_MUIC, B_MUIC_EN);
|
|
|
|
|
2022-09-08 13:12:52 +08:00
|
|
|
if (hal->antenna_tx)
|
|
|
|
ntx_path = hal->antenna_tx;
|
|
|
|
else
|
|
|
|
ntx_path = chan->band_type == RTW89_BAND_6G ? RF_B : RF_AB;
|
|
|
|
|
|
|
|
rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, (enum rtw89_mac_idx)phy_idx);
|
|
|
|
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw8852c_bb_reset_all(rtwdev, phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_set_channel(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:46 +08:00
|
|
|
const struct rtw89_chan *chan,
|
|
|
|
enum rtw89_mac_idx mac_idx,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-04-14 14:20:25 +08:00
|
|
|
{
|
2022-08-09 18:49:46 +08:00
|
|
|
rtw8852c_set_channel_mac(rtwdev, chan, mac_idx);
|
|
|
|
rtw8852c_set_channel_bb(rtwdev, chan, phy_idx);
|
|
|
|
rtw8852c_set_channel_rf(rtwdev, chan, phy_idx);
|
2022-04-14 14:20:25 +08:00
|
|
|
}
|
|
|
|
|
2022-04-14 14:20:26 +08:00
|
|
|
static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en)
|
|
|
|
{
|
|
|
|
if (en)
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en)
|
|
|
|
{
|
|
|
|
if (en)
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
|
|
|
|
0x0);
|
|
|
|
else
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
|
|
|
|
0xf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
|
2022-08-09 18:49:46 +08:00
|
|
|
struct rtw89_channel_help_params *p,
|
|
|
|
const struct rtw89_chan *chan,
|
|
|
|
enum rtw89_mac_idx mac_idx,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-04-14 14:20:26 +08:00
|
|
|
{
|
|
|
|
if (enter) {
|
2022-08-09 18:49:46 +08:00
|
|
|
rtw89_chip_stop_sch_tx(rtwdev, mac_idx, &p->tx_en,
|
|
|
|
RTW89_SCH_TX_SEL_ALL);
|
|
|
|
rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false);
|
2022-04-14 14:20:26 +08:00
|
|
|
rtw8852c_dfs_en(rtwdev, false);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_tssi_cont_en_phyidx(rtwdev, false, phy_idx, chan);
|
2022-04-14 14:20:26 +08:00
|
|
|
rtw8852c_adc_en(rtwdev, false);
|
|
|
|
fsleep(40);
|
2022-08-09 18:49:46 +08:00
|
|
|
rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, false);
|
2022-04-14 14:20:26 +08:00
|
|
|
} else {
|
2022-08-09 18:49:46 +08:00
|
|
|
rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true);
|
2022-04-14 14:20:26 +08:00
|
|
|
rtw8852c_adc_en(rtwdev, true);
|
|
|
|
rtw8852c_dfs_en(rtwdev, true);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_tssi_cont_en_phyidx(rtwdev, true, phy_idx, chan);
|
2022-08-09 18:49:46 +08:00
|
|
|
rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, true);
|
|
|
|
rtw89_chip_resume_sch_tx(rtwdev, mac_idx, p->tx_en);
|
2022-04-14 14:20:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:08:58 +08:00
|
|
|
static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
2022-11-29 16:31:25 +08:00
|
|
|
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
|
2022-04-21 20:08:58 +08:00
|
|
|
|
2022-05-03 07:54:04 +08:00
|
|
|
rtwdev->is_tssi_mode[RF_PATH_A] = false;
|
|
|
|
rtwdev->is_tssi_mode[RF_PATH_B] = false;
|
2022-11-29 16:31:25 +08:00
|
|
|
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
|
2022-05-03 07:54:03 +08:00
|
|
|
rtw8852c_lck_init(rtwdev);
|
2023-09-08 11:11:40 +08:00
|
|
|
rtw8852c_dpk_init(rtwdev);
|
2022-05-03 07:54:02 +08:00
|
|
|
|
2022-05-03 07:54:05 +08:00
|
|
|
rtw8852c_rck(rtwdev);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_dack(rtwdev, RTW89_CHANCTX_0);
|
2022-05-03 07:54:06 +08:00
|
|
|
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
|
2022-04-21 20:08:58 +08:00
|
|
|
}
|
|
|
|
|
2024-09-16 13:31:52 +08:00
|
|
|
static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
|
|
|
|
struct rtw89_vif_link *rtwvif_link)
|
2022-04-21 20:08:58 +08:00
|
|
|
{
|
2024-09-16 13:31:52 +08:00
|
|
|
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
|
|
|
|
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
2022-05-03 07:54:04 +08:00
|
|
|
|
2022-05-03 19:59:54 +08:00
|
|
|
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
|
2025-01-10 09:54:14 +08:00
|
|
|
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
|
|
|
|
2022-05-03 07:54:06 +08:00
|
|
|
rtw8852c_rx_dck(rtwdev, phy_idx, false);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx);
|
2025-01-10 09:54:14 +08:00
|
|
|
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx);
|
2025-01-10 09:54:14 +08:00
|
|
|
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx);
|
2025-01-10 09:54:14 +08:00
|
|
|
|
|
|
|
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
2022-04-21 20:08:58 +08:00
|
|
|
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:45 +08:00
|
|
|
static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
|
2024-08-19 17:17:17 +08:00
|
|
|
enum rtw89_phy_idx phy_idx,
|
|
|
|
const struct rtw89_chan *chan)
|
2022-05-03 07:54:04 +08:00
|
|
|
{
|
2024-08-19 17:17:21 +08:00
|
|
|
rtw8852c_tssi_scan(rtwdev, phy_idx, chan);
|
2022-05-03 07:54:04 +08:00
|
|
|
}
|
|
|
|
|
2024-09-16 13:31:52 +08:00
|
|
|
static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev,
|
|
|
|
struct rtw89_vif_link *rtwvif_link,
|
2024-07-27 16:06:48 +08:00
|
|
|
bool start)
|
2022-05-03 07:54:04 +08:00
|
|
|
{
|
2024-09-16 13:31:52 +08:00
|
|
|
rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
|
2022-05-03 07:54:04 +08:00
|
|
|
}
|
|
|
|
|
2022-05-03 07:54:03 +08:00
|
|
|
static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
2022-05-03 07:54:08 +08:00
|
|
|
rtw8852c_dpk_track(rtwdev);
|
2022-05-03 07:54:03 +08:00
|
|
|
rtw8852c_lck_track(rtwdev);
|
2022-05-20 15:17:29 +08:00
|
|
|
rtw8852c_rx_dck_track(rtwdev);
|
2022-05-03 07:54:03 +08:00
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:00 +08:00
|
|
|
static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
|
2024-11-11 14:51:32 +08:00
|
|
|
enum rtw89_phy_idx phy_idx,
|
|
|
|
s16 ref, u16 pwr_ofst_decrease)
|
2022-04-21 20:09:00 +08:00
|
|
|
{
|
|
|
|
u8 base_cw_0db = 0x27;
|
|
|
|
u16 tssi_16dbm_cw = 0x12c;
|
|
|
|
s16 pwr_s10_3 = 0;
|
|
|
|
s16 rf_pwr_cw = 0;
|
|
|
|
u16 bb_pwr_cw = 0;
|
|
|
|
u32 pwr_cw = 0;
|
|
|
|
u32 tssi_ofst_cw = 0;
|
|
|
|
|
2024-11-11 14:51:32 +08:00
|
|
|
pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease;
|
2022-04-21 20:09:00 +08:00
|
|
|
bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
|
|
|
|
rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
|
|
|
|
rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
|
|
|
|
pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
|
|
|
|
|
2024-11-11 14:51:32 +08:00
|
|
|
tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) -
|
|
|
|
pwr_ofst_decrease;
|
2022-04-21 20:09:00 +08:00
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
|
|
|
|
"[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
|
|
|
|
tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
|
|
|
|
|
|
|
|
return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0));
|
|
|
|
}
|
|
|
|
|
2022-03-17 13:55:34 +08:00
|
|
|
static
|
|
|
|
void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
|
|
|
|
s8 pw_ofst, enum rtw89_mac_idx mac_idx)
|
|
|
|
{
|
|
|
|
s8 pw_ofst_2tx;
|
|
|
|
s8 val_1t;
|
|
|
|
s8 val_2t;
|
|
|
|
u32 reg;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
if (pw_ofst < -32 || pw_ofst > 31) {
|
|
|
|
rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
val_1t = pw_ofst << 2;
|
|
|
|
pw_ofst_2tx = max(pw_ofst - 3, -32);
|
|
|
|
val_2t = pw_ofst_2tx << 2;
|
|
|
|
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t);
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t);
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
/* 1TX */
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
|
2022-03-17 13:55:34 +08:00
|
|
|
rtw89_write32_mask(rtwdev, reg,
|
|
|
|
B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
|
|
|
|
val_1t);
|
|
|
|
/* 2TX */
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
|
2022-03-17 13:55:34 +08:00
|
|
|
rtw89_write32_mask(rtwdev, reg,
|
|
|
|
B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
|
|
|
|
val_2t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:00 +08:00
|
|
|
static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
|
2024-11-11 14:51:32 +08:00
|
|
|
enum rtw89_phy_idx phy_idx, s16 pwr_ofst)
|
2022-04-21 20:09:00 +08:00
|
|
|
{
|
|
|
|
static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
|
2024-11-11 14:51:32 +08:00
|
|
|
u16 ofst_dec[RF_PATH_NUM_8852C];
|
2022-04-21 20:09:00 +08:00
|
|
|
const u32 mask = 0x7FFFFFF;
|
|
|
|
const u8 ofst_ofdm = 0x4;
|
|
|
|
const u8 ofst_cck = 0x8;
|
|
|
|
s16 ref_ofdm = 0;
|
|
|
|
s16 ref_cck = 0;
|
|
|
|
u32 val;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
|
|
|
|
|
|
|
|
rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
|
|
|
|
GENMASK(27, 10), 0x0);
|
|
|
|
|
2024-11-11 14:51:32 +08:00
|
|
|
ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst);
|
|
|
|
ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0;
|
2022-04-21 20:09:00 +08:00
|
|
|
|
2024-11-11 14:51:32 +08:00
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
|
|
|
|
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
|
|
|
|
val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx);
|
|
|
|
}
|
2022-04-21 20:09:00 +08:00
|
|
|
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
|
2024-11-11 14:51:32 +08:00
|
|
|
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
|
|
|
|
val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx);
|
|
|
|
}
|
2022-04-21 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
|
2023-02-01 11:20:57 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-21 20:09:00 +08:00
|
|
|
u8 tx_shape_idx,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
#define __DFIR_CFG_MASK 0xffffff
|
|
|
|
#define __DFIR_CFG_NR 8
|
|
|
|
#define __DECL_DFIR_VAR(_prefix, _name, _val...) \
|
|
|
|
static const u32 _prefix ## _ ## _name[] = {_val}; \
|
|
|
|
static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR)
|
|
|
|
#define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val)
|
|
|
|
#define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val)
|
|
|
|
|
|
|
|
__DECL_DFIR_PARAM(flat,
|
|
|
|
0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
|
|
|
|
0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5);
|
|
|
|
__DECL_DFIR_PARAM(sharp,
|
|
|
|
0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090,
|
|
|
|
0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5);
|
|
|
|
__DECL_DFIR_PARAM(sharp_14,
|
|
|
|
0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
|
|
|
|
0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A);
|
|
|
|
__DECL_DFIR_ADDR(filter,
|
|
|
|
0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
|
|
|
|
0x45C4, 0x45C8);
|
2022-08-09 18:49:42 +08:00
|
|
|
u8 ch = chan->channel;
|
2022-04-21 20:09:00 +08:00
|
|
|
const u32 *param;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (ch > 14) {
|
|
|
|
rtw89_warn(rtwdev,
|
|
|
|
"set tx shape dfir by unknown ch: %d on 2G\n", ch);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch == 14)
|
|
|
|
param = param_sharp_14;
|
|
|
|
else
|
|
|
|
param = tx_shape_idx == 0 ? param_flat : param_sharp;
|
|
|
|
|
|
|
|
for (i = 0; i < __DFIR_CFG_NR; i++) {
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
|
|
|
|
"set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i],
|
|
|
|
param[i]);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, addr_filter[i], __DFIR_CFG_MASK,
|
|
|
|
param[i], phy_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef __DECL_DFIR_ADDR
|
|
|
|
#undef __DECL_DFIR_PARAM
|
|
|
|
#undef __DECL_DFIR_VAR
|
|
|
|
#undef __DFIR_CFG_NR
|
|
|
|
#undef __DFIR_CFG_MASK
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
|
2022-08-09 18:49:44 +08:00
|
|
|
const struct rtw89_chan *chan,
|
2022-04-21 20:09:00 +08:00
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
2023-09-20 15:43:17 +08:00
|
|
|
const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
|
2022-08-09 18:49:42 +08:00
|
|
|
u8 band = chan->band_type;
|
2022-04-21 20:09:00 +08:00
|
|
|
u8 regd = rtw89_regd_get(rtwdev, band);
|
2023-09-20 15:43:21 +08:00
|
|
|
u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
|
|
|
|
u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
|
2022-04-21 20:09:00 +08:00
|
|
|
|
|
|
|
if (band == RTW89_BAND_2G)
|
2023-02-01 11:20:57 +08:00
|
|
|
rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
|
2022-04-21 20:09:00 +08:00
|
|
|
|
|
|
|
rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
|
|
|
|
(enum rtw89_mac_idx)phy_idx,
|
|
|
|
tx_shape_ofdm);
|
2023-08-30 17:28:48 +08:00
|
|
|
|
|
|
|
rtw89_phy_write32_set(rtwdev, R_P0_DAC_COMP_POST_DPD_EN,
|
|
|
|
B_P0_DAC_COMP_POST_DPD_EN);
|
|
|
|
rtw89_phy_write32_set(rtwdev, R_P1_DAC_COMP_POST_DPD_EN,
|
|
|
|
B_P1_DAC_COMP_POST_DPD_EN);
|
2022-04-21 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
2024-11-11 14:51:32 +08:00
|
|
|
static void rtw8852c_set_txpwr_diff(struct rtw89_dev *rtwdev,
|
|
|
|
const struct rtw89_chan *chan,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
s16 pwr_ofst;
|
|
|
|
|
|
|
|
pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
|
|
|
|
rtw8852c_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst);
|
|
|
|
}
|
|
|
|
|
2025-03-26 10:06:42 +08:00
|
|
|
static void rtw8852c_set_txpwr_sar_diff(struct rtw89_dev *rtwdev,
|
|
|
|
const struct rtw89_chan *chan,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
struct rtw89_sar_parm sar_parm = {
|
|
|
|
.center_freq = chan->freq,
|
|
|
|
.force_path = true,
|
|
|
|
};
|
|
|
|
s16 sar_rf;
|
|
|
|
s8 sar_mac;
|
|
|
|
|
|
|
|
if (phy_idx != RTW89_PHY_0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sar_parm.path = RF_PATH_A;
|
|
|
|
sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
|
|
|
|
sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_TXPWRB, B_TXPWRB_MAX, sar_rf);
|
|
|
|
|
|
|
|
sar_parm.path = RF_PATH_B;
|
|
|
|
sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
|
|
|
|
sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB, B_TXPWRB_MAX, sar_rf);
|
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:44 +08:00
|
|
|
static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
|
|
|
|
const struct rtw89_chan *chan,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-04-21 20:09:00 +08:00
|
|
|
{
|
wifi: rtw89: phy: make generic txpwr setting functions
Previously, we thought control registers or setting things for TX power
series may change according to chip. So, setting functions are implemented
chip by chip. However, until now, the functions keep the same among chips,
at least 8852A, 8852C, and 8852B. There is a sufficient number of chips to
share generic setting functions. So, we now remake them including TX power
by rate, TX power offset, TX power limit, and TX power limit RU as generic
ones in phy.c.
Besides, there are some code refinements in the generic ones, but almost
all of the logic doesn't change.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220928084336.34981-5-pkshih@realtek.com
2022-09-28 16:43:31 +08:00
|
|
|
rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
|
|
|
|
rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
|
2022-08-09 18:49:44 +08:00
|
|
|
rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
|
wifi: rtw89: phy: make generic txpwr setting functions
Previously, we thought control registers or setting things for TX power
series may change according to chip. So, setting functions are implemented
chip by chip. However, until now, the functions keep the same among chips,
at least 8852A, 8852C, and 8852B. There is a sufficient number of chips to
share generic setting functions. So, we now remake them including TX power
by rate, TX power offset, TX power limit, and TX power limit RU as generic
ones in phy.c.
Besides, there are some code refinements in the generic ones, but almost
all of the logic doesn't change.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220928084336.34981-5-pkshih@realtek.com
2022-09-28 16:43:31 +08:00
|
|
|
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
|
|
|
|
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
|
2024-11-11 14:51:32 +08:00
|
|
|
rtw8852c_set_txpwr_diff(rtwdev, chan, phy_idx);
|
2025-03-26 10:06:42 +08:00
|
|
|
rtw8852c_set_txpwr_sar_diff(rtwdev, chan, phy_idx);
|
2022-04-21 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
2022-08-09 18:49:44 +08:00
|
|
|
static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-04-21 20:09:00 +08:00
|
|
|
{
|
2024-11-11 14:51:32 +08:00
|
|
|
rtw8852c_set_txpwr_ref(rtwdev, phy_idx, 0);
|
2022-04-21 20:09:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
static const struct rtw89_reg2_def ctrl_ini[] = {
|
|
|
|
{0xD938, 0x00010100},
|
|
|
|
{0xD93C, 0x0500D500},
|
|
|
|
{0xD940, 0x00000500},
|
|
|
|
{0xD944, 0x00000005},
|
|
|
|
{0xD94C, 0x00220000},
|
|
|
|
{0xD950, 0x00030000},
|
|
|
|
};
|
|
|
|
u32 addr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4)
|
|
|
|
rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++)
|
|
|
|
rtw89_mac_txpwr_write32(rtwdev, phy_idx, ctrl_ini[i].addr,
|
|
|
|
ctrl_ini[i].data);
|
|
|
|
|
|
|
|
rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
|
|
|
|
(enum rtw89_mac_idx)phy_idx,
|
|
|
|
RTW89_TSSI_BANDEDGE_FLAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
rtw8852c_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ?
|
|
|
|
RTW89_MAC_1 :
|
|
|
|
RTW89_MAC_0);
|
|
|
|
rtw8852c_init_tssi_ctrl(rtwdev, phy_idx);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:08:59 +08:00
|
|
|
static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
|
|
|
|
{
|
2024-07-27 16:06:46 +08:00
|
|
|
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
2022-08-09 18:49:42 +08:00
|
|
|
u8 band = chan->band_type;
|
2022-04-21 20:08:59 +08:00
|
|
|
u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
|
|
|
|
u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
|
|
|
|
|
|
|
|
if (rtwdev->dbcc_en) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0,
|
|
|
|
1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1,
|
|
|
|
1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
|
|
|
|
B_RXHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
|
|
|
|
B_RXVHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
|
|
|
|
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT,
|
|
|
|
B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT,
|
|
|
|
B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0,
|
|
|
|
RTW89_PHY_1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
|
|
|
|
} else {
|
|
|
|
if (rx_path == RF_PATH_A) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
|
|
|
|
B_ANT_RX_SEG0, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG0, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG1, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
|
|
|
|
B_RXHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
|
|
|
|
B_RXVHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
|
|
|
|
0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
|
|
|
|
0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
|
|
|
|
rst_mask0, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
|
|
|
|
rst_mask0, 3);
|
|
|
|
} else if (rx_path == RF_PATH_B) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
|
|
|
|
B_ANT_RX_SEG0, 2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG0, 2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG1, 2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
|
|
|
|
B_RXHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
|
|
|
|
B_RXVHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
|
|
|
|
0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
|
|
|
|
0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
|
|
|
|
rst_mask1, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
|
|
|
|
rst_mask1, 3);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
|
|
|
|
B_ANT_RX_SEG0, 3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG0, 3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
|
|
|
|
B_ANT_RX_1RCCA_SEG1, 3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
|
|
|
|
B_RXHT_MCS_LIMIT, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
|
|
|
|
B_RXVHT_MCS_LIMIT, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
|
|
|
|
1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
|
|
|
|
1);
|
2023-10-16 14:51:11 +08:00
|
|
|
rtw8852c_ctrl_btg_bt_rx(rtwdev, band == RTW89_BAND_2G,
|
|
|
|
RTW89_PHY_0);
|
2022-04-21 20:08:59 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
|
|
|
|
rst_mask0, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
|
|
|
|
rst_mask0, 3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
|
|
|
|
rst_mask1, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
|
|
|
|
rst_mask1, 3);
|
|
|
|
}
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
|
|
|
|
enum rtw89_mac_idx mac_idx)
|
|
|
|
{
|
|
|
|
struct rtw89_reg2_def path_com[] = {
|
|
|
|
{R_AX_PATH_COM0, AX_PATH_COM0_DFVAL},
|
|
|
|
{R_AX_PATH_COM1, AX_PATH_COM1_DFVAL},
|
|
|
|
{R_AX_PATH_COM2, AX_PATH_COM2_DFVAL},
|
|
|
|
{R_AX_PATH_COM3, AX_PATH_COM3_DFVAL},
|
|
|
|
{R_AX_PATH_COM4, AX_PATH_COM4_DFVAL},
|
|
|
|
{R_AX_PATH_COM5, AX_PATH_COM5_DFVAL},
|
|
|
|
{R_AX_PATH_COM6, AX_PATH_COM6_DFVAL},
|
|
|
|
{R_AX_PATH_COM7, AX_PATH_COM7_DFVAL},
|
|
|
|
{R_AX_PATH_COM8, AX_PATH_COM8_DFVAL},
|
|
|
|
{R_AX_PATH_COM9, AX_PATH_COM9_DFVAL},
|
|
|
|
{R_AX_PATH_COM10, AX_PATH_COM10_DFVAL},
|
|
|
|
{R_AX_PATH_COM11, AX_PATH_COM11_DFVAL},
|
|
|
|
};
|
|
|
|
u32 addr;
|
|
|
|
u32 reg;
|
|
|
|
u8 cr_size = ARRAY_SIZE(path_com);
|
|
|
|
u8 i = 0;
|
|
|
|
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0);
|
|
|
|
rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1);
|
|
|
|
|
|
|
|
for (addr = R_AX_MACID_ANT_TABLE;
|
|
|
|
addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
reg = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx);
|
2022-04-21 20:08:59 +08:00
|
|
|
rtw89_write32(rtwdev, reg, 0);
|
|
|
|
}
|
|
|
|
|
2022-05-16 08:52:11 +08:00
|
|
|
if (tx_path == RF_A) {
|
2022-04-21 20:08:59 +08:00
|
|
|
path_com[0].data = AX_PATH_COM0_PATHA;
|
|
|
|
path_com[1].data = AX_PATH_COM1_PATHA;
|
|
|
|
path_com[2].data = AX_PATH_COM2_PATHA;
|
|
|
|
path_com[7].data = AX_PATH_COM7_PATHA;
|
|
|
|
path_com[8].data = AX_PATH_COM8_PATHA;
|
2022-05-16 08:52:11 +08:00
|
|
|
} else if (tx_path == RF_B) {
|
2022-04-21 20:08:59 +08:00
|
|
|
path_com[0].data = AX_PATH_COM0_PATHB;
|
|
|
|
path_com[1].data = AX_PATH_COM1_PATHB;
|
|
|
|
path_com[2].data = AX_PATH_COM2_PATHB;
|
|
|
|
path_com[7].data = AX_PATH_COM7_PATHB;
|
|
|
|
path_com[8].data = AX_PATH_COM8_PATHB;
|
2022-05-16 08:52:11 +08:00
|
|
|
} else if (tx_path == RF_AB) {
|
2022-04-21 20:08:59 +08:00
|
|
|
path_com[0].data = AX_PATH_COM0_PATHAB;
|
|
|
|
path_com[1].data = AX_PATH_COM1_PATHAB;
|
|
|
|
path_com[2].data = AX_PATH_COM2_PATHAB;
|
|
|
|
path_com[7].data = AX_PATH_COM7_PATHAB;
|
|
|
|
path_com[8].data = AX_PATH_COM8_PATHAB;
|
|
|
|
} else {
|
|
|
|
rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < cr_size; i++) {
|
|
|
|
rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n",
|
|
|
|
path_com[i].addr, path_com[i].data);
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
reg = rtw89_mac_reg_by_idx(rtwdev, path_com[i].addr, mac_idx);
|
2022-04-21 20:08:59 +08:00
|
|
|
rtw89_write32(rtwdev, reg, path_com[i].data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-16 14:51:11 +08:00
|
|
|
static void rtw8852c_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-05-03 19:59:55 +08:00
|
|
|
{
|
2023-10-16 14:51:11 +08:00
|
|
|
if (en) {
|
2022-05-03 19:59:55 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
|
|
|
|
B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
|
|
|
|
B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x3);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
|
|
|
|
B_PATH0_RXBB_MSK_V1, 0xf);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
|
|
|
|
B_PATH1_RXBB_MSK_V1, 0xf);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x80);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
|
|
|
|
B_PATH0_BT_BACKOFF_V1, 0x780D1E);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
|
|
|
|
B_PATH1_BT_BACKOFF_V1, 0x780D1E);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
|
|
|
|
B_P0_BACKOFF_IBADC_V1, 0x34);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
|
|
|
|
B_P1_BACKOFF_IBADC_V1, 0x34);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
|
|
|
|
B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
|
|
|
|
B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
|
|
|
|
B_PATH0_RXBB_MSK_V1, 0x60);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
|
|
|
|
B_PATH1_RXBB_MSK_V1, 0x60);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_LNA6_OP1DB_V1, 0x1a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
|
|
|
|
B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x2a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x2a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
|
|
|
|
B_PATH0_BT_BACKOFF_V1, 0x79E99E);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
|
|
|
|
B_PATH1_BT_BACKOFF_V1, 0x79E99E);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
|
|
|
|
B_P0_BACKOFF_IBADC_V1, 0x26);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
|
|
|
|
B_P1_BACKOFF_IBADC_V1, 0x26);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:08:59 +08:00
|
|
|
static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
struct rtw89_hal *hal = &rtwdev->hal;
|
|
|
|
|
|
|
|
rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
|
|
|
|
|
|
|
|
if (hal->rx_nss == 1) {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:01 +08:00
|
|
|
static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
|
|
|
|
{
|
|
|
|
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
|
|
|
|
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
|
|
|
|
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
|
|
|
|
|
|
|
|
fsleep(200);
|
|
|
|
|
|
|
|
return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:03 +08:00
|
|
|
static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
2024-02-29 15:45:09 +08:00
|
|
|
const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
|
|
|
|
union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
|
2022-04-21 20:09:03 +08:00
|
|
|
|
2024-02-29 15:45:09 +08:00
|
|
|
if (ver->fcxinit == 7) {
|
|
|
|
md->md_v7.rfe_type = rtwdev->efuse.rfe_type;
|
|
|
|
md->md_v7.kt_ver = rtwdev->hal.cv;
|
|
|
|
md->md_v7.bt_solo = 0;
|
|
|
|
md->md_v7.switch_type = BTC_SWITCH_INTERNAL;
|
2022-04-21 20:09:03 +08:00
|
|
|
|
2024-02-29 15:45:09 +08:00
|
|
|
if (md->md_v7.rfe_type > 0)
|
|
|
|
md->md_v7.ant.num = (md->md_v7.rfe_type % 2 ? 2 : 3);
|
|
|
|
else
|
|
|
|
md->md_v7.ant.num = 2;
|
2022-04-21 20:09:03 +08:00
|
|
|
|
2024-02-29 15:45:09 +08:00
|
|
|
md->md_v7.ant.diversity = 0;
|
|
|
|
md->md_v7.ant.isolation = 10;
|
2022-04-21 20:09:03 +08:00
|
|
|
|
2024-02-29 15:45:09 +08:00
|
|
|
if (md->md_v7.ant.num == 3) {
|
|
|
|
md->md_v7.ant.type = BTC_ANT_DEDICATED;
|
|
|
|
md->md_v7.bt_pos = BTC_BT_ALONE;
|
|
|
|
} else {
|
|
|
|
md->md_v7.ant.type = BTC_ANT_SHARED;
|
|
|
|
md->md_v7.bt_pos = BTC_BT_BTG;
|
|
|
|
}
|
|
|
|
rtwdev->btc.btg_pos = md->md_v7.ant.btg_pos;
|
|
|
|
rtwdev->btc.ant_type = md->md_v7.ant.type;
|
2022-04-21 20:09:03 +08:00
|
|
|
} else {
|
2024-02-29 15:45:09 +08:00
|
|
|
md->md.rfe_type = rtwdev->efuse.rfe_type;
|
|
|
|
md->md.cv = rtwdev->hal.cv;
|
|
|
|
md->md.bt_solo = 0;
|
|
|
|
md->md.switch_type = BTC_SWITCH_INTERNAL;
|
|
|
|
|
|
|
|
if (md->md.rfe_type > 0)
|
|
|
|
md->md.ant.num = (md->md.rfe_type % 2 ? 2 : 3);
|
|
|
|
else
|
|
|
|
md->md.ant.num = 2;
|
|
|
|
|
|
|
|
md->md.ant.diversity = 0;
|
|
|
|
md->md.ant.isolation = 10;
|
|
|
|
|
|
|
|
if (md->md.ant.num == 3) {
|
|
|
|
md->md.ant.type = BTC_ANT_DEDICATED;
|
|
|
|
md->md.bt_pos = BTC_BT_ALONE;
|
|
|
|
} else {
|
|
|
|
md->md.ant.type = BTC_ANT_SHARED;
|
|
|
|
md->md.bt_pos = BTC_BT_BTG;
|
|
|
|
}
|
|
|
|
rtwdev->btc.btg_pos = md->md.ant.btg_pos;
|
|
|
|
rtwdev->btc.ant_type = md->md.ant.type;
|
2022-04-21 20:09:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-16 14:51:11 +08:00
|
|
|
static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
|
|
|
|
enum rtw89_phy_idx phy_idx)
|
2022-04-14 14:20:25 +08:00
|
|
|
{
|
2023-10-16 14:51:11 +08:00
|
|
|
if (en) {
|
2022-04-14 14:20:25 +08:00
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
|
|
|
|
B_PATH0_BT_SHARE_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
|
|
|
|
B_PATH0_BTG_PATH_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_LNA6_OP1DB_V1, 0x20);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
|
|
|
|
B_PATH1_BT_SHARE_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
|
|
|
|
B_PATH1_BTG_PATH_V1, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x2);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
|
|
|
|
B_BT_DYN_DC_EST_EN_MSK, 0x1);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
|
|
|
|
0x1);
|
|
|
|
} else {
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
|
|
|
|
B_PATH0_BT_SHARE_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
|
|
|
|
B_PATH0_BTG_PATH_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
|
|
|
|
B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
|
|
|
|
B_PATH1_BT_SHARE_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
|
|
|
|
B_PATH1_BTG_PATH_V1, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
|
|
|
|
B_BT_DYN_DC_EST_EN_MSK, 0x0);
|
|
|
|
rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
|
|
|
|
0x0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-08 08:13:49 +08:00
|
|
|
static
|
|
|
|
void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
|
|
|
|
{
|
|
|
|
rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
|
|
|
|
rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
|
|
|
|
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
|
|
|
|
rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
struct rtw89_btc *btc = &rtwdev->btc;
|
|
|
|
const struct rtw89_chip_info *chip = rtwdev->chip;
|
|
|
|
const struct rtw89_mac_ax_coex coex_params = {
|
|
|
|
.pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
|
|
|
|
.direction = RTW89_MAC_AX_COEX_INNER,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* PTA init */
|
|
|
|
rtw89_mac_coex_init_v1(rtwdev, &coex_params);
|
|
|
|
|
|
|
|
/* set WL Tx response = Hi-Pri */
|
|
|
|
chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
|
|
|
|
chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
|
|
|
|
|
|
|
|
/* set rf gnt debug off */
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
|
|
|
|
|
|
|
|
/* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
|
2024-02-29 15:45:09 +08:00
|
|
|
if (btc->ant_type == BTC_ANT_SHARED) {
|
2022-04-08 08:13:49 +08:00
|
|
|
rtw8852c_set_trx_mask(rtwdev,
|
|
|
|
RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
|
|
|
|
rtw8852c_set_trx_mask(rtwdev,
|
|
|
|
RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
|
|
|
|
/* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
|
|
|
|
rtw8852c_set_trx_mask(rtwdev,
|
|
|
|
RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
|
|
|
|
} else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
|
|
|
|
rtw8852c_set_trx_mask(rtwdev,
|
|
|
|
RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
|
|
|
|
rtw8852c_set_trx_mask(rtwdev,
|
|
|
|
RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set PTA break table */
|
|
|
|
rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM);
|
|
|
|
|
|
|
|
/* enable BT counter 0xda10[1:0] = 2b'11 */
|
|
|
|
rtw89_write32_set(rtwdev,
|
|
|
|
R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN |
|
|
|
|
B_AX_BT_CNT_RST_V1);
|
|
|
|
btc->cx.wl.status.map.init_ok = true;
|
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:03 +08:00
|
|
|
static
|
|
|
|
void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
|
|
|
|
{
|
|
|
|
u32 bitmap = 0;
|
|
|
|
u32 reg = 0;
|
|
|
|
|
|
|
|
switch (map) {
|
|
|
|
case BTC_PRI_MASK_TX_RESP:
|
|
|
|
reg = R_BTC_COEX_WL_REQ;
|
|
|
|
bitmap = B_BTC_RSP_ACK_HI;
|
|
|
|
break;
|
|
|
|
case BTC_PRI_MASK_BEACON:
|
|
|
|
reg = R_BTC_COEX_WL_REQ;
|
|
|
|
bitmap = B_BTC_TX_BCN_HI;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state)
|
|
|
|
rtw89_write32_set(rtwdev, reg, bitmap);
|
|
|
|
else
|
|
|
|
rtw89_write32_clr(rtwdev, reg, bitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
union rtw8852c_btc_wl_txpwr_ctrl {
|
|
|
|
u32 txpwr_val;
|
|
|
|
struct {
|
|
|
|
union {
|
|
|
|
u16 ctrl_all_time;
|
|
|
|
struct {
|
|
|
|
s16 data:9;
|
|
|
|
u16 rsvd:6;
|
|
|
|
u16 flag:1;
|
|
|
|
} all_time;
|
|
|
|
};
|
|
|
|
union {
|
|
|
|
u16 ctrl_gnt_bt;
|
|
|
|
struct {
|
|
|
|
s16 data:9;
|
|
|
|
u16 rsvd:7;
|
|
|
|
} gnt_bt;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} __packed;
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
|
|
|
|
{
|
|
|
|
union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val };
|
|
|
|
s32 val;
|
|
|
|
|
|
|
|
#define __write_ctrl(_reg, _msk, _val, _en, _cond) \
|
|
|
|
do { \
|
rtw89: 8852c: fix warning of FIELD_PREP() mask type
To fix the compiler warning of clang with i386 config, but not complain
by gcc:
__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/realtek/rtw89/rtw8852c.c:2621:13: note: expanded from macro '__write_ctrl'
u32 _wrt = FIELD_PREP(__msk, _val); \
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:114:3: note: expanded from macro 'FIELD_PREP'
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:71:53: note: expanded from macro '__BF_FIELD_CHECK'
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^~~~~~~~~
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220503120001.79272-8-pkshih@realtek.com
2022-05-03 20:00:00 +08:00
|
|
|
u32 _wrt = FIELD_PREP(_msk, _val); \
|
|
|
|
BUILD_BUG_ON((_msk & _en) != 0); \
|
2022-04-21 20:09:03 +08:00
|
|
|
if (_cond) \
|
rtw89: 8852c: fix warning of FIELD_PREP() mask type
To fix the compiler warning of clang with i386 config, but not complain
by gcc:
__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/realtek/rtw89/rtw8852c.c:2621:13: note: expanded from macro '__write_ctrl'
u32 _wrt = FIELD_PREP(__msk, _val); \
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:114:3: note: expanded from macro 'FIELD_PREP'
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:71:53: note: expanded from macro '__BF_FIELD_CHECK'
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^~~~~~~~~
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220503120001.79272-8-pkshih@realtek.com
2022-05-03 20:00:00 +08:00
|
|
|
_wrt |= _en; \
|
2022-04-21 20:09:03 +08:00
|
|
|
else \
|
rtw89: 8852c: fix warning of FIELD_PREP() mask type
To fix the compiler warning of clang with i386 config, but not complain
by gcc:
__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/realtek/rtw89/rtw8852c.c:2621:13: note: expanded from macro '__write_ctrl'
u32 _wrt = FIELD_PREP(__msk, _val); \
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:114:3: note: expanded from macro 'FIELD_PREP'
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:71:53: note: expanded from macro '__BF_FIELD_CHECK'
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^~~~~~~~~
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220503120001.79272-8-pkshih@realtek.com
2022-05-03 20:00:00 +08:00
|
|
|
_wrt &= ~_en; \
|
2022-04-21 20:09:03 +08:00
|
|
|
rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \
|
rtw89: 8852c: fix warning of FIELD_PREP() mask type
To fix the compiler warning of clang with i386 config, but not complain
by gcc:
__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/realtek/rtw89/rtw8852c.c:2621:13: note: expanded from macro '__write_ctrl'
u32 _wrt = FIELD_PREP(__msk, _val); \
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:114:3: note: expanded from macro 'FIELD_PREP'
__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:71:53: note: expanded from macro '__BF_FIELD_CHECK'
BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^~~~~~~~~
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220503120001.79272-8-pkshih@realtek.com
2022-05-03 20:00:00 +08:00
|
|
|
_msk | _en, _wrt); \
|
2022-04-21 20:09:03 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
switch (arg.ctrl_all_time) {
|
|
|
|
case 0xffff:
|
|
|
|
val = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
val = arg.all_time.data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
|
|
|
|
val, B_AX_FORCE_PWR_BY_RATE_EN,
|
|
|
|
arg.ctrl_all_time != 0xffff);
|
|
|
|
|
|
|
|
switch (arg.ctrl_gnt_bt) {
|
|
|
|
case 0xffff:
|
|
|
|
val = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
val = arg.gnt_bt.data;
|
|
|
|
break;
|
2022-04-27 08:31:42 +08:00
|
|
|
}
|
2022-04-21 20:09:03 +08:00
|
|
|
|
|
|
|
__write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val,
|
|
|
|
B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff);
|
|
|
|
|
|
|
|
#undef __write_ctrl
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
|
|
|
|
{
|
2023-04-12 09:28:30 +08:00
|
|
|
/* +6 for compensate offset */
|
|
|
|
return clamp_t(s8, val + 6, -100, 0) + 100;
|
2022-04-21 20:09:03 +08:00
|
|
|
}
|
|
|
|
|
2022-05-03 19:59:56 +08:00
|
|
|
static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
|
|
|
|
{255, 0, 0, 7}, /* 0 -> original */
|
|
|
|
{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
|
|
|
|
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
|
|
|
|
{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
|
|
|
|
{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
|
2023-04-12 09:28:28 +08:00
|
|
|
{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
|
2022-05-03 19:59:56 +08:00
|
|
|
{6, 1, 0, 7},
|
|
|
|
{13, 1, 0, 7},
|
|
|
|
{13, 1, 0, 7}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
|
|
|
|
{255, 0, 0, 7}, /* 0 -> original */
|
|
|
|
{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
|
|
|
|
{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
|
|
|
|
{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
|
|
|
|
{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
|
2023-04-12 09:28:28 +08:00
|
|
|
{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
|
2022-05-03 19:59:56 +08:00
|
|
|
{255, 1, 0, 7},
|
|
|
|
{255, 1, 0, 7},
|
|
|
|
{255, 1, 0, 7}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u8 rtw89_btc_8852c_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
|
|
|
|
static const u8 rtw89_btc_8852c_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28};
|
|
|
|
|
|
|
|
static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = {
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda00),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda04),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda38),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda44),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda48),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
|
2023-04-12 09:28:29 +08:00
|
|
|
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778),
|
|
|
|
RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c),
|
2022-05-03 19:59:56 +08:00
|
|
|
};
|
|
|
|
|
2022-04-21 20:09:03 +08:00
|
|
|
static
|
|
|
|
void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
2022-07-25 10:35:03 +08:00
|
|
|
/* Feature move to firmware */
|
2022-04-21 20:09:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
|
|
|
|
{
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x620);
|
|
|
|
|
|
|
|
/* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
|
|
|
|
if (state)
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
|
|
|
|
RFREG_MASK, 0x179c);
|
|
|
|
else
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
|
|
|
|
RFREG_MASK, 0x208);
|
|
|
|
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
|
|
|
|
}
|
|
|
|
|
2022-09-20 09:09:36 +08:00
|
|
|
static void rtw8852c_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
|
|
|
|
{
|
|
|
|
/* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB
|
|
|
|
* level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB
|
|
|
|
* To improve BT ACI in co-rx
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch (level) {
|
|
|
|
case 0: /* default */
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
|
|
|
|
break;
|
|
|
|
case 1: /* Fix LNA2=5 */
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
|
|
|
|
rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
|
|
|
|
{
|
2023-03-14 10:06:15 +08:00
|
|
|
struct rtw89_btc *btc = &rtwdev->btc;
|
|
|
|
|
2022-09-20 09:09:36 +08:00
|
|
|
switch (level) {
|
|
|
|
case 0: /* original */
|
2023-03-14 10:06:15 +08:00
|
|
|
default:
|
2023-10-16 14:51:11 +08:00
|
|
|
rtw8852c_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
|
2023-03-14 10:06:15 +08:00
|
|
|
btc->dm.wl_lna2 = 0;
|
2022-09-20 09:09:36 +08:00
|
|
|
break;
|
|
|
|
case 1: /* for FDD free-run */
|
2023-10-16 14:51:11 +08:00
|
|
|
rtw8852c_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0);
|
2023-03-14 10:06:15 +08:00
|
|
|
btc->dm.wl_lna2 = 0;
|
2022-09-20 09:09:36 +08:00
|
|
|
break;
|
|
|
|
case 2: /* for BTG Co-Rx*/
|
2023-10-16 14:51:11 +08:00
|
|
|
rtw8852c_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
|
2023-03-14 10:06:15 +08:00
|
|
|
btc->dm.wl_lna2 = 1;
|
2022-09-20 09:09:36 +08:00
|
|
|
break;
|
|
|
|
}
|
2023-03-14 10:06:15 +08:00
|
|
|
|
|
|
|
rtw8852c_set_wl_lna2(rtwdev, btc->dm.wl_lna2);
|
2022-09-20 09:09:36 +08:00
|
|
|
}
|
|
|
|
|
2022-04-21 20:09:02 +08:00
|
|
|
static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
|
|
|
|
struct rtw89_rx_phy_ppdu *phy_ppdu,
|
|
|
|
struct ieee80211_rx_status *status)
|
|
|
|
{
|
|
|
|
u8 chan_idx = phy_ppdu->chan_idx;
|
|
|
|
enum nl80211_band band;
|
|
|
|
u8 ch;
|
|
|
|
|
|
|
|
if (chan_idx == 0)
|
|
|
|
return;
|
|
|
|
|
2023-02-20 15:01:59 +08:00
|
|
|
rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
|
2022-04-21 20:09:02 +08:00
|
|
|
status->freq = ieee80211_channel_to_frequency(ch, band);
|
|
|
|
status->band = band;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
|
|
|
|
struct rtw89_rx_phy_ppdu *phy_ppdu,
|
|
|
|
struct ieee80211_rx_status *status)
|
|
|
|
{
|
|
|
|
u8 path;
|
2022-09-08 15:41:39 +08:00
|
|
|
u8 *rx_power = phy_ppdu->rssi;
|
2022-04-21 20:09:02 +08:00
|
|
|
|
2024-11-28 13:54:31 +08:00
|
|
|
if (!status->signal)
|
|
|
|
status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
|
|
|
|
rx_power[RF_PATH_B]));
|
|
|
|
|
2022-04-21 20:09:02 +08:00
|
|
|
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
|
|
|
|
status->chains |= BIT(path);
|
2022-09-08 15:41:39 +08:00
|
|
|
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
|
2022-04-21 20:09:02 +08:00
|
|
|
}
|
|
|
|
if (phy_ppdu->valid)
|
|
|
|
rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
|
|
|
|
}
|
|
|
|
|
2022-03-25 14:00:49 +08:00
|
|
|
static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
|
|
|
|
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
|
|
|
|
|
|
|
|
rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
|
|
|
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
|
|
|
rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
|
|
|
|
|
|
|
rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1);
|
|
|
|
rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1);
|
|
|
|
|
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-09-27 14:26:06 +08:00
|
|
|
static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
|
2022-03-25 14:00:49 +08:00
|
|
|
{
|
2024-04-26 14:11:59 +08:00
|
|
|
rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
|
2022-03-25 14:00:49 +08:00
|
|
|
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
|
|
|
|
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
|
2022-09-27 14:26:06 +08:00
|
|
|
|
|
|
|
return 0;
|
2022-03-25 14:00:49 +08:00
|
|
|
}
|
|
|
|
|
2023-09-08 11:11:40 +08:00
|
|
|
static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = {
|
|
|
|
.callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb,
|
2025-03-06 10:11:41 +08:00
|
|
|
.callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb,
|
2023-09-08 11:11:40 +08:00
|
|
|
};
|
|
|
|
|
2022-10-27 13:27:06 +08:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = {
|
2024-08-05 17:00:28 +08:00
|
|
|
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
|
|
|
|
WIPHY_WOWLAN_NET_DETECT,
|
2022-10-27 13:27:07 +08:00
|
|
|
.n_patterns = RTW89_MAX_PATTERN_NUM,
|
|
|
|
.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
|
|
|
|
.pattern_min_len = 1,
|
2024-08-05 17:00:28 +08:00
|
|
|
.max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID,
|
2022-10-27 13:27:06 +08:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2022-03-07 14:04:45 +08:00
|
|
|
static const struct rtw89_chip_ops rtw8852c_chip_ops = {
|
2022-03-25 14:00:49 +08:00
|
|
|
.enable_bb_rf = rtw8852c_mac_enable_bb_rf,
|
|
|
|
.disable_bb_rf = rtw8852c_mac_disable_bb_rf,
|
2023-09-01 15:39:54 +08:00
|
|
|
.bb_preinit = NULL,
|
2024-01-20 08:38:28 +08:00
|
|
|
.bb_postinit = NULL,
|
2022-04-14 14:20:19 +08:00
|
|
|
.bb_reset = rtw8852c_bb_reset,
|
|
|
|
.bb_sethw = rtw8852c_bb_sethw,
|
2022-05-03 19:59:56 +08:00
|
|
|
.read_rf = rtw89_phy_read_rf_v1,
|
|
|
|
.write_rf = rtw89_phy_write_rf_v1,
|
2022-04-14 14:20:25 +08:00
|
|
|
.set_channel = rtw8852c_set_channel,
|
2022-04-14 14:20:26 +08:00
|
|
|
.set_channel_help = rtw8852c_set_channel_help,
|
2022-03-07 14:04:57 +08:00
|
|
|
.read_efuse = rtw8852c_read_efuse,
|
2022-03-07 14:04:56 +08:00
|
|
|
.read_phycap = rtw8852c_read_phycap,
|
2022-05-03 19:59:56 +08:00
|
|
|
.fem_setup = NULL,
|
2023-05-12 14:12:16 +08:00
|
|
|
.rfe_gpio = NULL,
|
2024-02-02 11:06:42 +08:00
|
|
|
.rfk_hw_init = NULL,
|
2022-04-21 20:08:58 +08:00
|
|
|
.rfk_init = rtw8852c_rfk_init,
|
2024-02-02 11:06:41 +08:00
|
|
|
.rfk_init_late = NULL,
|
2022-04-21 20:08:58 +08:00
|
|
|
.rfk_channel = rtw8852c_rfk_channel,
|
2022-05-03 07:54:04 +08:00
|
|
|
.rfk_band_changed = rtw8852c_rfk_band_changed,
|
|
|
|
.rfk_scan = rtw8852c_rfk_scan,
|
2022-05-03 07:54:03 +08:00
|
|
|
.rfk_track = rtw8852c_rfk_track,
|
2022-03-07 14:04:56 +08:00
|
|
|
.power_trim = rtw8852c_power_trim,
|
2022-04-21 20:09:00 +08:00
|
|
|
.set_txpwr = rtw8852c_set_txpwr,
|
|
|
|
.set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl,
|
|
|
|
.init_txpwr_unit = rtw8852c_init_txpwr_unit,
|
2022-04-21 20:09:01 +08:00
|
|
|
.get_thermal = rtw8852c_get_thermal,
|
2025-06-06 10:04:08 +08:00
|
|
|
.chan_to_rf18_val = NULL,
|
2023-10-16 14:51:11 +08:00
|
|
|
.ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx,
|
2022-04-21 20:09:02 +08:00
|
|
|
.query_ppdu = rtw8852c_query_ppdu,
|
2024-08-28 13:52:17 +08:00
|
|
|
.convert_rpl_to_rssi = NULL,
|
2024-11-28 13:54:31 +08:00
|
|
|
.phy_rpt_to_rssi = NULL,
|
2023-10-16 14:51:11 +08:00
|
|
|
.ctrl_nbtg_bt_tx = rtw8852c_ctrl_nbtg_bt_tx,
|
2022-04-21 20:08:59 +08:00
|
|
|
.cfg_txrx_path = rtw8852c_bb_cfg_txrx_path,
|
2022-05-03 19:59:56 +08:00
|
|
|
.set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
|
2024-08-09 15:20:08 +08:00
|
|
|
.digital_pwr_comp = NULL,
|
2022-03-07 14:04:50 +08:00
|
|
|
.pwr_on_func = rtw8852c_pwr_on_func,
|
|
|
|
.pwr_off_func = rtw8852c_pwr_off_func,
|
2023-05-22 20:25:09 +08:00
|
|
|
.query_rxdesc = rtw89_core_query_rxdesc,
|
2022-03-18 10:32:12 +08:00
|
|
|
.fill_txdesc = rtw89_core_fill_txdesc_v1,
|
2022-03-18 10:32:10 +08:00
|
|
|
.fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1,
|
2022-03-17 13:55:40 +08:00
|
|
|
.cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1,
|
|
|
|
.mac_cfg_gnt = rtw89_mac_cfg_gnt_v1,
|
2022-03-17 13:55:43 +08:00
|
|
|
.stop_sch_tx = rtw89_mac_stop_sch_tx_v1,
|
|
|
|
.resume_sch_tx = rtw89_mac_resume_sch_tx_v1,
|
2022-04-13 09:08:03 +08:00
|
|
|
.h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v1,
|
2024-01-15 11:37:39 +08:00
|
|
|
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
2024-01-15 11:37:37 +08:00
|
|
|
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
2024-01-15 11:37:38 +08:00
|
|
|
.h2c_ampdu_cmac_tbl = NULL,
|
2025-02-17 14:30:53 +08:00
|
|
|
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
2025-07-15 11:52:57 +08:00
|
|
|
.h2c_punctured_cmac_tbl = NULL,
|
2024-01-15 11:37:40 +08:00
|
|
|
.h2c_default_dmac_tbl = NULL,
|
2024-01-08 17:13:59 +08:00
|
|
|
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
2024-01-08 17:11:27 +08:00
|
|
|
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
2022-04-08 08:13:49 +08:00
|
|
|
|
2022-04-21 20:09:03 +08:00
|
|
|
.btc_set_rfe = rtw8852c_btc_set_rfe,
|
2022-04-08 08:13:49 +08:00
|
|
|
.btc_init_cfg = rtw8852c_btc_init_cfg,
|
2022-04-21 20:09:03 +08:00
|
|
|
.btc_set_wl_pri = rtw8852c_btc_set_wl_pri,
|
|
|
|
.btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl,
|
|
|
|
.btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi,
|
|
|
|
.btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt,
|
|
|
|
.btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby,
|
2022-09-20 09:09:36 +08:00
|
|
|
.btc_set_wl_rx_gain = rtw8852c_btc_set_wl_rx_gain,
|
2022-07-25 10:35:07 +08:00
|
|
|
.btc_set_policy = rtw89_btc_set_policy_v1,
|
2022-03-07 14:04:45 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct rtw89_chip_info rtw8852c_chip_info = {
|
|
|
|
.chip_id = RTL8852C,
|
2023-07-28 15:02:43 +08:00
|
|
|
.chip_gen = RTW89_CHIP_AX,
|
2022-03-07 14:04:45 +08:00
|
|
|
.ops = &rtw8852c_chip_ops,
|
wifi: rtw89: mac: add mac_gen_def::band1_offset to map MAC band1 register address
There are two copies of MAC hardware called band0 and band1. Basically,
the only difference between them is base address, so we can share functions
with a 'band' (or 'mac_idx') argument.
The offset of base address of WiFi 6 and 7 are 0x2000 and 0x4000
respectively, so add band1_offset field to new introduced struct
mac_gen_def to possibly reuse functions.
Using below spatch script to convert callers:
@@
expression reg, band;
@@
- rtw89_mac_reg_by_idx(reg, band)
+ rtw89_mac_reg_by_idx(rtwdev, reg, band)
@@
expression reg, port, band;
@@
- rtw89_mac_reg_by_port(reg, port, band)
+ rtw89_mac_reg_by_port(rtwdev, reg, port, band)
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230822125822.23817-2-pkshih@realtek.com
2023-08-22 20:58:17 +08:00
|
|
|
.mac_def = &rtw89_mac_gen_ax,
|
2023-08-22 20:58:21 +08:00
|
|
|
.phy_def = &rtw89_phy_gen_ax,
|
2023-03-20 21:06:06 +08:00
|
|
|
.fw_basename = RTW8852C_FW_BASENAME,
|
|
|
|
.fw_format_max = RTW8852C_FW_FORMAT_MAX,
|
2023-01-23 14:54:01 +08:00
|
|
|
.try_ce_fw = false,
|
2023-09-01 15:39:53 +08:00
|
|
|
.bbmcu_nr = 0,
|
2023-08-01 10:11:27 +08:00
|
|
|
.needed_fw_elms = 0,
|
2025-02-17 14:43:04 +08:00
|
|
|
.fw_blacklist = &rtw89_fw_blacklist_default,
|
2022-05-03 19:59:56 +08:00
|
|
|
.fifo_size = 458752,
|
2023-04-21 10:45:48 +08:00
|
|
|
.small_fifo_size = false,
|
2022-09-27 14:26:10 +08:00
|
|
|
.dle_scc_rsvd_size = 0,
|
2022-05-03 19:59:56 +08:00
|
|
|
.max_amsdu_limit = 8000,
|
|
|
|
.dis_2g_40m_ul_ofdma = false,
|
|
|
|
.rsvd_ple_ofst = 0x6f800,
|
2025-06-30 23:42:01 +03:00
|
|
|
.hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, NULL, NULL},
|
2025-06-30 23:41:34 +03:00
|
|
|
.dle_mem = {rtw8852c_dle_mem_pcie, NULL, NULL, NULL},
|
2023-11-24 15:16:59 +08:00
|
|
|
.wde_qempty_acq_grpnum = 16,
|
|
|
|
.wde_qempty_mgq_grpsel = 16,
|
2022-03-17 13:55:35 +08:00
|
|
|
.rf_base_addr = {0xe000, 0xf000},
|
2024-10-16 21:37:34 +08:00
|
|
|
.thermal_th = {0x32, 0x35},
|
2022-03-07 14:04:50 +08:00
|
|
|
.pwr_on_seq = NULL,
|
|
|
|
.pwr_off_seq = NULL,
|
2022-04-14 14:20:15 +08:00
|
|
|
.bb_table = &rtw89_8852c_phy_bb_table,
|
|
|
|
.bb_gain_table = &rtw89_8852c_phy_bb_gain_table,
|
|
|
|
.rf_table = {&rtw89_8852c_phy_radiob_table,
|
|
|
|
&rtw89_8852c_phy_radioa_table,},
|
|
|
|
.nctl_table = &rtw89_8852c_phy_nctl_table,
|
2023-04-21 10:45:46 +08:00
|
|
|
.nctl_post_table = NULL,
|
2023-03-30 16:03:31 +08:00
|
|
|
.dflt_parms = &rtw89_8852c_dflt_parms,
|
|
|
|
.rfe_parms_conf = NULL,
|
2023-09-08 11:11:40 +08:00
|
|
|
.chanctx_listener = &rtw8852c_chanctx_listener,
|
2024-11-11 14:51:32 +08:00
|
|
|
.txpwr_factor_bb = 3,
|
2022-04-14 14:20:16 +08:00
|
|
|
.txpwr_factor_rf = 2,
|
|
|
|
.txpwr_factor_mac = 1,
|
2022-04-08 08:13:48 +08:00
|
|
|
.dig_table = NULL,
|
2022-09-08 13:12:49 +08:00
|
|
|
.dig_regs = &rtw8852c_dig_regs,
|
2022-04-14 14:20:18 +08:00
|
|
|
.tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
|
2024-05-09 17:06:46 +08:00
|
|
|
.support_macid_num = RTW89_MAX_MAC_ID_NUM,
|
2024-08-19 17:17:24 +08:00
|
|
|
.support_link_num = 0,
|
2023-09-21 08:35:58 +08:00
|
|
|
.support_chanctx_num = 2,
|
2024-03-28 13:26:55 +08:00
|
|
|
.support_rnr = false,
|
2022-05-03 19:59:56 +08:00
|
|
|
.support_bands = BIT(NL80211_BAND_2GHZ) |
|
|
|
|
BIT(NL80211_BAND_5GHZ) |
|
|
|
|
BIT(NL80211_BAND_6GHZ),
|
2024-01-12 14:26:38 +08:00
|
|
|
.support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
|
|
|
|
BIT(NL80211_CHAN_WIDTH_40) |
|
|
|
|
BIT(NL80211_CHAN_WIDTH_80) |
|
|
|
|
BIT(NL80211_CHAN_WIDTH_160),
|
2023-05-08 16:12:10 +08:00
|
|
|
.support_unii4 = true,
|
2024-11-11 14:51:31 +08:00
|
|
|
.support_ant_gain = true,
|
2025-03-06 10:11:41 +08:00
|
|
|
.support_tas = true,
|
2025-03-26 10:06:42 +08:00
|
|
|
.support_sar_by_ant = true,
|
2023-09-29 08:40:23 +08:00
|
|
|
.ul_tb_waveform_ctrl = false,
|
2023-09-29 08:40:24 +08:00
|
|
|
.ul_tb_pwr_diff = true,
|
2025-02-20 14:43:57 +08:00
|
|
|
.rx_freq_frome_ie = false,
|
2022-03-18 10:32:13 +08:00
|
|
|
.hw_sec_hdr = true,
|
2024-07-31 15:05:05 +08:00
|
|
|
.hw_mgmt_tx_encrypt = true,
|
2025-02-20 14:23:44 +08:00
|
|
|
.hw_tkip_crypto = true,
|
2025-04-28 19:24:48 +08:00
|
|
|
.hw_mlo_bmc_crypto = false,
|
2022-05-03 19:59:56 +08:00
|
|
|
.rf_path_num = 2,
|
|
|
|
.tx_nss = 2,
|
|
|
|
.rx_nss = 2,
|
|
|
|
.acam_num = 128,
|
|
|
|
.bcam_num = 20,
|
|
|
|
.scam_num = 128,
|
2022-08-16 09:32:45 +08:00
|
|
|
.bacam_num = 8,
|
2022-08-16 09:32:46 +08:00
|
|
|
.bacam_dynamic_num = 8,
|
2023-04-21 10:45:49 +08:00
|
|
|
.bacam_ver = RTW89_BACAM_V0_EXT,
|
2023-10-27 09:50:57 +08:00
|
|
|
.ppdu_max_usr = 8,
|
2022-03-07 14:04:55 +08:00
|
|
|
.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,
|
wifi: rtw89: mac: add to access efuse for WiFi 7 chips
MAC address, hardware type, calibration values and etc are stored in efuse,
so we read them at probe stage and use them as capabilities to register
hardware.
There are two physical efuse -- one is the main efuse for digital hardware
part, and the other is for analog part. Because they are very similar, we
only describe the main efuse below.
The main efuse is split into two regions -- one is for logic map, and the
other is for physical map. For both regions, we use the same method to read
data, but need additional parser to get logic map. To allow reading
operation, we need to convert power state to active, and turn to idle state
after reading.
For WiFi 7 chips, we introduce efuse blocks to define feature group easier,
and these blocks are discontinue. For example, RF block is from 0x1_0000 ~
0x1_0240, and the next block PCIE_SDIO is starting from 0x2_0000.
Comparing to old one used by WiFi 6 chips, there is only single one logic
map, it would be a little hard to add an new field to a group if we don't
reserve a room in advance.
The relationship between efuse, region and block is shown as below:
(logical map)
+------------+ +---------------+ +-----------------+
| main efuse | | region 1 | | block 0x1_0000~ |
| (digital) | |(to logcal map)| +-----------------+
| | | | => +-----------------+
| | => | | | block 0x2_0000~ |
| | | | +-----------------+
| | |---------------| :
| | | region 2 |
+------------+ +---------------+
+------------+ +-----------------+
| 2nd efuse | ======================> | block 0x7_0000~ |
| (analog) | +-----------------+
+------------+
The parser converting from raw data to logic map is to decode block page,
block page offset, and word_en bits. Each word_en bit indicates two
following bytes as data of logic map, so total four word_en bits can
represent eight bytes. Thus, block page offset is 8-byte alignment.
The layout of a tuple is shown as below
+--------+--------+--------+--------+--------+--------+
| fixed 3 byte header | | | |
| | | | |
| [19:17] block_page | | | ... |
| [16:4] block_page_offset| | | |
| [3:0] word_en | ^ | ^ | |
+----|---+--------+--------+---|----+----|---+--------+
| | |
+-------------------------+---------+
a word_en bit indicates two bytes as data
For example,
block_page = 0x3
block_page_offset = 0x80 (must 8-byte alignment)
word_en = 0x6 (b'0110; 0 means data is presented)
following 4 bytes = 34 56 78 90
Then,
0x3_0080 = 34 56
0x3_0086 = 78 90
A special block page is RTW89_EFUSE_BLOCK_ADIE (7) that uses different
but similar format, because its real efuse size is smaller than main efuse.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231117024029.113845-4-pkshih@realtek.com
2023-11-17 10:40:26 +08:00
|
|
|
.efuse_blocks = NULL,
|
2022-03-07 14:04:56 +08:00
|
|
|
.phycap_addr = 0x590,
|
|
|
|
.phycap_size = 0x60,
|
2022-09-20 09:09:39 +08:00
|
|
|
.para_ver = 0x1,
|
|
|
|
.wlcx_desired = 0x06000000,
|
2022-05-03 19:59:56 +08:00
|
|
|
.scbd = 0x1,
|
|
|
|
.mailbox = 0x1,
|
2022-07-25 10:35:02 +08:00
|
|
|
|
2022-05-03 19:59:56 +08:00
|
|
|
.afh_guard_ch = 6,
|
|
|
|
.wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres,
|
|
|
|
.bt_rssi_thres = rtw89_btc_8852c_bt_rssi_thres,
|
|
|
|
.rssi_tol = 2,
|
|
|
|
.mon_reg_num = ARRAY_SIZE(rtw89_btc_8852c_mon_reg),
|
|
|
|
.mon_reg = rtw89_btc_8852c_mon_reg,
|
|
|
|
.rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_ul),
|
|
|
|
.rf_para_ulink = rtw89_btc_8852c_rf_ul,
|
|
|
|
.rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
|
|
|
|
.rf_para_dlink = rtw89_btc_8852c_rf_dl,
|
2022-09-08 13:12:54 +08:00
|
|
|
.ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) |
|
|
|
|
BIT(RTW89_PS_MODE_CLK_GATED) |
|
|
|
|
BIT(RTW89_PS_MODE_PWR_GATED),
|
2022-04-21 20:08:55 +08:00
|
|
|
.low_power_hci_modes = BIT(RTW89_PS_MODE_CLK_GATED) |
|
|
|
|
BIT(RTW89_PS_MODE_PWR_GATED),
|
2022-04-13 09:08:01 +08:00
|
|
|
.h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1,
|
2022-03-07 14:04:51 +08:00
|
|
|
.hci_func_en_addr = R_AX_HCI_FUNC_EN_V1,
|
2022-03-18 10:32:10 +08:00
|
|
|
.h2c_desc_size = sizeof(struct rtw89_rxdesc_short),
|
2022-03-18 10:32:12 +08:00
|
|
|
.txwd_body_size = sizeof(struct rtw89_txwd_body_v1),
|
2023-09-11 16:20:47 +08:00
|
|
|
.txwd_info_size = sizeof(struct rtw89_txwd_info),
|
2022-03-07 14:04:52 +08:00
|
|
|
.h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1,
|
2023-03-16 14:39:56 +08:00
|
|
|
.h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
|
2022-03-07 14:04:52 +08:00
|
|
|
.h2c_regs = rtw8852c_h2c_regs,
|
|
|
|
.c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1,
|
2023-03-16 14:39:56 +08:00
|
|
|
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
|
2022-03-07 14:04:52 +08:00
|
|
|
.c2h_regs = rtw8852c_c2h_regs,
|
2022-03-07 14:04:53 +08:00
|
|
|
.page_regs = &rtw8852c_page_regs,
|
2024-06-20 13:58:20 +08:00
|
|
|
.wow_reason_reg = rtw8852c_wow_wakeup_regs,
|
2022-11-17 14:30:00 +08:00
|
|
|
.cfo_src_fd = false,
|
2023-03-30 21:23:52 +08:00
|
|
|
.cfo_hw_comp = false,
|
2022-03-17 13:55:32 +08:00
|
|
|
.dcfo_comp = &rtw8852c_dcfo_comp,
|
2023-03-30 21:23:52 +08:00
|
|
|
.dcfo_comp_sft = 12,
|
2022-09-08 13:12:53 +08:00
|
|
|
.imr_info = &rtw8852c_imr_info,
|
2023-12-04 16:07:49 +08:00
|
|
|
.imr_dmac_table = NULL,
|
|
|
|
.imr_cmac_table = NULL,
|
2022-09-08 13:12:53 +08:00
|
|
|
.rrsr_cfgs = &rtw8852c_rrsr_cfgs,
|
2023-10-16 14:51:12 +08:00
|
|
|
.bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
|
2022-12-14 17:18:03 +08:00
|
|
|
.bss_clr_map_reg = R_BSS_CLR_MAP,
|
2024-07-24 13:26:24 +08:00
|
|
|
.rfkill_init = &rtw8852c_rfkill_regs,
|
|
|
|
.rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
|
2022-09-27 14:26:04 +08:00
|
|
|
.dma_ch_mask = 0,
|
2023-11-22 14:04:56 +08:00
|
|
|
.edcca_regs = &rtw8852c_edcca_regs,
|
2022-10-27 13:27:06 +08:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
.wowlan_stub = &rtw_wowlan_stub_8852c,
|
|
|
|
#endif
|
2023-04-21 10:45:47 +08:00
|
|
|
.xtal_info = NULL,
|
2022-03-07 14:04:45 +08:00
|
|
|
};
|
|
|
|
EXPORT_SYMBOL(rtw8852c_chip_info);
|
|
|
|
|
2023-03-20 21:06:06 +08:00
|
|
|
MODULE_FIRMWARE(RTW8852C_MODULE_FIRMWARE);
|
2022-03-07 14:04:45 +08:00
|
|
|
MODULE_AUTHOR("Realtek Corporation");
|
|
|
|
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
|
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|