File Index
Files and directories
Sign in
FILE

rtw8723x.c

File preview with syntax highlighting.

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