1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright(c) 2019-2022 Realtek Corporation
3 */
4
5#include "chan.h"
6#include "coex.h"
7#include "debug.h"
8#include "fw.h"
9#include "mac.h"
10#include "phy.h"
11#include "reg.h"
12#include "rtw8852c.h"
13#include "rtw8852c_rfk.h"
14#include "rtw8852c_table.h"
15#include "util.h"
16
17#define RTW8852C_FW_FORMAT_MAX 0
18#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw"
19#define RTW8852C_MODULE_FIRMWARE \
20 RTW8852C_FW_BASENAME ".bin"
21
22static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = {
23 {13, 1614, grp_0}, /* ACH 0 */
24 {13, 1614, grp_0}, /* ACH 1 */
25 {13, 1614, grp_0}, /* ACH 2 */
26 {13, 1614, grp_0}, /* ACH 3 */
27 {13, 1614, grp_1}, /* ACH 4 */
28 {13, 1614, grp_1}, /* ACH 5 */
29 {13, 1614, grp_1}, /* ACH 6 */
30 {13, 1614, grp_1}, /* ACH 7 */
31 {13, 1614, grp_0}, /* B0MGQ */
32 {13, 1614, grp_0}, /* B0HIQ */
33 {13, 1614, grp_1}, /* B1MGQ */
34 {13, 1614, grp_1}, /* B1HIQ */
35 {40, 0, 0} /* FWCMDQ */
36};
37
38static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_pcie = {
39 1614, /* Group 0 */
40 1614, /* Group 1 */
41 3228, /* Public Max */
42 0 /* WP threshold */
43};
44
45static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = {
46 [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_pcie, &rtw8852c_hfc_pubcfg_pcie,
47 &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH},
48 [RTW89_QTA_DLFW] = {NULL, NULL, .prec_cfg: &rtw89_mac_size.hfc_preccfg_pcie,
49 .mode: RTW89_HCIFC_POH},
50 [RTW89_QTA_INVALID] = {NULL},
51};
52
53static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
54 [RTW89_QTA_SCC] = {.mode: RTW89_QTA_SCC, .wde_size: &rtw89_mac_size.wde_size19,
55 .ple_size: &rtw89_mac_size.ple_size19, .wde_min_qt: &rtw89_mac_size.wde_qt18,
56 .wde_max_qt: &rtw89_mac_size.wde_qt18, .ple_min_qt: &rtw89_mac_size.ple_qt46,
57 .ple_max_qt: &rtw89_mac_size.ple_qt47},
58 [RTW89_QTA_DLFW] = {.mode: RTW89_QTA_DLFW, .wde_size: &rtw89_mac_size.wde_size18,
59 .ple_size: &rtw89_mac_size.ple_size18, .wde_min_qt: &rtw89_mac_size.wde_qt17,
60 .wde_max_qt: &rtw89_mac_size.wde_qt17, .ple_min_qt: &rtw89_mac_size.ple_qt44,
61 .ple_max_qt: &rtw89_mac_size.ple_qt45},
62 [RTW89_QTA_INVALID] = {.mode: RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
63 NULL},
64};
65
66static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
67 R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
68 R_AX_H2CREG_DATA3_V1
69};
70
71static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
72 R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1,
73 R_AX_C2HREG_DATA3_V1
74};
75
76static const struct rtw89_page_regs rtw8852c_page_regs = {
77 .hci_fc_ctrl = R_AX_HCI_FC_CTRL_V1,
78 .ch_page_ctrl = R_AX_CH_PAGE_CTRL_V1,
79 .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL_V1,
80 .ach_page_info = R_AX_ACH0_PAGE_INFO_V1,
81 .pub_page_info3 = R_AX_PUB_PAGE_INFO3_V1,
82 .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1_V1,
83 .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2_V1,
84 .pub_page_info1 = R_AX_PUB_PAGE_INFO1_V1,
85 .pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1,
86 .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1_V1,
87 .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2_V1,
88 .wp_page_info1 = R_AX_WP_PAGE_INFO1_V1,
89};
90
91static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
92 R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
93};
94
95static const struct rtw89_imr_info rtw8852c_imr_info = {
96 .wdrls_imr_set = B_AX_WDRLS_IMR_SET_V1,
97 .wsec_imr_reg = R_AX_SEC_ERROR_FLAG_IMR,
98 .wsec_imr_set = B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR,
99 .mpdu_tx_imr_set = B_AX_MPDU_TX_IMR_SET_V1,
100 .mpdu_rx_imr_set = B_AX_MPDU_RX_IMR_SET_V1,
101 .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET,
102 .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_B0_ERRFLAG_IMR,
103 .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR_V1,
104 .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET_V1,
105 .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_B1_ERRFLAG_IMR,
106 .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR_V1,
107 .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET_V1,
108 .wde_imr_clr = B_AX_WDE_IMR_CLR_V1,
109 .wde_imr_set = B_AX_WDE_IMR_SET_V1,
110 .ple_imr_clr = B_AX_PLE_IMR_CLR_V1,
111 .ple_imr_set = B_AX_PLE_IMR_SET_V1,
112 .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR_V1,
113 .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V1,
114 .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR_V1,
115 .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET_V1,
116 .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR_V1,
117 .other_disp_imr_set = B_AX_OTHER_DISP_IMR_SET_V1,
118 .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR,
119 .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR,
120 .bbrpt_err_imr_set = R_AX_BBRPT_CHINFO_IMR_SET_V1,
121 .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR,
122 .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_V1,
123 .ptcl_imr_set = B_AX_PTCL_IMR_SET_V1,
124 .cdma_imr_0_reg = R_AX_RX_ERR_FLAG_IMR,
125 .cdma_imr_0_clr = B_AX_RX_ERR_IMR_CLR_V1,
126 .cdma_imr_0_set = B_AX_RX_ERR_IMR_SET_V1,
127 .cdma_imr_1_reg = R_AX_TX_ERR_FLAG_IMR,
128 .cdma_imr_1_clr = B_AX_TX_ERR_IMR_CLR_V1,
129 .cdma_imr_1_set = B_AX_TX_ERR_IMR_SET_V1,
130 .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR_V1,
131 .phy_intf_imr_clr = B_AX_PHYINFO_IMR_CLR_V1,
132 .phy_intf_imr_set = B_AX_PHYINFO_IMR_SET_V1,
133 .rmac_imr_reg = R_AX_RX_ERR_IMR,
134 .rmac_imr_clr = B_AX_RMAC_IMR_CLR_V1,
135 .rmac_imr_set = B_AX_RMAC_IMR_SET_V1,
136 .tmac_imr_reg = R_AX_TRXPTCL_ERROR_INDICA_MASK,
137 .tmac_imr_clr = B_AX_TMAC_IMR_CLR_V1,
138 .tmac_imr_set = B_AX_TMAC_IMR_SET_V1,
139};
140
141static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = {
142 .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0},
143 .rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2},
144};
145
146static const struct rtw89_dig_regs rtw8852c_dig_regs = {
147 .seg0_pd_reg = R_SEG0R_PD,
148 .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
149 .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
150 .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
151 .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
152 .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
153 .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
154 .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
155 .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
156 .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
157 .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1},
158 .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1},
159 .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1},
160 .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V1,
161 B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
162 .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V1,
163 B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
164 .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V1,
165 B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
166 .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V1,
167 B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
168};
169
170static const struct rtw89_edcca_regs rtw8852c_edcca_regs = {
171 .edcca_level = R_SEG0R_EDCCA_LVL,
172 .edcca_mask = B_EDCCA_LVL_MSK0,
173 .edcca_p_mask = B_EDCCA_LVL_MSK1,
174 .ppdu_level = R_SEG0R_EDCCA_LVL,
175 .ppdu_mask = B_EDCCA_LVL_MSK3,
176 .rpt_a = R_EDCCA_RPT_A,
177 .rpt_b = R_EDCCA_RPT_B,
178 .rpt_sel = R_EDCCA_RPT_SEL,
179 .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
180 .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
181 .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
182};
183
184static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
185 enum rtw89_phy_idx phy_idx);
186
187static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
188 enum rtw89_mac_idx mac_idx);
189
190static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
191{
192 u32 val32;
193 u32 ret;
194
195 val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
196 if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
197 rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
198
199 rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
200 B_AX_AFSM_PCIE_SUS_EN);
201 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
202 rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
203 rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
204 rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
205
206 ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
207 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
208 if (ret)
209 return ret;
210
211 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
212 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
213
214 ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
215 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
216 if (ret)
217 return ret;
218
219 rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
220 rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
221 rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
222 rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
223
224 rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
225 rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
226
227 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
228 rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
229 rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN |
230 B_AX_R_SYM_WLCMAC1_P3_PC_EN |
231 B_AX_R_SYM_WLCMAC1_P2_PC_EN |
232 B_AX_R_SYM_WLCMAC1_P1_PC_EN |
233 B_AX_R_SYM_WLCMAC1_PC_EN);
234 rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
235
236 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL,
237 XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
238 if (ret)
239 return ret;
240
241 rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
242
243 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL,
244 XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
245 if (ret)
246 return ret;
247 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
248 XTAL_SI_OFF_WEI);
249 if (ret)
250 return ret;
251 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
252 XTAL_SI_OFF_EI);
253 if (ret)
254 return ret;
255 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_RFC2RF);
256 if (ret)
257 return ret;
258 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
259 XTAL_SI_PON_WEI);
260 if (ret)
261 return ret;
262 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
263 XTAL_SI_PON_EI);
264 if (ret)
265 return ret;
266 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_SRAM2RFC);
267 if (ret)
268 return ret;
269 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_XTAL_XMD_2, val: 0, XTAL_SI_LDO_LPS);
270 if (ret)
271 return ret;
272 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_XTAL_XMD_4, val: 0, XTAL_SI_LPS_CAP);
273 if (ret)
274 return ret;
275
276 rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
277 rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
278 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
279
280 fsleep(usecs: 1000);
281
282 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
283 rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
284 rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
285 B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
286 B_AX_LED1_PULL_LOW_EN);
287
288 rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
289 B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
290 B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
291 B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
292 B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
293 B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
294 B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN);
295
296 rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
297 B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
298 B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN |
299 B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
300 B_AX_TMAC_EN | B_AX_RMAC_EN);
301
302 rtw89_write32_mask(rtwdev, R_AX_LED1_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK,
303 PINMUX_EESK_FUNC_SEL_BT_LOG);
304
305 return 0;
306}
307
308static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
309{
310 u32 val32;
311 u32 ret;
312
313 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
314 XTAL_SI_RFC2RF);
315 if (ret)
316 return ret;
317 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_OFF_EI);
318 if (ret)
319 return ret;
320 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_OFF_WEI);
321 if (ret)
322 return ret;
323 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_WL_RFC_S0, val: 0, XTAL_SI_RF00);
324 if (ret)
325 return ret;
326 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_WL_RFC_S1, val: 0, XTAL_SI_RF10);
327 if (ret)
328 return ret;
329 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
330 XTAL_SI_SRAM2RFC);
331 if (ret)
332 return ret;
333 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_PON_EI);
334 if (ret)
335 return ret;
336 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_PON_WEI);
337 if (ret)
338 return ret;
339
340 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
341 rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
342 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
343 B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
344 rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
345
346 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_SHDN_WL);
347 if (ret)
348 return ret;
349
350 rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
351
352 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0, XTAL_SI_GND_SHDN_WL);
353 if (ret)
354 return ret;
355
356 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
357
358 ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
359 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
360 if (ret)
361 return ret;
362
363 rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, data: 0x0001A0B0);
364 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
365 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
366
367 return 0;
368}
369
370static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
371 struct rtw8852c_efuse *map)
372{
373 ether_addr_copy(dst: efuse->addr, src: map->e.mac_addr);
374 efuse->rfe_type = map->rfe_type;
375 efuse->xtal_cap = map->xtal_k;
376}
377
378static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
379 struct rtw8852c_efuse *map)
380{
381 struct rtw89_tssi_info *tssi = &rtwdev->tssi;
382 struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
383 u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
384 u8 i, j;
385
386 tssi->thermal[RF_PATH_A] = map->path_a_therm;
387 tssi->thermal[RF_PATH_B] = map->path_b_therm;
388
389 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
390 memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
391 sizeof(ofst[i]->cck_tssi));
392
393 for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
394 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
395 fmt: "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
396 i, j, tssi->tssi_cck[i][j]);
397
398 memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
399 sizeof(ofst[i]->bw40_tssi));
400 memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
401 ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
402 memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
403 sizeof(tssi->tssi_6g_mcs[i]));
404
405 for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
406 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
407 fmt: "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
408 i, j, tssi->tssi_mcs[i][j]);
409 }
410}
411
412static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low)
413{
414 if (high)
415 *high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), index: 3);
416 if (low)
417 *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), index: 3);
418
419 return data != 0xff;
420}
421
422static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
423 struct rtw8852c_efuse *map)
424{
425 struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
426 bool valid = false;
427
428 valid |= _decode_efuse_gain(data: map->rx_gain_2g_cck,
429 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK],
430 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]);
431 valid |= _decode_efuse_gain(data: map->rx_gain_2g_ofdm,
432 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM],
433 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]);
434 valid |= _decode_efuse_gain(data: map->rx_gain_5g_low,
435 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW],
436 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]);
437 valid |= _decode_efuse_gain(data: map->rx_gain_5g_mid,
438 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID],
439 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]);
440 valid |= _decode_efuse_gain(data: map->rx_gain_5g_high,
441 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH],
442 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]);
443 valid |= _decode_efuse_gain(data: map->rx_gain_6g_l0,
444 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0],
445 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0]);
446 valid |= _decode_efuse_gain(data: map->rx_gain_6g_l1,
447 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1],
448 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1]);
449 valid |= _decode_efuse_gain(data: map->rx_gain_6g_m0,
450 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0],
451 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0]);
452 valid |= _decode_efuse_gain(data: map->rx_gain_6g_m1,
453 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1],
454 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1]);
455 valid |= _decode_efuse_gain(data: map->rx_gain_6g_h0,
456 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0],
457 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0]);
458 valid |= _decode_efuse_gain(data: map->rx_gain_6g_h1,
459 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1],
460 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1]);
461 valid |= _decode_efuse_gain(data: map->rx_gain_6g_uh0,
462 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0],
463 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0]);
464 valid |= _decode_efuse_gain(data: map->rx_gain_6g_uh1,
465 high: &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1],
466 low: &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1]);
467
468 gain->offset_valid = valid;
469}
470
471static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
472 enum rtw89_efuse_block block)
473{
474 struct rtw89_efuse *efuse = &rtwdev->efuse;
475 struct rtw8852c_efuse *map;
476
477 map = (struct rtw8852c_efuse *)log_map;
478
479 efuse->country_code[0] = map->country_code[0];
480 efuse->country_code[1] = map->country_code[1];
481 rtw8852c_efuse_parsing_tssi(rtwdev, map);
482 rtw8852c_efuse_parsing_gain_offset(rtwdev, map);
483
484 switch (rtwdev->hci.type) {
485 case RTW89_HCI_TYPE_PCIE:
486 rtw8852c_e_efuse_parsing(efuse, map);
487 break;
488 default:
489 return -ENOTSUPP;
490 }
491
492 rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
493
494 return 0;
495}
496
497static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
498{
499 struct rtw89_tssi_info *tssi = &rtwdev->tssi;
500 static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
501 static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
502 u32 addr = rtwdev->chip->phycap_addr;
503 bool pg = false;
504 u32 ofst;
505 u8 i, j;
506
507 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
508 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
509 /* addrs are in decreasing order */
510 ofst = tssi_trim_addr[i] - addr - j;
511 tssi->tssi_trim[i][j] = phycap_map[ofst];
512
513 if (phycap_map[ofst] != 0xff)
514 pg = true;
515 }
516
517 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
518 /* addrs are in decreasing order */
519 ofst = tssi_trim_addr_6g[i] - addr - j;
520 tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
521
522 if (phycap_map[ofst] != 0xff)
523 pg = true;
524 }
525 }
526
527 if (!pg) {
528 memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
529 memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
530 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
531 fmt: "[TSSI][TRIM] no PG, set all trim info to 0\n");
532 }
533
534 for (i = 0; i < RF_PATH_NUM_8852C; i++)
535 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
536 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
537 fmt: "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
538 i, j, tssi->tssi_trim[i][j],
539 tssi_trim_addr[i] - j);
540}
541
542static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
543 u8 *phycap_map)
544{
545 struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
546 static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
547 u32 addr = rtwdev->chip->phycap_addr;
548 u8 i;
549
550 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
551 info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
552
553 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
554 fmt: "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
555 i, info->thermal_trim[i]);
556
557 if (info->thermal_trim[i] != 0xff)
558 info->pg_thermal_trim = true;
559 }
560}
561
562static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
563{
564#define __thm_setting(raw) \
565({ \
566 u8 __v = (raw); \
567 ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \
568})
569 struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
570 u8 i, val;
571
572 if (!info->pg_thermal_trim) {
573 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
574 fmt: "[THERMAL][TRIM] no PG, do nothing\n");
575
576 return;
577 }
578
579 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
580 val = __thm_setting(info->thermal_trim[i]);
581 rtw89_write_rf(rtwdev, rf_path: i, RR_TM2, RR_TM2_OFF, data: val);
582
583 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
584 fmt: "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
585 i, val);
586 }
587#undef __thm_setting
588}
589
590static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
591 u8 *phycap_map)
592{
593 struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
594 static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
595 u32 addr = rtwdev->chip->phycap_addr;
596 u8 i;
597
598 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
599 info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
600
601 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
602 fmt: "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
603 i, info->pa_bias_trim[i]);
604
605 if (info->pa_bias_trim[i] != 0xff)
606 info->pg_pa_bias_trim = true;
607 }
608}
609
610static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
611{
612 struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
613 u8 pabias_2g, pabias_5g;
614 u8 i;
615
616 if (!info->pg_pa_bias_trim) {
617 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
618 fmt: "[PA_BIAS][TRIM] no PG, do nothing\n");
619
620 return;
621 }
622
623 for (i = 0; i < RF_PATH_NUM_8852C; i++) {
624 pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
625 pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
626
627 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
628 fmt: "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
629 i, pabias_2g, pabias_5g);
630
631 rtw89_write_rf(rtwdev, rf_path: i, RR_BIASA, RR_BIASA_TXG, data: pabias_2g);
632 rtw89_write_rf(rtwdev, rf_path: i, RR_BIASA, RR_BIASA_TXA, data: pabias_5g);
633 }
634}
635
636static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
637{
638 rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
639 rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
640 rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
641
642 return 0;
643}
644
645static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
646{
647 rtw8852c_thermal_trim(rtwdev);
648 rtw8852c_pa_bias_trim(rtwdev);
649}
650
651static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
652 const struct rtw89_chan *chan,
653 u8 mac_idx)
654{
655 u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, band: mac_idx);
656 u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, band: mac_idx);
657 u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, band: mac_idx);
658 u8 txsc20 = 0, txsc40 = 0, txsc80 = 0;
659 u8 rf_mod_val = 0, chk_rate_mask = 0;
660 u32 txsc;
661
662 switch (chan->band_width) {
663 case RTW89_CHANNEL_WIDTH_160:
664 txsc80 = rtw89_phy_get_txsc(rtwdev, chan,
665 dbw: RTW89_CHANNEL_WIDTH_80);
666 fallthrough;
667 case RTW89_CHANNEL_WIDTH_80:
668 txsc40 = rtw89_phy_get_txsc(rtwdev, chan,
669 dbw: RTW89_CHANNEL_WIDTH_40);
670 fallthrough;
671 case RTW89_CHANNEL_WIDTH_40:
672 txsc20 = rtw89_phy_get_txsc(rtwdev, chan,
673 dbw: RTW89_CHANNEL_WIDTH_20);
674 break;
675 default:
676 break;
677 }
678
679 switch (chan->band_width) {
680 case RTW89_CHANNEL_WIDTH_160:
681 rf_mod_val = AX_WMAC_RFMOD_160M;
682 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
683 FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) |
684 FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80);
685 break;
686 case RTW89_CHANNEL_WIDTH_80:
687 rf_mod_val = AX_WMAC_RFMOD_80M;
688 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
689 FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40);
690 break;
691 case RTW89_CHANNEL_WIDTH_40:
692 rf_mod_val = AX_WMAC_RFMOD_40M;
693 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20);
694 break;
695 case RTW89_CHANNEL_WIDTH_20:
696 default:
697 rf_mod_val = AX_WMAC_RFMOD_20M;
698 txsc = 0;
699 break;
700 }
701 rtw89_write8_mask(rtwdev, addr: rf_mod, B_AX_WMAC_RFMOD_MASK, data: rf_mod_val);
702 rtw89_write32(rtwdev, addr: sub_carr, data: txsc);
703
704 switch (chan->band_type) {
705 case RTW89_BAND_2G:
706 chk_rate_mask = B_AX_BAND_MODE;
707 break;
708 case RTW89_BAND_5G:
709 case RTW89_BAND_6G:
710 chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6;
711 break;
712 default:
713 rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
714 return;
715 }
716 rtw89_write8_clr(rtwdev, addr: chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN |
717 B_AX_RTS_LIMIT_IN_OFDM6);
718 rtw89_write8_set(rtwdev, addr: chk_rate, bit: chk_rate_mask);
719}
720
721static const u32 rtw8852c_sco_barker_threshold[14] = {
722 0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6,
723 0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a
724};
725
726static const u32 rtw8852c_sco_cck_threshold[14] = {
727 0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db,
728 0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e
729};
730
731static int rtw8852c_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch,
732 u8 primary_ch, enum rtw89_bandwidth bw)
733{
734 u8 ch_element;
735
736 if (bw == RTW89_CHANNEL_WIDTH_20) {
737 ch_element = central_ch - 1;
738 } else if (bw == RTW89_CHANNEL_WIDTH_40) {
739 if (primary_ch == 1)
740 ch_element = central_ch - 1 + 2;
741 else
742 ch_element = central_ch - 1 - 2;
743 } else {
744 rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw);
745 return -EINVAL;
746 }
747 rtw89_phy_write32_mask(rtwdev, R_BK_FC0_INV_V1, B_BK_FC0_INV_MSK_V1,
748 data: rtw8852c_sco_barker_threshold[ch_element]);
749 rtw89_phy_write32_mask(rtwdev, R_CCK_FC0_INV_V1, B_CCK_FC0_INV_MSK_V1,
750 data: rtw8852c_sco_cck_threshold[ch_element]);
751
752 return 0;
753}
754
755struct rtw8852c_bb_gain {
756 u32 gain_g[BB_PATH_NUM_8852C];
757 u32 gain_a[BB_PATH_NUM_8852C];
758 u32 gain_mask;
759};
760
761static const struct rtw8852c_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
762 { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
763 .gain_mask = 0x00ff0000 },
764 { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
765 .gain_mask = 0xff000000 },
766 { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
767 .gain_mask = 0x000000ff },
768 { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
769 .gain_mask = 0x0000ff00 },
770 { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
771 .gain_mask = 0x00ff0000 },
772 { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
773 .gain_mask = 0xff000000 },
774 { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
775 .gain_mask = 0x000000ff },
776};
777
778static const struct rtw8852c_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
779 { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
780 .gain_mask = 0x00ff0000 },
781 { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
782 .gain_mask = 0xff000000 },
783};
784
785struct rtw8852c_bb_gain_bypass {
786 u32 gain_g[BB_PATH_NUM_8852C];
787 u32 gain_a[BB_PATH_NUM_8852C];
788 u32 gain_mask_g;
789 u32 gain_mask_a;
790};
791
792static
793const struct rtw8852c_bb_gain_bypass bb_gain_bypass_lna[LNA_GAIN_NUM] = {
794 { .gain_g = {0x4BB8, 0x4C7C}, .gain_a = {0x4BB4, 0x4C78},
795 .gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
796 { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
797 .gain_mask_g = 0xff, .gain_mask_a = 0xff00},
798 { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
799 .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
800 { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
801 .gain_mask_g = 0xff0000, .gain_mask_a = 0xff000000},
802 { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB8, 0x4C7C},
803 .gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
804 { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
805 .gain_mask_g = 0xff, .gain_mask_a = 0xff00},
806 { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
807 .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
808};
809
810struct rtw8852c_bb_gain_op1db {
811 struct {
812 u32 lna[BB_PATH_NUM_8852C];
813 u32 tia_lna[BB_PATH_NUM_8852C];
814 u32 mask;
815 } reg[LNA_GAIN_NUM];
816 u32 reg_tia0_lna6[BB_PATH_NUM_8852C];
817 u32 mask_tia0_lna6;
818};
819
820static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = {
821 .reg = {
822 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
823 .mask = 0xff},
824 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
825 .mask = 0xff00},
826 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
827 .mask = 0xff0000},
828 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
829 .mask = 0xff000000},
830 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
831 .mask = 0xff},
832 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
833 .mask = 0xff00},
834 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
835 .mask = 0xff0000},
836 },
837 .reg_tia0_lna6 = {0x4674, 0x4758},
838 .mask_tia0_lna6 = 0xff000000,
839};
840
841static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev,
842 enum rtw89_subband subband,
843 enum rtw89_rf_path path)
844{
845 const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
846 u8 gain_band = rtw89_subband_to_bb_gain_band(subband);
847 s32 val;
848 u32 reg;
849 u32 mask;
850 int i;
851
852 for (i = 0; i < LNA_GAIN_NUM; i++) {
853 if (subband == RTW89_CH_2G)
854 reg = bb_gain_lna[i].gain_g[path];
855 else
856 reg = bb_gain_lna[i].gain_a[path];
857
858 mask = bb_gain_lna[i].gain_mask;
859 val = gain->lna_gain[gain_band][path][i];
860 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
861
862 if (subband == RTW89_CH_2G) {
863 reg = bb_gain_bypass_lna[i].gain_g[path];
864 mask = bb_gain_bypass_lna[i].gain_mask_g;
865 } else {
866 reg = bb_gain_bypass_lna[i].gain_a[path];
867 mask = bb_gain_bypass_lna[i].gain_mask_a;
868 }
869
870 val = gain->lna_gain_bypass[gain_band][path][i];
871 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
872
873 if (subband != RTW89_CH_2G) {
874 reg = bb_gain_op1db_a.reg[i].lna[path];
875 mask = bb_gain_op1db_a.reg[i].mask;
876 val = gain->lna_op1db[gain_band][path][i];
877 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
878
879 reg = bb_gain_op1db_a.reg[i].tia_lna[path];
880 mask = bb_gain_op1db_a.reg[i].mask;
881 val = gain->tia_lna_op1db[gain_band][path][i];
882 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
883 }
884 }
885
886 if (subband != RTW89_CH_2G) {
887 reg = bb_gain_op1db_a.reg_tia0_lna6[path];
888 mask = bb_gain_op1db_a.mask_tia0_lna6;
889 val = gain->tia_lna_op1db[gain_band][path][7];
890 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
891 }
892
893 for (i = 0; i < TIA_GAIN_NUM; i++) {
894 if (subband == RTW89_CH_2G)
895 reg = bb_gain_tia[i].gain_g[path];
896 else
897 reg = bb_gain_tia[i].gain_a[path];
898
899 mask = bb_gain_tia[i].gain_mask;
900 val = gain->tia_gain[gain_band][path][i];
901 rtw89_phy_write32_mask(rtwdev, addr: reg, mask, data: val);
902 }
903}
904
905static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
906 const struct rtw89_chan *chan,
907 enum rtw89_phy_idx phy_idx,
908 enum rtw89_rf_path path)
909{
910 static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA0_LNA6_OP1DB_V1,
911 R_PATH1_G_TIA0_LNA6_OP1DB_V1};
912 static const u32 rpl_mask[2] = {B_RPL_PATHA_MASK, B_RPL_PATHB_MASK};
913 static const u32 rpl_tb_mask[2] = {B_RSSI_M_PATHA_MASK, B_RSSI_M_PATHB_MASK};
914 struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain;
915 enum rtw89_gain_offset gain_band;
916 s32 offset_q0, offset_base_q4;
917 s32 tmp = 0;
918
919 if (!efuse_gain->offset_valid)
920 return;
921
922 if (rtwdev->dbcc_en && path == RF_PATH_B)
923 phy_idx = RTW89_PHY_1;
924
925 if (chan->band_type == RTW89_BAND_2G) {
926 offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK];
927 offset_base_q4 = efuse_gain->offset_base[phy_idx];
928
929 tmp = clamp_t(s32, (-offset_q0 << 3) + (offset_base_q4 >> 1),
930 S8_MIN >> 1, S8_MAX >> 1);
931 rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, data: tmp & 0x7f);
932 }
933
934 gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband: chan->subband_type);
935
936 offset_q0 = -efuse_gain->offset[path][gain_band];
937 offset_base_q4 = efuse_gain->offset_base[phy_idx];
938
939 tmp = (offset_q0 << 2) + (offset_base_q4 >> 2);
940 tmp = clamp_t(s32, -tmp, S8_MIN, S8_MAX);
941 rtw89_phy_write32_mask(rtwdev, addr: rssi_ofst_addr[path], B_PATH0_R_G_OFST_MASK, data: tmp & 0xff);
942
943 tmp = clamp_t(s32, offset_q0 << 4, S8_MIN, S8_MAX);
944 rtw89_phy_write32_idx(rtwdev, R_RPL_PATHAB, mask: rpl_mask[path], data: tmp & 0xff, phy_idx);
945 rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, mask: rpl_tb_mask[path], data: tmp & 0xff, phy_idx);
946}
947
948static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
949 const struct rtw89_chan *chan,
950 enum rtw89_phy_idx phy_idx)
951{
952 u8 sco;
953 u16 central_freq = chan->freq;
954 u8 central_ch = chan->channel;
955 u8 band = chan->band_type;
956 u8 subband = chan->subband_type;
957 bool is_2g = band == RTW89_BAND_2G;
958 u8 chan_idx;
959
960 if (!central_freq) {
961 rtw89_warn(rtwdev, "Invalid central_freq\n");
962 return;
963 }
964
965 if (phy_idx == RTW89_PHY_0) {
966 /* Path A */
967 rtw8852c_set_gain_error(rtwdev, subband, path: RF_PATH_A);
968 rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, path: RF_PATH_A);
969
970 if (is_2g)
971 rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
972 B_PATH0_BAND_SEL_MSK_V1, data: 1,
973 phy_idx);
974 else
975 rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
976 B_PATH0_BAND_SEL_MSK_V1, data: 0,
977 phy_idx);
978 /* Path B */
979 if (!rtwdev->dbcc_en) {
980 rtw8852c_set_gain_error(rtwdev, subband, path: RF_PATH_B);
981 rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, path: RF_PATH_B);
982
983 if (is_2g)
984 rtw89_phy_write32_idx(rtwdev,
985 R_PATH1_BAND_SEL_V1,
986 B_PATH1_BAND_SEL_MSK_V1,
987 data: 1, phy_idx);
988 else
989 rtw89_phy_write32_idx(rtwdev,
990 R_PATH1_BAND_SEL_V1,
991 B_PATH1_BAND_SEL_MSK_V1,
992 data: 0, phy_idx);
993 rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
994 } else {
995 if (is_2g)
996 rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
997 else
998 rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
999 }
1000 /* SCO compensate FC setting */
1001 rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
1002 data: central_freq, phy_idx);
1003 /* round_up((1/fc0)*pow(2,18)) */
1004 sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
1005 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, data: sco,
1006 phy_idx);
1007 } else {
1008 /* Path B */
1009 rtw8852c_set_gain_error(rtwdev, subband, path: RF_PATH_B);
1010 rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, path: RF_PATH_B);
1011
1012 if (is_2g)
1013 rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
1014 B_PATH1_BAND_SEL_MSK_V1,
1015 data: 1, phy_idx);
1016 else
1017 rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
1018 B_PATH1_BAND_SEL_MSK_V1,
1019 data: 0, phy_idx);
1020 /* SCO compensate FC setting */
1021 rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
1022 data: central_freq, phy_idx);
1023 /* round_up((1/fc0)*pow(2,18)) */
1024 sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
1025 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, data: sco,
1026 phy_idx);
1027 }
1028 /* CCK parameters */
1029 if (band == RTW89_BAND_2G) {
1030 if (central_ch == 14) {
1031 rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
1032 B_PCOEFF01_MSK_V1, data: 0x3b13ff);
1033 rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
1034 B_PCOEFF23_MSK_V1, data: 0x1c42de);
1035 rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
1036 B_PCOEFF45_MSK_V1, data: 0xfdb0ad);
1037 rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
1038 B_PCOEFF67_MSK_V1, data: 0xf60f6e);
1039 rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
1040 B_PCOEFF89_MSK_V1, data: 0xfd8f92);
1041 rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
1042 B_PCOEFFAB_MSK_V1, data: 0x2d011);
1043 rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
1044 B_PCOEFFCD_MSK_V1, data: 0x1c02c);
1045 rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
1046 B_PCOEFFEF_MSK_V1, data: 0xfff00a);
1047 } else {
1048 rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
1049 B_PCOEFF01_MSK_V1, data: 0x3d23ff);
1050 rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
1051 B_PCOEFF23_MSK_V1, data: 0x29b354);
1052 rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
1053 B_PCOEFF45_MSK_V1, data: 0xfc1c8);
1054 rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
1055 B_PCOEFF67_MSK_V1, data: 0xfdb053);
1056 rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
1057 B_PCOEFF89_MSK_V1, data: 0xf86f9a);
1058 rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
1059 B_PCOEFFAB_MSK_V1, data: 0xfaef92);
1060 rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
1061 B_PCOEFFCD_MSK_V1, data: 0xfe5fcc);
1062 rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
1063 B_PCOEFFEF_MSK_V1, data: 0xffdff5);
1064 }
1065 }
1066
1067 chan_idx = rtw89_encode_chan_idx(rtwdev, central_ch: chan->primary_channel, band);
1068 rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, data: chan_idx, phy_idx);
1069}
1070
1071static void rtw8852c_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path)
1072{
1073 static const u32 adc_sel[2] = {0xC0EC, 0xC1EC};
1074 static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
1075
1076 switch (bw) {
1077 case RTW89_CHANNEL_WIDTH_5:
1078 rtw89_phy_write32_mask(rtwdev, addr: adc_sel[path], mask: 0x6000, data: 0x1);
1079 rtw89_phy_write32_mask(rtwdev, addr: wbadc_sel[path], mask: 0x30, data: 0x0);
1080 break;
1081 case RTW89_CHANNEL_WIDTH_10:
1082 rtw89_phy_write32_mask(rtwdev, addr: adc_sel[path], mask: 0x6000, data: 0x2);
1083 rtw89_phy_write32_mask(rtwdev, addr: wbadc_sel[path], mask: 0x30, data: 0x1);
1084 break;
1085 case RTW89_CHANNEL_WIDTH_20:
1086 case RTW89_CHANNEL_WIDTH_40:
1087 case RTW89_CHANNEL_WIDTH_80:
1088 case RTW89_CHANNEL_WIDTH_160:
1089 rtw89_phy_write32_mask(rtwdev, addr: adc_sel[path], mask: 0x6000, data: 0x0);
1090 rtw89_phy_write32_mask(rtwdev, addr: wbadc_sel[path], mask: 0x30, data: 0x2);
1091 break;
1092 default:
1093 rtw89_warn(rtwdev, "Fail to set ADC\n");
1094 }
1095}
1096
1097static void rtw8852c_edcca_per20_bitmap_sifs(struct rtw89_dev *rtwdev, u8 bw,
1098 enum rtw89_phy_idx phy_idx)
1099{
1100 if (bw == RTW89_CHANNEL_WIDTH_20) {
1101 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, data: 0xff, phy_idx);
1102 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, data: 0, phy_idx);
1103 } else {
1104 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, data: 0, phy_idx);
1105 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, data: 0, phy_idx);
1106 }
1107}
1108
1109static void
1110rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
1111 enum rtw89_phy_idx phy_idx)
1112{
1113 u8 mod_sbw = 0;
1114
1115 switch (bw) {
1116 case RTW89_CHANNEL_WIDTH_5:
1117 case RTW89_CHANNEL_WIDTH_10:
1118 case RTW89_CHANNEL_WIDTH_20:
1119 if (bw == RTW89_CHANNEL_WIDTH_5)
1120 mod_sbw = 0x1;
1121 else if (bw == RTW89_CHANNEL_WIDTH_10)
1122 mod_sbw = 0x2;
1123 else if (bw == RTW89_CHANNEL_WIDTH_20)
1124 mod_sbw = 0x0;
1125 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, data: 0x0,
1126 phy_idx);
1127 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW,
1128 data: mod_sbw, phy_idx);
1129 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, data: 0x0,
1130 phy_idx);
1131 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
1132 B_PATH0_SAMPL_DLY_T_MSK_V1, data: 0x3);
1133 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
1134 B_PATH1_SAMPL_DLY_T_MSK_V1, data: 0x3);
1135 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
1136 B_PATH0_BW_SEL_MSK_V1, data: 0xf);
1137 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
1138 B_PATH1_BW_SEL_MSK_V1, data: 0xf);
1139 break;
1140 case RTW89_CHANNEL_WIDTH_40:
1141 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, data: 0x1,
1142 phy_idx);
1143 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, data: 0x0,
1144 phy_idx);
1145 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
1146 data: pri_ch,
1147 phy_idx);
1148 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
1149 B_PATH0_SAMPL_DLY_T_MSK_V1, data: 0x3);
1150 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
1151 B_PATH1_SAMPL_DLY_T_MSK_V1, data: 0x3);
1152 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
1153 B_PATH0_BW_SEL_MSK_V1, data: 0xf);
1154 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
1155 B_PATH1_BW_SEL_MSK_V1, data: 0xf);
1156 break;
1157 case RTW89_CHANNEL_WIDTH_80:
1158 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, data: 0x2,
1159 phy_idx);
1160 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, data: 0x0,
1161 phy_idx);
1162 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
1163 data: pri_ch,
1164 phy_idx);
1165 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
1166 B_PATH0_SAMPL_DLY_T_MSK_V1, data: 0x2);
1167 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
1168 B_PATH1_SAMPL_DLY_T_MSK_V1, data: 0x2);
1169 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
1170 B_PATH0_BW_SEL_MSK_V1, data: 0xd);
1171 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
1172 B_PATH1_BW_SEL_MSK_V1, data: 0xd);
1173 break;
1174 case RTW89_CHANNEL_WIDTH_160:
1175 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, data: 0x3,
1176 phy_idx);
1177 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, data: 0x0,
1178 phy_idx);
1179 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
1180 data: pri_ch,
1181 phy_idx);
1182 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
1183 B_PATH0_SAMPL_DLY_T_MSK_V1, data: 0x1);
1184 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
1185 B_PATH1_SAMPL_DLY_T_MSK_V1, data: 0x1);
1186 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
1187 B_PATH0_BW_SEL_MSK_V1, data: 0xb);
1188 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
1189 B_PATH1_BW_SEL_MSK_V1, data: 0xb);
1190 break;
1191 default:
1192 rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
1193 pri_ch);
1194 }
1195
1196 if (bw == RTW89_CHANNEL_WIDTH_40) {
1197 rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
1198 B_RX_BW40_2XFFT_EN_MSK_V1, data: 0x1, phy_idx);
1199 rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, data: 1, phy_idx);
1200 } else {
1201 rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
1202 B_RX_BW40_2XFFT_EN_MSK_V1, data: 0x0, phy_idx);
1203 rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, data: 0, phy_idx);
1204 }
1205
1206 if (phy_idx == RTW89_PHY_0) {
1207 rtw8852c_bw_setting(rtwdev, bw, path: RF_PATH_A);
1208 if (!rtwdev->dbcc_en)
1209 rtw8852c_bw_setting(rtwdev, bw, path: RF_PATH_B);
1210 } else {
1211 rtw8852c_bw_setting(rtwdev, bw, path: RF_PATH_B);
1212 }
1213
1214 rtw8852c_edcca_per20_bitmap_sifs(rtwdev, bw, phy_idx);
1215}
1216
1217static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
1218 const struct rtw89_chan *chan)
1219{
1220 u8 center_chan = chan->channel;
1221 u8 bw = chan->band_width;
1222
1223 switch (chan->band_type) {
1224 case RTW89_BAND_2G:
1225 if (bw == RTW89_CHANNEL_WIDTH_20) {
1226 if (center_chan >= 5 && center_chan <= 8)
1227 return 2440;
1228 if (center_chan == 13)
1229 return 2480;
1230 } else if (bw == RTW89_CHANNEL_WIDTH_40) {
1231 if (center_chan >= 3 && center_chan <= 10)
1232 return 2440;
1233 }
1234 break;
1235 case RTW89_BAND_5G:
1236 if (center_chan == 151 || center_chan == 153 ||
1237 center_chan == 155 || center_chan == 163)
1238 return 5760;
1239 break;
1240 case RTW89_BAND_6G:
1241 if (center_chan == 195 || center_chan == 197 ||
1242 center_chan == 199 || center_chan == 207)
1243 return 6920;
1244 break;
1245 default:
1246 break;
1247 }
1248
1249 return 0;
1250}
1251
1252#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
1253#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
1254#define MAX_TONE_NUM 2048
1255
1256static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev,
1257 const struct rtw89_chan *chan,
1258 enum rtw89_phy_idx phy_idx)
1259{
1260 u32 spur_freq;
1261 s32 freq_diff, csi_idx, csi_tone_idx;
1262
1263 spur_freq = rtw8852c_spur_freq(rtwdev, chan);
1264 if (spur_freq == 0) {
1265 rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, data: 0, phy_idx);
1266 return;
1267 }
1268
1269 freq_diff = (spur_freq - chan->freq) * 1000000;
1270 csi_idx = s32_div_u32_round_closest(dividend: freq_diff, CARRIER_SPACING_78_125);
1271 s32_div_u32_round_down(dividend: csi_idx, MAX_TONE_NUM, remainder: &csi_tone_idx);
1272
1273 rtw89_phy_write32_idx(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, data: csi_tone_idx, phy_idx);
1274 rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, data: 1, phy_idx);
1275}
1276
1277static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = {
1278 [RF_PATH_A] = {
1279 .notch1_idx = {0x4C14, 0xFF},
1280 .notch1_frac_idx = {0x4C14, 0xC00},
1281 .notch1_en = {0x4C14, 0x1000},
1282 .notch2_idx = {0x4C20, 0xFF},
1283 .notch2_frac_idx = {0x4C20, 0xC00},
1284 .notch2_en = {0x4C20, 0x1000},
1285 },
1286 [RF_PATH_B] = {
1287 .notch1_idx = {0x4CD8, 0xFF},
1288 .notch1_frac_idx = {0x4CD8, 0xC00},
1289 .notch1_en = {0x4CD8, 0x1000},
1290 .notch2_idx = {0x4CE4, 0xFF},
1291 .notch2_frac_idx = {0x4CE4, 0xC00},
1292 .notch2_en = {0x4CE4, 0x1000},
1293 },
1294};
1295
1296static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
1297 const struct rtw89_chan *chan,
1298 enum rtw89_rf_path path)
1299{
1300 const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path];
1301 u32 spur_freq, fc;
1302 s32 freq_diff;
1303 s32 nbi_idx, nbi_tone_idx;
1304 s32 nbi_frac_idx, nbi_frac_tone_idx;
1305 bool notch2_chk = false;
1306
1307 spur_freq = rtw8852c_spur_freq(rtwdev, chan);
1308 if (spur_freq == 0) {
1309 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_en.addr, mask: nbi->notch1_en.mask, data: 0);
1310 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_en.addr, mask: nbi->notch1_en.mask, data: 0);
1311 return;
1312 }
1313
1314 fc = chan->freq;
1315 if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
1316 fc = (spur_freq > fc) ? fc + 40 : fc - 40;
1317 if ((fc > spur_freq &&
1318 chan->channel < chan->primary_channel) ||
1319 (fc < spur_freq &&
1320 chan->channel > chan->primary_channel))
1321 notch2_chk = true;
1322 }
1323
1324 freq_diff = (spur_freq - fc) * 1000000;
1325 nbi_idx = s32_div_u32_round_down(dividend: freq_diff, CARRIER_SPACING_312_5, remainder: &nbi_frac_idx);
1326
1327 if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
1328 s32_div_u32_round_down(dividend: nbi_idx + 32, divisor: 64, remainder: &nbi_tone_idx);
1329 } else {
1330 u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
1331 128 : 256;
1332
1333 s32_div_u32_round_down(dividend: nbi_idx, divisor: tone_para, remainder: &nbi_tone_idx);
1334 }
1335 nbi_frac_tone_idx = s32_div_u32_round_closest(dividend: nbi_frac_idx, CARRIER_SPACING_78_125);
1336
1337 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
1338 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch2_idx.addr,
1339 mask: nbi->notch2_idx.mask, data: nbi_tone_idx);
1340 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch2_frac_idx.addr,
1341 mask: nbi->notch2_frac_idx.mask, data: nbi_frac_tone_idx);
1342 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch2_en.addr, mask: nbi->notch2_en.mask, data: 0);
1343 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch2_en.addr, mask: nbi->notch2_en.mask, data: 1);
1344 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_en.addr, mask: nbi->notch1_en.mask, data: 0);
1345 } else {
1346 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_idx.addr,
1347 mask: nbi->notch1_idx.mask, data: nbi_tone_idx);
1348 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_frac_idx.addr,
1349 mask: nbi->notch1_frac_idx.mask, data: nbi_frac_tone_idx);
1350 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_en.addr, mask: nbi->notch1_en.mask, data: 0);
1351 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch1_en.addr, mask: nbi->notch1_en.mask, data: 1);
1352 rtw89_phy_write32_mask(rtwdev, addr: nbi->notch2_en.addr, mask: nbi->notch2_en.mask, data: 0);
1353 }
1354}
1355
1356static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val,
1357 enum rtw89_phy_idx phy_idx)
1358{
1359 u32 notch;
1360 u32 notch2;
1361
1362 if (phy_idx == RTW89_PHY_0) {
1363 notch = R_PATH0_NOTCH;
1364 notch2 = R_PATH0_NOTCH2;
1365 } else {
1366 notch = R_PATH1_NOTCH;
1367 notch2 = R_PATH1_NOTCH2;
1368 }
1369
1370 rtw89_phy_write32_mask(rtwdev, addr: notch,
1371 B_PATH0_NOTCH_VAL | B_PATH0_NOTCH_EN, data: val);
1372 rtw89_phy_write32_set(rtwdev, addr: notch, B_PATH0_NOTCH_EN);
1373 rtw89_phy_write32_mask(rtwdev, addr: notch2,
1374 B_PATH0_NOTCH2_VAL | B_PATH0_NOTCH2_EN, data: val);
1375 rtw89_phy_write32_set(rtwdev, addr: notch2, B_PATH0_NOTCH2_EN);
1376}
1377
1378static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
1379 const struct rtw89_chan *chan,
1380 u8 pri_ch_idx,
1381 enum rtw89_phy_idx phy_idx)
1382{
1383 rtw8852c_set_csi_tone_idx(rtwdev, chan, phy_idx);
1384
1385 if (phy_idx == RTW89_PHY_0) {
1386 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
1387 (pri_ch_idx == RTW89_SC_20_LOWER ||
1388 pri_ch_idx == RTW89_SC_20_UP3X)) {
1389 rtw8852c_spur_notch(rtwdev, val: 0xe7f, phy_idx: RTW89_PHY_0);
1390 if (!rtwdev->dbcc_en)
1391 rtw8852c_spur_notch(rtwdev, val: 0xe7f, phy_idx: RTW89_PHY_1);
1392 } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
1393 (pri_ch_idx == RTW89_SC_20_UPPER ||
1394 pri_ch_idx == RTW89_SC_20_LOW3X)) {
1395 rtw8852c_spur_notch(rtwdev, val: 0x280, phy_idx: RTW89_PHY_0);
1396 if (!rtwdev->dbcc_en)
1397 rtw8852c_spur_notch(rtwdev, val: 0x280, phy_idx: RTW89_PHY_1);
1398 } else {
1399 rtw8852c_set_nbi_tone_idx(rtwdev, chan, path: RF_PATH_A);
1400 if (!rtwdev->dbcc_en)
1401 rtw8852c_set_nbi_tone_idx(rtwdev, chan,
1402 path: RF_PATH_B);
1403 }
1404 } else {
1405 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
1406 (pri_ch_idx == RTW89_SC_20_LOWER ||
1407 pri_ch_idx == RTW89_SC_20_UP3X)) {
1408 rtw8852c_spur_notch(rtwdev, val: 0xe7f, phy_idx: RTW89_PHY_1);
1409 } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
1410 (pri_ch_idx == RTW89_SC_20_UPPER ||
1411 pri_ch_idx == RTW89_SC_20_LOW3X)) {
1412 rtw8852c_spur_notch(rtwdev, val: 0x280, phy_idx: RTW89_PHY_1);
1413 } else {
1414 rtw8852c_set_nbi_tone_idx(rtwdev, chan, path: RF_PATH_B);
1415 }
1416 }
1417
1418 if (pri_ch_idx == RTW89_SC_20_UP3X || pri_ch_idx == RTW89_SC_20_LOW3X)
1419 rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, data: 0, phy_idx);
1420 else
1421 rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, data: 1, phy_idx);
1422}
1423
1424static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
1425 const struct rtw89_chan *chan,
1426 enum rtw89_phy_idx phy_idx)
1427{
1428 u8 pri_ch = chan->pri_ch_idx;
1429 bool mask_5m_low;
1430 bool mask_5m_en;
1431
1432 switch (chan->band_width) {
1433 case RTW89_CHANNEL_WIDTH_40:
1434 mask_5m_en = true;
1435 mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
1436 break;
1437 case RTW89_CHANNEL_WIDTH_80:
1438 mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
1439 pri_ch == RTW89_SC_20_LOWEST;
1440 mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
1441 break;
1442 default:
1443 mask_5m_en = false;
1444 mask_5m_low = false;
1445 break;
1446 }
1447
1448 if (!mask_5m_en) {
1449 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, data: 0x0);
1450 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, data: 0x0);
1451 rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT,
1452 B_ASSIGN_SBD_OPT_EN, data: 0x0, phy_idx);
1453 } else {
1454 if (mask_5m_low) {
1455 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, data: 0x4);
1456 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, data: 0x1);
1457 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, data: 0x0);
1458 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, data: 0x1);
1459 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, data: 0x4);
1460 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, data: 0x1);
1461 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, data: 0x0);
1462 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, data: 0x1);
1463 } else {
1464 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, data: 0x4);
1465 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, data: 0x1);
1466 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, data: 0x1);
1467 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, data: 0x0);
1468 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, data: 0x4);
1469 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, data: 0x1);
1470 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, data: 0x1);
1471 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, data: 0x0);
1472 }
1473 rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, data: 0x1, phy_idx);
1474 }
1475}
1476
1477static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev,
1478 enum rtw89_phy_idx phy_idx)
1479{
1480 /*HW SI reset*/
1481 rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
1482 data: 0x7);
1483 rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
1484 data: 0x7);
1485
1486 udelay(1);
1487
1488 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, data: 1,
1489 phy_idx);
1490 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, data: 0,
1491 phy_idx);
1492 /*HW SI reset*/
1493 rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
1494 data: 0x0);
1495 rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
1496 data: 0x0);
1497
1498 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, data: 1,
1499 phy_idx);
1500}
1501
1502static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
1503 enum rtw89_phy_idx phy_idx, bool en)
1504{
1505 if (en) {
1506 rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
1507 B_S0_HW_SI_DIS_W_R_TRIG, data: 0x0, phy_idx);
1508 rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
1509 B_S1_HW_SI_DIS_W_R_TRIG, data: 0x0, phy_idx);
1510 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, data: 1,
1511 phy_idx);
1512 if (band == RTW89_BAND_2G)
1513 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, data: 0x0);
1514 rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, data: 0x0);
1515 } else {
1516 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, data: 0x1);
1517 rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, data: 0x1);
1518 rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
1519 B_S0_HW_SI_DIS_W_R_TRIG, data: 0x7, phy_idx);
1520 rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
1521 B_S1_HW_SI_DIS_W_R_TRIG, data: 0x7, phy_idx);
1522 fsleep(usecs: 1);
1523 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, data: 0,
1524 phy_idx);
1525 }
1526}
1527
1528static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev,
1529 enum rtw89_phy_idx phy_idx)
1530{
1531 rtw8852c_bb_reset_all(rtwdev, phy_idx);
1532}
1533
1534static
1535void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
1536 u8 tx_path_en, u8 trsw_tx,
1537 u8 trsw_rx, u8 trsw, u8 trsw_b)
1538{
1539 static const u32 path_cr_bases[] = {0x5868, 0x7868};
1540 u32 mask_ofst = 16;
1541 u32 cr;
1542 u32 val;
1543
1544 if (path >= ARRAY_SIZE(path_cr_bases))
1545 return;
1546
1547 cr = path_cr_bases[path];
1548
1549 mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2;
1550 val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b);
1551
1552 rtw89_phy_write32_mask(rtwdev, addr: cr, mask: (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, data: val);
1553}
1554
1555enum rtw8852c_rfe_src {
1556 PAPE_RFM,
1557 TRSW_RFM,
1558 LNAON_RFM,
1559};
1560
1561static
1562void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
1563 enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl,
1564 u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val)
1565{
1566 static const u32 path_cr_bases[] = {0x5894, 0x7894};
1567 static const u32 masks[] = {0, 8, 16};
1568 u32 mask, mask_ofst;
1569 u32 cr;
1570 u32 val;
1571
1572 if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases))
1573 return;
1574
1575 mask_ofst = masks[src];
1576 cr = path_cr_bases[path];
1577
1578 val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) |
1579 FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) |
1580 FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) |
1581 FIELD_PREP(B_P0_RFM_OUT, rfm_output_val);
1582 mask = 0xff << mask_ofst;
1583
1584 rtw89_phy_write32_mask(rtwdev, addr: cr, mask, data: val);
1585}
1586
1587static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev)
1588{
1589 static const u32 cr_bases[] = {0x5800, 0x7800};
1590 u32 addr;
1591 u8 i;
1592
1593 for (i = 0; i < ARRAY_SIZE(cr_bases); i++) {
1594 addr = cr_bases[i];
1595 rtw89_phy_write32_set(rtwdev, addr: (addr | 0x68), B_P0_TRSW_A);
1596 rtw89_phy_write32_clr(rtwdev, addr: (addr | 0x68), B_P0_TRSW_X);
1597 rtw89_phy_write32_clr(rtwdev, addr: (addr | 0x68), B_P0_TRSW_SO_A2);
1598 rtw89_phy_write32(rtwdev, addr: (addr | 0x80), data: 0x77777777);
1599 rtw89_phy_write32(rtwdev, addr: (addr | 0x84), data: 0x77777777);
1600 }
1601
1602 rtw89_phy_write32(rtwdev, R_RFE_E_A2, data: 0xffffffff);
1603 rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, data: 0);
1604 rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, data: 0);
1605 rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, data: 0);
1606
1607 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 0, trsw_tx: 0, trsw_rx: 0, trsw: 0, trsw_b: 1);
1608 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 0, trsw_tx: 0, trsw_rx: 1, trsw: 1, trsw_b: 0);
1609 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 0, trsw_tx: 1, trsw_rx: 0, trsw: 1, trsw_b: 0);
1610 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 0, trsw_tx: 1, trsw_rx: 1, trsw: 1, trsw_b: 0);
1611 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 1, trsw_tx: 0, trsw_rx: 0, trsw: 0, trsw_b: 1);
1612 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 1, trsw_tx: 0, trsw_rx: 1, trsw: 1, trsw_b: 0);
1613 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 1, trsw_tx: 1, trsw_rx: 0, trsw: 1, trsw_b: 0);
1614 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_A, tx_path_en: 1, trsw_tx: 1, trsw_rx: 1, trsw: 1, trsw_b: 0);
1615
1616 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 0, trsw_tx: 0, trsw_rx: 0, trsw: 0, trsw_b: 1);
1617 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 0, trsw_tx: 0, trsw_rx: 1, trsw: 1, trsw_b: 0);
1618 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 0, trsw_tx: 1, trsw_rx: 0, trsw: 1, trsw_b: 0);
1619 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 0, trsw_tx: 1, trsw_rx: 1, trsw: 1, trsw_b: 0);
1620 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 1, trsw_tx: 0, trsw_rx: 0, trsw: 0, trsw_b: 1);
1621 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 1, trsw_tx: 0, trsw_rx: 1, trsw: 1, trsw_b: 0);
1622 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 1, trsw_tx: 1, trsw_rx: 0, trsw: 1, trsw_b: 0);
1623 rtw8852c_bb_gpio_trsw(rtwdev, path: RF_PATH_B, tx_path_en: 1, trsw_tx: 1, trsw_rx: 1, trsw: 1, trsw_b: 0);
1624
1625 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_A, src: PAPE_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x0);
1626 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_A, src: TRSW_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x4);
1627 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_A, src: LNAON_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x8);
1628
1629 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_B, src: PAPE_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x0);
1630 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_B, src: TRSW_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x4);
1631 rtw8852c_bb_gpio_rfm(rtwdev, path: RF_PATH_B, src: LNAON_RFM, dis_tx_gnt_wl: 0, active_tx_opt: 0, act_bt_en: 0, rfm_output_val: 0x8);
1632}
1633
1634static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
1635 enum rtw89_phy_idx phy_idx)
1636{
1637 u32 addr;
1638
1639 for (addr = R_AX_PWR_MACID_LMT_TABLE0;
1640 addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
1641 rtw89_mac_txpwr_write32(rtwdev, phy_idx, reg_base: addr, val: 0);
1642}
1643
1644static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev)
1645{
1646 struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1647
1648 rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT,
1649 B_DBCC_80P80_SEL_EVM_RPT_EN);
1650 rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2,
1651 B_DBCC_80P80_SEL_EVM_RPT2_EN);
1652
1653 rtw8852c_bb_macid_ctrl_init(rtwdev, phy_idx: RTW89_PHY_0);
1654 rtw8852c_bb_gpio_init(rtwdev);
1655
1656 /* read these registers after loading BB parameters */
1657 gain->offset_base[RTW89_PHY_0] =
1658 rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK);
1659 gain->offset_base[RTW89_PHY_1] =
1660 rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK);
1661}
1662
1663static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
1664 const struct rtw89_chan *chan,
1665 enum rtw89_phy_idx phy_idx)
1666{
1667 static const u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
1668 B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
1669 struct rtw89_hal *hal = &rtwdev->hal;
1670 bool cck_en = chan->band_type == RTW89_BAND_2G;
1671 u8 pri_ch_idx = chan->pri_ch_idx;
1672 u32 mask, reg;
1673 u8 ntx_path;
1674
1675 if (chan->band_type == RTW89_BAND_2G)
1676 rtw8852c_ctrl_sco_cck(rtwdev, central_ch: chan->channel,
1677 primary_ch: chan->primary_channel,
1678 bw: chan->band_width);
1679
1680 rtw8852c_ctrl_ch(rtwdev, chan, phy_idx);
1681 rtw8852c_ctrl_bw(rtwdev, pri_ch: pri_ch_idx, bw: chan->band_width, phy_idx);
1682 if (cck_en) {
1683 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, data: 1);
1684 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, data: 0);
1685 rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
1686 B_PD_ARBITER_OFF, data: 0x0, phy_idx);
1687 } else {
1688 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, data: 0);
1689 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, data: 1);
1690 rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
1691 B_PD_ARBITER_OFF, data: 0x1, phy_idx);
1692 }
1693
1694 rtw8852c_spur_elimination(rtwdev, chan, pri_ch_idx, phy_idx);
1695 rtw8852c_ctrl_btg_bt_rx(rtwdev, en: chan->band_type == RTW89_BAND_2G,
1696 phy_idx: RTW89_PHY_0);
1697 rtw8852c_5m_mask(rtwdev, chan, phy_idx);
1698
1699 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
1700 rtwdev->hal.cv != CHIP_CAV) {
1701 rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ,
1702 B_P80_AT_HIGH_FREQ, data: 0x0, phy_idx);
1703 reg = rtw89_mac_reg_by_idx(rtwdev, R_P80_AT_HIGH_FREQ_BB_WRP, band: phy_idx);
1704 if (chan->primary_channel > chan->channel) {
1705 rtw89_phy_write32_mask(rtwdev,
1706 R_P80_AT_HIGH_FREQ_RU_ALLOC,
1707 mask: ru_alloc_msk[phy_idx], data: 1);
1708 rtw89_write32_mask(rtwdev, addr: reg,
1709 B_P80_AT_HIGH_FREQ_BB_WRP, data: 1);
1710 } else {
1711 rtw89_phy_write32_mask(rtwdev,
1712 R_P80_AT_HIGH_FREQ_RU_ALLOC,
1713 mask: ru_alloc_msk[phy_idx], data: 0);
1714 rtw89_write32_mask(rtwdev, addr: reg,
1715 B_P80_AT_HIGH_FREQ_BB_WRP, data: 0);
1716 }
1717 }
1718
1719 if (chan->band_type == RTW89_BAND_6G &&
1720 chan->band_width == RTW89_CHANNEL_WIDTH_160)
1721 rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
1722 B_CDD_EVM_CHK_EN, data: 0, phy_idx);
1723 else
1724 rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
1725 B_CDD_EVM_CHK_EN, data: 1, phy_idx);
1726
1727 if (!rtwdev->dbcc_en) {
1728 mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
1729 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, data: 0x1);
1730 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, data: 0x3);
1731 mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
1732 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, data: 0x1);
1733 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, data: 0x3);
1734 } else {
1735 if (phy_idx == RTW89_PHY_0) {
1736 mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
1737 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, data: 0x1);
1738 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, data: 0x3);
1739 } else {
1740 mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
1741 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, data: 0x1);
1742 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, data: 0x3);
1743 }
1744 }
1745
1746 if (chan->band_type == RTW89_BAND_6G)
1747 rtw89_phy_write32_set(rtwdev, R_MUIC, B_MUIC_EN);
1748 else
1749 rtw89_phy_write32_clr(rtwdev, R_MUIC, B_MUIC_EN);
1750
1751 if (hal->antenna_tx)
1752 ntx_path = hal->antenna_tx;
1753 else
1754 ntx_path = chan->band_type == RTW89_BAND_6G ? RF_B : RF_AB;
1755
1756 rtw8852c_ctrl_tx_path_tmac(rtwdev, tx_path: ntx_path, mac_idx: (enum rtw89_mac_idx)phy_idx);
1757
1758 rtw8852c_bb_reset_all(rtwdev, phy_idx);
1759}
1760
1761static void rtw8852c_set_channel(struct rtw89_dev *rtwdev,
1762 const struct rtw89_chan *chan,
1763 enum rtw89_mac_idx mac_idx,
1764 enum rtw89_phy_idx phy_idx)
1765{
1766 rtw8852c_set_channel_mac(rtwdev, chan, mac_idx);
1767 rtw8852c_set_channel_bb(rtwdev, chan, phy_idx);
1768 rtw8852c_set_channel_rf(rtwdev, chan, phy_idx);
1769}
1770
1771static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en)
1772{
1773 if (en)
1774 rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, data: 1);
1775 else
1776 rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, data: 0);
1777}
1778
1779static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en)
1780{
1781 if (en)
1782 rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
1783 data: 0x0);
1784 else
1785 rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
1786 data: 0xf);
1787}
1788
1789static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
1790 struct rtw89_channel_help_params *p,
1791 const struct rtw89_chan *chan,
1792 enum rtw89_mac_idx mac_idx,
1793 enum rtw89_phy_idx phy_idx)
1794{
1795 if (enter) {
1796 rtw89_chip_stop_sch_tx(rtwdev, mac_idx, tx_en: &p->tx_en,
1797 sel: RTW89_SCH_TX_SEL_ALL);
1798 rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, enable: false);
1799 rtw8852c_dfs_en(rtwdev, en: false);
1800 rtw8852c_tssi_cont_en_phyidx(rtwdev, en: false, phy_idx);
1801 rtw8852c_adc_en(rtwdev, en: false);
1802 fsleep(usecs: 40);
1803 rtw8852c_bb_reset_en(rtwdev, band: chan->band_type, phy_idx, en: false);
1804 } else {
1805 rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, enable: true);
1806 rtw8852c_adc_en(rtwdev, en: true);
1807 rtw8852c_dfs_en(rtwdev, en: true);
1808 rtw8852c_tssi_cont_en_phyidx(rtwdev, en: true, phy_idx);
1809 rtw8852c_bb_reset_en(rtwdev, band: chan->band_type, phy_idx, en: true);
1810 rtw89_chip_resume_sch_tx(rtwdev, mac_idx, tx_en: p->tx_en);
1811 }
1812}
1813
1814static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
1815{
1816 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
1817
1818 rtwdev->is_tssi_mode[RF_PATH_A] = false;
1819 rtwdev->is_tssi_mode[RF_PATH_B] = false;
1820 memset(rfk_mcc, 0, sizeof(*rfk_mcc));
1821 rtw8852c_lck_init(rtwdev);
1822 rtw8852c_dpk_init(rtwdev);
1823
1824 rtw8852c_rck(rtwdev);
1825 rtw8852c_dack(rtwdev);
1826 rtw8852c_rx_dck(rtwdev, phy_idx: RTW89_PHY_0, is_afe: false);
1827}
1828
1829static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
1830{
1831 enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
1832
1833 rtw8852c_mcc_get_ch_info(rtwdev, phy: phy_idx);
1834 rtw8852c_rx_dck(rtwdev, phy_idx, is_afe: false);
1835 rtw8852c_iqk(rtwdev, phy_idx);
1836 rtw8852c_tssi(rtwdev, phy: phy_idx);
1837 rtw8852c_dpk(rtwdev, phy: phy_idx);
1838 rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
1839}
1840
1841static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
1842 enum rtw89_phy_idx phy_idx)
1843{
1844 rtw8852c_tssi_scan(rtwdev, phy: phy_idx);
1845}
1846
1847static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start)
1848{
1849 rtw8852c_wifi_scan_notify(rtwdev, scan_start: start, phy_idx: RTW89_PHY_0);
1850}
1851
1852static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
1853{
1854 rtw8852c_dpk_track(rtwdev);
1855 rtw8852c_lck_track(rtwdev);
1856 rtw8852c_rx_dck_track(rtwdev);
1857}
1858
1859static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
1860 enum rtw89_phy_idx phy_idx, s16 ref)
1861{
1862 s8 ofst_int = 0;
1863 u8 base_cw_0db = 0x27;
1864 u16 tssi_16dbm_cw = 0x12c;
1865 s16 pwr_s10_3 = 0;
1866 s16 rf_pwr_cw = 0;
1867 u16 bb_pwr_cw = 0;
1868 u32 pwr_cw = 0;
1869 u32 tssi_ofst_cw = 0;
1870
1871 pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
1872 bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
1873 rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
1874 rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
1875 pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
1876
1877 tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
1878 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR,
1879 fmt: "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
1880 tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
1881
1882 return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0));
1883}
1884
1885static
1886void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
1887 s8 pw_ofst, enum rtw89_mac_idx mac_idx)
1888{
1889 s8 pw_ofst_2tx;
1890 s8 val_1t;
1891 s8 val_2t;
1892 u32 reg;
1893 u8 i;
1894
1895 if (pw_ofst < -32 || pw_ofst > 31) {
1896 rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
1897 return;
1898 }
1899 val_1t = pw_ofst << 2;
1900 pw_ofst_2tx = max(pw_ofst - 3, -32);
1901 val_2t = pw_ofst_2tx << 2;
1902
1903 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR, fmt: "[ULTB] val_1tx=0x%x\n", val_1t);
1904 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR, fmt: "[ULTB] val_2tx=0x%x\n", val_2t);
1905
1906 for (i = 0; i < 4; i++) {
1907 /* 1TX */
1908 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, band: mac_idx);
1909 rtw89_write32_mask(rtwdev, addr: reg,
1910 B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
1911 data: val_1t);
1912 /* 2TX */
1913 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, band: mac_idx);
1914 rtw89_write32_mask(rtwdev, addr: reg,
1915 B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
1916 data: val_2t);
1917 }
1918}
1919
1920static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
1921 enum rtw89_phy_idx phy_idx)
1922{
1923 static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
1924 const u32 mask = 0x7FFFFFF;
1925 const u8 ofst_ofdm = 0x4;
1926 const u8 ofst_cck = 0x8;
1927 s16 ref_ofdm = 0;
1928 s16 ref_cck = 0;
1929 u32 val;
1930 u8 i;
1931
1932 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR, fmt: "[TXPWR] set txpwr reference\n");
1933
1934 rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
1935 GENMASK(27, 10), val: 0x0);
1936
1937 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR, fmt: "[TXPWR] set bb ofdm txpwr ref\n");
1938 val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref: ref_ofdm);
1939
1940 for (i = 0; i < RF_PATH_NUM_8852C; i++)
1941 rtw89_phy_write32_idx(rtwdev, addr: addr[i] + ofst_ofdm, mask, data: val,
1942 phy_idx);
1943
1944 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR, fmt: "[TXPWR] set bb cck txpwr ref\n");
1945 val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref: ref_cck);
1946
1947 for (i = 0; i < RF_PATH_NUM_8852C; i++)
1948 rtw89_phy_write32_idx(rtwdev, addr: addr[i] + ofst_cck, mask, data: val,
1949 phy_idx);
1950}
1951
1952static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
1953 const struct rtw89_chan *chan,
1954 u8 tx_shape_idx,
1955 enum rtw89_phy_idx phy_idx)
1956{
1957#define __DFIR_CFG_MASK 0xffffff
1958#define __DFIR_CFG_NR 8
1959#define __DECL_DFIR_VAR(_prefix, _name, _val...) \
1960 static const u32 _prefix ## _ ## _name[] = {_val}; \
1961 static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR)
1962#define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val)
1963#define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val)
1964
1965 __DECL_DFIR_PARAM(flat,
1966 0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
1967 0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5);
1968 __DECL_DFIR_PARAM(sharp,
1969 0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090,
1970 0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5);
1971 __DECL_DFIR_PARAM(sharp_14,
1972 0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
1973 0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A);
1974 __DECL_DFIR_ADDR(filter,
1975 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
1976 0x45C4, 0x45C8);
1977 u8 ch = chan->channel;
1978 const u32 *param;
1979 int i;
1980
1981 if (ch > 14) {
1982 rtw89_warn(rtwdev,
1983 "set tx shape dfir by unknown ch: %d on 2G\n", ch);
1984 return;
1985 }
1986
1987 if (ch == 14)
1988 param = param_sharp_14;
1989 else
1990 param = tx_shape_idx == 0 ? param_flat : param_sharp;
1991
1992 for (i = 0; i < __DFIR_CFG_NR; i++) {
1993 rtw89_debug(rtwdev, mask: RTW89_DBG_TXPWR,
1994 fmt: "set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i],
1995 param[i]);
1996 rtw89_phy_write32_idx(rtwdev, addr: addr_filter[i], __DFIR_CFG_MASK,
1997 data: param[i], phy_idx);
1998 }
1999
2000#undef __DECL_DFIR_ADDR
2001#undef __DECL_DFIR_PARAM
2002#undef __DECL_DFIR_VAR
2003#undef __DFIR_CFG_NR
2004#undef __DFIR_CFG_MASK
2005}
2006
2007static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
2008 const struct rtw89_chan *chan,
2009 enum rtw89_phy_idx phy_idx)
2010{
2011 const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
2012 u8 band = chan->band_type;
2013 u8 regd = rtw89_regd_get(rtwdev, band);
2014 u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
2015 u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
2016
2017 if (band == RTW89_BAND_2G)
2018 rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_idx: tx_shape_cck, phy_idx);
2019
2020 rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
2021 mac_idx: (enum rtw89_mac_idx)phy_idx,
2022 bandedge_cfg: tx_shape_ofdm);
2023
2024 rtw89_phy_write32_set(rtwdev, R_P0_DAC_COMP_POST_DPD_EN,
2025 B_P0_DAC_COMP_POST_DPD_EN);
2026 rtw89_phy_write32_set(rtwdev, R_P1_DAC_COMP_POST_DPD_EN,
2027 B_P1_DAC_COMP_POST_DPD_EN);
2028}
2029
2030static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
2031 const struct rtw89_chan *chan,
2032 enum rtw89_phy_idx phy_idx)
2033{
2034 rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
2035 rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
2036 rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
2037 rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
2038 rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
2039}
2040
2041static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
2042 enum rtw89_phy_idx phy_idx)
2043{
2044 rtw8852c_set_txpwr_ref(rtwdev, phy_idx);
2045}
2046
2047static void
2048rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
2049{
2050 static const struct rtw89_reg2_def ctrl_ini[] = {
2051 {0xD938, 0x00010100},
2052 {0xD93C, 0x0500D500},
2053 {0xD940, 0x00000500},
2054 {0xD944, 0x00000005},
2055 {0xD94C, 0x00220000},
2056 {0xD950, 0x00030000},
2057 };
2058 u32 addr;
2059 int i;
2060
2061 for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4)
2062 rtw89_mac_txpwr_write32(rtwdev, phy_idx, reg_base: addr, val: 0);
2063
2064 for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++)
2065 rtw89_mac_txpwr_write32(rtwdev, phy_idx, reg_base: ctrl_ini[i].addr,
2066 val: ctrl_ini[i].data);
2067
2068 rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
2069 mac_idx: (enum rtw89_mac_idx)phy_idx,
2070 bandedge_cfg: RTW89_TSSI_BANDEDGE_FLAT);
2071}
2072
2073static int
2074rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
2075{
2076 int ret;
2077
2078 ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, val: 0x07763333);
2079 if (ret)
2080 return ret;
2081
2082 ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, val: 0x01ebf000);
2083 if (ret)
2084 return ret;
2085
2086 ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, val: 0x0002f8ff);
2087 if (ret)
2088 return ret;
2089
2090 rtw8852c_set_txpwr_ul_tb_offset(rtwdev, pw_ofst: 0, mac_idx: phy_idx == RTW89_PHY_1 ?
2091 RTW89_MAC_1 :
2092 RTW89_MAC_0);
2093 rtw8852c_init_tssi_ctrl(rtwdev, phy_idx);
2094
2095 return 0;
2096}
2097
2098static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
2099{
2100 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2101 u8 band = chan->band_type;
2102 u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
2103 u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
2104
2105 if (rtwdev->dbcc_en) {
2106 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, data: 1);
2107 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, data: 2,
2108 phy_idx: RTW89_PHY_1);
2109
2110 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0,
2111 data: 1);
2112 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1,
2113 data: 1);
2114 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, data: 2,
2115 phy_idx: RTW89_PHY_1);
2116 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, data: 2,
2117 phy_idx: RTW89_PHY_1);
2118
2119 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
2120 B_RXHT_MCS_LIMIT, data: 0);
2121 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
2122 B_RXVHT_MCS_LIMIT, data: 0);
2123 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, data: 8);
2124 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, data: 0);
2125 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, data: 0);
2126
2127 rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT,
2128 B_RXHT_MCS_LIMIT, data: 0, phy_idx: RTW89_PHY_1);
2129 rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT,
2130 B_RXVHT_MCS_LIMIT, data: 0, phy_idx: RTW89_PHY_1);
2131 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, data: 1,
2132 phy_idx: RTW89_PHY_1);
2133 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, data: 0,
2134 phy_idx: RTW89_PHY_1);
2135 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, data: 0,
2136 phy_idx: RTW89_PHY_1);
2137 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask: rst_mask0, data: 1);
2138 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask: rst_mask0, data: 3);
2139 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask: rst_mask1, data: 1);
2140 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask: rst_mask1, data: 3);
2141 } else {
2142 if (rx_path == RF_PATH_A) {
2143 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
2144 B_ANT_RX_SEG0, data: 1);
2145 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2146 B_ANT_RX_1RCCA_SEG0, data: 1);
2147 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2148 B_ANT_RX_1RCCA_SEG1, data: 1);
2149 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
2150 B_RXHT_MCS_LIMIT, data: 0);
2151 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
2152 B_RXVHT_MCS_LIMIT, data: 0);
2153 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
2154 data: 0);
2155 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
2156 data: 0);
2157 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
2158 mask: rst_mask0, data: 1);
2159 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
2160 mask: rst_mask0, data: 3);
2161 } else if (rx_path == RF_PATH_B) {
2162 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
2163 B_ANT_RX_SEG0, data: 2);
2164 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2165 B_ANT_RX_1RCCA_SEG0, data: 2);
2166 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2167 B_ANT_RX_1RCCA_SEG1, data: 2);
2168 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
2169 B_RXHT_MCS_LIMIT, data: 0);
2170 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
2171 B_RXVHT_MCS_LIMIT, data: 0);
2172 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
2173 data: 0);
2174 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
2175 data: 0);
2176 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
2177 mask: rst_mask1, data: 1);
2178 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
2179 mask: rst_mask1, data: 3);
2180 } else {
2181 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
2182 B_ANT_RX_SEG0, data: 3);
2183 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2184 B_ANT_RX_1RCCA_SEG0, data: 3);
2185 rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
2186 B_ANT_RX_1RCCA_SEG1, data: 3);
2187 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
2188 B_RXHT_MCS_LIMIT, data: 1);
2189 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
2190 B_RXVHT_MCS_LIMIT, data: 1);
2191 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
2192 data: 1);
2193 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
2194 data: 1);
2195 rtw8852c_ctrl_btg_bt_rx(rtwdev, en: band == RTW89_BAND_2G,
2196 phy_idx: RTW89_PHY_0);
2197 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
2198 mask: rst_mask0, data: 1);
2199 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
2200 mask: rst_mask0, data: 3);
2201 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
2202 mask: rst_mask1, data: 1);
2203 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
2204 mask: rst_mask1, data: 3);
2205 }
2206 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, data: 8);
2207 }
2208}
2209
2210static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
2211 enum rtw89_mac_idx mac_idx)
2212{
2213 struct rtw89_reg2_def path_com[] = {
2214 {R_AX_PATH_COM0, AX_PATH_COM0_DFVAL},
2215 {R_AX_PATH_COM1, AX_PATH_COM1_DFVAL},
2216 {R_AX_PATH_COM2, AX_PATH_COM2_DFVAL},
2217 {R_AX_PATH_COM3, AX_PATH_COM3_DFVAL},
2218 {R_AX_PATH_COM4, AX_PATH_COM4_DFVAL},
2219 {R_AX_PATH_COM5, AX_PATH_COM5_DFVAL},
2220 {R_AX_PATH_COM6, AX_PATH_COM6_DFVAL},
2221 {R_AX_PATH_COM7, AX_PATH_COM7_DFVAL},
2222 {R_AX_PATH_COM8, AX_PATH_COM8_DFVAL},
2223 {R_AX_PATH_COM9, AX_PATH_COM9_DFVAL},
2224 {R_AX_PATH_COM10, AX_PATH_COM10_DFVAL},
2225 {R_AX_PATH_COM11, AX_PATH_COM11_DFVAL},
2226 };
2227 u32 addr;
2228 u32 reg;
2229 u8 cr_size = ARRAY_SIZE(path_com);
2230 u8 i = 0;
2231
2232 rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, data: 0, phy_idx: RTW89_PHY_0);
2233 rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, data: 0, phy_idx: RTW89_PHY_1);
2234
2235 for (addr = R_AX_MACID_ANT_TABLE;
2236 addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
2237 reg = rtw89_mac_reg_by_idx(rtwdev, reg_base: addr, band: mac_idx);
2238 rtw89_write32(rtwdev, addr: reg, data: 0);
2239 }
2240
2241 if (tx_path == RF_A) {
2242 path_com[0].data = AX_PATH_COM0_PATHA;
2243 path_com[1].data = AX_PATH_COM1_PATHA;
2244 path_com[2].data = AX_PATH_COM2_PATHA;
2245 path_com[7].data = AX_PATH_COM7_PATHA;
2246 path_com[8].data = AX_PATH_COM8_PATHA;
2247 } else if (tx_path == RF_B) {
2248 path_com[0].data = AX_PATH_COM0_PATHB;
2249 path_com[1].data = AX_PATH_COM1_PATHB;
2250 path_com[2].data = AX_PATH_COM2_PATHB;
2251 path_com[7].data = AX_PATH_COM7_PATHB;
2252 path_com[8].data = AX_PATH_COM8_PATHB;
2253 } else if (tx_path == RF_AB) {
2254 path_com[0].data = AX_PATH_COM0_PATHAB;
2255 path_com[1].data = AX_PATH_COM1_PATHAB;
2256 path_com[2].data = AX_PATH_COM2_PATHAB;
2257 path_com[7].data = AX_PATH_COM7_PATHAB;
2258 path_com[8].data = AX_PATH_COM8_PATHAB;
2259 } else {
2260 rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path);
2261 return;
2262 }
2263
2264 for (i = 0; i < cr_size; i++) {
2265 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "0x%x = 0x%x\n",
2266 path_com[i].addr, path_com[i].data);
2267 reg = rtw89_mac_reg_by_idx(rtwdev, reg_base: path_com[i].addr, band: mac_idx);
2268 rtw89_write32(rtwdev, addr: reg, data: path_com[i].data);
2269 }
2270}
2271
2272static void rtw8852c_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
2273 enum rtw89_phy_idx phy_idx)
2274{
2275 if (en) {
2276 rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
2277 B_PATH0_FRC_FIR_TYPE_MSK_V1, data: 0x3);
2278 rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
2279 B_PATH1_FRC_FIR_TYPE_MSK_V1, data: 0x3);
2280 rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
2281 B_PATH0_RXBB_MSK_V1, data: 0xf);
2282 rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
2283 B_PATH1_RXBB_MSK_V1, data: 0xf);
2284 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
2285 B_PATH0_G_LNA6_OP1DB_V1, data: 0x80);
2286 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
2287 B_PATH1_G_LNA6_OP1DB_V1, data: 0x80);
2288 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
2289 B_PATH0_G_TIA0_LNA6_OP1DB_V1, data: 0x80);
2290 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
2291 B_PATH0_G_TIA1_LNA6_OP1DB_V1, data: 0x80);
2292 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
2293 B_PATH1_G_TIA0_LNA6_OP1DB_V1, data: 0x80);
2294 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
2295 B_PATH1_G_TIA1_LNA6_OP1DB_V1, data: 0x80);
2296 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
2297 B_PATH0_BT_BACKOFF_V1, data: 0x780D1E);
2298 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
2299 B_PATH1_BT_BACKOFF_V1, data: 0x780D1E);
2300 rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
2301 B_P0_BACKOFF_IBADC_V1, data: 0x34);
2302 rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
2303 B_P1_BACKOFF_IBADC_V1, data: 0x34);
2304 } else {
2305 rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
2306 B_PATH0_FRC_FIR_TYPE_MSK_V1, data: 0x0);
2307 rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
2308 B_PATH1_FRC_FIR_TYPE_MSK_V1, data: 0x0);
2309 rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
2310 B_PATH0_RXBB_MSK_V1, data: 0x60);
2311 rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
2312 B_PATH1_RXBB_MSK_V1, data: 0x60);
2313 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
2314 B_PATH0_G_LNA6_OP1DB_V1, data: 0x1a);
2315 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
2316 B_PATH1_G_LNA6_OP1DB_V1, data: 0x1a);
2317 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
2318 B_PATH0_G_TIA0_LNA6_OP1DB_V1, data: 0x2a);
2319 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
2320 B_PATH0_G_TIA1_LNA6_OP1DB_V1, data: 0x2a);
2321 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
2322 B_PATH1_G_TIA0_LNA6_OP1DB_V1, data: 0x2a);
2323 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
2324 B_PATH1_G_TIA1_LNA6_OP1DB_V1, data: 0x2a);
2325 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
2326 B_PATH0_BT_BACKOFF_V1, data: 0x79E99E);
2327 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
2328 B_PATH1_BT_BACKOFF_V1, data: 0x79E99E);
2329 rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
2330 B_P0_BACKOFF_IBADC_V1, data: 0x26);
2331 rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
2332 B_P1_BACKOFF_IBADC_V1, data: 0x26);
2333 }
2334}
2335
2336static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
2337{
2338 struct rtw89_hal *hal = &rtwdev->hal;
2339
2340 rtw8852c_bb_cfg_rx_path(rtwdev, rx_path: RF_PATH_AB);
2341
2342 if (hal->rx_nss == 1) {
2343 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, data: 0);
2344 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, data: 0);
2345 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, data: 0);
2346 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, data: 0);
2347 } else {
2348 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, data: 1);
2349 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, data: 1);
2350 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, data: 1);
2351 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, data: 1);
2352 }
2353}
2354
2355static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
2356{
2357 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, data: 0x1);
2358 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, data: 0x0);
2359 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, data: 0x1);
2360
2361 fsleep(usecs: 200);
2362
2363 return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
2364}
2365
2366static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev)
2367{
2368 const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
2369 union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
2370
2371 if (ver->fcxinit == 7) {
2372 md->md_v7.rfe_type = rtwdev->efuse.rfe_type;
2373 md->md_v7.kt_ver = rtwdev->hal.cv;
2374 md->md_v7.bt_solo = 0;
2375 md->md_v7.switch_type = BTC_SWITCH_INTERNAL;
2376
2377 if (md->md_v7.rfe_type > 0)
2378 md->md_v7.ant.num = (md->md_v7.rfe_type % 2 ? 2 : 3);
2379 else
2380 md->md_v7.ant.num = 2;
2381
2382 md->md_v7.ant.diversity = 0;
2383 md->md_v7.ant.isolation = 10;
2384
2385 if (md->md_v7.ant.num == 3) {
2386 md->md_v7.ant.type = BTC_ANT_DEDICATED;
2387 md->md_v7.bt_pos = BTC_BT_ALONE;
2388 } else {
2389 md->md_v7.ant.type = BTC_ANT_SHARED;
2390 md->md_v7.bt_pos = BTC_BT_BTG;
2391 }
2392 rtwdev->btc.btg_pos = md->md_v7.ant.btg_pos;
2393 rtwdev->btc.ant_type = md->md_v7.ant.type;
2394 } else {
2395 md->md.rfe_type = rtwdev->efuse.rfe_type;
2396 md->md.cv = rtwdev->hal.cv;
2397 md->md.bt_solo = 0;
2398 md->md.switch_type = BTC_SWITCH_INTERNAL;
2399
2400 if (md->md.rfe_type > 0)
2401 md->md.ant.num = (md->md.rfe_type % 2 ? 2 : 3);
2402 else
2403 md->md.ant.num = 2;
2404
2405 md->md.ant.diversity = 0;
2406 md->md.ant.isolation = 10;
2407
2408 if (md->md.ant.num == 3) {
2409 md->md.ant.type = BTC_ANT_DEDICATED;
2410 md->md.bt_pos = BTC_BT_ALONE;
2411 } else {
2412 md->md.ant.type = BTC_ANT_SHARED;
2413 md->md.bt_pos = BTC_BT_BTG;
2414 }
2415 rtwdev->btc.btg_pos = md->md.ant.btg_pos;
2416 rtwdev->btc.ant_type = md->md.ant.type;
2417 }
2418}
2419
2420static void rtw8852c_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
2421 enum rtw89_phy_idx phy_idx)
2422{
2423 if (en) {
2424 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
2425 B_PATH0_BT_SHARE_V1, data: 0x1);
2426 rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
2427 B_PATH0_BTG_PATH_V1, data: 0x0);
2428 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
2429 B_PATH1_G_LNA6_OP1DB_V1, data: 0x20);
2430 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
2431 B_PATH1_G_TIA0_LNA6_OP1DB_V1, data: 0x30);
2432 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
2433 B_PATH1_BT_SHARE_V1, data: 0x1);
2434 rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
2435 B_PATH1_BTG_PATH_V1, data: 0x1);
2436 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, data: 0x0);
2437 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, data: 0x1);
2438 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, data: 0x2);
2439 rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
2440 B_BT_DYN_DC_EST_EN_MSK, data: 0x1);
2441 rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
2442 data: 0x1);
2443 } else {
2444 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
2445 B_PATH0_BT_SHARE_V1, data: 0x0);
2446 rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
2447 B_PATH0_BTG_PATH_V1, data: 0x0);
2448 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
2449 B_PATH1_G_LNA6_OP1DB_V1, data: 0x1a);
2450 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
2451 B_PATH1_G_TIA0_LNA6_OP1DB_V1, data: 0x2a);
2452 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
2453 B_PATH1_BT_SHARE_V1, data: 0x0);
2454 rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
2455 B_PATH1_BTG_PATH_V1, data: 0x0);
2456 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, data: 0xf);
2457 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, data: 0x4);
2458 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, data: 0x0);
2459 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, data: 0x0);
2460 rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
2461 B_BT_DYN_DC_EST_EN_MSK, data: 0x0);
2462 rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
2463 data: 0x0);
2464 }
2465}
2466
2467static
2468void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
2469{
2470 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RFREG_MASK, data: 0x20000);
2471 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RFREG_MASK, data: group);
2472 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RFREG_MASK, data: val);
2473 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RFREG_MASK, data: 0x0);
2474}
2475
2476static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev)
2477{
2478 struct rtw89_btc *btc = &rtwdev->btc;
2479 const struct rtw89_chip_info *chip = rtwdev->chip;
2480 const struct rtw89_mac_ax_coex coex_params = {
2481 .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
2482 .direction = RTW89_MAC_AX_COEX_INNER,
2483 };
2484
2485 /* PTA init */
2486 rtw89_mac_coex_init_v1(rtwdev, coex: &coex_params);
2487
2488 /* set WL Tx response = Hi-Pri */
2489 chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
2490 chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
2491
2492 /* set rf gnt debug off */
2493 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_WLSEL, RFREG_MASK, data: 0x0);
2494 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_WLSEL, RFREG_MASK, data: 0x0);
2495
2496 /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
2497 if (btc->ant_type == BTC_ANT_SHARED) {
2498 rtw8852c_set_trx_mask(rtwdev,
2499 path: RF_PATH_A, group: BTC_BT_SS_GROUP, val: 0x5ff);
2500 rtw8852c_set_trx_mask(rtwdev,
2501 path: RF_PATH_B, group: BTC_BT_SS_GROUP, val: 0x5ff);
2502 /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
2503 rtw8852c_set_trx_mask(rtwdev,
2504 path: RF_PATH_A, group: BTC_BT_TX_GROUP, val: 0x5ff);
2505 } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
2506 rtw8852c_set_trx_mask(rtwdev,
2507 path: RF_PATH_A, group: BTC_BT_SS_GROUP, val: 0x5df);
2508 rtw8852c_set_trx_mask(rtwdev,
2509 path: RF_PATH_B, group: BTC_BT_SS_GROUP, val: 0x5df);
2510 }
2511
2512 /* set PTA break table */
2513 rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM);
2514
2515 /* enable BT counter 0xda10[1:0] = 2b'11 */
2516 rtw89_write32_set(rtwdev,
2517 R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN |
2518 B_AX_BT_CNT_RST_V1);
2519 btc->cx.wl.status.map.init_ok = true;
2520}
2521
2522static
2523void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
2524{
2525 u32 bitmap = 0;
2526 u32 reg = 0;
2527
2528 switch (map) {
2529 case BTC_PRI_MASK_TX_RESP:
2530 reg = R_BTC_COEX_WL_REQ;
2531 bitmap = B_BTC_RSP_ACK_HI;
2532 break;
2533 case BTC_PRI_MASK_BEACON:
2534 reg = R_BTC_COEX_WL_REQ;
2535 bitmap = B_BTC_TX_BCN_HI;
2536 break;
2537 default:
2538 return;
2539 }
2540
2541 if (state)
2542 rtw89_write32_set(rtwdev, addr: reg, bit: bitmap);
2543 else
2544 rtw89_write32_clr(rtwdev, addr: reg, bit: bitmap);
2545}
2546
2547union rtw8852c_btc_wl_txpwr_ctrl {
2548 u32 txpwr_val;
2549 struct {
2550 union {
2551 u16 ctrl_all_time;
2552 struct {
2553 s16 data:9;
2554 u16 rsvd:6;
2555 u16 flag:1;
2556 } all_time;
2557 };
2558 union {
2559 u16 ctrl_gnt_bt;
2560 struct {
2561 s16 data:9;
2562 u16 rsvd:7;
2563 } gnt_bt;
2564 };
2565 };
2566} __packed;
2567
2568static void
2569rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
2570{
2571 union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val };
2572 s32 val;
2573
2574#define __write_ctrl(_reg, _msk, _val, _en, _cond) \
2575do { \
2576 u32 _wrt = FIELD_PREP(_msk, _val); \
2577 BUILD_BUG_ON((_msk & _en) != 0); \
2578 if (_cond) \
2579 _wrt |= _en; \
2580 else \
2581 _wrt &= ~_en; \
2582 rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \
2583 _msk | _en, _wrt); \
2584} while (0)
2585
2586 switch (arg.ctrl_all_time) {
2587 case 0xffff:
2588 val = 0;
2589 break;
2590 default:
2591 val = arg.all_time.data;
2592 break;
2593 }
2594
2595 __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
2596 val, B_AX_FORCE_PWR_BY_RATE_EN,
2597 arg.ctrl_all_time != 0xffff);
2598
2599 switch (arg.ctrl_gnt_bt) {
2600 case 0xffff:
2601 val = 0;
2602 break;
2603 default:
2604 val = arg.gnt_bt.data;
2605 break;
2606 }
2607
2608 __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val,
2609 B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff);
2610
2611#undef __write_ctrl
2612}
2613
2614static
2615s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
2616{
2617 /* +6 for compensate offset */
2618 return clamp_t(s8, val + 6, -100, 0) + 100;
2619}
2620
2621static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
2622 {255, 0, 0, 7}, /* 0 -> original */
2623 {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
2624 {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
2625 {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
2626 {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
2627 {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
2628 {6, 1, 0, 7},
2629 {13, 1, 0, 7},
2630 {13, 1, 0, 7}
2631};
2632
2633static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
2634 {255, 0, 0, 7}, /* 0 -> original */
2635 {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
2636 {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
2637 {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
2638 {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
2639 {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
2640 {255, 1, 0, 7},
2641 {255, 1, 0, 7},
2642 {255, 1, 0, 7}
2643};
2644
2645static const u8 rtw89_btc_8852c_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
2646static const u8 rtw89_btc_8852c_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28};
2647
2648static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = {
2649 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda00),
2650 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda04),
2651 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24),
2652 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30),
2653 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34),
2654 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda38),
2655 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda44),
2656 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda48),
2657 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c),
2658 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
2659 RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
2660 RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
2661 RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4),
2662 RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778),
2663 RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c),
2664};
2665
2666static
2667void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
2668{
2669 /* Feature move to firmware */
2670}
2671
2672static
2673void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
2674{
2675 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x80000);
2676 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x1);
2677 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD1, RFREG_MASK, data: 0x620);
2678
2679 /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
2680 if (state)
2681 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0,
2682 RFREG_MASK, data: 0x179c);
2683 else
2684 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0,
2685 RFREG_MASK, data: 0x208);
2686
2687 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x0);
2688}
2689
2690static void rtw8852c_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
2691{
2692 /* level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB
2693 * level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB
2694 * To improve BT ACI in co-rx
2695 */
2696
2697 switch (level) {
2698 case 0: /* default */
2699 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x1000);
2700 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x0);
2701 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x15);
2702 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x1);
2703 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x17);
2704 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x2);
2705 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x15);
2706 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x3);
2707 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x17);
2708 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x0);
2709 break;
2710 case 1: /* Fix LNA2=5 */
2711 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x1000);
2712 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x0);
2713 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x15);
2714 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x1);
2715 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x5);
2716 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x2);
2717 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x15);
2718 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWA, RFREG_MASK, data: 0x3);
2719 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWD0, RFREG_MASK, data: 0x5);
2720 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_LUTWE, RFREG_MASK, data: 0x0);
2721 break;
2722 }
2723}
2724
2725static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
2726{
2727 struct rtw89_btc *btc = &rtwdev->btc;
2728
2729 switch (level) {
2730 case 0: /* original */
2731 default:
2732 rtw8852c_ctrl_nbtg_bt_tx(rtwdev, en: false, phy_idx: RTW89_PHY_0);
2733 btc->dm.wl_lna2 = 0;
2734 break;
2735 case 1: /* for FDD free-run */
2736 rtw8852c_ctrl_nbtg_bt_tx(rtwdev, en: true, phy_idx: RTW89_PHY_0);
2737 btc->dm.wl_lna2 = 0;
2738 break;
2739 case 2: /* for BTG Co-Rx*/
2740 rtw8852c_ctrl_nbtg_bt_tx(rtwdev, en: false, phy_idx: RTW89_PHY_0);
2741 btc->dm.wl_lna2 = 1;
2742 break;
2743 }
2744
2745 rtw8852c_set_wl_lna2(rtwdev, level: btc->dm.wl_lna2);
2746}
2747
2748static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
2749 struct rtw89_rx_phy_ppdu *phy_ppdu,
2750 struct ieee80211_rx_status *status)
2751{
2752 u8 chan_idx = phy_ppdu->chan_idx;
2753 enum nl80211_band band;
2754 u8 ch;
2755
2756 if (chan_idx == 0)
2757 return;
2758
2759 rtw89_decode_chan_idx(rtwdev, chan_idx, ch: &ch, band: &band);
2760 status->freq = ieee80211_channel_to_frequency(chan: ch, band);
2761 status->band = band;
2762}
2763
2764static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
2765 struct rtw89_rx_phy_ppdu *phy_ppdu,
2766 struct ieee80211_rx_status *status)
2767{
2768 u8 path;
2769 u8 *rx_power = phy_ppdu->rssi;
2770
2771 status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
2772 for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
2773 status->chains |= BIT(path);
2774 status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
2775 }
2776 if (phy_ppdu->valid)
2777 rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
2778}
2779
2780static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
2781{
2782 int ret;
2783
2784 rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
2785 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
2786
2787 rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
2788 rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
2789 rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
2790
2791 rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, data: 0x1);
2792 rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, data: 0x1);
2793
2794 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL0, val: 0x7, FULL_BIT_MASK);
2795 if (ret)
2796 return ret;
2797
2798 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_ANAPAR_WL, val: 0x6c, FULL_BIT_MASK);
2799 if (ret)
2800 return ret;
2801
2802 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_WL_RFC_S0, val: 0xc7, FULL_BIT_MASK);
2803 if (ret)
2804 return ret;
2805
2806 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL_SI_WL_RFC_S1, val: 0xc7, FULL_BIT_MASK);
2807 if (ret)
2808 return ret;
2809
2810 ret = rtw89_mac_write_xtal_si(rtwdev, offset: XTAL3, val: 0xd, FULL_BIT_MASK);
2811 if (ret)
2812 return ret;
2813
2814 return 0;
2815}
2816
2817static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
2818{
2819 rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
2820 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
2821
2822 return 0;
2823}
2824
2825static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = {
2826 .callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb,
2827};
2828
2829#ifdef CONFIG_PM
2830static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = {
2831 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
2832 .n_patterns = RTW89_MAX_PATTERN_NUM,
2833 .pattern_max_len = RTW89_MAX_PATTERN_SIZE,
2834 .pattern_min_len = 1,
2835};
2836#endif
2837
2838static const struct rtw89_chip_ops rtw8852c_chip_ops = {
2839 .enable_bb_rf = rtw8852c_mac_enable_bb_rf,
2840 .disable_bb_rf = rtw8852c_mac_disable_bb_rf,
2841 .bb_preinit = NULL,
2842 .bb_postinit = NULL,
2843 .bb_reset = rtw8852c_bb_reset,
2844 .bb_sethw = rtw8852c_bb_sethw,
2845 .read_rf = rtw89_phy_read_rf_v1,
2846 .write_rf = rtw89_phy_write_rf_v1,
2847 .set_channel = rtw8852c_set_channel,
2848 .set_channel_help = rtw8852c_set_channel_help,
2849 .read_efuse = rtw8852c_read_efuse,
2850 .read_phycap = rtw8852c_read_phycap,
2851 .fem_setup = NULL,
2852 .rfe_gpio = NULL,
2853 .rfk_hw_init = NULL,
2854 .rfk_init = rtw8852c_rfk_init,
2855 .rfk_init_late = NULL,
2856 .rfk_channel = rtw8852c_rfk_channel,
2857 .rfk_band_changed = rtw8852c_rfk_band_changed,
2858 .rfk_scan = rtw8852c_rfk_scan,
2859 .rfk_track = rtw8852c_rfk_track,
2860 .power_trim = rtw8852c_power_trim,
2861 .set_txpwr = rtw8852c_set_txpwr,
2862 .set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl,
2863 .init_txpwr_unit = rtw8852c_init_txpwr_unit,
2864 .get_thermal = rtw8852c_get_thermal,
2865 .ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx,
2866 .query_ppdu = rtw8852c_query_ppdu,
2867 .ctrl_nbtg_bt_tx = rtw8852c_ctrl_nbtg_bt_tx,
2868 .cfg_txrx_path = rtw8852c_bb_cfg_txrx_path,
2869 .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
2870 .pwr_on_func = rtw8852c_pwr_on_func,
2871 .pwr_off_func = rtw8852c_pwr_off_func,
2872 .query_rxdesc = rtw89_core_query_rxdesc,
2873 .fill_txdesc = rtw89_core_fill_txdesc_v1,
2874 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1,
2875 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1,
2876 .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1,
2877 .stop_sch_tx = rtw89_mac_stop_sch_tx_v1,
2878 .resume_sch_tx = rtw89_mac_resume_sch_tx_v1,
2879 .h2c_dctl_sec_cam = rtw89_fw_h2c_dctl_sec_cam_v1,
2880 .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
2881 .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
2882 .h2c_ampdu_cmac_tbl = NULL,
2883 .h2c_default_dmac_tbl = NULL,
2884 .h2c_update_beacon = rtw89_fw_h2c_update_beacon,
2885 .h2c_ba_cam = rtw89_fw_h2c_ba_cam,
2886
2887 .btc_set_rfe = rtw8852c_btc_set_rfe,
2888 .btc_init_cfg = rtw8852c_btc_init_cfg,
2889 .btc_set_wl_pri = rtw8852c_btc_set_wl_pri,
2890 .btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl,
2891 .btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi,
2892 .btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt,
2893 .btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby,
2894 .btc_set_wl_rx_gain = rtw8852c_btc_set_wl_rx_gain,
2895 .btc_set_policy = rtw89_btc_set_policy_v1,
2896};
2897
2898const struct rtw89_chip_info rtw8852c_chip_info = {
2899 .chip_id = RTL8852C,
2900 .chip_gen = RTW89_CHIP_AX,
2901 .ops = &rtw8852c_chip_ops,
2902 .mac_def = &rtw89_mac_gen_ax,
2903 .phy_def = &rtw89_phy_gen_ax,
2904 .fw_basename = RTW8852C_FW_BASENAME,
2905 .fw_format_max = RTW8852C_FW_FORMAT_MAX,
2906 .try_ce_fw = false,
2907 .bbmcu_nr = 0,
2908 .needed_fw_elms = 0,
2909 .fifo_size = 458752,
2910 .small_fifo_size = false,
2911 .dle_scc_rsvd_size = 0,
2912 .max_amsdu_limit = 8000,
2913 .dis_2g_40m_ul_ofdma = false,
2914 .rsvd_ple_ofst = 0x6f800,
2915 .hfc_param_ini = rtw8852c_hfc_param_ini_pcie,
2916 .dle_mem = rtw8852c_dle_mem_pcie,
2917 .wde_qempty_acq_grpnum = 16,
2918 .wde_qempty_mgq_grpsel = 16,
2919 .rf_base_addr = {0xe000, 0xf000},
2920 .pwr_on_seq = NULL,
2921 .pwr_off_seq = NULL,
2922 .bb_table = &rtw89_8852c_phy_bb_table,
2923 .bb_gain_table = &rtw89_8852c_phy_bb_gain_table,
2924 .rf_table = {&rtw89_8852c_phy_radiob_table,
2925 &rtw89_8852c_phy_radioa_table,},
2926 .nctl_table = &rtw89_8852c_phy_nctl_table,
2927 .nctl_post_table = NULL,
2928 .dflt_parms = &rtw89_8852c_dflt_parms,
2929 .rfe_parms_conf = NULL,
2930 .chanctx_listener = &rtw8852c_chanctx_listener,
2931 .txpwr_factor_rf = 2,
2932 .txpwr_factor_mac = 1,
2933 .dig_table = NULL,
2934 .dig_regs = &rtw8852c_dig_regs,
2935 .tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
2936 .support_chanctx_num = 2,
2937 .support_bands = BIT(NL80211_BAND_2GHZ) |
2938 BIT(NL80211_BAND_5GHZ) |
2939 BIT(NL80211_BAND_6GHZ),
2940 .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
2941 BIT(NL80211_CHAN_WIDTH_40) |
2942 BIT(NL80211_CHAN_WIDTH_80) |
2943 BIT(NL80211_CHAN_WIDTH_160),
2944 .support_unii4 = true,
2945 .ul_tb_waveform_ctrl = false,
2946 .ul_tb_pwr_diff = true,
2947 .hw_sec_hdr = true,
2948 .rf_path_num = 2,
2949 .tx_nss = 2,
2950 .rx_nss = 2,
2951 .acam_num = 128,
2952 .bcam_num = 20,
2953 .scam_num = 128,
2954 .bacam_num = 8,
2955 .bacam_dynamic_num = 8,
2956 .bacam_ver = RTW89_BACAM_V0_EXT,
2957 .ppdu_max_usr = 8,
2958 .sec_ctrl_efuse_size = 4,
2959 .physical_efuse_size = 1216,
2960 .logical_efuse_size = 2048,
2961 .limit_efuse_size = 1280,
2962 .dav_phy_efuse_size = 96,
2963 .dav_log_efuse_size = 16,
2964 .efuse_blocks = NULL,
2965 .phycap_addr = 0x590,
2966 .phycap_size = 0x60,
2967 .para_ver = 0x1,
2968 .wlcx_desired = 0x06000000,
2969 .btcx_desired = 0x7,
2970 .scbd = 0x1,
2971 .mailbox = 0x1,
2972
2973 .afh_guard_ch = 6,
2974 .wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres,
2975 .bt_rssi_thres = rtw89_btc_8852c_bt_rssi_thres,
2976 .rssi_tol = 2,
2977 .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852c_mon_reg),
2978 .mon_reg = rtw89_btc_8852c_mon_reg,
2979 .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_ul),
2980 .rf_para_ulink = rtw89_btc_8852c_rf_ul,
2981 .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
2982 .rf_para_dlink = rtw89_btc_8852c_rf_dl,
2983 .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) |
2984 BIT(RTW89_PS_MODE_CLK_GATED) |
2985 BIT(RTW89_PS_MODE_PWR_GATED),
2986 .low_power_hci_modes = BIT(RTW89_PS_MODE_CLK_GATED) |
2987 BIT(RTW89_PS_MODE_PWR_GATED),
2988 .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD_V1,
2989 .hci_func_en_addr = R_AX_HCI_FUNC_EN_V1,
2990 .h2c_desc_size = sizeof(struct rtw89_rxdesc_short),
2991 .txwd_body_size = sizeof(struct rtw89_txwd_body_v1),
2992 .txwd_info_size = sizeof(struct rtw89_txwd_info),
2993 .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1,
2994 .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
2995 .h2c_regs = rtw8852c_h2c_regs,
2996 .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1,
2997 .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
2998 .c2h_regs = rtw8852c_c2h_regs,
2999 .page_regs = &rtw8852c_page_regs,
3000 .wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3,
3001 .cfo_src_fd = false,
3002 .cfo_hw_comp = false,
3003 .dcfo_comp = &rtw8852c_dcfo_comp,
3004 .dcfo_comp_sft = 12,
3005 .imr_info = &rtw8852c_imr_info,
3006 .imr_dmac_table = NULL,
3007 .imr_cmac_table = NULL,
3008 .rrsr_cfgs = &rtw8852c_rrsr_cfgs,
3009 .bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
3010 .bss_clr_map_reg = R_BSS_CLR_MAP,
3011 .dma_ch_mask = 0,
3012 .edcca_regs = &rtw8852c_edcca_regs,
3013#ifdef CONFIG_PM
3014 .wowlan_stub = &rtw_wowlan_stub_8852c,
3015#endif
3016 .xtal_info = NULL,
3017};
3018EXPORT_SYMBOL(rtw8852c_chip_info);
3019
3020MODULE_FIRMWARE(RTW8852C_MODULE_FIRMWARE);
3021MODULE_AUTHOR("Realtek Corporation");
3022MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
3023MODULE_LICENSE("Dual BSD/GPL");
3024

source code of linux/drivers/net/wireless/realtek/rtw89/rtw8852c.c