1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright 2024 Fiona Klute
3 *
4 * Based on code originally in rtw8723d.[ch],
5 * Copyright(c) 2018-2019  Realtek Corporation
6 */
7
8#include "main.h"
9#include "debug.h"
10#include "phy.h"
11#include "reg.h"
12#include "tx.h"
13#include "rtw8723x.h"
14
15static const struct rtw_hw_reg rtw8723x_txagc[] = {
16	[DESC_RATE1M]	= { .addr = 0xe08, .mask = 0x0000ff00 },
17	[DESC_RATE2M]	= { .addr = 0x86c, .mask = 0x0000ff00 },
18	[DESC_RATE5_5M]	= { .addr = 0x86c, .mask = 0x00ff0000 },
19	[DESC_RATE11M]	= { .addr = 0x86c, .mask = 0xff000000 },
20	[DESC_RATE6M]	= { .addr = 0xe00, .mask = 0x000000ff },
21	[DESC_RATE9M]	= { .addr = 0xe00, .mask = 0x0000ff00 },
22	[DESC_RATE12M]	= { .addr = 0xe00, .mask = 0x00ff0000 },
23	[DESC_RATE18M]	= { .addr = 0xe00, .mask = 0xff000000 },
24	[DESC_RATE24M]	= { .addr = 0xe04, .mask = 0x000000ff },
25	[DESC_RATE36M]	= { .addr = 0xe04, .mask = 0x0000ff00 },
26	[DESC_RATE48M]	= { .addr = 0xe04, .mask = 0x00ff0000 },
27	[DESC_RATE54M]	= { .addr = 0xe04, .mask = 0xff000000 },
28	[DESC_RATEMCS0]	= { .addr = 0xe10, .mask = 0x000000ff },
29	[DESC_RATEMCS1]	= { .addr = 0xe10, .mask = 0x0000ff00 },
30	[DESC_RATEMCS2]	= { .addr = 0xe10, .mask = 0x00ff0000 },
31	[DESC_RATEMCS3]	= { .addr = 0xe10, .mask = 0xff000000 },
32	[DESC_RATEMCS4]	= { .addr = 0xe14, .mask = 0x000000ff },
33	[DESC_RATEMCS5]	= { .addr = 0xe14, .mask = 0x0000ff00 },
34	[DESC_RATEMCS6]	= { .addr = 0xe14, .mask = 0x00ff0000 },
35	[DESC_RATEMCS7]	= { .addr = 0xe14, .mask = 0xff000000 },
36};
37
38static void __rtw8723x_lck(struct rtw_dev *rtwdev)
39{
40	u32 lc_cal;
41	u8 val_ctx, rf_val;
42	int ret;
43
44	val_ctx = rtw_read8(rtwdev, REG_CTX);
45	if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
46		rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);
47	else
48		rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);
49	lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
50
51	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);
52
53	ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,
54				10000, 1000000, false,
55				rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);
56	if (ret)
57		rtw_warn(rtwdev, "failed to poll LCK status bit\n");
58
59	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
60	if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
61		rtw_write8(rtwdev, REG_CTX, val_ctx);
62	else
63		rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
64}
65
66#define DBG_EFUSE_VAL(rtwdev, map, name)			\
67	rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n",	\
68		(map)->name)
69#define DBG_EFUSE_2BYTE(rtwdev, map, name)			\
70	rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n",	\
71		(map)->name[0], (map)->name[1])
72
73static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev,
74				  struct rtw8723x_efuse *map)
75{
76	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr);
77	DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id);
78	DBG_EFUSE_2BYTE(rtwdev, map, e.device_id);
79	DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id);
80	DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id);
81}
82
83static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev,
84				  struct rtw8723x_efuse *map)
85{
86	DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id);
87	DBG_EFUSE_2BYTE(rtwdev, map, u.product_id);
88	DBG_EFUSE_VAL(rtwdev, map, u.usb_option);
89	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr);
90}
91
92static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev,
93				  struct rtw8723x_efuse *map)
94{
95	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr);
96}
97
98static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev,
99					 struct rtw_txpwr_idx *table,
100					 int tx_path_count)
101{
102	if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
103		return;
104
105	rtw_dbg(rtwdev, RTW_DBG_EFUSE,
106		"Power index table (2.4G):\n");
107	/* CCK base */
108	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n");
109	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF    G0  G1  G2  G3  G4  G5\n");
110	for (int i = 0; i < tx_path_count; i++)
111		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
112			"[%c]: %3u %3u %3u %3u %3u %3u\n",
113			'A' + i,
114			table[i].pwr_idx_2g.cck_base[0],
115			table[i].pwr_idx_2g.cck_base[1],
116			table[i].pwr_idx_2g.cck_base[2],
117			table[i].pwr_idx_2g.cck_base[3],
118			table[i].pwr_idx_2g.cck_base[4],
119			table[i].pwr_idx_2g.cck_base[5]);
120	/* CCK diff */
121	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n");
122	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF   1S 2S 3S 4S\n");
123	for (int i = 0; i < tx_path_count; i++)
124		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
125			"[%c]: %2d %2d %2d %2d\n",
126			'A' + i, 0 /* no diff for 1S */,
127			table[i].pwr_idx_2g.ht_2s_diff.cck,
128			table[i].pwr_idx_2g.ht_3s_diff.cck,
129			table[i].pwr_idx_2g.ht_4s_diff.cck);
130	/* BW40-1S base */
131	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n");
132	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF    G0  G1  G2  G3  G4\n");
133	for (int i = 0; i < tx_path_count; i++)
134		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
135			"[%c]: %3u %3u %3u %3u %3u\n",
136			'A' + i,
137			table[i].pwr_idx_2g.bw40_base[0],
138			table[i].pwr_idx_2g.bw40_base[1],
139			table[i].pwr_idx_2g.bw40_base[2],
140			table[i].pwr_idx_2g.bw40_base[3],
141			table[i].pwr_idx_2g.bw40_base[4]);
142	/* OFDM diff */
143	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n");
144	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF   1S 2S 3S 4S\n");
145	for (int i = 0; i < tx_path_count; i++)
146		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
147			"[%c]: %2d %2d %2d %2d\n",
148			'A' + i,
149			table[i].pwr_idx_2g.ht_1s_diff.ofdm,
150			table[i].pwr_idx_2g.ht_2s_diff.ofdm,
151			table[i].pwr_idx_2g.ht_3s_diff.ofdm,
152			table[i].pwr_idx_2g.ht_4s_diff.ofdm);
153	/* BW20 diff */
154	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n");
155	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF   1S 2S 3S 4S\n");
156	for (int i = 0; i < tx_path_count; i++)
157		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
158			"[%c]: %2d %2d %2d %2d\n",
159			'A' + i,
160			table[i].pwr_idx_2g.ht_1s_diff.bw20,
161			table[i].pwr_idx_2g.ht_2s_diff.bw20,
162			table[i].pwr_idx_2g.ht_3s_diff.bw20,
163			table[i].pwr_idx_2g.ht_4s_diff.bw20);
164	/* BW40 diff */
165	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n");
166	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF   1S 2S 3S 4S\n");
167	for (int i = 0; i < tx_path_count; i++)
168		rtw_dbg(rtwdev, RTW_DBG_EFUSE,
169			"[%c]: %2d %2d %2d %2d\n",
170			'A' + i, 0 /* no diff for 1S */,
171			table[i].pwr_idx_2g.ht_2s_diff.bw40,
172			table[i].pwr_idx_2g.ht_3s_diff.bw40,
173			table[i].pwr_idx_2g.ht_4s_diff.bw40);
174}
175
176static void efuse_debug_dump(struct rtw_dev *rtwdev,
177			     struct rtw8723x_efuse *map)
178{
179	if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
180		return;
181
182	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n");
183	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
184		       (u8 *)map, sizeof(struct rtw8723x_efuse), false);
185	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n");
186	DBG_EFUSE_VAL(rtwdev, map, rtl_id);
187	DBG_EFUSE_VAL(rtwdev, map, afe);
188	rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4);
189	DBG_EFUSE_VAL(rtwdev, map, channel_plan);
190	DBG_EFUSE_VAL(rtwdev, map, xtal_k);
191	DBG_EFUSE_VAL(rtwdev, map, thermal_meter);
192	DBG_EFUSE_VAL(rtwdev, map, iqk_lck);
193	DBG_EFUSE_VAL(rtwdev, map, pa_type);
194	DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g);
195	DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g);
196	DBG_EFUSE_VAL(rtwdev, map, rf_board_option);
197	DBG_EFUSE_VAL(rtwdev, map, rf_feature_option);
198	DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting);
199	DBG_EFUSE_VAL(rtwdev, map, eeprom_version);
200	DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id);
201	DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g);
202	DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate);
203	DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option);
204	DBG_EFUSE_VAL(rtwdev, map, rfe_option);
205	DBG_EFUSE_2BYTE(rtwdev, map, country_code);
206
207	switch (rtw_hci_type(rtwdev)) {
208	case RTW_HCI_TYPE_PCIE:
209		rtw8723xe_efuse_debug(rtwdev, map);
210		break;
211	case RTW_HCI_TYPE_USB:
212		rtw8723xu_efuse_debug(rtwdev, map);
213		break;
214	case RTW_HCI_TYPE_SDIO:
215		rtw8723xs_efuse_debug(rtwdev, map);
216		break;
217	default:
218		/* unsupported now */
219		break;
220	}
221}
222
223static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse,
224				    struct rtw8723x_efuse *map)
225{
226	ether_addr_copy(efuse->addr, map->e.mac_addr);
227}
228
229static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse,
230				    struct rtw8723x_efuse *map)
231{
232	ether_addr_copy(efuse->addr, map->u.mac_addr);
233}
234
235static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse,
236				    struct rtw8723x_efuse *map)
237{
238	ether_addr_copy(efuse->addr, map->s.mac_addr);
239}
240
241static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
242{
243	struct rtw_efuse *efuse = &rtwdev->efuse;
244	struct rtw8723x_efuse *map;
245	int i;
246
247	map = (struct rtw8723x_efuse *)log_map;
248	efuse_debug_dump(rtwdev, map);
249
250	efuse->rfe_option = 0;
251	efuse->rf_board_option = map->rf_board_option;
252	efuse->crystal_cap = map->xtal_k;
253	efuse->pa_type_2g = map->pa_type;
254	efuse->lna_type_2g = map->lna_type_2g[0];
255	efuse->channel_plan = map->channel_plan;
256	efuse->country_code[0] = map->country_code[0];
257	efuse->country_code[1] = map->country_code[1];
258	efuse->bt_setting = map->rf_bt_setting;
259	efuse->regd = map->rf_board_option & 0x7;
260	efuse->thermal_meter[0] = map->thermal_meter;
261	efuse->thermal_meter_k = map->thermal_meter;
262	efuse->afe = map->afe;
263
264	for (i = 0; i < 4; i++)
265		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
266
267	switch (rtw_hci_type(rtwdev)) {
268	case RTW_HCI_TYPE_PCIE:
269		rtw8723xe_efuse_parsing(efuse, map);
270		break;
271	case RTW_HCI_TYPE_USB:
272		rtw8723xu_efuse_parsing(efuse, map);
273		break;
274	case RTW_HCI_TYPE_SDIO:
275		rtw8723xs_efuse_parsing(efuse, map);
276		break;
277	default:
278		/* unsupported now */
279		return -EOPNOTSUPP;
280	}
281
282	return 0;
283}
284
285#define BIT_CFENDFORM		BIT(9)
286#define BIT_WMAC_TCR_ERR0	BIT(12)
287#define BIT_WMAC_TCR_ERR1	BIT(13)
288#define BIT_TCR_CFG		(BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 |	       \
289				 BIT_WMAC_TCR_ERR1)
290#define WLAN_RX_FILTER0		0xFFFF
291#define WLAN_RX_FILTER1		0x400
292#define WLAN_RX_FILTER2		0xFFFF
293#define WLAN_RCR_CFG		0x700060CE
294
295static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)
296{
297	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
298	rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
299
300	rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
301	rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);
302	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
303	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
304
305	rtw_write32(rtwdev, REG_INT_MIG, 0);
306	rtw_write32(rtwdev, REG_MCUTST_1, 0x0);
307
308	rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);
309	rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);
310
311	return 0;
312}
313
314static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
315{
316	u8 ldo_pwr;
317
318	ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
319	if (enable) {
320		ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;
321		ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;
322	} else {
323		ldo_pwr &= ~BIT_LDO25_EN;
324	}
325	rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
326}
327
328static void
329rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
330{
331	struct rtw_hal *hal = &rtwdev->hal;
332	const struct rtw_hw_reg *txagc;
333	u8 rate, pwr_index;
334	int j;
335
336	for (j = 0; j < rtw_rate_size[rs]; j++) {
337		rate = rtw_rate_section[rs][j];
338		pwr_index = hal->tx_pwr_tbl[path][rate];
339
340		if (rate >= ARRAY_SIZE(rtw8723x_txagc)) {
341			rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);
342			continue;
343		}
344		txagc = &rtw8723x_txagc[rate];
345		if (!txagc->addr) {
346			rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);
347			continue;
348		}
349
350		rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);
351	}
352}
353
354static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev)
355{
356	struct rtw_hal *hal = &rtwdev->hal;
357	int rs, path;
358
359	for (path = 0; path < hal->rf_path_num; path++) {
360		for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)
361			rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs);
362	}
363}
364
365static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on)
366{
367	if (on) {
368		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
369
370		rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);
371		rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M);
372	} else {
373		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
374	}
375}
376
377static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev)
378{
379	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
380	u32 cck_fa_cnt;
381	u32 ofdm_fa_cnt;
382	u32 crc32_cnt;
383	u32 val32;
384
385	/* hold counter */
386	rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
387	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
388	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
389	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
390
391	cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
392	cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
393
394	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
395	ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
396	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
397	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
398	dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
399	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
400	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
401	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
402	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
403	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
404	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
405
406	dm_info->cck_fa_cnt = cck_fa_cnt;
407	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
408	dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
409
410	dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
411	dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
412	crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
413	dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
414	dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
415	crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
416	dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
417	dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
418	dm_info->vht_err_cnt = 0;
419	dm_info->vht_ok_cnt = 0;
420
421	val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
422	dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
423			       u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
424	dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
425
426	/* reset counter */
427	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
428	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
429	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
430	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
431	rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
432	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
433	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
434	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
435	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
436	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
437	rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
438	rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
439}
440
441/* IQK (IQ calibration) */
442
443static
444void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev,
445				struct rtw8723x_iqk_backup_regs *backup)
446{
447	int i;
448
449	for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
450		backup->adda[i] = rtw_read32(rtwdev,
451					     rtw8723x_common.iqk_adda_regs[i]);
452
453	for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
454		backup->mac8[i] = rtw_read8(rtwdev,
455					    rtw8723x_common.iqk_mac8_regs[i]);
456	for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
457		backup->mac32[i] = rtw_read32(rtwdev,
458					      rtw8723x_common.iqk_mac32_regs[i]);
459
460	for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
461		backup->bb[i] = rtw_read32(rtwdev,
462					   rtw8723x_common.iqk_bb_regs[i]);
463
464	backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);
465	backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);
466
467	backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);
468}
469
470static
471void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev,
472				 const struct rtw8723x_iqk_backup_regs *backup)
473{
474	int i;
475
476	for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
477		rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i],
478			    backup->adda[i]);
479
480	for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
481		rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],
482			   backup->mac8[i]);
483	for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
484		rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i],
485			    backup->mac32[i]);
486
487	for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
488		rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i],
489			    backup->bb[i]);
490
491	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
492	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);
493
494	rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);
495	rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);
496
497	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);
498	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);
499}
500
501static
502bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev,
503				   s32 result[][IQK_NR],
504				   u8 c1, u8 c2)
505{
506	u32 i, j, diff;
507	u32 bitmap = 0;
508	u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};
509	bool ret = true;
510
511	s32 tmp1, tmp2;
512
513	for (i = 0; i < IQK_NR; i++) {
514		tmp1 = iqkxy_to_s32(result[c1][i]);
515		tmp2 = iqkxy_to_s32(result[c2][i]);
516
517		diff = abs(tmp1 - tmp2);
518
519		if (diff <= MAX_TOLERANCE)
520			continue;
521
522		if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {
523			if (result[c1][i] + result[c1][i + 1] == 0)
524				candidate[i / IQK_SX_NR] = c2;
525			else if (result[c2][i] + result[c2][i + 1] == 0)
526				candidate[i / IQK_SX_NR] = c1;
527			else
528				bitmap |= BIT(i);
529		} else {
530			bitmap |= BIT(i);
531		}
532	}
533
534	if (bitmap != 0)
535		goto check_sim;
536
537	for (i = 0; i < PATH_NR; i++) {
538		if (candidate[i] == IQK_ROUND_INVALID)
539			continue;
540
541		for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)
542			result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];
543		ret = false;
544	}
545
546	return ret;
547
548check_sim:
549	for (i = 0; i < IQK_NR; i++) {
550		j = i & ~1;	/* 2 bits are a pair for IQ[X, Y] */
551		if (bitmap & GENMASK(j + 1, j))
552			continue;
553
554		result[IQK_ROUND_HYBRID][i] = result[c1][i];
555	}
556
557	return false;
558}
559
560static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
561{
562	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
563	u8 tx_rate = dm_info->tx_rate;
564	u8 limit_ofdm = 30;
565
566	switch (tx_rate) {
567	case DESC_RATE1M...DESC_RATE5_5M:
568	case DESC_RATE11M:
569		break;
570	case DESC_RATE6M...DESC_RATE48M:
571		limit_ofdm = 36;
572		break;
573	case DESC_RATE54M:
574		limit_ofdm = 34;
575		break;
576	case DESC_RATEMCS0...DESC_RATEMCS2:
577		limit_ofdm = 38;
578		break;
579	case DESC_RATEMCS3...DESC_RATEMCS4:
580		limit_ofdm = 36;
581		break;
582	case DESC_RATEMCS5...DESC_RATEMCS7:
583		limit_ofdm = 34;
584		break;
585	default:
586		rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);
587		break;
588	}
589
590	return limit_ofdm;
591}
592
593static
594void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
595				  u8 delta)
596{
597	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
598	const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
599	const s8 *pwrtrk_xtal;
600	s8 xtal_cap;
601
602	if (dm_info->thermal_avg[therm_path] >
603	    rtwdev->efuse.thermal_meter[therm_path])
604		pwrtrk_xtal = tbl->pwrtrk_xtal_p;
605	else
606		pwrtrk_xtal = tbl->pwrtrk_xtal_n;
607
608	xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
609	xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);
610	rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
611			 xtal_cap | (xtal_cap << 6));
612}
613
614static
615void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
616				     struct rtw_tx_pkt_info *pkt_info,
617				     u8 *txdesc)
618{
619	size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
620	__le16 chksum = 0;
621	__le16 *data = (__le16 *)(txdesc);
622	struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;
623
624	le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);
625
626	while (words--)
627		chksum ^= *data++;
628
629	chksum = ~chksum;
630
631	le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum),
632			   RTW_TX_DESC_W7_TXDESC_CHECKSUM);
633}
634
635static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)
636{
637	/* enable TBTT nterrupt */
638	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
639
640	/* BT report packet sample rate	 */
641	/* 0x790[5:0]=0x5 */
642	rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
643
644	/* enable BT counter statistics */
645	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
646
647	/* enable PTA (3-wire function form BT side) */
648	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
649	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
650
651	/* enable PTA (tx/rx signal form WiFi side) */
652	rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
653}
654
655const struct rtw8723x_common rtw8723x_common = {
656	.iqk_adda_regs = {
657		0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
658		0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec
659	},
660	.iqk_mac8_regs = {0x522, 0x550, 0x551},
661	.iqk_mac32_regs = {0x40},
662	.iqk_bb_regs = {
663		0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04
664	},
665
666	.ltecoex_addr = {
667		.ctrl = REG_LTECOEX_CTRL,
668		.wdata = REG_LTECOEX_WRITE_DATA,
669		.rdata = REG_LTECOEX_READ_DATA,
670	},
671	.rf_sipi_addr = {
672		[RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read    = 0x8a0,
673				.hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
674		[RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read    = 0x8a4,
675				.hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},
676	},
677	.dig = {
678		[0] = { .addr = 0xc50, .mask = 0x7f },
679		[1] = { .addr = 0xc50, .mask = 0x7f },
680	},
681	.dig_cck = {
682		[0] = { .addr = 0xa0c, .mask = 0x3f00 },
683	},
684	.prioq_addrs = {
685		.prio[RTW_DMA_MAPPING_EXTRA] = {
686			.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
687		},
688		.prio[RTW_DMA_MAPPING_LOW] = {
689			.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
690		},
691		.prio[RTW_DMA_MAPPING_NORMAL] = {
692			.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
693		},
694		.prio[RTW_DMA_MAPPING_HIGH] = {
695			.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
696		},
697		.wsize = false,
698	},
699
700	.lck = __rtw8723x_lck,
701	.read_efuse = __rtw8723x_read_efuse,
702	.mac_init = __rtw8723x_mac_init,
703	.cfg_ldo25 = __rtw8723x_cfg_ldo25,
704	.set_tx_power_index = __rtw8723x_set_tx_power_index,
705	.efuse_grant = __rtw8723x_efuse_grant,
706	.false_alarm_statistics = __rtw8723x_false_alarm_statistics,
707	.iqk_backup_regs = __rtw8723x_iqk_backup_regs,
708	.iqk_restore_regs = __rtw8723x_iqk_restore_regs,
709	.iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp,
710	.pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm,
711	.pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal,
712	.coex_cfg_init = __rtw8723x_coex_cfg_init,
713	.fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum,
714	.debug_txpwr_limit = __rtw8723x_debug_txpwr_limit,
715};
716EXPORT_SYMBOL(rtw8723x_common);
717
718MODULE_AUTHOR("Realtek Corporation");
719MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>");
720MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers");
721MODULE_LICENSE("Dual BSD/GPL");
722