xref: /freebsd/sys/contrib/dev/rtw88/rtw8822c.c (revision a0ccc12f6882a886d89ae279c541b2c2b62c6aca)
12774f206SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22774f206SBjoern A. Zeeb /* Copyright(c) 2018-2019  Realtek Corporation
32774f206SBjoern A. Zeeb  */
42774f206SBjoern A. Zeeb 
52774f206SBjoern A. Zeeb #include <linux/module.h>
62774f206SBjoern A. Zeeb #include "main.h"
72774f206SBjoern A. Zeeb #include "coex.h"
82774f206SBjoern A. Zeeb #include "fw.h"
92774f206SBjoern A. Zeeb #include "tx.h"
102774f206SBjoern A. Zeeb #include "rx.h"
112774f206SBjoern A. Zeeb #include "phy.h"
122774f206SBjoern A. Zeeb #include "rtw8822c.h"
132774f206SBjoern A. Zeeb #include "rtw8822c_table.h"
142774f206SBjoern A. Zeeb #include "mac.h"
152774f206SBjoern A. Zeeb #include "reg.h"
162774f206SBjoern A. Zeeb #include "debug.h"
172774f206SBjoern A. Zeeb #include "util.h"
182774f206SBjoern A. Zeeb #include "bf.h"
192774f206SBjoern A. Zeeb #include "efuse.h"
202774f206SBjoern A. Zeeb 
212774f206SBjoern A. Zeeb #define IQK_DONE_8822C 0xaa
222774f206SBjoern A. Zeeb 
232774f206SBjoern A. Zeeb static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
242774f206SBjoern A. Zeeb 				     u8 rx_path, bool is_tx2_path);
252774f206SBjoern A. Zeeb 
262774f206SBjoern A. Zeeb static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse,
272774f206SBjoern A. Zeeb 				    struct rtw8822c_efuse *map)
282774f206SBjoern A. Zeeb {
292774f206SBjoern A. Zeeb 	ether_addr_copy(efuse->addr, map->e.mac_addr);
302774f206SBjoern A. Zeeb }
312774f206SBjoern A. Zeeb 
3290aac0d8SBjoern A. Zeeb static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse,
3390aac0d8SBjoern A. Zeeb 				    struct rtw8822c_efuse *map)
3490aac0d8SBjoern A. Zeeb {
3590aac0d8SBjoern A. Zeeb 	ether_addr_copy(efuse->addr, map->u.mac_addr);
3690aac0d8SBjoern A. Zeeb }
3790aac0d8SBjoern A. Zeeb 
3890aac0d8SBjoern A. Zeeb static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse,
3990aac0d8SBjoern A. Zeeb 				    struct rtw8822c_efuse *map)
4090aac0d8SBjoern A. Zeeb {
4190aac0d8SBjoern A. Zeeb 	ether_addr_copy(efuse->addr, map->s.mac_addr);
4290aac0d8SBjoern A. Zeeb }
4390aac0d8SBjoern A. Zeeb 
442774f206SBjoern A. Zeeb static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
452774f206SBjoern A. Zeeb {
462774f206SBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
472774f206SBjoern A. Zeeb 	struct rtw8822c_efuse *map;
482774f206SBjoern A. Zeeb 	int i;
492774f206SBjoern A. Zeeb 
502774f206SBjoern A. Zeeb 	map = (struct rtw8822c_efuse *)log_map;
512774f206SBjoern A. Zeeb 
52*a0ccc12fSBjoern A. Zeeb 	efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7));
532774f206SBjoern A. Zeeb 	efuse->rfe_option = map->rfe_option;
542774f206SBjoern A. Zeeb 	efuse->rf_board_option = map->rf_board_option;
552774f206SBjoern A. Zeeb 	efuse->crystal_cap = map->xtal_k & XCAP_MASK;
562774f206SBjoern A. Zeeb 	efuse->channel_plan = map->channel_plan;
572774f206SBjoern A. Zeeb 	efuse->country_code[0] = map->country_code[0];
582774f206SBjoern A. Zeeb 	efuse->country_code[1] = map->country_code[1];
592774f206SBjoern A. Zeeb 	efuse->bt_setting = map->rf_bt_setting;
602774f206SBjoern A. Zeeb 	efuse->regd = map->rf_board_option & 0x7;
612774f206SBjoern A. Zeeb 	efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal;
622774f206SBjoern A. Zeeb 	efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal;
632774f206SBjoern A. Zeeb 	efuse->thermal_meter_k =
642774f206SBjoern A. Zeeb 			(map->path_a_thermal + map->path_b_thermal) >> 1;
652774f206SBjoern A. Zeeb 	efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf;
662774f206SBjoern A. Zeeb 
672774f206SBjoern A. Zeeb 	for (i = 0; i < 4; i++)
682774f206SBjoern A. Zeeb 		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
692774f206SBjoern A. Zeeb 
702774f206SBjoern A. Zeeb 	switch (rtw_hci_type(rtwdev)) {
712774f206SBjoern A. Zeeb 	case RTW_HCI_TYPE_PCIE:
722774f206SBjoern A. Zeeb 		rtw8822ce_efuse_parsing(efuse, map);
732774f206SBjoern A. Zeeb 		break;
7490aac0d8SBjoern A. Zeeb 	case RTW_HCI_TYPE_USB:
7590aac0d8SBjoern A. Zeeb 		rtw8822cu_efuse_parsing(efuse, map);
7690aac0d8SBjoern A. Zeeb 		break;
7790aac0d8SBjoern A. Zeeb 	case RTW_HCI_TYPE_SDIO:
7890aac0d8SBjoern A. Zeeb 		rtw8822cs_efuse_parsing(efuse, map);
7990aac0d8SBjoern A. Zeeb 		break;
802774f206SBjoern A. Zeeb 	default:
812774f206SBjoern A. Zeeb 		/* unsupported now */
822774f206SBjoern A. Zeeb 		return -ENOTSUPP;
832774f206SBjoern A. Zeeb 	}
842774f206SBjoern A. Zeeb 
852774f206SBjoern A. Zeeb 	return 0;
862774f206SBjoern A. Zeeb }
872774f206SBjoern A. Zeeb 
882774f206SBjoern A. Zeeb static void rtw8822c_header_file_init(struct rtw_dev *rtwdev, bool pre)
892774f206SBjoern A. Zeeb {
902774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN);
912774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_PI_ON);
922774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN);
932774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_PI_ON);
942774f206SBjoern A. Zeeb 
952774f206SBjoern A. Zeeb 	if (pre)
962774f206SBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN);
972774f206SBjoern A. Zeeb 	else
982774f206SBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN);
992774f206SBjoern A. Zeeb }
1002774f206SBjoern A. Zeeb 
1012774f206SBjoern A. Zeeb static void rtw8822c_bb_reset(struct rtw_dev *rtwdev)
1022774f206SBjoern A. Zeeb {
1032774f206SBjoern A. Zeeb 	rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB);
1042774f206SBjoern A. Zeeb 	rtw_write16_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB);
1052774f206SBjoern A. Zeeb 	rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB);
1062774f206SBjoern A. Zeeb }
1072774f206SBjoern A. Zeeb 
1082774f206SBjoern A. Zeeb static void rtw8822c_dac_backup_reg(struct rtw_dev *rtwdev,
1092774f206SBjoern A. Zeeb 				    struct rtw_backup_info *backup,
1102774f206SBjoern A. Zeeb 				    struct rtw_backup_info *backup_rf)
1112774f206SBjoern A. Zeeb {
1122774f206SBjoern A. Zeeb 	u32 path, i;
1132774f206SBjoern A. Zeeb 	u32 val;
1142774f206SBjoern A. Zeeb 	u32 reg;
1152774f206SBjoern A. Zeeb 	u32 rf_addr[DACK_RF_8822C] = {0x8f};
1162774f206SBjoern A. Zeeb 	u32 addrs[DACK_REG_8822C] = {0x180c, 0x1810, 0x410c, 0x4110,
1172774f206SBjoern A. Zeeb 				     0x1c3c, 0x1c24, 0x1d70, 0x9b4,
1182774f206SBjoern A. Zeeb 				     0x1a00, 0x1a14, 0x1d58, 0x1c38,
1192774f206SBjoern A. Zeeb 				     0x1e24, 0x1e28, 0x1860, 0x4160};
1202774f206SBjoern A. Zeeb 
1212774f206SBjoern A. Zeeb 	for (i = 0; i < DACK_REG_8822C; i++) {
1222774f206SBjoern A. Zeeb 		backup[i].len = 4;
1232774f206SBjoern A. Zeeb 		backup[i].reg = addrs[i];
1242774f206SBjoern A. Zeeb 		backup[i].val = rtw_read32(rtwdev, addrs[i]);
1252774f206SBjoern A. Zeeb 	}
1262774f206SBjoern A. Zeeb 
1272774f206SBjoern A. Zeeb 	for (path = 0; path < DACK_PATH_8822C; path++) {
1282774f206SBjoern A. Zeeb 		for (i = 0; i < DACK_RF_8822C; i++) {
1292774f206SBjoern A. Zeeb 			reg = rf_addr[i];
1302774f206SBjoern A. Zeeb 			val = rtw_read_rf(rtwdev, path, reg, RFREG_MASK);
1312774f206SBjoern A. Zeeb 			backup_rf[path * i + i].reg = reg;
1322774f206SBjoern A. Zeeb 			backup_rf[path * i + i].val = val;
1332774f206SBjoern A. Zeeb 		}
1342774f206SBjoern A. Zeeb 	}
1352774f206SBjoern A. Zeeb }
1362774f206SBjoern A. Zeeb 
1372774f206SBjoern A. Zeeb static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev,
1382774f206SBjoern A. Zeeb 				     struct rtw_backup_info *backup,
1392774f206SBjoern A. Zeeb 				     struct rtw_backup_info *backup_rf)
1402774f206SBjoern A. Zeeb {
1412774f206SBjoern A. Zeeb 	u32 path, i;
1422774f206SBjoern A. Zeeb 	u32 val;
1432774f206SBjoern A. Zeeb 	u32 reg;
1442774f206SBjoern A. Zeeb 
1452774f206SBjoern A. Zeeb 	rtw_restore_reg(rtwdev, backup, DACK_REG_8822C);
1462774f206SBjoern A. Zeeb 
1472774f206SBjoern A. Zeeb 	for (path = 0; path < DACK_PATH_8822C; path++) {
1482774f206SBjoern A. Zeeb 		for (i = 0; i < DACK_RF_8822C; i++) {
1492774f206SBjoern A. Zeeb 			val = backup_rf[path * i + i].val;
1502774f206SBjoern A. Zeeb 			reg = backup_rf[path * i + i].reg;
1512774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, reg, RFREG_MASK, val);
1522774f206SBjoern A. Zeeb 		}
1532774f206SBjoern A. Zeeb 	}
1542774f206SBjoern A. Zeeb }
1552774f206SBjoern A. Zeeb 
1562774f206SBjoern A. Zeeb static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value,
1572774f206SBjoern A. Zeeb 				   u32 *min, u32 *max)
1582774f206SBjoern A. Zeeb {
1592774f206SBjoern A. Zeeb 	if (value >= 0x200) {
1602774f206SBjoern A. Zeeb 		if (*min >= 0x200) {
1612774f206SBjoern A. Zeeb 			if (*min > value)
1622774f206SBjoern A. Zeeb 				*min = value;
1632774f206SBjoern A. Zeeb 		} else {
1642774f206SBjoern A. Zeeb 			*min = value;
1652774f206SBjoern A. Zeeb 		}
1662774f206SBjoern A. Zeeb 		if (*max >= 0x200) {
1672774f206SBjoern A. Zeeb 			if (*max < value)
1682774f206SBjoern A. Zeeb 				*max = value;
1692774f206SBjoern A. Zeeb 		}
1702774f206SBjoern A. Zeeb 	} else {
1712774f206SBjoern A. Zeeb 		if (*min < 0x200) {
1722774f206SBjoern A. Zeeb 			if (*min > value)
1732774f206SBjoern A. Zeeb 				*min = value;
1742774f206SBjoern A. Zeeb 		}
1752774f206SBjoern A. Zeeb 
1762774f206SBjoern A. Zeeb 		if (*max  >= 0x200) {
1772774f206SBjoern A. Zeeb 			*max = value;
1782774f206SBjoern A. Zeeb 		} else {
1792774f206SBjoern A. Zeeb 			if (*max < value)
1802774f206SBjoern A. Zeeb 				*max = value;
1812774f206SBjoern A. Zeeb 		}
1822774f206SBjoern A. Zeeb 	}
1832774f206SBjoern A. Zeeb }
1842774f206SBjoern A. Zeeb 
1852774f206SBjoern A. Zeeb static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2)
1862774f206SBjoern A. Zeeb {
1872774f206SBjoern A. Zeeb 	if (*v1 >= 0x200 && *v2 >= 0x200) {
1882774f206SBjoern A. Zeeb 		if (*v1 > *v2)
1892774f206SBjoern A. Zeeb 			swap(*v1, *v2);
1902774f206SBjoern A. Zeeb 	} else if (*v1 < 0x200 && *v2 < 0x200) {
1912774f206SBjoern A. Zeeb 		if (*v1 > *v2)
1922774f206SBjoern A. Zeeb 			swap(*v1, *v2);
1932774f206SBjoern A. Zeeb 	} else if (*v1 < 0x200 && *v2 >= 0x200) {
1942774f206SBjoern A. Zeeb 		swap(*v1, *v2);
1952774f206SBjoern A. Zeeb 	}
1962774f206SBjoern A. Zeeb }
1972774f206SBjoern A. Zeeb 
1982774f206SBjoern A. Zeeb static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
1992774f206SBjoern A. Zeeb {
2002774f206SBjoern A. Zeeb 	u32 i, j;
2012774f206SBjoern A. Zeeb 
2022774f206SBjoern A. Zeeb 	for (i = 0; i < DACK_SN_8822C - 1; i++) {
2032774f206SBjoern A. Zeeb 		for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) {
2042774f206SBjoern A. Zeeb 			__rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]);
2052774f206SBjoern A. Zeeb 			__rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]);
2062774f206SBjoern A. Zeeb 		}
2072774f206SBjoern A. Zeeb 	}
2082774f206SBjoern A. Zeeb }
2092774f206SBjoern A. Zeeb 
2102774f206SBjoern A. Zeeb static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val)
2112774f206SBjoern A. Zeeb {
2122774f206SBjoern A. Zeeb 	u32 p, m, t, i;
2132774f206SBjoern A. Zeeb 
2142774f206SBjoern A. Zeeb 	m = 0;
2152774f206SBjoern A. Zeeb 	p = 0;
2162774f206SBjoern A. Zeeb 	for (i = 10; i < DACK_SN_8822C - 10; i++) {
2172774f206SBjoern A. Zeeb 		if (vec[i] > 0x200)
2182774f206SBjoern A. Zeeb 			m = (0x400 - vec[i]) + m;
2192774f206SBjoern A. Zeeb 		else
2202774f206SBjoern A. Zeeb 			p = vec[i] + p;
2212774f206SBjoern A. Zeeb 	}
2222774f206SBjoern A. Zeeb 
2232774f206SBjoern A. Zeeb 	if (p > m) {
2242774f206SBjoern A. Zeeb 		t = p - m;
2252774f206SBjoern A. Zeeb 		t = t / (DACK_SN_8822C - 20);
2262774f206SBjoern A. Zeeb 	} else {
2272774f206SBjoern A. Zeeb 		t = m - p;
2282774f206SBjoern A. Zeeb 		t = t / (DACK_SN_8822C - 20);
2292774f206SBjoern A. Zeeb 		if (t != 0x0)
2302774f206SBjoern A. Zeeb 			t = 0x400 - t;
2312774f206SBjoern A. Zeeb 	}
2322774f206SBjoern A. Zeeb 
2332774f206SBjoern A. Zeeb 	*val = t;
2342774f206SBjoern A. Zeeb }
2352774f206SBjoern A. Zeeb 
2362774f206SBjoern A. Zeeb static u32 rtw8822c_get_path_write_addr(u8 path)
2372774f206SBjoern A. Zeeb {
2382774f206SBjoern A. Zeeb 	u32 base_addr;
2392774f206SBjoern A. Zeeb 
2402774f206SBjoern A. Zeeb 	switch (path) {
2412774f206SBjoern A. Zeeb 	case RF_PATH_A:
2422774f206SBjoern A. Zeeb 		base_addr = 0x1800;
2432774f206SBjoern A. Zeeb 		break;
2442774f206SBjoern A. Zeeb 	case RF_PATH_B:
2452774f206SBjoern A. Zeeb 		base_addr = 0x4100;
2462774f206SBjoern A. Zeeb 		break;
2472774f206SBjoern A. Zeeb 	default:
2482774f206SBjoern A. Zeeb 		WARN_ON(1);
2492774f206SBjoern A. Zeeb 		return -1;
2502774f206SBjoern A. Zeeb 	}
2512774f206SBjoern A. Zeeb 
2522774f206SBjoern A. Zeeb 	return base_addr;
2532774f206SBjoern A. Zeeb }
2542774f206SBjoern A. Zeeb 
2552774f206SBjoern A. Zeeb static u32 rtw8822c_get_path_read_addr(u8 path)
2562774f206SBjoern A. Zeeb {
2572774f206SBjoern A. Zeeb 	u32 base_addr;
2582774f206SBjoern A. Zeeb 
2592774f206SBjoern A. Zeeb 	switch (path) {
2602774f206SBjoern A. Zeeb 	case RF_PATH_A:
2612774f206SBjoern A. Zeeb 		base_addr = 0x2800;
2622774f206SBjoern A. Zeeb 		break;
2632774f206SBjoern A. Zeeb 	case RF_PATH_B:
2642774f206SBjoern A. Zeeb 		base_addr = 0x4500;
2652774f206SBjoern A. Zeeb 		break;
2662774f206SBjoern A. Zeeb 	default:
2672774f206SBjoern A. Zeeb 		WARN_ON(1);
2682774f206SBjoern A. Zeeb 		return -1;
2692774f206SBjoern A. Zeeb 	}
2702774f206SBjoern A. Zeeb 
2712774f206SBjoern A. Zeeb 	return base_addr;
2722774f206SBjoern A. Zeeb }
2732774f206SBjoern A. Zeeb 
2742774f206SBjoern A. Zeeb static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value)
2752774f206SBjoern A. Zeeb {
2762774f206SBjoern A. Zeeb 	bool ret = true;
2772774f206SBjoern A. Zeeb 
2782774f206SBjoern A. Zeeb 	if ((value >= 0x200 && (0x400 - value) > 0x64) ||
2792774f206SBjoern A. Zeeb 	    (value < 0x200 && value > 0x64)) {
2802774f206SBjoern A. Zeeb 		ret = false;
2812774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n");
2822774f206SBjoern A. Zeeb 	}
2832774f206SBjoern A. Zeeb 
2842774f206SBjoern A. Zeeb 	return ret;
2852774f206SBjoern A. Zeeb }
2862774f206SBjoern A. Zeeb 
2872774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
2882774f206SBjoern A. Zeeb {
2892774f206SBjoern A. Zeeb 	u32 temp;
2902774f206SBjoern A. Zeeb 	int i = 0, cnt = 0;
2912774f206SBjoern A. Zeeb 
2922774f206SBjoern A. Zeeb 	while (i < DACK_SN_8822C && cnt < 10000) {
2932774f206SBjoern A. Zeeb 		cnt++;
2942774f206SBjoern A. Zeeb 		temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
2952774f206SBjoern A. Zeeb 		iv[i] = (temp & 0x3ff000) >> 12;
2962774f206SBjoern A. Zeeb 		qv[i] = temp & 0x3ff;
2972774f206SBjoern A. Zeeb 
2982774f206SBjoern A. Zeeb 		if (rtw8822c_dac_iq_check(rtwdev, iv[i]) &&
2992774f206SBjoern A. Zeeb 		    rtw8822c_dac_iq_check(rtwdev, qv[i]))
3002774f206SBjoern A. Zeeb 			i++;
3012774f206SBjoern A. Zeeb 	}
3022774f206SBjoern A. Zeeb }
3032774f206SBjoern A. Zeeb 
3042774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
3052774f206SBjoern A. Zeeb 				       u32 *iv, u32 *qv,
3062774f206SBjoern A. Zeeb 				       u32 *i_value, u32 *q_value)
3072774f206SBjoern A. Zeeb {
3082774f206SBjoern A. Zeeb 	u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;
3092774f206SBjoern A. Zeeb 	u32 i_delta, q_delta;
3102774f206SBjoern A. Zeeb 	u32 temp;
3112774f206SBjoern A. Zeeb 	int i, cnt = 0;
3122774f206SBjoern A. Zeeb 
3132774f206SBjoern A. Zeeb 	do {
3142774f206SBjoern A. Zeeb 		i_min = iv[0];
3152774f206SBjoern A. Zeeb 		i_max = iv[0];
3162774f206SBjoern A. Zeeb 		q_min = qv[0];
3172774f206SBjoern A. Zeeb 		q_max = qv[0];
3182774f206SBjoern A. Zeeb 		for (i = 0; i < DACK_SN_8822C; i++) {
3192774f206SBjoern A. Zeeb 			rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max);
3202774f206SBjoern A. Zeeb 			rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max);
3212774f206SBjoern A. Zeeb 		}
3222774f206SBjoern A. Zeeb 
3232774f206SBjoern A. Zeeb 		if (i_max < 0x200 && i_min < 0x200)
3242774f206SBjoern A. Zeeb 			i_delta = i_max - i_min;
3252774f206SBjoern A. Zeeb 		else if (i_max >= 0x200 && i_min >= 0x200)
3262774f206SBjoern A. Zeeb 			i_delta = i_max - i_min;
3272774f206SBjoern A. Zeeb 		else
3282774f206SBjoern A. Zeeb 			i_delta = i_max + (0x400 - i_min);
3292774f206SBjoern A. Zeeb 
3302774f206SBjoern A. Zeeb 		if (q_max < 0x200 && q_min < 0x200)
3312774f206SBjoern A. Zeeb 			q_delta = q_max - q_min;
3322774f206SBjoern A. Zeeb 		else if (q_max >= 0x200 && q_min >= 0x200)
3332774f206SBjoern A. Zeeb 			q_delta = q_max - q_min;
3342774f206SBjoern A. Zeeb 		else
3352774f206SBjoern A. Zeeb 			q_delta = q_max + (0x400 - q_min);
3362774f206SBjoern A. Zeeb 
3372774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
3382774f206SBjoern A. Zeeb 			"[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n",
3392774f206SBjoern A. Zeeb 			i_min, i_max, i_delta);
3402774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
3412774f206SBjoern A. Zeeb 			"[DACK] q: min=0x%08x, max=0x%08x, delta=0x%08x\n",
3422774f206SBjoern A. Zeeb 			q_min, q_max, q_delta);
3432774f206SBjoern A. Zeeb 
3442774f206SBjoern A. Zeeb 		rtw8822c_dac_iq_sort(rtwdev, iv, qv);
3452774f206SBjoern A. Zeeb 
3462774f206SBjoern A. Zeeb 		if (i_delta > 5 || q_delta > 5) {
3472774f206SBjoern A. Zeeb 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
3482774f206SBjoern A. Zeeb 			iv[0] = (temp & 0x3ff000) >> 12;
3492774f206SBjoern A. Zeeb 			qv[0] = temp & 0x3ff;
3502774f206SBjoern A. Zeeb 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
3512774f206SBjoern A. Zeeb 			iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12;
3522774f206SBjoern A. Zeeb 			qv[DACK_SN_8822C - 1] = temp & 0x3ff;
3532774f206SBjoern A. Zeeb 		} else {
3542774f206SBjoern A. Zeeb 			break;
3552774f206SBjoern A. Zeeb 		}
3562774f206SBjoern A. Zeeb 	} while (cnt++ < 100);
3572774f206SBjoern A. Zeeb 
3582774f206SBjoern A. Zeeb 	rtw8822c_dac_iq_offset(rtwdev, iv, i_value);
3592774f206SBjoern A. Zeeb 	rtw8822c_dac_iq_offset(rtwdev, qv, q_value);
3602774f206SBjoern A. Zeeb }
3612774f206SBjoern A. Zeeb 
3622774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,
3632774f206SBjoern A. Zeeb 				     u32 *i_value, u32 *q_value)
3642774f206SBjoern A. Zeeb {
3652774f206SBjoern A. Zeeb 	u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
3662774f206SBjoern A. Zeeb 	u32 rf_a, rf_b;
3672774f206SBjoern A. Zeeb 
3682774f206SBjoern A. Zeeb 	rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK);
3692774f206SBjoern A. Zeeb 	rf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK);
3702774f206SBjoern A. Zeeb 
3712774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-A=0x%05x\n", rf_a);
3722774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-B=0x%05x\n", rf_b);
3732774f206SBjoern A. Zeeb 
3742774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_iq_sample(rtwdev, iv, qv);
3752774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value);
3762774f206SBjoern A. Zeeb }
3772774f206SBjoern A. Zeeb 
3782774f206SBjoern A. Zeeb static void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev)
3792774f206SBjoern A. Zeeb {
3802774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1d58, 0xff8, 0x1ff);
3812774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1a00, 0x3, 0x2);
3822774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1a14, 0x300, 0x3);
3832774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1d70, 0x7e7e7e7e);
3842774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x180c, 0x3, 0x0);
3852774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x410c, 0x3, 0x0);
3862774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b00, 0x00000008);
3872774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1bcc, 0x3f);
3882774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b00, 0x0000000a);
3892774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1bcc, 0x3f);
3902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1e24, BIT(31), 0x0);
3912774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1e28, 0xf, 0x3);
3922774f206SBjoern A. Zeeb }
3932774f206SBjoern A. Zeeb 
3942774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev,
3952774f206SBjoern A. Zeeb 				 u8 path, u32 *adc_ic, u32 *adc_qc)
3962774f206SBjoern A. Zeeb {
3972774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
3982774f206SBjoern A. Zeeb 	u32 ic = 0, qc = 0, temp = 0;
3992774f206SBjoern A. Zeeb 	u32 base_addr;
4002774f206SBjoern A. Zeeb 	u32 path_sel;
4012774f206SBjoern A. Zeeb 	int i;
4022774f206SBjoern A. Zeeb 
4032774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK path(%d)\n", path);
4042774f206SBjoern A. Zeeb 
4052774f206SBjoern A. Zeeb 	base_addr = rtw8822c_get_path_write_addr(path);
4062774f206SBjoern A. Zeeb 	switch (path) {
4072774f206SBjoern A. Zeeb 	case RF_PATH_A:
4082774f206SBjoern A. Zeeb 		path_sel = 0xa0000;
4092774f206SBjoern A. Zeeb 		break;
4102774f206SBjoern A. Zeeb 	case RF_PATH_B:
4112774f206SBjoern A. Zeeb 		path_sel = 0x80000;
4122774f206SBjoern A. Zeeb 		break;
4132774f206SBjoern A. Zeeb 	default:
4142774f206SBjoern A. Zeeb 		WARN_ON(1);
4152774f206SBjoern A. Zeeb 		return;
4162774f206SBjoern A. Zeeb 	}
4172774f206SBjoern A. Zeeb 
4182774f206SBjoern A. Zeeb 	/* ADCK step1 */
4192774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x0);
4202774f206SBjoern A. Zeeb 	if (path == RF_PATH_B)
4212774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, base_addr + 0x30, 0x30db8041);
4222774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0);
4232774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);
4242774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02dd08c4);
4252774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260);
4262774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK, 0x10000);
4272774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK, 0x10000);
4282774f206SBjoern A. Zeeb 	for (i = 0; i < 10; i++) {
4292774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK count=%d\n", i);
4302774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8003);
4312774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, 0x1c24, 0x00010002);
4322774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc);
4332774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
4342774f206SBjoern A. Zeeb 			"[DACK] before: i=0x%x, q=0x%x\n", ic, qc);
4352774f206SBjoern A. Zeeb 
4362774f206SBjoern A. Zeeb 		/* compensation value */
4372774f206SBjoern A. Zeeb 		if (ic != 0x0) {
4382774f206SBjoern A. Zeeb 			ic = 0x400 - ic;
4392774f206SBjoern A. Zeeb 			*adc_ic = ic;
4402774f206SBjoern A. Zeeb 		}
4412774f206SBjoern A. Zeeb 		if (qc != 0x0) {
4422774f206SBjoern A. Zeeb 			qc = 0x400 - qc;
4432774f206SBjoern A. Zeeb 			*adc_qc = qc;
4442774f206SBjoern A. Zeeb 		}
4452774f206SBjoern A. Zeeb 		temp = (ic & 0x3ff) | ((qc & 0x3ff) << 10);
4462774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, base_addr + 0x68, temp);
4472774f206SBjoern A. Zeeb 		dm_info->dack_adck[path] = temp;
4482774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK 0x%08x=0x08%x\n",
4492774f206SBjoern A. Zeeb 			base_addr + 0x68, temp);
4502774f206SBjoern A. Zeeb 		/* check ADC DC offset */
4512774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103);
4522774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc);
4532774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
4542774f206SBjoern A. Zeeb 			"[DACK] after:  i=0x%08x, q=0x%08x\n", ic, qc);
4552774f206SBjoern A. Zeeb 		if (ic >= 0x200)
4562774f206SBjoern A. Zeeb 			ic = 0x400 - ic;
4572774f206SBjoern A. Zeeb 		if (qc >= 0x200)
4582774f206SBjoern A. Zeeb 			qc = 0x400 - qc;
4592774f206SBjoern A. Zeeb 		if (ic < 5 && qc < 5)
4602774f206SBjoern A. Zeeb 			break;
4612774f206SBjoern A. Zeeb 	}
4622774f206SBjoern A. Zeeb 
4632774f206SBjoern A. Zeeb 	/* ADCK step2 */
4642774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1c3c, 0x00000003);
4652774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260);
4662774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4);
4672774f206SBjoern A. Zeeb 
4682774f206SBjoern A. Zeeb 	/* release pull low switch on IQ path */
4692774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, 0x8f, BIT(13), 0x1);
4702774f206SBjoern A. Zeeb }
4712774f206SBjoern A. Zeeb 
4722774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path)
4732774f206SBjoern A. Zeeb {
4742774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
4752774f206SBjoern A. Zeeb 	u32 base_addr;
4762774f206SBjoern A. Zeeb 	u32 read_addr;
4772774f206SBjoern A. Zeeb 
4782774f206SBjoern A. Zeeb 	base_addr = rtw8822c_get_path_write_addr(path);
4792774f206SBjoern A. Zeeb 	read_addr = rtw8822c_get_path_read_addr(path);
4802774f206SBjoern A. Zeeb 
4812774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x68, dm_info->dack_adck[path]);
4822774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);
4832774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
4842774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0);
4852774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, 0x1c38, 0xffffffff);
4862774f206SBjoern A. Zeeb 	}
4872774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);
4882774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb66db00);
4892774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88);
4902774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff81);
4912774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208);
4922774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88);
4932774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xd8, 0x0008ff81);
4942774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208);
4952774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000);
4962774f206SBjoern A. Zeeb 	mdelay(2);
4972774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xbc, 0x000aff8d);
4982774f206SBjoern A. Zeeb 	mdelay(2);
4992774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89);
5002774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89);
5012774f206SBjoern A. Zeeb 	mdelay(1);
5022774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000);
5032774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000);
5042774f206SBjoern A. Zeeb 	mdelay(20);
5052774f206SBjoern A. Zeeb 	if (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) ||
5062774f206SBjoern A. Zeeb 	    !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff))
5072774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "failed to wait for dack ready\n");
5082774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000);
5092774f206SBjoern A. Zeeb 	mdelay(1);
5102774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87);
5112774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb6db600);
5122774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);
5132774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87);
5142774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000);
5152774f206SBjoern A. Zeeb }
5162774f206SBjoern A. Zeeb 
5172774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev,
5182774f206SBjoern A. Zeeb 				   u8 path, u32 *ic_out, u32 *qc_out)
5192774f206SBjoern A. Zeeb {
5202774f206SBjoern A. Zeeb 	u32 base_addr;
5212774f206SBjoern A. Zeeb 	u32 ic, qc, ic_in, qc_in;
5222774f206SBjoern A. Zeeb 
5232774f206SBjoern A. Zeeb 	base_addr = rtw8822c_get_path_write_addr(path);
5242774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0);
5252774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, 0x8);
5262774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, 0x0);
5272774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, 0x8);
5282774f206SBjoern A. Zeeb 
5292774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b00, 0x00000008);
5302774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1bcc, 0x03f);
5312774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);
5322774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);
5332774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1c3c, 0x00088103);
5342774f206SBjoern A. Zeeb 
5352774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_rf_mode(rtwdev, &ic_in, &qc_in);
5362774f206SBjoern A. Zeeb 	ic = ic_in;
5372774f206SBjoern A. Zeeb 	qc = qc_in;
5382774f206SBjoern A. Zeeb 
5392774f206SBjoern A. Zeeb 	/* compensation value */
5402774f206SBjoern A. Zeeb 	if (ic != 0x0)
5412774f206SBjoern A. Zeeb 		ic = 0x400 - ic;
5422774f206SBjoern A. Zeeb 	if (qc != 0x0)
5432774f206SBjoern A. Zeeb 		qc = 0x400 - qc;
5442774f206SBjoern A. Zeeb 	if (ic < 0x300) {
5452774f206SBjoern A. Zeeb 		ic = ic * 2 * 6 / 5;
5462774f206SBjoern A. Zeeb 		ic = ic + 0x80;
5472774f206SBjoern A. Zeeb 	} else {
5482774f206SBjoern A. Zeeb 		ic = (0x400 - ic) * 2 * 6 / 5;
5492774f206SBjoern A. Zeeb 		ic = 0x7f - ic;
5502774f206SBjoern A. Zeeb 	}
5512774f206SBjoern A. Zeeb 	if (qc < 0x300) {
5522774f206SBjoern A. Zeeb 		qc = qc * 2 * 6 / 5;
5532774f206SBjoern A. Zeeb 		qc = qc + 0x80;
5542774f206SBjoern A. Zeeb 	} else {
5552774f206SBjoern A. Zeeb 		qc = (0x400 - qc) * 2 * 6 / 5;
5562774f206SBjoern A. Zeeb 		qc = 0x7f - qc;
5572774f206SBjoern A. Zeeb 	}
5582774f206SBjoern A. Zeeb 
5592774f206SBjoern A. Zeeb 	*ic_out = ic;
5602774f206SBjoern A. Zeeb 	*qc_out = qc;
5612774f206SBjoern A. Zeeb 
5622774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] before i=0x%x, q=0x%x\n", ic_in, qc_in);
5632774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] after  i=0x%x, q=0x%x\n", ic, qc);
5642774f206SBjoern A. Zeeb }
5652774f206SBjoern A. Zeeb 
5662774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path,
5672774f206SBjoern A. Zeeb 				   u32 adc_ic, u32 adc_qc,
5682774f206SBjoern A. Zeeb 				   u32 *ic_in, u32 *qc_in,
5692774f206SBjoern A. Zeeb 				   u32 *i_out, u32 *q_out)
5702774f206SBjoern A. Zeeb {
5712774f206SBjoern A. Zeeb 	u32 base_addr;
5722774f206SBjoern A. Zeeb 	u32 read_addr;
5732774f206SBjoern A. Zeeb 	u32 ic, qc;
5742774f206SBjoern A. Zeeb 	u32 temp;
5752774f206SBjoern A. Zeeb 
5762774f206SBjoern A. Zeeb 	base_addr = rtw8822c_get_path_write_addr(path);
5772774f206SBjoern A. Zeeb 	read_addr = rtw8822c_get_path_read_addr(path);
5782774f206SBjoern A. Zeeb 	ic = *ic_in;
5792774f206SBjoern A. Zeeb 	qc = *qc_in;
5802774f206SBjoern A. Zeeb 
5812774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);
5822774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);
5832774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb66db00);
5842774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88);
5852774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xbc, 0xc008ff81);
5862774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208);
5872774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, ic & 0xf);
5882774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, (ic & 0xf0) >> 4);
5892774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88);
5902774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xd8, 0xe008ff81);
5912774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208);
5922774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, qc & 0xf);
5932774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, (qc & 0xf0) >> 4);
5942774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000);
5952774f206SBjoern A. Zeeb 	mdelay(2);
5962774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x6);
5972774f206SBjoern A. Zeeb 	mdelay(2);
5982774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89);
5992774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89);
6002774f206SBjoern A. Zeeb 	mdelay(1);
6012774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000);
6022774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000);
6032774f206SBjoern A. Zeeb 	mdelay(20);
6042774f206SBjoern A. Zeeb 	if (!check_hw_ready(rtwdev, read_addr + 0x24, 0x07f80000, ic) ||
6052774f206SBjoern A. Zeeb 	    !check_hw_ready(rtwdev, read_addr + 0x50, 0x07f80000, qc))
6062774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "failed to write IQ vector to hardware\n");
6072774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000);
6082774f206SBjoern A. Zeeb 	mdelay(1);
6092774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x3);
6102774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb6db600);
6112774f206SBjoern A. Zeeb 
6122774f206SBjoern A. Zeeb 	/* check DAC DC offset */
6132774f206SBjoern A. Zeeb 	temp = ((adc_ic + 0x10) & 0x3ff) | (((adc_qc + 0x10) & 0x3ff) << 10);
6142774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x68, temp);
6152774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);
6162774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000);
6172774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc);
6182774f206SBjoern A. Zeeb 	if (ic >= 0x10)
6192774f206SBjoern A. Zeeb 		ic = ic - 0x10;
6202774f206SBjoern A. Zeeb 	else
6212774f206SBjoern A. Zeeb 		ic = 0x400 - (0x10 - ic);
6222774f206SBjoern A. Zeeb 
6232774f206SBjoern A. Zeeb 	if (qc >= 0x10)
6242774f206SBjoern A. Zeeb 		qc = qc - 0x10;
6252774f206SBjoern A. Zeeb 	else
6262774f206SBjoern A. Zeeb 		qc = 0x400 - (0x10 - qc);
6272774f206SBjoern A. Zeeb 
6282774f206SBjoern A. Zeeb 	*i_out = ic;
6292774f206SBjoern A. Zeeb 	*q_out = qc;
6302774f206SBjoern A. Zeeb 
6312774f206SBjoern A. Zeeb 	if (ic >= 0x200)
6322774f206SBjoern A. Zeeb 		ic = 0x400 - ic;
6332774f206SBjoern A. Zeeb 	if (qc >= 0x200)
6342774f206SBjoern A. Zeeb 		qc = 0x400 - qc;
6352774f206SBjoern A. Zeeb 
6362774f206SBjoern A. Zeeb 	*ic_in = ic;
6372774f206SBjoern A. Zeeb 	*qc_in = qc;
6382774f206SBjoern A. Zeeb 
6392774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK,
6402774f206SBjoern A. Zeeb 		"[DACK] after  DACK i=0x%x, q=0x%x\n", *i_out, *q_out);
6412774f206SBjoern A. Zeeb }
6422774f206SBjoern A. Zeeb 
6432774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path)
6442774f206SBjoern A. Zeeb {
6452774f206SBjoern A. Zeeb 	u32 base_addr = rtw8822c_get_path_write_addr(path);
6462774f206SBjoern A. Zeeb 
6472774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x68, 0x0);
6482774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4);
6492774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0xbc, 0x1, 0x0);
6502774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x1);
6512774f206SBjoern A. Zeeb }
6522774f206SBjoern A. Zeeb 
6532774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev,
6542774f206SBjoern A. Zeeb 					u8 path, u8 vec, u32 w_addr, u32 r_addr)
6552774f206SBjoern A. Zeeb {
6562774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
6572774f206SBjoern A. Zeeb 	u16 val;
6582774f206SBjoern A. Zeeb 	u32 i;
6592774f206SBjoern A. Zeeb 
6602774f206SBjoern A. Zeeb 	if (WARN_ON(vec >= 2))
6612774f206SBjoern A. Zeeb 		return;
6622774f206SBjoern A. Zeeb 
6632774f206SBjoern A. Zeeb 	for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) {
6642774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_addr, 0xf0000000, i);
6652774f206SBjoern A. Zeeb 		val = (u16)rtw_read32_mask(rtwdev, r_addr, 0x7fc0000);
6662774f206SBjoern A. Zeeb 		dm_info->dack_msbk[path][vec][i] = val;
6672774f206SBjoern A. Zeeb 	}
6682774f206SBjoern A. Zeeb }
6692774f206SBjoern A. Zeeb 
6702774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path)
6712774f206SBjoern A. Zeeb {
6722774f206SBjoern A. Zeeb 	u32 w_off = 0x1c;
6732774f206SBjoern A. Zeeb 	u32 r_off = 0x2c;
6742774f206SBjoern A. Zeeb 	u32 w_addr, r_addr;
6752774f206SBjoern A. Zeeb 
6762774f206SBjoern A. Zeeb 	if (WARN_ON(path >= 2))
6772774f206SBjoern A. Zeeb 		return;
6782774f206SBjoern A. Zeeb 
6792774f206SBjoern A. Zeeb 	/* backup I vector */
6802774f206SBjoern A. Zeeb 	w_addr = rtw8822c_get_path_write_addr(path) + 0xb0;
6812774f206SBjoern A. Zeeb 	r_addr = rtw8822c_get_path_read_addr(path) + 0x10;
6822774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr);
6832774f206SBjoern A. Zeeb 
6842774f206SBjoern A. Zeeb 	/* backup Q vector */
6852774f206SBjoern A. Zeeb 	w_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off;
6862774f206SBjoern A. Zeeb 	r_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off;
6872774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr);
6882774f206SBjoern A. Zeeb }
6892774f206SBjoern A. Zeeb 
6902774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev)
6912774f206SBjoern A. Zeeb {
6922774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
6932774f206SBjoern A. Zeeb 	u8 val;
6942774f206SBjoern A. Zeeb 
6952774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000);
6962774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_A][0][0] = val;
6972774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_1, 0xf);
6982774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_A][0][1] = val;
6992774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000);
7002774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_A][1][0] = val;
7012774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_1, 0xf);
7022774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_A][1][1] = val;
7032774f206SBjoern A. Zeeb 
7042774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000);
7052774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_B][0][0] = val;
7062774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_1, 0xf);
7072774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_B][1][0] = val;
7082774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000);
7092774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_B][0][1] = val;
7102774f206SBjoern A. Zeeb 	val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_1, 0xf);
7112774f206SBjoern A. Zeeb 	dm_info->dack_dck[RF_PATH_B][1][1] = val;
7122774f206SBjoern A. Zeeb }
7132774f206SBjoern A. Zeeb 
7142774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev)
7152774f206SBjoern A. Zeeb {
7162774f206SBjoern A. Zeeb 	u32 temp[3];
7172774f206SBjoern A. Zeeb 
7182774f206SBjoern A. Zeeb 	temp[0] = rtw_read32(rtwdev, 0x1860);
7192774f206SBjoern A. Zeeb 	temp[1] = rtw_read32(rtwdev, 0x4160);
7202774f206SBjoern A. Zeeb 	temp[2] = rtw_read32(rtwdev, 0x9b4);
7212774f206SBjoern A. Zeeb 
7222774f206SBjoern A. Zeeb 	/* set clock */
7232774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb66db00);
7242774f206SBjoern A. Zeeb 
7252774f206SBjoern A. Zeeb 	/* backup path-A I/Q */
7262774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, 0x1830, BIT(30));
7272774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c);
7282774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A);
7292774f206SBjoern A. Zeeb 
7302774f206SBjoern A. Zeeb 	/* backup path-B I/Q */
7312774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, 0x4130, BIT(30));
7322774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c);
7332774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B);
7342774f206SBjoern A. Zeeb 
7352774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup_dck(rtwdev);
7362774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, 0x1830, BIT(30));
7372774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, 0x4130, BIT(30));
7382774f206SBjoern A. Zeeb 
7392774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1860, temp[0]);
7402774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x4160, temp[1]);
7412774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, temp[2]);
7422774f206SBjoern A. Zeeb }
7432774f206SBjoern A. Zeeb 
7442774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev)
7452774f206SBjoern A. Zeeb {
7462774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
7472774f206SBjoern A. Zeeb 	u8 val;
7482774f206SBjoern A. Zeeb 
7492774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_DCKA_I_0, BIT(19));
7502774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_A][0][0];
7512774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000, val);
7522774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_A][0][1];
7532774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKA_I_1, 0xf, val);
7542774f206SBjoern A. Zeeb 
7552774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_DCKA_Q_0, BIT(19));
7562774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_A][1][0];
7572774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000, val);
7582774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_A][1][1];
7592774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKA_Q_1, 0xf, val);
7602774f206SBjoern A. Zeeb 
7612774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_DCKB_I_0, BIT(19));
7622774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_B][0][0];
7632774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000, val);
7642774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_B][0][1];
7652774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKB_I_1, 0xf, val);
7662774f206SBjoern A. Zeeb 
7672774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_DCKB_Q_0, BIT(19));
7682774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_B][1][0];
7692774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000, val);
7702774f206SBjoern A. Zeeb 	val = dm_info->dack_dck[RF_PATH_B][1][1];
7712774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DCKB_Q_1, 0xf, val);
7722774f206SBjoern A. Zeeb }
7732774f206SBjoern A. Zeeb 
7742774f206SBjoern A. Zeeb static void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev)
7752774f206SBjoern A. Zeeb {
7762774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, 0xdb66db00);
7772774f206SBjoern A. Zeeb 
7782774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x0);
7792774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x0);
7802774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x0);
7812774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x0);
7822774f206SBjoern A. Zeeb 
7832774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x0);
7842774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c);
7852774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b4, BIT(0), 0x1);
7862774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18d0, BIT(0), 0x1);
7872774f206SBjoern A. Zeeb 
7882774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x0);
7892774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c);
7902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b4, BIT(0), 0x1);
7912774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41d0, BIT(0), 0x1);
7922774f206SBjoern A. Zeeb 
7932774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b0, 0xf00, 0x0);
7942774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18c0, BIT(14), 0x0);
7952774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18cc, 0xf00, 0x0);
7962774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18dc, BIT(14), 0x0);
7972774f206SBjoern A. Zeeb 
7982774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x0);
7992774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x0);
8002774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x1);
8012774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x1);
8022774f206SBjoern A. Zeeb 
8032774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_restore_dck(rtwdev);
8042774f206SBjoern A. Zeeb 
8052774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18c0, 0x38000, 0x7);
8062774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18dc, 0x38000, 0x7);
8072774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41c0, 0x38000, 0x7);
8082774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41dc, 0x38000, 0x7);
8092774f206SBjoern A. Zeeb 
8102774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b8, BIT(26) | BIT(25), 0x1);
8112774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18d4, BIT(26) | BIT(25), 0x1);
8122774f206SBjoern A. Zeeb 
8132774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b0, 0xf00, 0x0);
8142774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41c0, BIT(14), 0x0);
8152774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41cc, 0xf00, 0x0);
8162774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41dc, BIT(14), 0x0);
8172774f206SBjoern A. Zeeb 
8182774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x0);
8192774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x0);
8202774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x1);
8212774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x1);
8222774f206SBjoern A. Zeeb 
8232774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b8, BIT(26) | BIT(25), 0x1);
8242774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41d4, BIT(26) | BIT(25), 0x1);
8252774f206SBjoern A. Zeeb }
8262774f206SBjoern A. Zeeb 
8272774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev,
8282774f206SBjoern A. Zeeb 					  u32 target_addr, u32 toggle_addr)
8292774f206SBjoern A. Zeeb {
8302774f206SBjoern A. Zeeb 	u32 cnt = 0;
8312774f206SBjoern A. Zeeb 
8322774f206SBjoern A. Zeeb 	do {
8332774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x0);
8342774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x2);
8352774f206SBjoern A. Zeeb 
8362774f206SBjoern A. Zeeb 		if (rtw_read32_mask(rtwdev, target_addr, 0xf) == 0x6)
8372774f206SBjoern A. Zeeb 			return true;
8382774f206SBjoern A. Zeeb 
8392774f206SBjoern A. Zeeb 	} while (cnt++ < 100);
8402774f206SBjoern A. Zeeb 
8412774f206SBjoern A. Zeeb 	return false;
8422774f206SBjoern A. Zeeb }
8432774f206SBjoern A. Zeeb 
8442774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path)
8452774f206SBjoern A. Zeeb {
8462774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
8472774f206SBjoern A. Zeeb 	u32 w_off = 0x1c;
8482774f206SBjoern A. Zeeb 	u32 r_off = 0x2c;
8492774f206SBjoern A. Zeeb 	u32 w_i, r_i, w_q, r_q;
8502774f206SBjoern A. Zeeb 	u32 value;
8512774f206SBjoern A. Zeeb 	u32 i;
8522774f206SBjoern A. Zeeb 
8532774f206SBjoern A. Zeeb 	w_i = rtw8822c_get_path_write_addr(path) + 0xb0;
8542774f206SBjoern A. Zeeb 	r_i = rtw8822c_get_path_read_addr(path) + 0x08;
8552774f206SBjoern A. Zeeb 	w_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off;
8562774f206SBjoern A. Zeeb 	r_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off;
8572774f206SBjoern A. Zeeb 
8582774f206SBjoern A. Zeeb 	if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8))
8592774f206SBjoern A. Zeeb 		return false;
8602774f206SBjoern A. Zeeb 
8612774f206SBjoern A. Zeeb 	for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) {
8622774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0);
8632774f206SBjoern A. Zeeb 		value = dm_info->dack_msbk[path][0][i];
8642774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_i + 0x4, 0xff8, value);
8652774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_i, 0xf0000000, i);
8662774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x1);
8672774f206SBjoern A. Zeeb 	}
8682774f206SBjoern A. Zeeb 
8692774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0);
8702774f206SBjoern A. Zeeb 
8712774f206SBjoern A. Zeeb 	if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8))
8722774f206SBjoern A. Zeeb 		return false;
8732774f206SBjoern A. Zeeb 
8742774f206SBjoern A. Zeeb 	for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) {
8752774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0);
8762774f206SBjoern A. Zeeb 		value = dm_info->dack_msbk[path][1][i];
8772774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_q + 0x4, 0xff8, value);
8782774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_q, 0xf0000000, i);
8792774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x1);
8802774f206SBjoern A. Zeeb 	}
8812774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0);
8822774f206SBjoern A. Zeeb 
8832774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_i + 0x8, BIT(26) | BIT(25), 0x0);
8842774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_q + 0x8, BIT(26) | BIT(25), 0x0);
8852774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_i + 0x4, BIT(0), 0x0);
8862774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, w_q + 0x4, BIT(0), 0x0);
8872774f206SBjoern A. Zeeb 
8882774f206SBjoern A. Zeeb 	return true;
8892774f206SBjoern A. Zeeb }
8902774f206SBjoern A. Zeeb 
8912774f206SBjoern A. Zeeb static bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev)
8922774f206SBjoern A. Zeeb {
8932774f206SBjoern A. Zeeb 	if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A))
8942774f206SBjoern A. Zeeb 		return false;
8952774f206SBjoern A. Zeeb 
8962774f206SBjoern A. Zeeb 	if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B))
8972774f206SBjoern A. Zeeb 		return false;
8982774f206SBjoern A. Zeeb 
8992774f206SBjoern A. Zeeb 	return true;
9002774f206SBjoern A. Zeeb }
9012774f206SBjoern A. Zeeb 
9022774f206SBjoern A. Zeeb static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev)
9032774f206SBjoern A. Zeeb {
9042774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
9052774f206SBjoern A. Zeeb 	u32 temp[3];
9062774f206SBjoern A. Zeeb 
9072774f206SBjoern A. Zeeb 	/* sample the first element for both path's IQ vector */
9082774f206SBjoern A. Zeeb 	if (dm_info->dack_msbk[RF_PATH_A][0][0] == 0 &&
9092774f206SBjoern A. Zeeb 	    dm_info->dack_msbk[RF_PATH_A][1][0] == 0 &&
9102774f206SBjoern A. Zeeb 	    dm_info->dack_msbk[RF_PATH_B][0][0] == 0 &&
9112774f206SBjoern A. Zeeb 	    dm_info->dack_msbk[RF_PATH_B][1][0] == 0)
9122774f206SBjoern A. Zeeb 		return false;
9132774f206SBjoern A. Zeeb 
9142774f206SBjoern A. Zeeb 	temp[0] = rtw_read32(rtwdev, 0x1860);
9152774f206SBjoern A. Zeeb 	temp[1] = rtw_read32(rtwdev, 0x4160);
9162774f206SBjoern A. Zeeb 	temp[2] = rtw_read32(rtwdev, 0x9b4);
9172774f206SBjoern A. Zeeb 
9182774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_restore_prepare(rtwdev);
9192774f206SBjoern A. Zeeb 	if (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) ||
9202774f206SBjoern A. Zeeb 	    !check_hw_ready(rtwdev, 0x2834, 0x7fff80, 0xffff) ||
9212774f206SBjoern A. Zeeb 	    !check_hw_ready(rtwdev, 0x4508, 0x7fff80, 0xffff) ||
9222774f206SBjoern A. Zeeb 	    !check_hw_ready(rtwdev, 0x4534, 0x7fff80, 0xffff))
9232774f206SBjoern A. Zeeb 		return false;
9242774f206SBjoern A. Zeeb 
9252774f206SBjoern A. Zeeb 	if (!__rtw8822c_dac_cal_restore(rtwdev)) {
9262774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "failed to restore dack vectors\n");
9272774f206SBjoern A. Zeeb 		return false;
9282774f206SBjoern A. Zeeb 	}
9292774f206SBjoern A. Zeeb 
9302774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x1);
9312774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1);
9322774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1860, temp[0]);
9332774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x4160, temp[1]);
9342774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x1);
9352774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x1);
9362774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x1);
9372774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x1);
9382774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x9b4, temp[2]);
9392774f206SBjoern A. Zeeb 
9402774f206SBjoern A. Zeeb 	return true;
9412774f206SBjoern A. Zeeb }
9422774f206SBjoern A. Zeeb 
9432774f206SBjoern A. Zeeb static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev)
9442774f206SBjoern A. Zeeb {
9452774f206SBjoern A. Zeeb 	struct rtw_backup_info backup_rf[DACK_RF_8822C * DACK_PATH_8822C];
9462774f206SBjoern A. Zeeb 	struct rtw_backup_info backup[DACK_REG_8822C];
9472774f206SBjoern A. Zeeb 	u32 ic = 0, qc = 0, i;
9482774f206SBjoern A. Zeeb 	u32 i_a = 0x0, q_a = 0x0, i_b = 0x0, q_b = 0x0;
9492774f206SBjoern A. Zeeb 	u32 ic_a = 0x0, qc_a = 0x0, ic_b = 0x0, qc_b = 0x0;
9502774f206SBjoern A. Zeeb 	u32 adc_ic_a = 0x0, adc_qc_a = 0x0, adc_ic_b = 0x0, adc_qc_b = 0x0;
9512774f206SBjoern A. Zeeb 
9522774f206SBjoern A. Zeeb 	if (rtw8822c_dac_cal_restore(rtwdev))
9532774f206SBjoern A. Zeeb 		return;
9542774f206SBjoern A. Zeeb 
9552774f206SBjoern A. Zeeb 	/* not able to restore, do it */
9562774f206SBjoern A. Zeeb 
9572774f206SBjoern A. Zeeb 	rtw8822c_dac_backup_reg(rtwdev, backup, backup_rf);
9582774f206SBjoern A. Zeeb 
9592774f206SBjoern A. Zeeb 	rtw8822c_dac_bb_setting(rtwdev);
9602774f206SBjoern A. Zeeb 
9612774f206SBjoern A. Zeeb 	/* path-A */
9622774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_adc(rtwdev, RF_PATH_A, &adc_ic_a, &adc_qc_a);
9632774f206SBjoern A. Zeeb 	for (i = 0; i < 10; i++) {
9642774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step1(rtwdev, RF_PATH_A);
9652774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step2(rtwdev, RF_PATH_A, &ic, &qc);
9662774f206SBjoern A. Zeeb 		ic_a = ic;
9672774f206SBjoern A. Zeeb 		qc_a = qc;
9682774f206SBjoern A. Zeeb 
9692774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step3(rtwdev, RF_PATH_A, adc_ic_a, adc_qc_a,
9702774f206SBjoern A. Zeeb 				       &ic, &qc, &i_a, &q_a);
9712774f206SBjoern A. Zeeb 
9722774f206SBjoern A. Zeeb 		if (ic < 5 && qc < 5)
9732774f206SBjoern A. Zeeb 			break;
9742774f206SBjoern A. Zeeb 	}
9752774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_step4(rtwdev, RF_PATH_A);
9762774f206SBjoern A. Zeeb 
9772774f206SBjoern A. Zeeb 	/* path-B */
9782774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_adc(rtwdev, RF_PATH_B, &adc_ic_b, &adc_qc_b);
9792774f206SBjoern A. Zeeb 	for (i = 0; i < 10; i++) {
9802774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step1(rtwdev, RF_PATH_B);
9812774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step2(rtwdev, RF_PATH_B, &ic, &qc);
9822774f206SBjoern A. Zeeb 		ic_b = ic;
9832774f206SBjoern A. Zeeb 		qc_b = qc;
9842774f206SBjoern A. Zeeb 
9852774f206SBjoern A. Zeeb 		rtw8822c_dac_cal_step3(rtwdev, RF_PATH_B, adc_ic_b, adc_qc_b,
9862774f206SBjoern A. Zeeb 				       &ic, &qc, &i_b, &q_b);
9872774f206SBjoern A. Zeeb 
9882774f206SBjoern A. Zeeb 		if (ic < 5 && qc < 5)
9892774f206SBjoern A. Zeeb 			break;
9902774f206SBjoern A. Zeeb 	}
9912774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_step4(rtwdev, RF_PATH_B);
9922774f206SBjoern A. Zeeb 
9932774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b00, 0x00000008);
9942774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1);
9952774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1bcc, 0x0);
9962774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b00, 0x0000000a);
9972774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1bcc, 0x0);
9982774f206SBjoern A. Zeeb 
9992774f206SBjoern A. Zeeb 	rtw8822c_dac_restore_reg(rtwdev, backup, backup_rf);
10002774f206SBjoern A. Zeeb 
10012774f206SBjoern A. Zeeb 	/* backup results to restore, saving a lot of time */
10022774f206SBjoern A. Zeeb 	rtw8822c_dac_cal_backup(rtwdev);
10032774f206SBjoern A. Zeeb 
10042774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: ic=0x%x, qc=0x%x\n", ic_a, qc_a);
10052774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: ic=0x%x, qc=0x%x\n", ic_b, qc_b);
10062774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: i=0x%x, q=0x%x\n", i_a, q_a);
10072774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: i=0x%x, q=0x%x\n", i_b, q_b);
10082774f206SBjoern A. Zeeb }
10092774f206SBjoern A. Zeeb 
10102774f206SBjoern A. Zeeb static void rtw8822c_rf_x2_check(struct rtw_dev *rtwdev)
10112774f206SBjoern A. Zeeb {
10122774f206SBjoern A. Zeeb 	u8 x2k_busy;
10132774f206SBjoern A. Zeeb 
10142774f206SBjoern A. Zeeb 	mdelay(1);
10152774f206SBjoern A. Zeeb 	x2k_busy = rtw_read_rf(rtwdev, RF_PATH_A, 0xb8, BIT(15));
10162774f206SBjoern A. Zeeb 	if (x2k_busy == 1) {
10172774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0xC4440);
10182774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, 0xba, RFREG_MASK, 0x6840D);
10192774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0x80440);
10202774f206SBjoern A. Zeeb 		mdelay(1);
10212774f206SBjoern A. Zeeb 	}
10222774f206SBjoern A. Zeeb }
10232774f206SBjoern A. Zeeb 
10242774f206SBjoern A. Zeeb static void rtw8822c_set_power_trim(struct rtw_dev *rtwdev, s8 bb_gain[2][8])
10252774f206SBjoern A. Zeeb {
10262774f206SBjoern A. Zeeb #define RF_SET_POWER_TRIM(_path, _seq, _idx)					\
10272774f206SBjoern A. Zeeb 		do {								\
10282774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, _path, 0x33, RFREG_MASK, _seq);	\
10292774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, _path, 0x3f, RFREG_MASK,		\
10302774f206SBjoern A. Zeeb 				     bb_gain[_path][_idx]);			\
10312774f206SBjoern A. Zeeb 		} while (0)
10322774f206SBjoern A. Zeeb 	u8 path;
10332774f206SBjoern A. Zeeb 
10342774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
10352774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, 0xee, BIT(19), 1);
10362774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x0, 0);
10372774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x1, 1);
10382774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x2, 2);
10392774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x3, 2);
10402774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x4, 3);
10412774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x5, 4);
10422774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x6, 5);
10432774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x7, 6);
10442774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x8, 7);
10452774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0x9, 3);
10462774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0xa, 4);
10472774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0xb, 5);
10482774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0xc, 6);
10492774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0xd, 7);
10502774f206SBjoern A. Zeeb 		RF_SET_POWER_TRIM(path, 0xe, 7);
10512774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, 0xee, BIT(19), 0);
10522774f206SBjoern A. Zeeb 	}
10532774f206SBjoern A. Zeeb #undef RF_SET_POWER_TRIM
10542774f206SBjoern A. Zeeb }
10552774f206SBjoern A. Zeeb 
10562774f206SBjoern A. Zeeb static void rtw8822c_power_trim(struct rtw_dev *rtwdev)
10572774f206SBjoern A. Zeeb {
10582774f206SBjoern A. Zeeb 	u8 pg_pwr = 0xff, i, path, idx;
10592774f206SBjoern A. Zeeb 	s8 bb_gain[2][8] = {};
10602774f206SBjoern A. Zeeb 	u16 rf_efuse_2g[3] = {PPG_2GL_TXAB, PPG_2GM_TXAB, PPG_2GH_TXAB};
10612774f206SBjoern A. Zeeb 	u16 rf_efuse_5g[2][5] = {{PPG_5GL1_TXA, PPG_5GL2_TXA, PPG_5GM1_TXA,
10622774f206SBjoern A. Zeeb 				  PPG_5GM2_TXA, PPG_5GH1_TXA},
10632774f206SBjoern A. Zeeb 				 {PPG_5GL1_TXB, PPG_5GL2_TXB, PPG_5GM1_TXB,
10642774f206SBjoern A. Zeeb 				  PPG_5GM2_TXB, PPG_5GH1_TXB} };
10652774f206SBjoern A. Zeeb 	bool set = false;
10662774f206SBjoern A. Zeeb 
10672774f206SBjoern A. Zeeb 	for (i = 0; i < ARRAY_SIZE(rf_efuse_2g); i++) {
10682774f206SBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[i], &pg_pwr);
10692774f206SBjoern A. Zeeb 		if (pg_pwr == EFUSE_READ_FAIL)
10702774f206SBjoern A. Zeeb 			continue;
10712774f206SBjoern A. Zeeb 		set = true;
10722774f206SBjoern A. Zeeb 		bb_gain[RF_PATH_A][i] = FIELD_GET(PPG_2G_A_MASK, pg_pwr);
10732774f206SBjoern A. Zeeb 		bb_gain[RF_PATH_B][i] = FIELD_GET(PPG_2G_B_MASK, pg_pwr);
10742774f206SBjoern A. Zeeb 	}
10752774f206SBjoern A. Zeeb 
10762774f206SBjoern A. Zeeb 	for (i = 0; i < ARRAY_SIZE(rf_efuse_5g[0]); i++) {
10772774f206SBjoern A. Zeeb 		for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
10782774f206SBjoern A. Zeeb 			rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path][i],
10792774f206SBjoern A. Zeeb 						 &pg_pwr);
10802774f206SBjoern A. Zeeb 			if (pg_pwr == EFUSE_READ_FAIL)
10812774f206SBjoern A. Zeeb 				continue;
10822774f206SBjoern A. Zeeb 			set = true;
10832774f206SBjoern A. Zeeb 			idx = i + ARRAY_SIZE(rf_efuse_2g);
10842774f206SBjoern A. Zeeb 			bb_gain[path][idx] = FIELD_GET(PPG_5G_MASK, pg_pwr);
10852774f206SBjoern A. Zeeb 		}
10862774f206SBjoern A. Zeeb 	}
10872774f206SBjoern A. Zeeb 	if (set)
10882774f206SBjoern A. Zeeb 		rtw8822c_set_power_trim(rtwdev, bb_gain);
10892774f206SBjoern A. Zeeb 
10902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL);
10912774f206SBjoern A. Zeeb }
10922774f206SBjoern A. Zeeb 
10932774f206SBjoern A. Zeeb static void rtw8822c_thermal_trim(struct rtw_dev *rtwdev)
10942774f206SBjoern A. Zeeb {
10952774f206SBjoern A. Zeeb 	u16 rf_efuse[2] = {PPG_THERMAL_A, PPG_THERMAL_B};
10962774f206SBjoern A. Zeeb 	u8 pg_therm = 0xff, thermal[2] = {0}, path;
10972774f206SBjoern A. Zeeb 
10982774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
10992774f206SBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, rf_efuse[path], &pg_therm);
11002774f206SBjoern A. Zeeb 		if (pg_therm == EFUSE_READ_FAIL)
11012774f206SBjoern A. Zeeb 			return;
11022774f206SBjoern A. Zeeb 		/* Efuse value of BIT(0) shall be move to BIT(3), and the value
11032774f206SBjoern A. Zeeb 		 * of BIT(1) to BIT(3) should be right shifted 1 bit.
11042774f206SBjoern A. Zeeb 		 */
11052774f206SBjoern A. Zeeb 		thermal[path] = FIELD_GET(GENMASK(3, 1), pg_therm);
11062774f206SBjoern A. Zeeb 		thermal[path] |= FIELD_PREP(BIT(3), pg_therm & BIT(0));
11072774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, 0x43, RF_THEMAL_MASK, thermal[path]);
11082774f206SBjoern A. Zeeb 	}
11092774f206SBjoern A. Zeeb }
11102774f206SBjoern A. Zeeb 
11112774f206SBjoern A. Zeeb static void rtw8822c_pa_bias(struct rtw_dev *rtwdev)
11122774f206SBjoern A. Zeeb {
11132774f206SBjoern A. Zeeb 	u16 rf_efuse_2g[2] = {PPG_PABIAS_2GA, PPG_PABIAS_2GB};
11142774f206SBjoern A. Zeeb 	u16 rf_efuse_5g[2] = {PPG_PABIAS_5GA, PPG_PABIAS_5GB};
11152774f206SBjoern A. Zeeb 	u8 pg_pa_bias = 0xff, path;
11162774f206SBjoern A. Zeeb 
11172774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
11182774f206SBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[path],
11192774f206SBjoern A. Zeeb 					 &pg_pa_bias);
11202774f206SBjoern A. Zeeb 		if (pg_pa_bias == EFUSE_READ_FAIL)
11212774f206SBjoern A. Zeeb 			return;
11222774f206SBjoern A. Zeeb 		pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias);
11232774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_2G_MASK, pg_pa_bias);
11242774f206SBjoern A. Zeeb 	}
11252774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
11262774f206SBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path],
11272774f206SBjoern A. Zeeb 					 &pg_pa_bias);
11282774f206SBjoern A. Zeeb 		pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias);
11292774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_5G_MASK, pg_pa_bias);
11302774f206SBjoern A. Zeeb 	}
11312774f206SBjoern A. Zeeb }
11322774f206SBjoern A. Zeeb 
11332774f206SBjoern A. Zeeb static void rtw8822c_rfk_handshake(struct rtw_dev *rtwdev, bool is_before_k)
11342774f206SBjoern A. Zeeb {
11352774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm = &rtwdev->dm_info;
11362774f206SBjoern A. Zeeb 	u8 u1b_tmp;
11372774f206SBjoern A. Zeeb 	u8 u4b_tmp;
11382774f206SBjoern A. Zeeb 	int ret;
11392774f206SBjoern A. Zeeb 
11402774f206SBjoern A. Zeeb 	if (is_before_k) {
11412774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
11422774f206SBjoern A. Zeeb 			"[RFK] WiFi / BT RFK handshake start!!\n");
11432774f206SBjoern A. Zeeb 
11442774f206SBjoern A. Zeeb 		if (!dm->is_bt_iqk_timeout) {
11452774f206SBjoern A. Zeeb 			ret = read_poll_timeout(rtw_read32_mask, u4b_tmp,
11462774f206SBjoern A. Zeeb 						u4b_tmp == 0, 20, 600000, false,
11472774f206SBjoern A. Zeeb 						rtwdev, REG_PMC_DBG_CTRL1,
11482774f206SBjoern A. Zeeb 						BITS_PMC_BT_IQK_STS);
11492774f206SBjoern A. Zeeb 			if (ret) {
11502774f206SBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
11512774f206SBjoern A. Zeeb 					"[RFK] Wait BT IQK finish timeout!!\n");
11522774f206SBjoern A. Zeeb 				dm->is_bt_iqk_timeout = true;
11532774f206SBjoern A. Zeeb 			}
11542774f206SBjoern A. Zeeb 		}
11552774f206SBjoern A. Zeeb 
11562774f206SBjoern A. Zeeb 		rtw_fw_inform_rfk_status(rtwdev, true);
11572774f206SBjoern A. Zeeb 
11582774f206SBjoern A. Zeeb 		ret = read_poll_timeout(rtw_read8_mask, u1b_tmp,
11592774f206SBjoern A. Zeeb 					u1b_tmp == 1, 20, 100000, false,
11602774f206SBjoern A. Zeeb 					rtwdev, REG_ARFR4, BIT_WL_RFK);
11612774f206SBjoern A. Zeeb 		if (ret)
11622774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
11632774f206SBjoern A. Zeeb 				"[RFK] Send WiFi RFK start H2C cmd FAIL!!\n");
11642774f206SBjoern A. Zeeb 	} else {
11652774f206SBjoern A. Zeeb 		rtw_fw_inform_rfk_status(rtwdev, false);
11662774f206SBjoern A. Zeeb 		ret = read_poll_timeout(rtw_read8_mask, u1b_tmp,
11672774f206SBjoern A. Zeeb 					u1b_tmp == 1, 20, 100000, false,
11682774f206SBjoern A. Zeeb 					rtwdev, REG_ARFR4,
11692774f206SBjoern A. Zeeb 					BIT_WL_RFK);
11702774f206SBjoern A. Zeeb 		if (ret)
11712774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
11722774f206SBjoern A. Zeeb 				"[RFK] Send WiFi RFK finish H2C cmd FAIL!!\n");
11732774f206SBjoern A. Zeeb 
11742774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
11752774f206SBjoern A. Zeeb 			"[RFK] WiFi / BT RFK handshake finish!!\n");
11762774f206SBjoern A. Zeeb 	}
11772774f206SBjoern A. Zeeb }
11782774f206SBjoern A. Zeeb 
11792774f206SBjoern A. Zeeb static void rtw8822c_rfk_power_save(struct rtw_dev *rtwdev,
11802774f206SBjoern A. Zeeb 				    bool is_power_save)
11812774f206SBjoern A. Zeeb {
11822774f206SBjoern A. Zeeb 	u8 path;
11832774f206SBjoern A. Zeeb 
11842774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
11852774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
11862774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_PS_EN,
11872774f206SBjoern A. Zeeb 				 is_power_save ? 0 : 1);
11882774f206SBjoern A. Zeeb 	}
11892774f206SBjoern A. Zeeb }
11902774f206SBjoern A. Zeeb 
11912774f206SBjoern A. Zeeb static void rtw8822c_txgapk_backup_bb_reg(struct rtw_dev *rtwdev, const u32 reg[],
11922774f206SBjoern A. Zeeb 					  u32 reg_backup[], u32 reg_num)
11932774f206SBjoern A. Zeeb {
11942774f206SBjoern A. Zeeb 	u32 i;
11952774f206SBjoern A. Zeeb 
11962774f206SBjoern A. Zeeb 	for (i = 0; i < reg_num; i++) {
11972774f206SBjoern A. Zeeb 		reg_backup[i] = rtw_read32(rtwdev, reg[i]);
11982774f206SBjoern A. Zeeb 
11992774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Backup BB 0x%x = 0x%x\n",
12002774f206SBjoern A. Zeeb 			reg[i], reg_backup[i]);
12012774f206SBjoern A. Zeeb 	}
12022774f206SBjoern A. Zeeb }
12032774f206SBjoern A. Zeeb 
12042774f206SBjoern A. Zeeb static void rtw8822c_txgapk_reload_bb_reg(struct rtw_dev *rtwdev,
12052774f206SBjoern A. Zeeb 					  const u32 reg[], u32 reg_backup[],
12062774f206SBjoern A. Zeeb 					  u32 reg_num)
12072774f206SBjoern A. Zeeb {
12082774f206SBjoern A. Zeeb 	u32 i;
12092774f206SBjoern A. Zeeb 
12102774f206SBjoern A. Zeeb 	for (i = 0; i < reg_num; i++) {
12112774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, reg[i], reg_backup[i]);
12122774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Reload BB 0x%x = 0x%x\n",
12132774f206SBjoern A. Zeeb 			reg[i], reg_backup[i]);
12142774f206SBjoern A. Zeeb 	}
12152774f206SBjoern A. Zeeb }
12162774f206SBjoern A. Zeeb 
12172774f206SBjoern A. Zeeb static bool check_rf_status(struct rtw_dev *rtwdev, u8 status)
12182774f206SBjoern A. Zeeb {
12192774f206SBjoern A. Zeeb 	u8 reg_rf0_a, reg_rf0_b;
12202774f206SBjoern A. Zeeb 
12212774f206SBjoern A. Zeeb 	reg_rf0_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A,
12222774f206SBjoern A. Zeeb 				    RF_MODE_TRXAGC, BIT_RF_MODE);
12232774f206SBjoern A. Zeeb 	reg_rf0_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B,
12242774f206SBjoern A. Zeeb 				    RF_MODE_TRXAGC, BIT_RF_MODE);
12252774f206SBjoern A. Zeeb 
12262774f206SBjoern A. Zeeb 	if (reg_rf0_a == status || reg_rf0_b == status)
12272774f206SBjoern A. Zeeb 		return false;
12282774f206SBjoern A. Zeeb 
12292774f206SBjoern A. Zeeb 	return true;
12302774f206SBjoern A. Zeeb }
12312774f206SBjoern A. Zeeb 
12322774f206SBjoern A. Zeeb static void rtw8822c_txgapk_tx_pause(struct rtw_dev *rtwdev)
12332774f206SBjoern A. Zeeb {
12342774f206SBjoern A. Zeeb 	bool status;
12352774f206SBjoern A. Zeeb 	int ret;
12362774f206SBjoern A. Zeeb 
12372774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_TXPAUSE, BIT_AC_QUEUE);
12382774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TX_FIFO, BIT_STOP_TX, 0x2);
12392774f206SBjoern A. Zeeb 
12402774f206SBjoern A. Zeeb 	ret = read_poll_timeout_atomic(check_rf_status, status, status,
12412774f206SBjoern A. Zeeb 				       2, 5000, false, rtwdev, 2);
12422774f206SBjoern A. Zeeb 	if (ret)
12432774f206SBjoern A. Zeeb 		rtw_warn(rtwdev, "failed to pause TX\n");
12442774f206SBjoern A. Zeeb 
12452774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Tx pause!!\n");
12462774f206SBjoern A. Zeeb }
12472774f206SBjoern A. Zeeb 
12482774f206SBjoern A. Zeeb static void rtw8822c_txgapk_bb_dpk(struct rtw_dev *rtwdev, u8 path)
12492774f206SBjoern A. Zeeb {
12502774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
12512774f206SBjoern A. Zeeb 
12522774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_ENFN, BIT_IQK_DPK_EN, 0x1);
12532774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2,
12542774f206SBjoern A. Zeeb 			 BIT_IQK_DPK_CLOCK_SRC, 0x1);
12552774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2,
12562774f206SBjoern A. Zeeb 			 BIT_IQK_DPK_RESET_SRC, 0x1);
12572774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_EN_IOQ_IQK_DPK, 0x1);
12582774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_TST_IQK2SET_SRC, 0x0);
12592774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x1ff);
12602774f206SBjoern A. Zeeb 
12612774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
12622774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A,
12632774f206SBjoern A. Zeeb 				 BIT_RFTXEN_GCK_FORCE_ON, 0x1);
12642774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x1);
12652774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A,
12662774f206SBjoern A. Zeeb 				 BIT_TX_SCALE_0DB, 0x1);
12672774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x0);
12682774f206SBjoern A. Zeeb 	} else if (path == RF_PATH_B) {
12692774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B,
12702774f206SBjoern A. Zeeb 				 BIT_RFTXEN_GCK_FORCE_ON, 0x1);
12712774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE2,
12722774f206SBjoern A. Zeeb 				 BIT_DIS_SHARERX_TXGAT, 0x1);
12732774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B,
12742774f206SBjoern A. Zeeb 				 BIT_TX_SCALE_0DB, 0x1);
12752774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x0);
12762774f206SBjoern A. Zeeb 	}
12772774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x2);
12782774f206SBjoern A. Zeeb }
12792774f206SBjoern A. Zeeb 
12802774f206SBjoern A. Zeeb static void rtw8822c_txgapk_afe_dpk(struct rtw_dev *rtwdev, u8 path)
12812774f206SBjoern A. Zeeb {
12822774f206SBjoern A. Zeeb 	u32 reg;
12832774f206SBjoern A. Zeeb 
12842774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
12852774f206SBjoern A. Zeeb 
12862774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
12872774f206SBjoern A. Zeeb 		reg = REG_ANAPAR_A;
12882774f206SBjoern A. Zeeb 	} else if (path == RF_PATH_B) {
12892774f206SBjoern A. Zeeb 		reg = REG_ANAPAR_B;
12902774f206SBjoern A. Zeeb 	} else {
12912774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path);
12922774f206SBjoern A. Zeeb 		return;
12932774f206SBjoern A. Zeeb 	}
12942774f206SBjoern A. Zeeb 
12952774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, MASKDWORD);
12962774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001);
12972774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001);
12982774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x701f0001);
12992774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x702f0001);
13002774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x703f0001);
13012774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x704f0001);
13022774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705f0001);
13032774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x706f0001);
13042774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707f0001);
13052774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708f0001);
13062774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709f0001);
13072774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70af0001);
13082774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bf0001);
13092774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cf0001);
13102774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70df0001);
13112774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ef0001);
13122774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001);
13132774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001);
13142774f206SBjoern A. Zeeb }
13152774f206SBjoern A. Zeeb 
13162774f206SBjoern A. Zeeb static void rtw8822c_txgapk_afe_dpk_restore(struct rtw_dev *rtwdev, u8 path)
13172774f206SBjoern A. Zeeb {
13182774f206SBjoern A. Zeeb 	u32 reg;
13192774f206SBjoern A. Zeeb 
13202774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
13212774f206SBjoern A. Zeeb 
13222774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
13232774f206SBjoern A. Zeeb 		reg = REG_ANAPAR_A;
13242774f206SBjoern A. Zeeb 	} else if (path == RF_PATH_B) {
13252774f206SBjoern A. Zeeb 		reg = REG_ANAPAR_B;
13262774f206SBjoern A. Zeeb 	} else {
13272774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path);
13282774f206SBjoern A. Zeeb 		return;
13292774f206SBjoern A. Zeeb 	}
13302774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, 0xffa1005e);
13312774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700b8041);
13322774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70144041);
13332774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70244041);
13342774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70344041);
13352774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70444041);
13362774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705b8041);
13372774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70644041);
13382774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707b8041);
13392774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708b8041);
13402774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709b8041);
13412774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ab8041);
13422774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bb8041);
13432774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cb8041);
13442774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70db8041);
13452774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70eb8041);
13462774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70fb8041);
13472774f206SBjoern A. Zeeb }
13482774f206SBjoern A. Zeeb 
13492774f206SBjoern A. Zeeb static void rtw8822c_txgapk_bb_dpk_restore(struct rtw_dev *rtwdev, u8 path)
13502774f206SBjoern A. Zeeb {
13512774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
13522774f206SBjoern A. Zeeb 
13532774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x0);
13542774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TIA_BYPASS, 0x0);
13552774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TXBB, 0x0);
13562774f206SBjoern A. Zeeb 
13572774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0);
13582774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
13592774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0);
13602774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00);
13612774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x1);
13622774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
13632774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0);
13642774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00);
13652774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0);
13662774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x0);
13672774f206SBjoern A. Zeeb 
13682774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
13692774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A,
13702774f206SBjoern A. Zeeb 				 BIT_RFTXEN_GCK_FORCE_ON, 0x0);
13712774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x0);
13722774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A,
13732774f206SBjoern A. Zeeb 				 BIT_TX_SCALE_0DB, 0x0);
13742774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x3);
13752774f206SBjoern A. Zeeb 	} else if (path == RF_PATH_B) {
13762774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B,
13772774f206SBjoern A. Zeeb 				 BIT_RFTXEN_GCK_FORCE_ON, 0x0);
13782774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE2,
13792774f206SBjoern A. Zeeb 				 BIT_DIS_SHARERX_TXGAT, 0x0);
13802774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B,
13812774f206SBjoern A. Zeeb 				 BIT_TX_SCALE_0DB, 0x0);
13822774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x3);
13832774f206SBjoern A. Zeeb 	}
13842774f206SBjoern A. Zeeb 
13852774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x0);
13862774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_CFIR_EN, 0x5);
13872774f206SBjoern A. Zeeb }
13882774f206SBjoern A. Zeeb 
13892774f206SBjoern A. Zeeb static bool _rtw8822c_txgapk_gain_valid(struct rtw_dev *rtwdev, u32 gain)
13902774f206SBjoern A. Zeeb {
13912774f206SBjoern A. Zeeb 	if ((FIELD_GET(BIT_GAIN_TX_PAD_H, gain) >= 0xc) &&
13922774f206SBjoern A. Zeeb 	    (FIELD_GET(BIT_GAIN_TX_PAD_L, gain) >= 0xe))
13932774f206SBjoern A. Zeeb 		return true;
13942774f206SBjoern A. Zeeb 
13952774f206SBjoern A. Zeeb 	return false;
13962774f206SBjoern A. Zeeb }
13972774f206SBjoern A. Zeeb 
13982774f206SBjoern A. Zeeb static void _rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev,
13992774f206SBjoern A. Zeeb 						 u8 band, u8 path)
14002774f206SBjoern A. Zeeb {
14012774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
14022774f206SBjoern A. Zeeb 	u32 v, tmp_3f = 0;
14032774f206SBjoern A. Zeeb 	u8 gain, check_txgain;
14042774f206SBjoern A. Zeeb 
14052774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
14062774f206SBjoern A. Zeeb 
14072774f206SBjoern A. Zeeb 	switch (band) {
14082774f206SBjoern A. Zeeb 	case RF_BAND_2G_OFDM:
14092774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0);
14102774f206SBjoern A. Zeeb 		break;
14112774f206SBjoern A. Zeeb 	case RF_BAND_5G_L:
14122774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2);
14132774f206SBjoern A. Zeeb 		break;
14142774f206SBjoern A. Zeeb 	case RF_BAND_5G_M:
14152774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3);
14162774f206SBjoern A. Zeeb 		break;
14172774f206SBjoern A. Zeeb 	case RF_BAND_5G_H:
14182774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4);
14192774f206SBjoern A. Zeeb 		break;
14202774f206SBjoern A. Zeeb 	default:
14212774f206SBjoern A. Zeeb 		break;
14222774f206SBjoern A. Zeeb 	}
14232774f206SBjoern A. Zeeb 
14242774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, MASKBYTE0, 0x88);
14252774f206SBjoern A. Zeeb 
14262774f206SBjoern A. Zeeb 	check_txgain = 0;
14272774f206SBjoern A. Zeeb 	for (gain = 0; gain < RF_GAIN_NUM; gain++) {
14282774f206SBjoern A. Zeeb 		v = txgapk->rf3f_bp[band][gain][path];
14292774f206SBjoern A. Zeeb 		if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) {
14302774f206SBjoern A. Zeeb 			if (!check_txgain) {
14312774f206SBjoern A. Zeeb 				tmp_3f = txgapk->rf3f_bp[band][gain][path];
14322774f206SBjoern A. Zeeb 				check_txgain = 1;
14332774f206SBjoern A. Zeeb 			}
14342774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
14352774f206SBjoern A. Zeeb 				"[TXGAPK] tx_gain=0x%03X >= 0xCEX\n",
14362774f206SBjoern A. Zeeb 				txgapk->rf3f_bp[band][gain][path]);
14372774f206SBjoern A. Zeeb 		} else {
14382774f206SBjoern A. Zeeb 			tmp_3f = txgapk->rf3f_bp[band][gain][path];
14392774f206SBjoern A. Zeeb 		}
14402774f206SBjoern A. Zeeb 
14412774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN, tmp_3f);
14422774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_I_GAIN, gain);
14432774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x1);
14442774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x0);
14452774f206SBjoern A. Zeeb 
14462774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
14472774f206SBjoern A. Zeeb 			"[TXGAPK] Band=%d 0x1b98[11:0]=0x%03X path=%d\n",
14482774f206SBjoern A. Zeeb 			band, tmp_3f, path);
14492774f206SBjoern A. Zeeb 	}
14502774f206SBjoern A. Zeeb }
14512774f206SBjoern A. Zeeb 
14522774f206SBjoern A. Zeeb static void rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev)
14532774f206SBjoern A. Zeeb {
14542774f206SBjoern A. Zeeb 	u8 path, band;
14552774f206SBjoern A. Zeeb 
14562774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n",
14572774f206SBjoern A. Zeeb 		__func__, rtwdev->dm_info.gapk.channel);
14582774f206SBjoern A. Zeeb 
14592774f206SBjoern A. Zeeb 	for (band = 0; band < RF_BAND_MAX; band++) {
14602774f206SBjoern A. Zeeb 		for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
14612774f206SBjoern A. Zeeb 			_rtw8822c_txgapk_write_gain_bb_table(rtwdev,
14622774f206SBjoern A. Zeeb 							     band, path);
14632774f206SBjoern A. Zeeb 		}
14642774f206SBjoern A. Zeeb 	}
14652774f206SBjoern A. Zeeb }
14662774f206SBjoern A. Zeeb 
14672774f206SBjoern A. Zeeb static void rtw8822c_txgapk_read_offset(struct rtw_dev *rtwdev, u8 path)
14682774f206SBjoern A. Zeeb {
14692774f206SBjoern A. Zeeb 	static const u32 cfg1_1b00[2] = {0x00000d18, 0x00000d2a};
14702774f206SBjoern A. Zeeb 	static const u32 cfg2_1b00[2] = {0x00000d19, 0x00000d2b};
14712774f206SBjoern A. Zeeb 	static const u32 set_pi[2] = {REG_RSV_CTRL, REG_WLRF1};
14722774f206SBjoern A. Zeeb 	static const u32 path_setting[2] = {REG_ORITXCODE, REG_ORITXCODE2};
14732774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
14742774f206SBjoern A. Zeeb 	u8 channel = txgapk->channel;
14752774f206SBjoern A. Zeeb 	u32 val;
14762774f206SBjoern A. Zeeb 	int i;
14772774f206SBjoern A. Zeeb 
14782774f206SBjoern A. Zeeb 	if (path >= ARRAY_SIZE(cfg1_1b00) ||
14792774f206SBjoern A. Zeeb 	    path >= ARRAY_SIZE(cfg2_1b00) ||
14802774f206SBjoern A. Zeeb 	    path >= ARRAY_SIZE(set_pi) ||
14812774f206SBjoern A. Zeeb 	    path >= ARRAY_SIZE(path_setting)) {
14822774f206SBjoern A. Zeeb 		rtw_warn(rtwdev, "[TXGAPK] wrong path %d\n", path);
14832774f206SBjoern A. Zeeb 		return;
14842774f206SBjoern A. Zeeb 	}
14852774f206SBjoern A. Zeeb 
14862774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_ANTMAP0, BIT_ANT_PATH, path + 1);
14872774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXLGMAP, MASKDWORD, 0xe4e40000);
14882774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXANTSEG, BIT_ANTSEG, 0x3);
14892774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, path_setting[path], MASK20BITS, 0x33312);
14902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, path_setting[path], BIT_PATH_EN, 0x1);
14912774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x0);
14922774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT_TXA_TANK, 0x1);
14932774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_IDAC, BIT_TX_MODE, 0x820);
14942774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
14952774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0);
14962774f206SBjoern A. Zeeb 
14972774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TX_TONE_IDX, MASKBYTE0, 0x018);
14982774f206SBjoern A. Zeeb 	fsleep(1000);
14992774f206SBjoern A. Zeeb 	if (channel >= 1 && channel <= 14)
15002774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_2G_SWING);
15012774f206SBjoern A. Zeeb 	else
15022774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_5G_SWING);
15032774f206SBjoern A. Zeeb 	fsleep(1000);
15042774f206SBjoern A. Zeeb 
15052774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg1_1b00[path]);
15062774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg2_1b00[path]);
15072774f206SBjoern A. Zeeb 
15082774f206SBjoern A. Zeeb 	read_poll_timeout(rtw_read32_mask, val,
15092774f206SBjoern A. Zeeb 			  val == 0x55, 1000, 100000, false,
15102774f206SBjoern A. Zeeb 			  rtwdev, REG_RPT_CIP, BIT_RPT_CIP_STATUS);
15112774f206SBjoern A. Zeeb 
15122774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x2);
15132774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
15142774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_EN, 0x1);
15152774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x12);
15162774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x3);
15172774f206SBjoern A. Zeeb 	val = rtw_read32(rtwdev, REG_STAT_RPT);
15182774f206SBjoern A. Zeeb 
15192774f206SBjoern A. Zeeb 	txgapk->offset[0][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val);
15202774f206SBjoern A. Zeeb 	txgapk->offset[1][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val);
15212774f206SBjoern A. Zeeb 	txgapk->offset[2][path] = (s8)FIELD_GET(BIT_GAPK_RPT2, val);
15222774f206SBjoern A. Zeeb 	txgapk->offset[3][path] = (s8)FIELD_GET(BIT_GAPK_RPT3, val);
15232774f206SBjoern A. Zeeb 	txgapk->offset[4][path] = (s8)FIELD_GET(BIT_GAPK_RPT4, val);
15242774f206SBjoern A. Zeeb 	txgapk->offset[5][path] = (s8)FIELD_GET(BIT_GAPK_RPT5, val);
15252774f206SBjoern A. Zeeb 	txgapk->offset[6][path] = (s8)FIELD_GET(BIT_GAPK_RPT6, val);
15262774f206SBjoern A. Zeeb 	txgapk->offset[7][path] = (s8)FIELD_GET(BIT_GAPK_RPT7, val);
15272774f206SBjoern A. Zeeb 
15282774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x4);
15292774f206SBjoern A. Zeeb 	val = rtw_read32(rtwdev, REG_STAT_RPT);
15302774f206SBjoern A. Zeeb 
15312774f206SBjoern A. Zeeb 	txgapk->offset[8][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val);
15322774f206SBjoern A. Zeeb 	txgapk->offset[9][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val);
15332774f206SBjoern A. Zeeb 
15342774f206SBjoern A. Zeeb 	for (i = 0; i < RF_HW_OFFSET_NUM; i++)
15352774f206SBjoern A. Zeeb 		if (txgapk->offset[i][path] & BIT(3))
15362774f206SBjoern A. Zeeb 			txgapk->offset[i][path] = txgapk->offset[i][path] |
15372774f206SBjoern A. Zeeb 						  0xf0;
15382774f206SBjoern A. Zeeb 	for (i = 0; i < RF_HW_OFFSET_NUM; i++)
15392774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
15402774f206SBjoern A. Zeeb 			"[TXGAPK] offset %d %d path=%d\n",
15412774f206SBjoern A. Zeeb 			txgapk->offset[i][path], i, path);
15422774f206SBjoern A. Zeeb }
15432774f206SBjoern A. Zeeb 
15442774f206SBjoern A. Zeeb static void rtw8822c_txgapk_calculate_offset(struct rtw_dev *rtwdev, u8 path)
15452774f206SBjoern A. Zeeb {
15462774f206SBjoern A. Zeeb 	static const u32 bb_reg[] = {REG_ANTMAP0, REG_TXLGMAP, REG_TXANTSEG,
15472774f206SBjoern A. Zeeb 				     REG_ORITXCODE, REG_ORITXCODE2};
15482774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
15492774f206SBjoern A. Zeeb 	u8 channel = txgapk->channel;
15502774f206SBjoern A. Zeeb 	u32 reg_backup[ARRAY_SIZE(bb_reg)] = {0};
15512774f206SBjoern A. Zeeb 
15522774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n",
15532774f206SBjoern A. Zeeb 		__func__, channel);
15542774f206SBjoern A. Zeeb 
15552774f206SBjoern A. Zeeb 	rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg,
15562774f206SBjoern A. Zeeb 				      reg_backup, ARRAY_SIZE(bb_reg));
15572774f206SBjoern A. Zeeb 
15582774f206SBjoern A. Zeeb 	if (channel >= 1 && channel <= 14) {
15592774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev,
15602774f206SBjoern A. Zeeb 				 REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0);
15612774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
15622774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f);
15632774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
15642774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1);
15652774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x5000f);
15662774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x0);
15672774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x1);
15682774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0f);
15692774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1);
15702774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1);
15712774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0);
15722774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1);
15732774f206SBjoern A. Zeeb 
15742774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x00);
15752774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0);
15762774f206SBjoern A. Zeeb 
15772774f206SBjoern A. Zeeb 		rtw8822c_txgapk_read_offset(rtwdev, path);
15782774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n");
15792774f206SBjoern A. Zeeb 
15802774f206SBjoern A. Zeeb 	} else {
15812774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev,
15822774f206SBjoern A. Zeeb 				 REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0);
15832774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path);
15842774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f);
15852774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
15862774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1);
15872774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50011);
15882774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x3);
15892774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x3);
15902774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1);
15912774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path,
15922774f206SBjoern A. Zeeb 			     RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0x2);
15932774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x12);
15942774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1);
15952774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0);
15962774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1);
15972774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x5);
15982774f206SBjoern A. Zeeb 
15992774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0);
16002774f206SBjoern A. Zeeb 
16012774f206SBjoern A. Zeeb 		if (channel >= 36 && channel <= 64)
16022774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev,
16032774f206SBjoern A. Zeeb 					 REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2);
16042774f206SBjoern A. Zeeb 		else if (channel >= 100 && channel <= 144)
16052774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev,
16062774f206SBjoern A. Zeeb 					 REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3);
16072774f206SBjoern A. Zeeb 		else if (channel >= 149 && channel <= 177)
16082774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev,
16092774f206SBjoern A. Zeeb 					 REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4);
16102774f206SBjoern A. Zeeb 
16112774f206SBjoern A. Zeeb 		rtw8822c_txgapk_read_offset(rtwdev, path);
16122774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n");
16132774f206SBjoern A. Zeeb 	}
16142774f206SBjoern A. Zeeb 	rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg,
16152774f206SBjoern A. Zeeb 				      reg_backup, ARRAY_SIZE(bb_reg));
16162774f206SBjoern A. Zeeb }
16172774f206SBjoern A. Zeeb 
16182774f206SBjoern A. Zeeb static void rtw8822c_txgapk_rf_restore(struct rtw_dev *rtwdev, u8 path)
16192774f206SBjoern A. Zeeb {
16202774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
16212774f206SBjoern A. Zeeb 
16222774f206SBjoern A. Zeeb 	if (path >= rtwdev->hal.rf_path_num)
16232774f206SBjoern A. Zeeb 		return;
16242774f206SBjoern A. Zeeb 
16252774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x3);
16262774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x0);
16272774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x0);
16282774f206SBjoern A. Zeeb }
16292774f206SBjoern A. Zeeb 
16302774f206SBjoern A. Zeeb static u32 rtw8822c_txgapk_cal_gain(struct rtw_dev *rtwdev, u32 gain, s8 offset)
16312774f206SBjoern A. Zeeb {
16322774f206SBjoern A. Zeeb 	u32 gain_x2, new_gain;
16332774f206SBjoern A. Zeeb 
16342774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
16352774f206SBjoern A. Zeeb 
16362774f206SBjoern A. Zeeb 	if (_rtw8822c_txgapk_gain_valid(rtwdev, gain)) {
16372774f206SBjoern A. Zeeb 		new_gain = gain;
16382774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
16392774f206SBjoern A. Zeeb 			"[TXGAPK] gain=0x%03X(>=0xCEX) offset=%d new_gain=0x%03X\n",
16402774f206SBjoern A. Zeeb 			gain, offset, new_gain);
16412774f206SBjoern A. Zeeb 		return new_gain;
16422774f206SBjoern A. Zeeb 	}
16432774f206SBjoern A. Zeeb 
16442774f206SBjoern A. Zeeb 	gain_x2 = (gain << 1) + offset;
16452774f206SBjoern A. Zeeb 	new_gain = (gain_x2 >> 1) | (gain_x2 & BIT(0) ? BIT_GAIN_EXT : 0);
16462774f206SBjoern A. Zeeb 
16472774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK,
16482774f206SBjoern A. Zeeb 		"[TXGAPK] gain=0x%X offset=%d new_gain=0x%X\n",
16492774f206SBjoern A. Zeeb 		gain, offset, new_gain);
16502774f206SBjoern A. Zeeb 
16512774f206SBjoern A. Zeeb 	return new_gain;
16522774f206SBjoern A. Zeeb }
16532774f206SBjoern A. Zeeb 
16542774f206SBjoern A. Zeeb static void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev)
16552774f206SBjoern A. Zeeb {
16562774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
16572774f206SBjoern A. Zeeb 	u32 i, j, tmp = 0x20, tmp_3f, v;
16582774f206SBjoern A. Zeeb 	s8 offset_tmp[RF_GAIN_NUM] = {0};
16592774f206SBjoern A. Zeeb 	u8 path, band = RF_BAND_2G_OFDM, channel = txgapk->channel;
16602774f206SBjoern A. Zeeb 
16612774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
16622774f206SBjoern A. Zeeb 
16632774f206SBjoern A. Zeeb 	if (channel >= 1 && channel <= 14) {
16642774f206SBjoern A. Zeeb 		tmp = 0x20;
16652774f206SBjoern A. Zeeb 		band = RF_BAND_2G_OFDM;
16662774f206SBjoern A. Zeeb 	} else if (channel >= 36 && channel <= 64) {
16672774f206SBjoern A. Zeeb 		tmp = 0x200;
16682774f206SBjoern A. Zeeb 		band = RF_BAND_5G_L;
16692774f206SBjoern A. Zeeb 	} else if (channel >= 100 && channel <= 144) {
16702774f206SBjoern A. Zeeb 		tmp = 0x280;
16712774f206SBjoern A. Zeeb 		band = RF_BAND_5G_M;
16722774f206SBjoern A. Zeeb 	} else if (channel >= 149 && channel <= 177) {
16732774f206SBjoern A. Zeeb 		tmp = 0x300;
16742774f206SBjoern A. Zeeb 		band = RF_BAND_5G_H;
16752774f206SBjoern A. Zeeb 	} else {
16762774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "[TXGAPK] unknown channel %d!!\n", channel);
16772774f206SBjoern A. Zeeb 		return;
16782774f206SBjoern A. Zeeb 	}
16792774f206SBjoern A. Zeeb 
16802774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
16812774f206SBjoern A. Zeeb 		for (i = 0; i < RF_GAIN_NUM; i++) {
16822774f206SBjoern A. Zeeb 			offset_tmp[i] = 0;
16832774f206SBjoern A. Zeeb 			for (j = i; j < RF_GAIN_NUM; j++) {
16842774f206SBjoern A. Zeeb 				v = txgapk->rf3f_bp[band][j][path];
16852774f206SBjoern A. Zeeb 				if (_rtw8822c_txgapk_gain_valid(rtwdev, v))
16862774f206SBjoern A. Zeeb 					continue;
16872774f206SBjoern A. Zeeb 
16882774f206SBjoern A. Zeeb 				offset_tmp[i] += txgapk->offset[j][path];
16892774f206SBjoern A. Zeeb 				txgapk->fianl_offset[i][path] = offset_tmp[i];
16902774f206SBjoern A. Zeeb 			}
16912774f206SBjoern A. Zeeb 
16922774f206SBjoern A. Zeeb 			v = txgapk->rf3f_bp[band][i][path];
16932774f206SBjoern A. Zeeb 			if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) {
16942774f206SBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
16952774f206SBjoern A. Zeeb 					"[TXGAPK] tx_gain=0x%03X >= 0xCEX\n",
16962774f206SBjoern A. Zeeb 					txgapk->rf3f_bp[band][i][path]);
16972774f206SBjoern A. Zeeb 			} else {
16982774f206SBjoern A. Zeeb 				txgapk->rf3f_fs[path][i] = offset_tmp[i];
16992774f206SBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
17002774f206SBjoern A. Zeeb 					"[TXGAPK] offset %d %d\n",
17012774f206SBjoern A. Zeeb 					offset_tmp[i], i);
17022774f206SBjoern A. Zeeb 			}
17032774f206SBjoern A. Zeeb 		}
17042774f206SBjoern A. Zeeb 
17052774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x10000);
17062774f206SBjoern A. Zeeb 		for (i = 0; i < RF_GAIN_NUM; i++) {
17072774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path,
17082774f206SBjoern A. Zeeb 				     RF_LUTWA, RFREG_MASK, tmp + i);
17092774f206SBjoern A. Zeeb 
17102774f206SBjoern A. Zeeb 			tmp_3f = rtw8822c_txgapk_cal_gain(rtwdev,
17112774f206SBjoern A. Zeeb 							  txgapk->rf3f_bp[band][i][path],
17122774f206SBjoern A. Zeeb 							  offset_tmp[i]);
17132774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, RF_LUTWD0,
17142774f206SBjoern A. Zeeb 				     BIT_GAIN_EXT | BIT_DATA_L, tmp_3f);
17152774f206SBjoern A. Zeeb 
17162774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
17172774f206SBjoern A. Zeeb 				"[TXGAPK] 0x33=0x%05X 0x3f=0x%04X\n",
17182774f206SBjoern A. Zeeb 				tmp + i, tmp_3f);
17192774f206SBjoern A. Zeeb 		}
17202774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x0);
17212774f206SBjoern A. Zeeb 	}
17222774f206SBjoern A. Zeeb }
17232774f206SBjoern A. Zeeb 
17242774f206SBjoern A. Zeeb static void rtw8822c_txgapk_save_all_tx_gain_table(struct rtw_dev *rtwdev)
17252774f206SBjoern A. Zeeb {
17262774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
17272774f206SBjoern A. Zeeb 	static const u32 three_wire[2] = {REG_3WIRE, REG_3WIRE2};
17282774f206SBjoern A. Zeeb 	static const u8 ch_num[RF_BAND_MAX] = {1, 1, 36, 100, 149};
17292774f206SBjoern A. Zeeb 	static const u8 band_num[RF_BAND_MAX] = {0x0, 0x0, 0x1, 0x3, 0x5};
17302774f206SBjoern A. Zeeb 	static const u8 cck[RF_BAND_MAX] = {0x1, 0x0, 0x0, 0x0, 0x0};
17312774f206SBjoern A. Zeeb 	u8 path, band, gain, rf0_idx;
17322774f206SBjoern A. Zeeb 	u32 rf18, v;
17332774f206SBjoern A. Zeeb 
17342774f206SBjoern A. Zeeb 	if (rtwdev->dm_info.dm_flags & BIT(RTW_DM_CAP_TXGAPK))
17352774f206SBjoern A. Zeeb 		return;
17362774f206SBjoern A. Zeeb 
17372774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
17382774f206SBjoern A. Zeeb 
17392774f206SBjoern A. Zeeb 	if (txgapk->read_txgain == 1) {
17402774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
17412774f206SBjoern A. Zeeb 			"[TXGAPK] Already Read txgapk->read_txgain return!!!\n");
17422774f206SBjoern A. Zeeb 		rtw8822c_txgapk_write_gain_bb_table(rtwdev);
17432774f206SBjoern A. Zeeb 		return;
17442774f206SBjoern A. Zeeb 	}
17452774f206SBjoern A. Zeeb 
17462774f206SBjoern A. Zeeb 	for (band = 0; band < RF_BAND_MAX; band++) {
17472774f206SBjoern A. Zeeb 		for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
17482774f206SBjoern A. Zeeb 			rf18 = rtw_read_rf(rtwdev, path, RF_CFGCH, RFREG_MASK);
17492774f206SBjoern A. Zeeb 
17502774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev,
17512774f206SBjoern A. Zeeb 					 three_wire[path], BIT_3WIRE_EN, 0x0);
17522774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path,
17532774f206SBjoern A. Zeeb 				     RF_CFGCH, MASKBYTE0, ch_num[band]);
17542774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path,
17552774f206SBjoern A. Zeeb 				     RF_CFGCH, BIT_BAND, band_num[band]);
17562774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path,
17572774f206SBjoern A. Zeeb 				     RF_BW_TRXBB, BIT_DBG_CCK_CCA, cck[band]);
17582774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path,
17592774f206SBjoern A. Zeeb 				     RF_BW_TRXBB, BIT_TX_CCK_IND, cck[band]);
17602774f206SBjoern A. Zeeb 			gain = 0;
17612774f206SBjoern A. Zeeb 			for (rf0_idx = 1; rf0_idx < 32; rf0_idx += 3) {
17622774f206SBjoern A. Zeeb 				rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC,
17632774f206SBjoern A. Zeeb 					     MASKBYTE0, rf0_idx);
17642774f206SBjoern A. Zeeb 				v = rtw_read_rf(rtwdev, path,
17652774f206SBjoern A. Zeeb 						RF_TX_RESULT, RFREG_MASK);
17662774f206SBjoern A. Zeeb 				txgapk->rf3f_bp[band][gain][path] = v & BIT_DATA_L;
17672774f206SBjoern A. Zeeb 
17682774f206SBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
17692774f206SBjoern A. Zeeb 					"[TXGAPK] 0x5f=0x%03X band=%d path=%d\n",
17702774f206SBjoern A. Zeeb 					txgapk->rf3f_bp[band][gain][path],
17712774f206SBjoern A. Zeeb 					band, path);
17722774f206SBjoern A. Zeeb 				gain++;
17732774f206SBjoern A. Zeeb 			}
17742774f206SBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, RF_CFGCH, RFREG_MASK, rf18);
17752774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev,
17762774f206SBjoern A. Zeeb 					 three_wire[path], BIT_3WIRE_EN, 0x3);
17772774f206SBjoern A. Zeeb 		}
17782774f206SBjoern A. Zeeb 	}
17792774f206SBjoern A. Zeeb 	rtw8822c_txgapk_write_gain_bb_table(rtwdev);
17802774f206SBjoern A. Zeeb 	txgapk->read_txgain = 1;
17812774f206SBjoern A. Zeeb }
17822774f206SBjoern A. Zeeb 
17832774f206SBjoern A. Zeeb static void rtw8822c_txgapk(struct rtw_dev *rtwdev)
17842774f206SBjoern A. Zeeb {
17852774f206SBjoern A. Zeeb 	static const u32 bb_reg[2] = {REG_TX_PTCL_CTRL, REG_TX_FIFO};
17862774f206SBjoern A. Zeeb 	struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;
17872774f206SBjoern A. Zeeb 	u32 bb_reg_backup[2];
17882774f206SBjoern A. Zeeb 	u8 path;
17892774f206SBjoern A. Zeeb 
17902774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__);
17912774f206SBjoern A. Zeeb 
17922774f206SBjoern A. Zeeb 	rtw8822c_txgapk_save_all_tx_gain_table(rtwdev);
17932774f206SBjoern A. Zeeb 
17942774f206SBjoern A. Zeeb 	if (txgapk->read_txgain == 0) {
17952774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
17962774f206SBjoern A. Zeeb 			"[TXGAPK] txgapk->read_txgain == 0 return!!!\n");
17972774f206SBjoern A. Zeeb 		return;
17982774f206SBjoern A. Zeeb 	}
17992774f206SBjoern A. Zeeb 
18002774f206SBjoern A. Zeeb 	if (rtwdev->efuse.power_track_type >= 4 &&
18012774f206SBjoern A. Zeeb 	    rtwdev->efuse.power_track_type <= 7) {
18022774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
18032774f206SBjoern A. Zeeb 			"[TXGAPK] Normal Mode in TSSI mode. return!!!\n");
18042774f206SBjoern A. Zeeb 		return;
18052774f206SBjoern A. Zeeb 	}
18062774f206SBjoern A. Zeeb 
18072774f206SBjoern A. Zeeb 	rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg,
18082774f206SBjoern A. Zeeb 				      bb_reg_backup, ARRAY_SIZE(bb_reg));
18092774f206SBjoern A. Zeeb 	rtw8822c_txgapk_tx_pause(rtwdev);
18102774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
18112774f206SBjoern A. Zeeb 		txgapk->channel = rtw_read_rf(rtwdev, path,
18122774f206SBjoern A. Zeeb 					      RF_CFGCH, RFREG_MASK) & MASKBYTE0;
18132774f206SBjoern A. Zeeb 		rtw8822c_txgapk_bb_dpk(rtwdev, path);
18142774f206SBjoern A. Zeeb 		rtw8822c_txgapk_afe_dpk(rtwdev, path);
18152774f206SBjoern A. Zeeb 		rtw8822c_txgapk_calculate_offset(rtwdev, path);
18162774f206SBjoern A. Zeeb 		rtw8822c_txgapk_rf_restore(rtwdev, path);
18172774f206SBjoern A. Zeeb 		rtw8822c_txgapk_afe_dpk_restore(rtwdev, path);
18182774f206SBjoern A. Zeeb 		rtw8822c_txgapk_bb_dpk_restore(rtwdev, path);
18192774f206SBjoern A. Zeeb 	}
18202774f206SBjoern A. Zeeb 	rtw8822c_txgapk_write_tx_gain(rtwdev);
18212774f206SBjoern A. Zeeb 	rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg,
18222774f206SBjoern A. Zeeb 				      bb_reg_backup, ARRAY_SIZE(bb_reg));
18232774f206SBjoern A. Zeeb }
18242774f206SBjoern A. Zeeb 
18252774f206SBjoern A. Zeeb static void rtw8822c_do_gapk(struct rtw_dev *rtwdev)
18262774f206SBjoern A. Zeeb {
18272774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm = &rtwdev->dm_info;
18282774f206SBjoern A. Zeeb 
18292774f206SBjoern A. Zeeb 	if (dm->dm_flags & BIT(RTW_DM_CAP_TXGAPK)) {
18302774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] feature disable!!!\n");
18312774f206SBjoern A. Zeeb 		return;
18322774f206SBjoern A. Zeeb 	}
18332774f206SBjoern A. Zeeb 	rtw8822c_rfk_handshake(rtwdev, true);
18342774f206SBjoern A. Zeeb 	rtw8822c_txgapk(rtwdev);
18352774f206SBjoern A. Zeeb 	rtw8822c_rfk_handshake(rtwdev, false);
18362774f206SBjoern A. Zeeb }
18372774f206SBjoern A. Zeeb 
18382774f206SBjoern A. Zeeb static void rtw8822c_rf_init(struct rtw_dev *rtwdev)
18392774f206SBjoern A. Zeeb {
18402774f206SBjoern A. Zeeb 	rtw8822c_rf_dac_cal(rtwdev);
18412774f206SBjoern A. Zeeb 	rtw8822c_rf_x2_check(rtwdev);
18422774f206SBjoern A. Zeeb 	rtw8822c_thermal_trim(rtwdev);
18432774f206SBjoern A. Zeeb 	rtw8822c_power_trim(rtwdev);
18442774f206SBjoern A. Zeeb 	rtw8822c_pa_bias(rtwdev);
18452774f206SBjoern A. Zeeb }
18462774f206SBjoern A. Zeeb 
18472774f206SBjoern A. Zeeb static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev)
18482774f206SBjoern A. Zeeb {
18492774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
18502774f206SBjoern A. Zeeb 	u8 path;
18512774f206SBjoern A. Zeeb 
18522774f206SBjoern A. Zeeb 	for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) {
18532774f206SBjoern A. Zeeb 		dm_info->delta_power_index[path] = 0;
18542774f206SBjoern A. Zeeb 		ewma_thermal_init(&dm_info->avg_thermal[path]);
18552774f206SBjoern A. Zeeb 		dm_info->thermal_avg[path] = 0xff;
18562774f206SBjoern A. Zeeb 	}
18572774f206SBjoern A. Zeeb 
18582774f206SBjoern A. Zeeb 	dm_info->pwr_trk_triggered = false;
18592774f206SBjoern A. Zeeb 	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
18602774f206SBjoern A. Zeeb 	dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k;
18612774f206SBjoern A. Zeeb }
18622774f206SBjoern A. Zeeb 
18632774f206SBjoern A. Zeeb static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)
18642774f206SBjoern A. Zeeb {
18652774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
18662774f206SBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
18672774f206SBjoern A. Zeeb 	u8 crystal_cap;
18682774f206SBjoern A. Zeeb 	u8 cck_gi_u_bnd_msb = 0;
18692774f206SBjoern A. Zeeb 	u8 cck_gi_u_bnd_lsb = 0;
18702774f206SBjoern A. Zeeb 	u8 cck_gi_l_bnd_msb = 0;
18712774f206SBjoern A. Zeeb 	u8 cck_gi_l_bnd_lsb = 0;
18722774f206SBjoern A. Zeeb 	bool is_tx2_path;
18732774f206SBjoern A. Zeeb 
18742774f206SBjoern A. Zeeb 	/* power on BB/RF domain */
18752774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
18762774f206SBjoern A. Zeeb 		       BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB);
18772774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_RF_CTRL,
18782774f206SBjoern A. Zeeb 		       BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
18792774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
18802774f206SBjoern A. Zeeb 
18812774f206SBjoern A. Zeeb 	/* disable low rate DPD */
18822774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL);
18832774f206SBjoern A. Zeeb 
18842774f206SBjoern A. Zeeb 	/* pre init before header files config */
18852774f206SBjoern A. Zeeb 	rtw8822c_header_file_init(rtwdev, true);
18862774f206SBjoern A. Zeeb 
18872774f206SBjoern A. Zeeb 	rtw_phy_load_tables(rtwdev);
18882774f206SBjoern A. Zeeb 
18892774f206SBjoern A. Zeeb 	crystal_cap = rtwdev->efuse.crystal_cap & 0x7f;
18902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, 0xfffc00,
18912774f206SBjoern A. Zeeb 			 crystal_cap | (crystal_cap << 7));
18922774f206SBjoern A. Zeeb 
18932774f206SBjoern A. Zeeb 	/* post init after header files config */
18942774f206SBjoern A. Zeeb 	rtw8822c_header_file_init(rtwdev, false);
18952774f206SBjoern A. Zeeb 
18962774f206SBjoern A. Zeeb 	is_tx2_path = false;
18972774f206SBjoern A. Zeeb 	rtw8822c_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
18982774f206SBjoern A. Zeeb 				 is_tx2_path);
18992774f206SBjoern A. Zeeb 	rtw_phy_init(rtwdev);
19002774f206SBjoern A. Zeeb 
19012774f206SBjoern A. Zeeb 	cck_gi_u_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc000);
19022774f206SBjoern A. Zeeb 	cck_gi_u_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1aa8, 0xf0000);
19032774f206SBjoern A. Zeeb 	cck_gi_l_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc0);
19042774f206SBjoern A. Zeeb 	cck_gi_l_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1a70, 0x0f000000);
19052774f206SBjoern A. Zeeb 
19062774f206SBjoern A. Zeeb 	dm_info->cck_gi_u_bnd = ((cck_gi_u_bnd_msb << 4) | (cck_gi_u_bnd_lsb));
19072774f206SBjoern A. Zeeb 	dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb));
19082774f206SBjoern A. Zeeb 
19092774f206SBjoern A. Zeeb 	rtw8822c_rf_init(rtwdev);
19102774f206SBjoern A. Zeeb 	rtw8822c_pwrtrack_init(rtwdev);
19112774f206SBjoern A. Zeeb 
19122774f206SBjoern A. Zeeb 	rtw_bf_phy_init(rtwdev);
19132774f206SBjoern A. Zeeb }
19142774f206SBjoern A. Zeeb 
19152774f206SBjoern A. Zeeb #define WLAN_TXQ_RPT_EN		0x1F
19162774f206SBjoern A. Zeeb #define WLAN_SLOT_TIME		0x09
19172774f206SBjoern A. Zeeb #define WLAN_PIFS_TIME		0x1C
19182774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_CONT_TX	0x0A
19192774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_CONT_TX	0x0E
19202774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_TRX	0x0A
19212774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_TRX	0x10
19222774f206SBjoern A. Zeeb #define WLAN_NAV_MAX		0xC8
19232774f206SBjoern A. Zeeb #define WLAN_RDG_NAV		0x05
19242774f206SBjoern A. Zeeb #define WLAN_TXOP_NAV		0x1B
19252774f206SBjoern A. Zeeb #define WLAN_CCK_RX_TSF		0x30
19262774f206SBjoern A. Zeeb #define WLAN_OFDM_RX_TSF	0x30
19272774f206SBjoern A. Zeeb #define WLAN_TBTT_PROHIBIT	0x04 /* unit : 32us */
19282774f206SBjoern A. Zeeb #define WLAN_TBTT_HOLD_TIME	0x064 /* unit : 32us */
19292774f206SBjoern A. Zeeb #define WLAN_DRV_EARLY_INT	0x04
19302774f206SBjoern A. Zeeb #define WLAN_BCN_CTRL_CLT0	0x10
19312774f206SBjoern A. Zeeb #define WLAN_BCN_DMA_TIME	0x02
19322774f206SBjoern A. Zeeb #define WLAN_BCN_MAX_ERR	0xFF
19332774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_DUR_TUNE	0x0A
19342774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_DUR_TUNE	0x10
19352774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_CTX	0x0A
19362774f206SBjoern A. Zeeb #define WLAN_SIFS_CCK_IRX	0x0A
19372774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_CTX	0x0E
19382774f206SBjoern A. Zeeb #define WLAN_SIFS_OFDM_IRX	0x0E
19392774f206SBjoern A. Zeeb #define WLAN_EIFS_DUR_TUNE	0x40
19402774f206SBjoern A. Zeeb #define WLAN_EDCA_VO_PARAM	0x002FA226
19412774f206SBjoern A. Zeeb #define WLAN_EDCA_VI_PARAM	0x005EA328
19422774f206SBjoern A. Zeeb #define WLAN_EDCA_BE_PARAM	0x005EA42B
19432774f206SBjoern A. Zeeb #define WLAN_EDCA_BK_PARAM	0x0000A44F
19442774f206SBjoern A. Zeeb 
19452774f206SBjoern A. Zeeb #define WLAN_RX_FILTER0		0xFFFFFFFF
19462774f206SBjoern A. Zeeb #define WLAN_RX_FILTER2		0xFFFF
19472774f206SBjoern A. Zeeb #define WLAN_RCR_CFG		0xE400220E
19482774f206SBjoern A. Zeeb #define WLAN_RXPKT_MAX_SZ	12288
19492774f206SBjoern A. Zeeb #define WLAN_RXPKT_MAX_SZ_512	(WLAN_RXPKT_MAX_SZ >> 9)
19502774f206SBjoern A. Zeeb 
19512774f206SBjoern A. Zeeb #define WLAN_AMPDU_MAX_TIME		0x70
19522774f206SBjoern A. Zeeb #define WLAN_RTS_LEN_TH			0xFF
19532774f206SBjoern A. Zeeb #define WLAN_RTS_TX_TIME_TH		0x08
19542774f206SBjoern A. Zeeb #define WLAN_MAX_AGG_PKT_LIMIT		0x3f
19552774f206SBjoern A. Zeeb #define WLAN_RTS_MAX_AGG_PKT_LIMIT	0x3f
19562774f206SBjoern A. Zeeb #define WLAN_PRE_TXCNT_TIME_TH		0x1E0
19572774f206SBjoern A. Zeeb #define FAST_EDCA_VO_TH		0x06
19582774f206SBjoern A. Zeeb #define FAST_EDCA_VI_TH		0x06
19592774f206SBjoern A. Zeeb #define FAST_EDCA_BE_TH		0x06
19602774f206SBjoern A. Zeeb #define FAST_EDCA_BK_TH		0x06
19612774f206SBjoern A. Zeeb #define WLAN_BAR_RETRY_LIMIT		0x01
19622774f206SBjoern A. Zeeb #define WLAN_BAR_ACK_TYPE		0x05
19632774f206SBjoern A. Zeeb #define WLAN_RA_TRY_RATE_AGG_LIMIT	0x08
19642774f206SBjoern A. Zeeb #define WLAN_RESP_TXRATE		0x84
19652774f206SBjoern A. Zeeb #define WLAN_ACK_TO			0x21
19662774f206SBjoern A. Zeeb #define WLAN_ACK_TO_CCK			0x6A
19672774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_CNT_1_4	0x01000000
19682774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_CNT_5_8	0x08070504
19692774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_CNT_5_8	0x08070504
19702774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_RATE0		0xFE01F010
19712774f206SBjoern A. Zeeb #define WLAN_DATA_RATE_FB_RATE0_H	0x40000000
19722774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE1		0x003FF010
19732774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE1_H	0x40000000
19742774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE4		0x0600F010
19752774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE4_H	0x400003E0
19762774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE5		0x0600F015
19772774f206SBjoern A. Zeeb #define WLAN_RTS_RATE_FB_RATE5_H	0x000000E0
19782774f206SBjoern A. Zeeb #define WLAN_MULTI_ADDR			0xFFFFFFFF
19792774f206SBjoern A. Zeeb 
19802774f206SBjoern A. Zeeb #define WLAN_TX_FUNC_CFG1		0x30
19812774f206SBjoern A. Zeeb #define WLAN_TX_FUNC_CFG2		0x30
19822774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_NORM_FUNC1		0x98
19832774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_LB_FUNC1		0x80
19842774f206SBjoern A. Zeeb #define WLAN_MAC_OPT_FUNC2		0xb0810041
19852774f206SBjoern A. Zeeb #define WLAN_MAC_INT_MIG_CFG		0x33330000
19862774f206SBjoern A. Zeeb 
19872774f206SBjoern A. Zeeb #define WLAN_SIFS_CFG	(WLAN_SIFS_CCK_CONT_TX | \
19882774f206SBjoern A. Zeeb 			(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
19892774f206SBjoern A. Zeeb 			(WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
19902774f206SBjoern A. Zeeb 			(WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
19912774f206SBjoern A. Zeeb 
19922774f206SBjoern A. Zeeb #define WLAN_SIFS_DUR_TUNE	(WLAN_SIFS_CCK_DUR_TUNE | \
19932774f206SBjoern A. Zeeb 				(WLAN_SIFS_OFDM_DUR_TUNE << 8))
19942774f206SBjoern A. Zeeb 
19952774f206SBjoern A. Zeeb #define WLAN_TBTT_TIME	(WLAN_TBTT_PROHIBIT |\
19962774f206SBjoern A. Zeeb 			(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
19972774f206SBjoern A. Zeeb 
19982774f206SBjoern A. Zeeb #define WLAN_NAV_CFG		(WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
19992774f206SBjoern A. Zeeb #define WLAN_RX_TSF_CFG		(WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
20002774f206SBjoern A. Zeeb 
20012774f206SBjoern A. Zeeb #define MAC_CLK_SPEED	80 /* 80M */
20022774f206SBjoern A. Zeeb #define EFUSE_PCB_INFO_OFFSET	0xCA
20032774f206SBjoern A. Zeeb 
20042774f206SBjoern A. Zeeb static int rtw8822c_mac_init(struct rtw_dev *rtwdev)
20052774f206SBjoern A. Zeeb {
20062774f206SBjoern A. Zeeb 	u8 value8;
20072774f206SBjoern A. Zeeb 	u16 value16;
20082774f206SBjoern A. Zeeb 	u32 value32;
20092774f206SBjoern A. Zeeb 	u16 pre_txcnt;
20102774f206SBjoern A. Zeeb 
20112774f206SBjoern A. Zeeb 	/* txq control */
20122774f206SBjoern A. Zeeb 	value8 = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL);
20132774f206SBjoern A. Zeeb 	value8 |= (BIT(7) & ~BIT(1) & ~BIT(2));
20142774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, value8);
20152774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
20162774f206SBjoern A. Zeeb 	/* sifs control */
20172774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SIFS_DUR_TUNE);
20182774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
20192774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RESP_SIFS_CCK,
20202774f206SBjoern A. Zeeb 		    WLAN_SIFS_CCK_CTX | WLAN_SIFS_CCK_IRX << 8);
20212774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RESP_SIFS_OFDM,
20222774f206SBjoern A. Zeeb 		    WLAN_SIFS_OFDM_CTX | WLAN_SIFS_OFDM_IRX << 8);
20232774f206SBjoern A. Zeeb 	/* rate fallback control */
20242774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DARFRC, WLAN_DATA_RATE_FB_CNT_1_4);
20252774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DARFRCH, WLAN_DATA_RATE_FB_CNT_5_8);
20262774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RARFRCH, WLAN_RTS_RATE_FB_CNT_5_8);
20272774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR0, WLAN_DATA_RATE_FB_RATE0);
20282774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH0, WLAN_DATA_RATE_FB_RATE0_H);
20292774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR1_V1, WLAN_RTS_RATE_FB_RATE1);
20302774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH1_V1, WLAN_RTS_RATE_FB_RATE1_H);
20312774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR4, WLAN_RTS_RATE_FB_RATE4);
20322774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH4, WLAN_RTS_RATE_FB_RATE4_H);
20332774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR5, WLAN_RTS_RATE_FB_RATE5);
20342774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH5, WLAN_RTS_RATE_FB_RATE5_H);
20352774f206SBjoern A. Zeeb 	/* protocol configuration */
20362774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
20372774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
20382774f206SBjoern A. Zeeb 	pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT;
20392774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF));
20402774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8));
20412774f206SBjoern A. Zeeb 	value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
20422774f206SBjoern A. Zeeb 		  (WLAN_MAX_AGG_PKT_LIMIT << 16) |
20432774f206SBjoern A. Zeeb 		  (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
20442774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
20452774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
20462774f206SBjoern A. Zeeb 		    WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
20472774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
20482774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
20492774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
20502774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
20512774f206SBjoern A. Zeeb 	/* close BA parser */
20522774f206SBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_LIFETIME_EN, BIT_BA_PARSER_EN);
20532774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_RRSR, BITS_RRSR_RSC);
20542774f206SBjoern A. Zeeb 
20552774f206SBjoern A. Zeeb 	/* EDCA configuration */
20562774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_VO_PARAM, WLAN_EDCA_VO_PARAM);
20572774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_VI_PARAM, WLAN_EDCA_VI_PARAM);
20582774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_BE_PARAM, WLAN_EDCA_BE_PARAM);
20592774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_BK_PARAM, WLAN_EDCA_BK_PARAM);
20602774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
20612774f206SBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
20622774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_RD_CTRL + 1,
20632774f206SBjoern A. Zeeb 		       (BIT_DIS_TXOP_CFE | BIT_DIS_LSIG_CFE |
20642774f206SBjoern A. Zeeb 			BIT_DIS_STBC_CFE) >> 8);
20652774f206SBjoern A. Zeeb 
20662774f206SBjoern A. Zeeb 	/* MAC clock configuration */
20672774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BIT_MAC_CLK_SEL);
20682774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED);
20692774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED);
20702774f206SBjoern A. Zeeb 
20712774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_MISC_CTRL,
20722774f206SBjoern A. Zeeb 		       BIT_EN_FREE_CNT | BIT_DIS_SECOND_CCA);
20732774f206SBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
20742774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_TXPAUSE, 0x0000);
20752774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
20762774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
20772774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
20782774f206SBjoern A. Zeeb 	/* Set beacon cotnrol - enable TSF and other related functions */
20792774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
20802774f206SBjoern A. Zeeb 	/* Set send beacon related registers */
20812774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
20822774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
20832774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCN_CTRL_CLINT0, WLAN_BCN_CTRL_CLT0);
20842774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
20852774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCN_MAX_ERR, WLAN_BCN_MAX_ERR);
20862774f206SBjoern A. Zeeb 
20872774f206SBjoern A. Zeeb 	/* WMAC configuration */
20882774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_MAR, WLAN_MULTI_ADDR);
20892774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_MAR + 4, WLAN_MULTI_ADDR);
20902774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BBPSF_CTRL + 2, WLAN_RESP_TXRATE);
20912774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_ACKTO, WLAN_ACK_TO);
20922774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_ACKTO_CCK, WLAN_ACK_TO_CCK);
20932774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_EIFS, WLAN_EIFS_DUR_TUNE);
20942774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_NAV_CTRL + 2, WLAN_NAV_MAX);
20952774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H  + 2, WLAN_BAR_ACK_TYPE);
20962774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
20972774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
20982774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
20992774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
21002774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
21012774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
21022774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_GENERAL_OPTION, BIT_DUMMY_FCS_READY_MASK_EN);
21032774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
21042774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION_1, WLAN_MAC_OPT_NORM_FUNC1);
21052774f206SBjoern A. Zeeb 
21062774f206SBjoern A. Zeeb 	/* init low power */
21072774f206SBjoern A. Zeeb 	value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL + 2) & 0xF00F;
21082774f206SBjoern A. Zeeb 	value16 |= (BIT_RXGCK_VHT_FIFOTHR(1) | BIT_RXGCK_HT_FIFOTHR(1) |
21092774f206SBjoern A. Zeeb 		    BIT_RXGCK_OFDM_FIFOTHR(1) | BIT_RXGCK_CCK_FIFOTHR(1)) >> 16;
21102774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXPSF_CTRL + 2, value16);
21112774f206SBjoern A. Zeeb 	value16 = 0;
21122774f206SBjoern A. Zeeb 	value16 = BIT_SET_RXPSF_PKTLENTHR(value16, 1);
21132774f206SBjoern A. Zeeb 	value16 |= BIT_RXPSF_CTRLEN | BIT_RXPSF_VHTCHKEN | BIT_RXPSF_HTCHKEN
21142774f206SBjoern A. Zeeb 		| BIT_RXPSF_OFDMCHKEN | BIT_RXPSF_CCKCHKEN
21152774f206SBjoern A. Zeeb 		| BIT_RXPSF_OFDMRST;
21162774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXPSF_CTRL, value16);
21172774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXPSF_TYPE_CTRL, 0xFFFFFFFF);
21182774f206SBjoern A. Zeeb 	/* rx ignore configuration */
21192774f206SBjoern A. Zeeb 	value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL);
21202774f206SBjoern A. Zeeb 	value16 &= ~(BIT_RXPSF_MHCHKEN | BIT_RXPSF_CCKRST |
21212774f206SBjoern A. Zeeb 		     BIT_RXPSF_CONT_ERRCHKEN);
21222774f206SBjoern A. Zeeb 	value16 = BIT_SET_RXPSF_ERRTHR(value16, 0x07);
21232774f206SBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXPSF_CTRL, value16);
21242774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL,
21252774f206SBjoern A. Zeeb 		       BIT_DIS_CHK_VHTSIGB_CRC);
21262774f206SBjoern A. Zeeb 
21272774f206SBjoern A. Zeeb 	/* Interrupt migration configuration */
21282774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG);
21292774f206SBjoern A. Zeeb 
21302774f206SBjoern A. Zeeb 	return 0;
21312774f206SBjoern A. Zeeb }
21322774f206SBjoern A. Zeeb 
21332774f206SBjoern A. Zeeb #define FWCD_SIZE_REG_8822C 0x2000
21342774f206SBjoern A. Zeeb #define FWCD_SIZE_DMEM_8822C 0x10000
21352774f206SBjoern A. Zeeb #define FWCD_SIZE_IMEM_8822C 0x10000
21362774f206SBjoern A. Zeeb #define FWCD_SIZE_EMEM_8822C 0x20000
21372774f206SBjoern A. Zeeb #define FWCD_SIZE_ROM_8822C 0x10000
21382774f206SBjoern A. Zeeb 
21392774f206SBjoern A. Zeeb static const u32 __fwcd_segs_8822c[] = {
21402774f206SBjoern A. Zeeb 	FWCD_SIZE_REG_8822C,
21412774f206SBjoern A. Zeeb 	FWCD_SIZE_DMEM_8822C,
21422774f206SBjoern A. Zeeb 	FWCD_SIZE_IMEM_8822C,
21432774f206SBjoern A. Zeeb 	FWCD_SIZE_EMEM_8822C,
21442774f206SBjoern A. Zeeb 	FWCD_SIZE_ROM_8822C,
21452774f206SBjoern A. Zeeb };
21462774f206SBjoern A. Zeeb 
21472774f206SBjoern A. Zeeb static const struct rtw_fwcd_segs rtw8822c_fwcd_segs = {
21482774f206SBjoern A. Zeeb 	.segs = __fwcd_segs_8822c,
21492774f206SBjoern A. Zeeb 	.num = ARRAY_SIZE(__fwcd_segs_8822c),
21502774f206SBjoern A. Zeeb };
21512774f206SBjoern A. Zeeb 
21522774f206SBjoern A. Zeeb static int rtw8822c_dump_fw_crash(struct rtw_dev *rtwdev)
21532774f206SBjoern A. Zeeb {
21542774f206SBjoern A. Zeeb #define __dump_fw_8822c(_dev, _mem) \
21552774f206SBjoern A. Zeeb 	rtw_dump_fw(_dev, OCPBASE_ ## _mem ## _88XX, \
21562774f206SBjoern A. Zeeb 		    FWCD_SIZE_ ## _mem ## _8822C, RTW_FWCD_ ## _mem)
21572774f206SBjoern A. Zeeb 	int ret;
21582774f206SBjoern A. Zeeb 
21592774f206SBjoern A. Zeeb 	ret = rtw_dump_reg(rtwdev, 0x0, FWCD_SIZE_REG_8822C);
21602774f206SBjoern A. Zeeb 	if (ret)
21612774f206SBjoern A. Zeeb 		return ret;
21622774f206SBjoern A. Zeeb 	ret = __dump_fw_8822c(rtwdev, DMEM);
21632774f206SBjoern A. Zeeb 	if (ret)
21642774f206SBjoern A. Zeeb 		return ret;
21652774f206SBjoern A. Zeeb 	ret = __dump_fw_8822c(rtwdev, IMEM);
21662774f206SBjoern A. Zeeb 	if (ret)
21672774f206SBjoern A. Zeeb 		return ret;
21682774f206SBjoern A. Zeeb 	ret = __dump_fw_8822c(rtwdev, EMEM);
21692774f206SBjoern A. Zeeb 	if (ret)
21702774f206SBjoern A. Zeeb 		return ret;
21712774f206SBjoern A. Zeeb 	ret = __dump_fw_8822c(rtwdev, ROM);
21722774f206SBjoern A. Zeeb 	if (ret)
21732774f206SBjoern A. Zeeb 		return ret;
21742774f206SBjoern A. Zeeb 
21752774f206SBjoern A. Zeeb 	return 0;
21762774f206SBjoern A. Zeeb 
21772774f206SBjoern A. Zeeb #undef __dump_fw_8822c
21782774f206SBjoern A. Zeeb }
21792774f206SBjoern A. Zeeb 
21802774f206SBjoern A. Zeeb static void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable)
21812774f206SBjoern A. Zeeb {
21822774f206SBjoern A. Zeeb 	if (enable) {
21832774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x1);
21842774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANAPAR_A, BIT_ANAPAR_UPDATE, 0x1);
21852774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANAPAR_B, BIT_ANAPAR_UPDATE, 0x1);
21862774f206SBjoern A. Zeeb 	} else {
21872774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x0);
21882774f206SBjoern A. Zeeb 	}
21892774f206SBjoern A. Zeeb }
21902774f206SBjoern A. Zeeb 
21912774f206SBjoern A. Zeeb static void rtw8822c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
21922774f206SBjoern A. Zeeb {
21932774f206SBjoern A. Zeeb #define RF18_BAND_MASK		(BIT(16) | BIT(9) | BIT(8))
21942774f206SBjoern A. Zeeb #define RF18_BAND_2G		(0)
21952774f206SBjoern A. Zeeb #define RF18_BAND_5G		(BIT(16) | BIT(8))
21962774f206SBjoern A. Zeeb #define RF18_CHANNEL_MASK	(MASKBYTE0)
21972774f206SBjoern A. Zeeb #define RF18_RFSI_MASK		(BIT(18) | BIT(17))
21982774f206SBjoern A. Zeeb #define RF18_RFSI_GE_CH80	(BIT(17))
21992774f206SBjoern A. Zeeb #define RF18_RFSI_GT_CH140	(BIT(18))
22002774f206SBjoern A. Zeeb #define RF18_BW_MASK		(BIT(13) | BIT(12))
22012774f206SBjoern A. Zeeb #define RF18_BW_20M		(BIT(13) | BIT(12))
22022774f206SBjoern A. Zeeb #define RF18_BW_40M		(BIT(13))
22032774f206SBjoern A. Zeeb #define RF18_BW_80M		(BIT(12))
22042774f206SBjoern A. Zeeb 
22052774f206SBjoern A. Zeeb 	u32 rf_reg18 = 0;
22062774f206SBjoern A. Zeeb 	u32 rf_rxbb = 0;
22072774f206SBjoern A. Zeeb 
22084f3b2bbaSBjoern A. Zeeb #if defined(__linux__)
22092774f206SBjoern A. Zeeb 	rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
22104f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__)
22114f3b2bbaSBjoern A. Zeeb 	rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
22124f3b2bbaSBjoern A. Zeeb #endif
22132774f206SBjoern A. Zeeb 
22142774f206SBjoern A. Zeeb 	rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
22152774f206SBjoern A. Zeeb 		      RF18_BW_MASK);
22162774f206SBjoern A. Zeeb 
22172774f206SBjoern A. Zeeb 	rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G);
22182774f206SBjoern A. Zeeb 	rf_reg18 |= (channel & RF18_CHANNEL_MASK);
22192774f206SBjoern A. Zeeb 	if (IS_CH_5G_BAND_4(channel))
22202774f206SBjoern A. Zeeb 		rf_reg18 |= RF18_RFSI_GT_CH140;
22212774f206SBjoern A. Zeeb 	else if (IS_CH_5G_BAND_3(channel))
22222774f206SBjoern A. Zeeb 		rf_reg18 |= RF18_RFSI_GE_CH80;
22232774f206SBjoern A. Zeeb 
22242774f206SBjoern A. Zeeb 	switch (bw) {
22252774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_5:
22262774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_10:
22272774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_20:
22282774f206SBjoern A. Zeeb 	default:
22292774f206SBjoern A. Zeeb 		rf_reg18 |= RF18_BW_20M;
22302774f206SBjoern A. Zeeb 		rf_rxbb = 0x18;
22312774f206SBjoern A. Zeeb 		break;
22322774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_40:
22332774f206SBjoern A. Zeeb 		/* RF bandwidth */
22342774f206SBjoern A. Zeeb 		rf_reg18 |= RF18_BW_40M;
22352774f206SBjoern A. Zeeb 		rf_rxbb = 0x10;
22362774f206SBjoern A. Zeeb 		break;
22372774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_80:
22382774f206SBjoern A. Zeeb 		rf_reg18 |= RF18_BW_80M;
22392774f206SBjoern A. Zeeb 		rf_rxbb = 0x8;
22402774f206SBjoern A. Zeeb 		break;
22412774f206SBjoern A. Zeeb 	}
22422774f206SBjoern A. Zeeb 
22432774f206SBjoern A. Zeeb 	rtw8822c_rstb_3wire(rtwdev, false);
22442774f206SBjoern A. Zeeb 
22452774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x01);
22462774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, 0x1f, 0x12);
22472774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, 0xfffff, rf_rxbb);
22482774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x00);
22492774f206SBjoern A. Zeeb 
22502774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x01);
22512774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWA, 0x1f, 0x12);
22522774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWD0, 0xfffff, rf_rxbb);
22532774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x00);
22542774f206SBjoern A. Zeeb 
22552774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_reg18);
22562774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_reg18);
22572774f206SBjoern A. Zeeb 
22582774f206SBjoern A. Zeeb 	rtw8822c_rstb_3wire(rtwdev, true);
22592774f206SBjoern A. Zeeb }
22602774f206SBjoern A. Zeeb 
22612774f206SBjoern A. Zeeb static void rtw8822c_toggle_igi(struct rtw_dev *rtwdev)
22622774f206SBjoern A. Zeeb {
22632774f206SBjoern A. Zeeb 	u32 igi;
22642774f206SBjoern A. Zeeb 
22652774f206SBjoern A. Zeeb 	igi = rtw_read32_mask(rtwdev, REG_RXIGI, 0x7f);
22662774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi - 2);
22672774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi - 2);
22682774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi);
22692774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi);
22702774f206SBjoern A. Zeeb }
22712774f206SBjoern A. Zeeb 
22722774f206SBjoern A. Zeeb static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
22732774f206SBjoern A. Zeeb 				    u8 primary_ch_idx)
22742774f206SBjoern A. Zeeb {
22752774f206SBjoern A. Zeeb 	if (IS_CH_2G_BAND(channel)) {
22762774f206SBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT);
22772774f206SBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_TXF4, BIT(20));
22782774f206SBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
22792774f206SBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN);
22802774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0xF);
22812774f206SBjoern A. Zeeb 
22822774f206SBjoern A. Zeeb 		switch (bw) {
22832774f206SBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_20:
22842774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK,
22852774f206SBjoern A. Zeeb 					 0x5);
22862774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK,
22872774f206SBjoern A. Zeeb 					 0x5);
22882774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM,
22892774f206SBjoern A. Zeeb 					 0x6);
22902774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM,
22912774f206SBjoern A. Zeeb 					 0x6);
22922774f206SBjoern A. Zeeb 			break;
22932774f206SBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_40:
22942774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK,
22952774f206SBjoern A. Zeeb 					 0x4);
22962774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK,
22972774f206SBjoern A. Zeeb 					 0x4);
22982774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM,
22992774f206SBjoern A. Zeeb 					 0x0);
23002774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM,
23012774f206SBjoern A. Zeeb 					 0x0);
23022774f206SBjoern A. Zeeb 			break;
23032774f206SBjoern A. Zeeb 		}
23042774f206SBjoern A. Zeeb 		if (channel == 13 || channel == 14)
23052774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x969);
23062774f206SBjoern A. Zeeb 		else if (channel == 11 || channel == 12)
23072774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x96a);
23082774f206SBjoern A. Zeeb 		else
23092774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x9aa);
23102774f206SBjoern A. Zeeb 		if (channel == 14) {
23112774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x3da0);
23122774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD,
23132774f206SBjoern A. Zeeb 					 0x4962c931);
23142774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x6aa3);
23152774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xaa7b);
23162774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xf3d7);
23172774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 0x0);
23182774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD,
23192774f206SBjoern A. Zeeb 					 0xff012455);
23202774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 0xffff);
23212774f206SBjoern A. Zeeb 		} else {
23222774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x5284);
23232774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD,
23242774f206SBjoern A. Zeeb 					 0x3e18fec8);
23252774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x0a88);
23262774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xacc4);
23272774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xc8b2);
23282774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD,
23292774f206SBjoern A. Zeeb 					 0x00faf0de);
23302774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD,
23312774f206SBjoern A. Zeeb 					 0x00122344);
23322774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD,
23332774f206SBjoern A. Zeeb 					 0x0fffffff);
23342774f206SBjoern A. Zeeb 		}
23352774f206SBjoern A. Zeeb 		if (channel == 13)
23362774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3);
23372774f206SBjoern A. Zeeb 		else
23382774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x1);
23392774f206SBjoern A. Zeeb 	} else if (IS_CH_5G_BAND(channel)) {
23402774f206SBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN);
23412774f206SBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
23422774f206SBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT);
23432774f206SBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_TXF4, BIT(20));
23442774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22);
23452774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3);
23462774f206SBjoern A. Zeeb 		if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) {
23472774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM,
23482774f206SBjoern A. Zeeb 					 0x1);
23492774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM,
23502774f206SBjoern A. Zeeb 					 0x1);
23512774f206SBjoern A. Zeeb 		} else if (IS_CH_5G_BAND_3(channel)) {
23522774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM,
23532774f206SBjoern A. Zeeb 					 0x2);
23542774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM,
23552774f206SBjoern A. Zeeb 					 0x2);
23562774f206SBjoern A. Zeeb 		} else if (IS_CH_5G_BAND_4(channel)) {
23572774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM,
23582774f206SBjoern A. Zeeb 					 0x3);
23592774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM,
23602774f206SBjoern A. Zeeb 					 0x3);
23612774f206SBjoern A. Zeeb 		}
23622774f206SBjoern A. Zeeb 
23632774f206SBjoern A. Zeeb 		if (channel >= 36 && channel <= 51)
23642774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x494);
23652774f206SBjoern A. Zeeb 		else if (channel >= 52 && channel <= 55)
23662774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x493);
23672774f206SBjoern A. Zeeb 		else if (channel >= 56 && channel <= 111)
23682774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x453);
23692774f206SBjoern A. Zeeb 		else if (channel >= 112 && channel <= 119)
23702774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x452);
23712774f206SBjoern A. Zeeb 		else if (channel >= 120 && channel <= 172)
23722774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x412);
23732774f206SBjoern A. Zeeb 		else if (channel >= 173 && channel <= 177)
23742774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x411);
23752774f206SBjoern A. Zeeb 	}
23762774f206SBjoern A. Zeeb 
23772774f206SBjoern A. Zeeb 	switch (bw) {
23782774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_20:
23792774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x19B);
23802774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0);
23812774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x0);
23822774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x7);
23832774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x6);
23842774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0);
23852774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1);
23862774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0);
23872774f206SBjoern A. Zeeb 		break;
23882774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_40:
23892774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4),
23902774f206SBjoern A. Zeeb 				 (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0));
23912774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x5);
23922774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0);
23932774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00,
23942774f206SBjoern A. Zeeb 				 (primary_ch_idx | (primary_ch_idx << 4)));
23952774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x1);
23962774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1);
23972774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1);
23982774f206SBjoern A. Zeeb 		break;
23992774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_80:
24002774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0xa);
24012774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0);
24022774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00,
24032774f206SBjoern A. Zeeb 				 (primary_ch_idx | (primary_ch_idx << 4)));
24042774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x6);
24052774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1);
24062774f206SBjoern A. Zeeb 		break;
24072774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_5:
24082774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB);
24092774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0);
24102774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x1);
24112774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x4);
24122774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x4);
24132774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0);
24142774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1);
24152774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0);
24162774f206SBjoern A. Zeeb 		break;
24172774f206SBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_10:
24182774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB);
24192774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0);
24202774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x2);
24212774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x6);
24222774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x5);
24232774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0);
24242774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1);
24252774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0);
24262774f206SBjoern A. Zeeb 		break;
24272774f206SBjoern A. Zeeb 	}
24282774f206SBjoern A. Zeeb }
24292774f206SBjoern A. Zeeb 
24302774f206SBjoern A. Zeeb static void rtw8822c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
24312774f206SBjoern A. Zeeb 				 u8 primary_chan_idx)
24322774f206SBjoern A. Zeeb {
24332774f206SBjoern A. Zeeb 	rtw8822c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
24342774f206SBjoern A. Zeeb 	rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
24352774f206SBjoern A. Zeeb 	rtw8822c_set_channel_rf(rtwdev, channel, bw);
24362774f206SBjoern A. Zeeb 	rtw8822c_toggle_igi(rtwdev);
24372774f206SBjoern A. Zeeb }
24382774f206SBjoern A. Zeeb 
24392774f206SBjoern A. Zeeb static void rtw8822c_config_cck_rx_path(struct rtw_dev *rtwdev, u8 rx_path)
24402774f206SBjoern A. Zeeb {
24412774f206SBjoern A. Zeeb 	if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) {
24422774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x0);
24432774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x0);
24442774f206SBjoern A. Zeeb 	} else if (rx_path == BB_PATH_AB) {
24452774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x1);
24462774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x1);
24472774f206SBjoern A. Zeeb 	}
24482774f206SBjoern A. Zeeb 
24492774f206SBjoern A. Zeeb 	if (rx_path == BB_PATH_A)
24502774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x0);
24512774f206SBjoern A. Zeeb 	else if (rx_path == BB_PATH_B)
24522774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x5);
24532774f206SBjoern A. Zeeb 	else if (rx_path == BB_PATH_AB)
24542774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x1);
24552774f206SBjoern A. Zeeb }
24562774f206SBjoern A. Zeeb 
24572774f206SBjoern A. Zeeb static void rtw8822c_config_ofdm_rx_path(struct rtw_dev *rtwdev, u8 rx_path)
24582774f206SBjoern A. Zeeb {
24592774f206SBjoern A. Zeeb 	if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) {
24602774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x0);
24612774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x0);
24622774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x0);
24632774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x0);
24642774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x0);
24652774f206SBjoern A. Zeeb 	} else if (rx_path == BB_PATH_AB) {
24662774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x1);
24672774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x1);
24682774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x1);
24692774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x1);
24702774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x1);
24712774f206SBjoern A. Zeeb 	}
24722774f206SBjoern A. Zeeb 
24732774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x824, 0x0f000000, rx_path);
24742774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x824, 0x000f0000, rx_path);
24752774f206SBjoern A. Zeeb }
24762774f206SBjoern A. Zeeb 
24772774f206SBjoern A. Zeeb static void rtw8822c_config_rx_path(struct rtw_dev *rtwdev, u8 rx_path)
24782774f206SBjoern A. Zeeb {
24792774f206SBjoern A. Zeeb 	rtw8822c_config_cck_rx_path(rtwdev, rx_path);
24802774f206SBjoern A. Zeeb 	rtw8822c_config_ofdm_rx_path(rtwdev, rx_path);
24812774f206SBjoern A. Zeeb }
24822774f206SBjoern A. Zeeb 
24832774f206SBjoern A. Zeeb static void rtw8822c_config_cck_tx_path(struct rtw_dev *rtwdev, u8 tx_path,
24842774f206SBjoern A. Zeeb 					bool is_tx2_path)
24852774f206SBjoern A. Zeeb {
24862774f206SBjoern A. Zeeb 	if (tx_path == BB_PATH_A) {
24872774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8);
24882774f206SBjoern A. Zeeb 	} else if (tx_path == BB_PATH_B) {
24892774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x4);
24902774f206SBjoern A. Zeeb 	} else {
24912774f206SBjoern A. Zeeb 		if (is_tx2_path)
24922774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0xc);
24932774f206SBjoern A. Zeeb 		else
24942774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8);
24952774f206SBjoern A. Zeeb 	}
24962774f206SBjoern A. Zeeb 	rtw8822c_bb_reset(rtwdev);
24972774f206SBjoern A. Zeeb }
24982774f206SBjoern A. Zeeb 
24992774f206SBjoern A. Zeeb static void rtw8822c_config_ofdm_tx_path(struct rtw_dev *rtwdev, u8 tx_path,
25002774f206SBjoern A. Zeeb 					 enum rtw_bb_path tx_path_sel_1ss)
25012774f206SBjoern A. Zeeb {
25022774f206SBjoern A. Zeeb 	if (tx_path == BB_PATH_A) {
25032774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x11);
25042774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0);
25052774f206SBjoern A. Zeeb 	} else if (tx_path == BB_PATH_B) {
25062774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x12);
25072774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0);
25082774f206SBjoern A. Zeeb 	} else {
25092774f206SBjoern A. Zeeb 		if (tx_path_sel_1ss == BB_PATH_AB) {
25102774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x33);
25112774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0404);
25122774f206SBjoern A. Zeeb 		} else if (tx_path_sel_1ss == BB_PATH_B) {
25132774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x32);
25142774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400);
25152774f206SBjoern A. Zeeb 		} else if (tx_path_sel_1ss == BB_PATH_A) {
25162774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x31);
25172774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400);
25182774f206SBjoern A. Zeeb 		}
25192774f206SBjoern A. Zeeb 	}
25202774f206SBjoern A. Zeeb 	rtw8822c_bb_reset(rtwdev);
25212774f206SBjoern A. Zeeb }
25222774f206SBjoern A. Zeeb 
25232774f206SBjoern A. Zeeb static void rtw8822c_config_tx_path(struct rtw_dev *rtwdev, u8 tx_path,
25242774f206SBjoern A. Zeeb 				    enum rtw_bb_path tx_path_sel_1ss,
25252774f206SBjoern A. Zeeb 				    enum rtw_bb_path tx_path_cck,
25262774f206SBjoern A. Zeeb 				    bool is_tx2_path)
25272774f206SBjoern A. Zeeb {
25282774f206SBjoern A. Zeeb 	rtw8822c_config_cck_tx_path(rtwdev, tx_path_cck, is_tx2_path);
25292774f206SBjoern A. Zeeb 	rtw8822c_config_ofdm_tx_path(rtwdev, tx_path, tx_path_sel_1ss);
25302774f206SBjoern A. Zeeb 	rtw8822c_bb_reset(rtwdev);
25312774f206SBjoern A. Zeeb }
25322774f206SBjoern A. Zeeb 
25332774f206SBjoern A. Zeeb static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
25342774f206SBjoern A. Zeeb 				     u8 rx_path, bool is_tx2_path)
25352774f206SBjoern A. Zeeb {
25362774f206SBjoern A. Zeeb 	if ((tx_path | rx_path) & BB_PATH_A)
25372774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x33312);
25382774f206SBjoern A. Zeeb 	else
25392774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x11111);
25402774f206SBjoern A. Zeeb 	if ((tx_path | rx_path) & BB_PATH_B)
25412774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x33312);
25422774f206SBjoern A. Zeeb 	else
25432774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x11111);
25442774f206SBjoern A. Zeeb 
25452774f206SBjoern A. Zeeb 	rtw8822c_config_rx_path(rtwdev, rx_path);
25462774f206SBjoern A. Zeeb 	rtw8822c_config_tx_path(rtwdev, tx_path, BB_PATH_A, BB_PATH_A,
25472774f206SBjoern A. Zeeb 				is_tx2_path);
25482774f206SBjoern A. Zeeb 
25492774f206SBjoern A. Zeeb 	rtw8822c_toggle_igi(rtwdev);
25502774f206SBjoern A. Zeeb }
25512774f206SBjoern A. Zeeb 
25522774f206SBjoern A. Zeeb static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
25532774f206SBjoern A. Zeeb 				   struct rtw_rx_pkt_stat *pkt_stat)
25542774f206SBjoern A. Zeeb {
25552774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
25562774f206SBjoern A. Zeeb 	u8 l_bnd, u_bnd;
25572774f206SBjoern A. Zeeb 	u8 gain_a, gain_b;
25582774f206SBjoern A. Zeeb 	s8 rx_power[RTW_RF_PATH_MAX];
25592774f206SBjoern A. Zeeb 	s8 min_rx_power = -120;
25602774f206SBjoern A. Zeeb 	u8 rssi;
25612774f206SBjoern A. Zeeb 	u8 channel;
25622774f206SBjoern A. Zeeb 	int path;
25632774f206SBjoern A. Zeeb 
25642774f206SBjoern A. Zeeb 	rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status);
25652774f206SBjoern A. Zeeb 	rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status);
25662774f206SBjoern A. Zeeb 	l_bnd = dm_info->cck_gi_l_bnd;
25672774f206SBjoern A. Zeeb 	u_bnd = dm_info->cck_gi_u_bnd;
25682774f206SBjoern A. Zeeb 	gain_a = GET_PHY_STAT_P0_GAIN_A(phy_status);
25692774f206SBjoern A. Zeeb 	gain_b = GET_PHY_STAT_P0_GAIN_B(phy_status);
25702774f206SBjoern A. Zeeb 	if (gain_a < l_bnd)
25712774f206SBjoern A. Zeeb 		rx_power[RF_PATH_A] += (l_bnd - gain_a) << 1;
25722774f206SBjoern A. Zeeb 	else if (gain_a > u_bnd)
25732774f206SBjoern A. Zeeb 		rx_power[RF_PATH_A] -= (gain_a - u_bnd) << 1;
25742774f206SBjoern A. Zeeb 	if (gain_b < l_bnd)
25752774f206SBjoern A. Zeeb 		rx_power[RF_PATH_B] += (l_bnd - gain_b) << 1;
25762774f206SBjoern A. Zeeb 	else if (gain_b > u_bnd)
25772774f206SBjoern A. Zeeb 		rx_power[RF_PATH_B] -= (gain_b - u_bnd) << 1;
25782774f206SBjoern A. Zeeb 
25792774f206SBjoern A. Zeeb 	rx_power[RF_PATH_A] -= 110;
25802774f206SBjoern A. Zeeb 	rx_power[RF_PATH_B] -= 110;
25812774f206SBjoern A. Zeeb 
25822774f206SBjoern A. Zeeb 	channel = GET_PHY_STAT_P0_CHANNEL(phy_status);
2583*a0ccc12fSBjoern A. Zeeb 	if (channel != 0)
25842774f206SBjoern A. Zeeb 		rtw_set_rx_freq_band(pkt_stat, channel);
2585*a0ccc12fSBjoern A. Zeeb 	else
2586*a0ccc12fSBjoern A. Zeeb 		pkt_stat->channel_invalid = true;
25872774f206SBjoern A. Zeeb 
25882774f206SBjoern A. Zeeb 	pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A];
25892774f206SBjoern A. Zeeb 	pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B];
25902774f206SBjoern A. Zeeb 
25912774f206SBjoern A. Zeeb 	for (path = 0; path <= rtwdev->hal.rf_path_num; path++) {
25922774f206SBjoern A. Zeeb 		rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1);
25932774f206SBjoern A. Zeeb 		dm_info->rssi[path] = rssi;
25942774f206SBjoern A. Zeeb 	}
25952774f206SBjoern A. Zeeb 
25962774f206SBjoern A. Zeeb 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
25972774f206SBjoern A. Zeeb 	pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
25982774f206SBjoern A. Zeeb 	pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
25992774f206SBjoern A. Zeeb 				     min_rx_power);
26002774f206SBjoern A. Zeeb }
26012774f206SBjoern A. Zeeb 
26022774f206SBjoern A. Zeeb static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
26032774f206SBjoern A. Zeeb 				   struct rtw_rx_pkt_stat *pkt_stat)
26042774f206SBjoern A. Zeeb {
26052774f206SBjoern A. Zeeb 	struct rtw_path_div *p_div = &rtwdev->dm_path_div;
26062774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
26072774f206SBjoern A. Zeeb 	u8 rxsc, bw;
26082774f206SBjoern A. Zeeb 	s8 min_rx_power = -120;
26092774f206SBjoern A. Zeeb 	s8 rx_evm;
26102774f206SBjoern A. Zeeb 	u8 evm_dbm = 0;
26112774f206SBjoern A. Zeeb 	u8 rssi;
26122774f206SBjoern A. Zeeb 	int path;
26132774f206SBjoern A. Zeeb 	u8 channel;
26142774f206SBjoern A. Zeeb 
26152774f206SBjoern A. Zeeb 	if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
26162774f206SBjoern A. Zeeb 		rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
26172774f206SBjoern A. Zeeb 	else
26182774f206SBjoern A. Zeeb 		rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
26192774f206SBjoern A. Zeeb 
2620*a0ccc12fSBjoern A. Zeeb 	if (rxsc == 0)
2621*a0ccc12fSBjoern A. Zeeb 		bw = rtwdev->hal.current_band_width;
2622*a0ccc12fSBjoern A. Zeeb 	else if (rxsc >= 1 && rxsc <= 8)
26232774f206SBjoern A. Zeeb 		bw = RTW_CHANNEL_WIDTH_20;
2624*a0ccc12fSBjoern A. Zeeb 	else if (rxsc >= 9 && rxsc <= 12)
2625*a0ccc12fSBjoern A. Zeeb 		bw = RTW_CHANNEL_WIDTH_40;
2626*a0ccc12fSBjoern A. Zeeb 	else
2627*a0ccc12fSBjoern A. Zeeb 		bw = RTW_CHANNEL_WIDTH_80;
26282774f206SBjoern A. Zeeb 
26292774f206SBjoern A. Zeeb 	channel = GET_PHY_STAT_P1_CHANNEL(phy_status);
26302774f206SBjoern A. Zeeb 	rtw_set_rx_freq_band(pkt_stat, channel);
26312774f206SBjoern A. Zeeb 
26322774f206SBjoern A. Zeeb 	pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
26332774f206SBjoern A. Zeeb 	pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110;
26342774f206SBjoern A. Zeeb 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2);
26352774f206SBjoern A. Zeeb 	pkt_stat->bw = bw;
26362774f206SBjoern A. Zeeb 	pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A],
26372774f206SBjoern A. Zeeb 				      pkt_stat->rx_power[RF_PATH_B],
26382774f206SBjoern A. Zeeb 				      min_rx_power);
26392774f206SBjoern A. Zeeb 
26402774f206SBjoern A. Zeeb 	dm_info->curr_rx_rate = pkt_stat->rate;
26412774f206SBjoern A. Zeeb 
26422774f206SBjoern A. Zeeb 	pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
26432774f206SBjoern A. Zeeb 	pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status);
26442774f206SBjoern A. Zeeb 
26452774f206SBjoern A. Zeeb 	pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
26462774f206SBjoern A. Zeeb 	pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status);
26472774f206SBjoern A. Zeeb 
26482774f206SBjoern A. Zeeb 	pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
26492774f206SBjoern A. Zeeb 	pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status);
26502774f206SBjoern A. Zeeb 
26512774f206SBjoern A. Zeeb 	for (path = 0; path <= rtwdev->hal.rf_path_num; path++) {
26522774f206SBjoern A. Zeeb 		rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1);
26532774f206SBjoern A. Zeeb 		dm_info->rssi[path] = rssi;
26542774f206SBjoern A. Zeeb 		if (path == RF_PATH_A) {
26552774f206SBjoern A. Zeeb 			p_div->path_a_sum += rssi;
26562774f206SBjoern A. Zeeb 			p_div->path_a_cnt++;
26572774f206SBjoern A. Zeeb 		} else if (path == RF_PATH_B) {
26582774f206SBjoern A. Zeeb 			p_div->path_b_sum += rssi;
26592774f206SBjoern A. Zeeb 			p_div->path_b_cnt++;
26602774f206SBjoern A. Zeeb 		}
26612774f206SBjoern A. Zeeb 		dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1;
26622774f206SBjoern A. Zeeb 		dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1;
26632774f206SBjoern A. Zeeb 
26642774f206SBjoern A. Zeeb 		rx_evm = pkt_stat->rx_evm[path];
26652774f206SBjoern A. Zeeb 
26662774f206SBjoern A. Zeeb 		if (rx_evm < 0) {
26672774f206SBjoern A. Zeeb 			if (rx_evm == S8_MIN)
26682774f206SBjoern A. Zeeb 				evm_dbm = 0;
26692774f206SBjoern A. Zeeb 			else
26702774f206SBjoern A. Zeeb 				evm_dbm = ((u8)-rx_evm >> 1);
26712774f206SBjoern A. Zeeb 		}
26722774f206SBjoern A. Zeeb 		dm_info->rx_evm_dbm[path] = evm_dbm;
26732774f206SBjoern A. Zeeb 	}
26742774f206SBjoern A. Zeeb 	rtw_phy_parsing_cfo(rtwdev, pkt_stat);
26752774f206SBjoern A. Zeeb }
26762774f206SBjoern A. Zeeb 
26772774f206SBjoern A. Zeeb static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
26782774f206SBjoern A. Zeeb 			     struct rtw_rx_pkt_stat *pkt_stat)
26792774f206SBjoern A. Zeeb {
26802774f206SBjoern A. Zeeb 	u8 page;
26812774f206SBjoern A. Zeeb 
26822774f206SBjoern A. Zeeb 	page = *phy_status & 0xf;
26832774f206SBjoern A. Zeeb 
26842774f206SBjoern A. Zeeb 	switch (page) {
26852774f206SBjoern A. Zeeb 	case 0:
26862774f206SBjoern A. Zeeb 		query_phy_status_page0(rtwdev, phy_status, pkt_stat);
26872774f206SBjoern A. Zeeb 		break;
26882774f206SBjoern A. Zeeb 	case 1:
26892774f206SBjoern A. Zeeb 		query_phy_status_page1(rtwdev, phy_status, pkt_stat);
26902774f206SBjoern A. Zeeb 		break;
26912774f206SBjoern A. Zeeb 	default:
26922774f206SBjoern A. Zeeb 		rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
26932774f206SBjoern A. Zeeb 		return;
26942774f206SBjoern A. Zeeb 	}
26952774f206SBjoern A. Zeeb }
26962774f206SBjoern A. Zeeb 
26972774f206SBjoern A. Zeeb static void
26982774f206SBjoern A. Zeeb rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck,
26992774f206SBjoern A. Zeeb 				u8 *tx_pwr_ref_ofdm)
27002774f206SBjoern A. Zeeb {
27012774f206SBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
27022774f206SBjoern A. Zeeb 	u32 txref_cck[2] = {0x18a0, 0x41a0};
27032774f206SBjoern A. Zeeb 	u32 txref_ofdm[2] = {0x18e8, 0x41e8};
27042774f206SBjoern A. Zeeb 	u8 path;
27052774f206SBjoern A. Zeeb 
27062774f206SBjoern A. Zeeb 	for (path = 0; path < hal->rf_path_num; path++) {
27072774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0);
27082774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, txref_cck[path], 0x7f0000,
27092774f206SBjoern A. Zeeb 				 tx_pwr_ref_cck[path]);
27102774f206SBjoern A. Zeeb 	}
27112774f206SBjoern A. Zeeb 	for (path = 0; path < hal->rf_path_num; path++) {
27122774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0);
27132774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, txref_ofdm[path], 0x1fc00,
27142774f206SBjoern A. Zeeb 				 tx_pwr_ref_ofdm[path]);
27152774f206SBjoern A. Zeeb 	}
27162774f206SBjoern A. Zeeb }
27172774f206SBjoern A. Zeeb 
27182774f206SBjoern A. Zeeb static void rtw8822c_set_tx_power_diff(struct rtw_dev *rtwdev, u8 rate,
27192774f206SBjoern A. Zeeb 				       s8 *diff_idx)
27202774f206SBjoern A. Zeeb {
27212774f206SBjoern A. Zeeb 	u32 offset_txagc = 0x3a00;
27222774f206SBjoern A. Zeeb 	u8 rate_idx = rate & 0xfc;
27232774f206SBjoern A. Zeeb 	u8 pwr_idx[4];
27242774f206SBjoern A. Zeeb 	u32 phy_pwr_idx;
27252774f206SBjoern A. Zeeb 	int i;
27262774f206SBjoern A. Zeeb 
27272774f206SBjoern A. Zeeb 	for (i = 0; i < 4; i++)
27282774f206SBjoern A. Zeeb 		pwr_idx[i] = diff_idx[i] & 0x7f;
27292774f206SBjoern A. Zeeb 
27302774f206SBjoern A. Zeeb 	phy_pwr_idx = pwr_idx[0] |
27312774f206SBjoern A. Zeeb 		      (pwr_idx[1] << 8) |
27322774f206SBjoern A. Zeeb 		      (pwr_idx[2] << 16) |
27332774f206SBjoern A. Zeeb 		      (pwr_idx[3] << 24);
27342774f206SBjoern A. Zeeb 
27352774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0x0);
27362774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, offset_txagc + rate_idx, MASKDWORD,
27372774f206SBjoern A. Zeeb 			 phy_pwr_idx);
27382774f206SBjoern A. Zeeb }
27392774f206SBjoern A. Zeeb 
27402774f206SBjoern A. Zeeb static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev)
27412774f206SBjoern A. Zeeb {
27422774f206SBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
27432774f206SBjoern A. Zeeb 	u8 rs, rate, j;
27442774f206SBjoern A. Zeeb 	u8 pwr_ref_cck[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATE11M],
27452774f206SBjoern A. Zeeb 			     hal->tx_pwr_tbl[RF_PATH_B][DESC_RATE11M]};
27462774f206SBjoern A. Zeeb 	u8 pwr_ref_ofdm[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATEMCS7],
27472774f206SBjoern A. Zeeb 			      hal->tx_pwr_tbl[RF_PATH_B][DESC_RATEMCS7]};
27482774f206SBjoern A. Zeeb 	s8 diff_a, diff_b;
27492774f206SBjoern A. Zeeb 	u8 pwr_a, pwr_b;
27502774f206SBjoern A. Zeeb 	s8 diff_idx[4];
27512774f206SBjoern A. Zeeb 
27522774f206SBjoern A. Zeeb 	rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm);
27532774f206SBjoern A. Zeeb 	for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
27542774f206SBjoern A. Zeeb 		for (j = 0; j < rtw_rate_size[rs]; j++) {
27552774f206SBjoern A. Zeeb 			rate = rtw_rate_section[rs][j];
27562774f206SBjoern A. Zeeb 			pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate];
27572774f206SBjoern A. Zeeb 			pwr_b = hal->tx_pwr_tbl[RF_PATH_B][rate];
27582774f206SBjoern A. Zeeb 			if (rs == 0) {
27592774f206SBjoern A. Zeeb 				diff_a = (s8)pwr_a - (s8)pwr_ref_cck[0];
27602774f206SBjoern A. Zeeb 				diff_b = (s8)pwr_b - (s8)pwr_ref_cck[1];
27612774f206SBjoern A. Zeeb 			} else {
27622774f206SBjoern A. Zeeb 				diff_a = (s8)pwr_a - (s8)pwr_ref_ofdm[0];
27632774f206SBjoern A. Zeeb 				diff_b = (s8)pwr_b - (s8)pwr_ref_ofdm[1];
27642774f206SBjoern A. Zeeb 			}
27652774f206SBjoern A. Zeeb 			diff_idx[rate % 4] = min(diff_a, diff_b);
27662774f206SBjoern A. Zeeb 			if (rate % 4 == 3)
27672774f206SBjoern A. Zeeb 				rtw8822c_set_tx_power_diff(rtwdev, rate - 3,
27682774f206SBjoern A. Zeeb 							   diff_idx);
27692774f206SBjoern A. Zeeb 		}
27702774f206SBjoern A. Zeeb 	}
27712774f206SBjoern A. Zeeb }
27722774f206SBjoern A. Zeeb 
27732774f206SBjoern A. Zeeb static int rtw8822c_set_antenna(struct rtw_dev *rtwdev,
27742774f206SBjoern A. Zeeb 				u32 antenna_tx,
27752774f206SBjoern A. Zeeb 				u32 antenna_rx)
27762774f206SBjoern A. Zeeb {
27772774f206SBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
27782774f206SBjoern A. Zeeb 
27792774f206SBjoern A. Zeeb 	switch (antenna_tx) {
27802774f206SBjoern A. Zeeb 	case BB_PATH_A:
27812774f206SBjoern A. Zeeb 	case BB_PATH_B:
27822774f206SBjoern A. Zeeb 	case BB_PATH_AB:
27832774f206SBjoern A. Zeeb 		break;
27842774f206SBjoern A. Zeeb 	default:
27859c951734SBjoern A. Zeeb 		rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
27862774f206SBjoern A. Zeeb 		return -EINVAL;
27872774f206SBjoern A. Zeeb 	}
27882774f206SBjoern A. Zeeb 
27892774f206SBjoern A. Zeeb 	/* path B only is not available for RX */
27902774f206SBjoern A. Zeeb 	switch (antenna_rx) {
27912774f206SBjoern A. Zeeb 	case BB_PATH_A:
27922774f206SBjoern A. Zeeb 	case BB_PATH_AB:
27932774f206SBjoern A. Zeeb 		break;
27942774f206SBjoern A. Zeeb 	default:
27959c951734SBjoern A. Zeeb 		rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
27962774f206SBjoern A. Zeeb 		return -EINVAL;
27972774f206SBjoern A. Zeeb 	}
27982774f206SBjoern A. Zeeb 
27992774f206SBjoern A. Zeeb 	hal->antenna_tx = antenna_tx;
28002774f206SBjoern A. Zeeb 	hal->antenna_rx = antenna_rx;
28012774f206SBjoern A. Zeeb 
28022774f206SBjoern A. Zeeb 	rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
28032774f206SBjoern A. Zeeb 
28042774f206SBjoern A. Zeeb 	return 0;
28052774f206SBjoern A. Zeeb }
28062774f206SBjoern A. Zeeb 
28072774f206SBjoern A. Zeeb static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
28082774f206SBjoern A. Zeeb {
28092774f206SBjoern A. Zeeb 	u8 ldo_pwr;
28102774f206SBjoern A. Zeeb 
28112774f206SBjoern A. Zeeb 	ldo_pwr = rtw_read8(rtwdev, REG_ANAPARLDO_POW_MAC);
28122774f206SBjoern A. Zeeb 	ldo_pwr = enable ? ldo_pwr | BIT_LDOE25_PON : ldo_pwr & ~BIT_LDOE25_PON;
28132774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr);
28142774f206SBjoern A. Zeeb }
28152774f206SBjoern A. Zeeb 
28162774f206SBjoern A. Zeeb static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev)
28172774f206SBjoern A. Zeeb {
28182774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
28192774f206SBjoern A. Zeeb 	u32 cck_enable;
28202774f206SBjoern A. Zeeb 	u32 cck_fa_cnt;
28212774f206SBjoern A. Zeeb 	u32 crc32_cnt;
28222774f206SBjoern A. Zeeb 	u32 cca32_cnt;
28232774f206SBjoern A. Zeeb 	u32 ofdm_fa_cnt;
28242774f206SBjoern A. Zeeb 	u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5;
28252774f206SBjoern A. Zeeb 	u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail,
28262774f206SBjoern A. Zeeb 	    fast_fsync, crc8_fail_vhta, mcs_fail_vht;
28272774f206SBjoern A. Zeeb 
28282774f206SBjoern A. Zeeb 	cck_enable = rtw_read32(rtwdev, REG_ENCCK) & BIT_CCK_BLK_EN;
28292774f206SBjoern A. Zeeb 	cck_fa_cnt = rtw_read16(rtwdev, REG_CCK_FACNT);
28302774f206SBjoern A. Zeeb 
28312774f206SBjoern A. Zeeb 	ofdm_fa_cnt1 = rtw_read32(rtwdev, REG_OFDM_FACNT1);
28322774f206SBjoern A. Zeeb 	ofdm_fa_cnt2 = rtw_read32(rtwdev, REG_OFDM_FACNT2);
28332774f206SBjoern A. Zeeb 	ofdm_fa_cnt3 = rtw_read32(rtwdev, REG_OFDM_FACNT3);
28342774f206SBjoern A. Zeeb 	ofdm_fa_cnt4 = rtw_read32(rtwdev, REG_OFDM_FACNT4);
28352774f206SBjoern A. Zeeb 	ofdm_fa_cnt5 = rtw_read32(rtwdev, REG_OFDM_FACNT5);
28362774f206SBjoern A. Zeeb 
28372774f206SBjoern A. Zeeb 	parity_fail	= FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt1);
28382774f206SBjoern A. Zeeb 	rate_illegal	= FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt2);
28392774f206SBjoern A. Zeeb 	crc8_fail	= FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt2);
28402774f206SBjoern A. Zeeb 	crc8_fail_vhta	= FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt3);
28412774f206SBjoern A. Zeeb 	mcs_fail	= FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt4);
28422774f206SBjoern A. Zeeb 	mcs_fail_vht	= FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt4);
28432774f206SBjoern A. Zeeb 	fast_fsync	= FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt5);
28442774f206SBjoern A. Zeeb 	sb_search_fail	= FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt5);
28452774f206SBjoern A. Zeeb 
28462774f206SBjoern A. Zeeb 	ofdm_fa_cnt = parity_fail + rate_illegal + crc8_fail + crc8_fail_vhta +
28472774f206SBjoern A. Zeeb 		      mcs_fail + mcs_fail_vht + fast_fsync + sb_search_fail;
28482774f206SBjoern A. Zeeb 
28492774f206SBjoern A. Zeeb 	dm_info->cck_fa_cnt = cck_fa_cnt;
28502774f206SBjoern A. Zeeb 	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
28512774f206SBjoern A. Zeeb 	dm_info->total_fa_cnt = ofdm_fa_cnt;
28522774f206SBjoern A. Zeeb 	dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0;
28532774f206SBjoern A. Zeeb 
28542774f206SBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, 0x2c04);
28552774f206SBjoern A. Zeeb 	dm_info->cck_ok_cnt = crc32_cnt & 0xffff;
28562774f206SBjoern A. Zeeb 	dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
28572774f206SBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, 0x2c14);
28582774f206SBjoern A. Zeeb 	dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff;
28592774f206SBjoern A. Zeeb 	dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
28602774f206SBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, 0x2c10);
28612774f206SBjoern A. Zeeb 	dm_info->ht_ok_cnt = crc32_cnt & 0xffff;
28622774f206SBjoern A. Zeeb 	dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
28632774f206SBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, 0x2c0c);
28642774f206SBjoern A. Zeeb 	dm_info->vht_ok_cnt = crc32_cnt & 0xffff;
28652774f206SBjoern A. Zeeb 	dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
28662774f206SBjoern A. Zeeb 
28672774f206SBjoern A. Zeeb 	cca32_cnt = rtw_read32(rtwdev, 0x2c08);
28682774f206SBjoern A. Zeeb 	dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16);
28692774f206SBjoern A. Zeeb 	dm_info->cck_cca_cnt = cca32_cnt & 0xffff;
28702774f206SBjoern A. Zeeb 	dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
28712774f206SBjoern A. Zeeb 	if (cck_enable)
28722774f206SBjoern A. Zeeb 		dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
28732774f206SBjoern A. Zeeb 
28742774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0);
28752774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2);
28762774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0);
28772774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 2);
28782774f206SBjoern A. Zeeb 
28792774f206SBjoern A. Zeeb 	/* disable rx clk gating to reset counters */
28802774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN);
28812774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST);
28822774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST);
28832774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN);
28842774f206SBjoern A. Zeeb }
28852774f206SBjoern A. Zeeb 
28862774f206SBjoern A. Zeeb static void rtw8822c_do_lck(struct rtw_dev *rtwdev)
28872774f206SBjoern A. Zeeb {
28882774f206SBjoern A. Zeeb 	u32 val;
28892774f206SBjoern A. Zeeb 
28902774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010);
28912774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA);
28922774f206SBjoern A. Zeeb 	fsleep(1);
28932774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000);
28942774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001);
28952774f206SBjoern A. Zeeb 	read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000,
28962774f206SBjoern A. Zeeb 			  true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000);
28972774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8);
28982774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010);
28992774f206SBjoern A. Zeeb 
29002774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
29012774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000);
29022774f206SBjoern A. Zeeb 	fsleep(1);
29032774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000);
29042774f206SBjoern A. Zeeb }
29052774f206SBjoern A. Zeeb 
29062774f206SBjoern A. Zeeb static void rtw8822c_do_iqk(struct rtw_dev *rtwdev)
29072774f206SBjoern A. Zeeb {
29082774f206SBjoern A. Zeeb 	struct rtw_iqk_para para = {0};
29092774f206SBjoern A. Zeeb 	u8 iqk_chk;
29102774f206SBjoern A. Zeeb 	int ret;
29112774f206SBjoern A. Zeeb 
29122774f206SBjoern A. Zeeb 	para.clear = 1;
29132774f206SBjoern A. Zeeb 	rtw_fw_do_iqk(rtwdev, &para);
29142774f206SBjoern A. Zeeb 
29152774f206SBjoern A. Zeeb 	ret = read_poll_timeout(rtw_read8, iqk_chk, iqk_chk == IQK_DONE_8822C,
29162774f206SBjoern A. Zeeb 				20000, 300000, false, rtwdev, REG_RPT_CIP);
29172774f206SBjoern A. Zeeb 	if (ret)
29182774f206SBjoern A. Zeeb 		rtw_warn(rtwdev, "failed to poll iqk status bit\n");
29192774f206SBjoern A. Zeeb 
29202774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_IQKSTAT, 0x0);
29212774f206SBjoern A. Zeeb }
29222774f206SBjoern A. Zeeb 
29232774f206SBjoern A. Zeeb /* for coex */
29242774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_init(struct rtw_dev *rtwdev)
29252774f206SBjoern A. Zeeb {
29262774f206SBjoern A. Zeeb 	/* enable TBTT nterrupt */
29272774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
29282774f206SBjoern A. Zeeb 
29292774f206SBjoern A. Zeeb 	/* BT report packet sample rate */
29302774f206SBjoern A. Zeeb 	/* 0x790[5:0]=0x5 */
29312774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
29322774f206SBjoern A. Zeeb 
29332774f206SBjoern A. Zeeb 	/* enable BT counter statistics */
29342774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
29352774f206SBjoern A. Zeeb 
29362774f206SBjoern A. Zeeb 	/* enable PTA (3-wire function form BT side) */
29372774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
29382774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
29392774f206SBjoern A. Zeeb 
29402774f206SBjoern A. Zeeb 	/* enable PTA (tx/rx signal form WiFi side) */
29412774f206SBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
29422774f206SBjoern A. Zeeb 	/* wl tx signal to PTA not case EDCCA */
29432774f206SBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
29442774f206SBjoern A. Zeeb 	/* GNT_BT=1 while select both */
29452774f206SBjoern A. Zeeb 	rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
29462774f206SBjoern A. Zeeb 	/* BT_CCA = ~GNT_WL_BB, not or GNT_BT_BB, LTE_Rx */
29472774f206SBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_DUMMY_PAGE4_V1, BIT_BTCCA_CTRL);
29482774f206SBjoern A. Zeeb 
29492774f206SBjoern A. Zeeb 	/* to avoid RF parameter error */
29502774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_MODOPT, 0xfffff, 0x40000);
29512774f206SBjoern A. Zeeb }
29522774f206SBjoern A. Zeeb 
29532774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
29542774f206SBjoern A. Zeeb {
29552774f206SBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
29562774f206SBjoern A. Zeeb 	struct rtw_coex_stat *coex_stat = &coex->stat;
29572774f206SBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
29582774f206SBjoern A. Zeeb 	u32 rf_0x1;
29592774f206SBjoern A. Zeeb 
29602774f206SBjoern A. Zeeb 	if (coex_stat->gnt_workaround_state == coex_stat->wl_coex_mode)
29612774f206SBjoern A. Zeeb 		return;
29622774f206SBjoern A. Zeeb 
29632774f206SBjoern A. Zeeb 	coex_stat->gnt_workaround_state = coex_stat->wl_coex_mode;
29642774f206SBjoern A. Zeeb 
29652774f206SBjoern A. Zeeb 	if ((coex_stat->kt_ver == 0 && coex->under_5g) || coex->freerun)
29662774f206SBjoern A. Zeeb 		rf_0x1 = 0x40021;
29672774f206SBjoern A. Zeeb 	else
29682774f206SBjoern A. Zeeb 		rf_0x1 = 0x40000;
29692774f206SBjoern A. Zeeb 
29702774f206SBjoern A. Zeeb 	/* BT at S1 for Shared-Ant */
29712774f206SBjoern A. Zeeb 	if (efuse->share_ant)
29722774f206SBjoern A. Zeeb 		rf_0x1 |= BIT(13);
29732774f206SBjoern A. Zeeb 
29742774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, 0x1, 0xfffff, rf_0x1);
29752774f206SBjoern A. Zeeb 
29762774f206SBjoern A. Zeeb 	/* WL-S0 2G RF TRX cannot be masked by GNT_BT
29772774f206SBjoern A. Zeeb 	 * enable "WLS0 BB chage RF mode if GNT_BT = 1" for shared-antenna type
29782774f206SBjoern A. Zeeb 	 * disable:0x1860[3] = 1, enable:0x1860[3] = 0
29792774f206SBjoern A. Zeeb 	 *
29802774f206SBjoern A. Zeeb 	 * enable "DAC off if GNT_WL = 0" for non-shared-antenna
29812774f206SBjoern A. Zeeb 	 * disable 0x1c30[22] = 0,
29822774f206SBjoern A. Zeeb 	 * enable: 0x1c30[22] = 1, 0x1c38[12] = 0, 0x1c38[28] = 1
29839c951734SBjoern A. Zeeb 	 */
29849c951734SBjoern A. Zeeb 	if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) {
29859c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_ANAPAR + 2,
29869c951734SBjoern A. Zeeb 				BIT_ANAPAR_BTPS >> 16, 0);
29879c951734SBjoern A. Zeeb 	} else {
29889c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_ANAPAR + 2,
29899c951734SBjoern A. Zeeb 				BIT_ANAPAR_BTPS >> 16, 1);
29909c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1,
29919c951734SBjoern A. Zeeb 				BIT_DAC_OFF_ENABLE, 0);
29929c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3,
29939c951734SBjoern A. Zeeb 				BIT_DAC_OFF_ENABLE, 1);
29949c951734SBjoern A. Zeeb 	}
29959c951734SBjoern A. Zeeb 
29969c951734SBjoern A. Zeeb 	/* disable WL-S1 BB chage RF mode if GNT_BT
29972774f206SBjoern A. Zeeb 	 * since RF TRx mask can do it
29982774f206SBjoern A. Zeeb 	 */
29999c951734SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_IGN_GNTBT4,
30009c951734SBjoern A. Zeeb 			BIT_PI_IGNORE_GNT_BT, 1);
30012774f206SBjoern A. Zeeb 
30022774f206SBjoern A. Zeeb 	/* disable WL-S0 BB chage RF mode if wifi is at 5G,
30032774f206SBjoern A. Zeeb 	 * or antenna path is separated
30042774f206SBjoern A. Zeeb 	 */
30059c951734SBjoern A. Zeeb 	if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) {
30069c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1,
30079c951734SBjoern A. Zeeb 				BIT_PI_IGNORE_GNT_BT, 1);
30089c951734SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_NOMASK_TXBT,
30099c951734SBjoern A. Zeeb 				BIT_NOMASK_TXBT_ENABLE, 1);
30109c951734SBjoern A. Zeeb 	} else if (coex_stat->wl_coex_mode == COEX_WLINK_5G ||
30112774f206SBjoern A. Zeeb 	    coex->under_5g || !efuse->share_ant) {
30122774f206SBjoern A. Zeeb 		if (coex_stat->kt_ver >= 3) {
30132774f206SBjoern A. Zeeb 			rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1,
30142774f206SBjoern A. Zeeb 					BIT_PI_IGNORE_GNT_BT, 0);
30152774f206SBjoern A. Zeeb 			rtw_write8_mask(rtwdev, REG_NOMASK_TXBT,
30162774f206SBjoern A. Zeeb 					BIT_NOMASK_TXBT_ENABLE, 1);
30172774f206SBjoern A. Zeeb 		} else {
30182774f206SBjoern A. Zeeb 			rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1,
30192774f206SBjoern A. Zeeb 					BIT_PI_IGNORE_GNT_BT, 1);
30202774f206SBjoern A. Zeeb 		}
30212774f206SBjoern A. Zeeb 	} else {
30222774f206SBjoern A. Zeeb 		/* shared-antenna */
30232774f206SBjoern A. Zeeb 		rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1,
30242774f206SBjoern A. Zeeb 				BIT_PI_IGNORE_GNT_BT, 0);
30252774f206SBjoern A. Zeeb 		if (coex_stat->kt_ver >= 3) {
30262774f206SBjoern A. Zeeb 			rtw_write8_mask(rtwdev, REG_NOMASK_TXBT,
30272774f206SBjoern A. Zeeb 					BIT_NOMASK_TXBT_ENABLE, 0);
30282774f206SBjoern A. Zeeb 		}
30292774f206SBjoern A. Zeeb 	}
30302774f206SBjoern A. Zeeb }
30312774f206SBjoern A. Zeeb 
30322774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
30332774f206SBjoern A. Zeeb {
30342774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0);
30352774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0);
30362774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0);
30372774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0);
30382774f206SBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0);
30392774f206SBjoern A. Zeeb }
30402774f206SBjoern A. Zeeb 
30412774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
30422774f206SBjoern A. Zeeb {
30432774f206SBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
30442774f206SBjoern A. Zeeb 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
30452774f206SBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
30462774f206SBjoern A. Zeeb 
30472774f206SBjoern A. Zeeb 	coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
30482774f206SBjoern A. Zeeb 	coex_rfe->ant_switch_polarity = 0;
30492774f206SBjoern A. Zeeb 	coex_rfe->ant_switch_exist = false;
30502774f206SBjoern A. Zeeb 	coex_rfe->ant_switch_with_bt = false;
30512774f206SBjoern A. Zeeb 	coex_rfe->ant_switch_diversity = false;
30522774f206SBjoern A. Zeeb 
30532774f206SBjoern A. Zeeb 	if (efuse->share_ant)
30542774f206SBjoern A. Zeeb 		coex_rfe->wlg_at_btg = true;
30552774f206SBjoern A. Zeeb 	else
30562774f206SBjoern A. Zeeb 		coex_rfe->wlg_at_btg = false;
30572774f206SBjoern A. Zeeb 
30582774f206SBjoern A. Zeeb 	/* disable LTE coex in wifi side */
30592774f206SBjoern A. Zeeb 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0);
30602774f206SBjoern A. Zeeb 	rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
30612774f206SBjoern A. Zeeb 	rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
30622774f206SBjoern A. Zeeb }
30632774f206SBjoern A. Zeeb 
30642774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
30652774f206SBjoern A. Zeeb {
30662774f206SBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
30672774f206SBjoern A. Zeeb 	struct rtw_coex_dm *coex_dm = &coex->dm;
30682774f206SBjoern A. Zeeb 
30692774f206SBjoern A. Zeeb 	if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
30702774f206SBjoern A. Zeeb 		return;
30712774f206SBjoern A. Zeeb 
30722774f206SBjoern A. Zeeb 	coex_dm->cur_wl_pwr_lvl = wl_pwr;
30732774f206SBjoern A. Zeeb }
30742774f206SBjoern A. Zeeb 
30752774f206SBjoern A. Zeeb static void rtw8822c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
30762774f206SBjoern A. Zeeb {
30772774f206SBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
30782774f206SBjoern A. Zeeb 	struct rtw_coex_dm *coex_dm = &coex->dm;
30792774f206SBjoern A. Zeeb 
30802774f206SBjoern A. Zeeb 	if (low_gain == coex_dm->cur_wl_rx_low_gain_en)
30812774f206SBjoern A. Zeeb 		return;
30822774f206SBjoern A. Zeeb 
30832774f206SBjoern A. Zeeb 	coex_dm->cur_wl_rx_low_gain_en = low_gain;
30842774f206SBjoern A. Zeeb 
30852774f206SBjoern A. Zeeb 	if (coex_dm->cur_wl_rx_low_gain_en) {
30862774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n");
30872774f206SBjoern A. Zeeb 
30882774f206SBjoern A. Zeeb 		/* set Rx filter corner RCK offset */
30892774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x22);
30902774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x36);
30912774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x22);
30922774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x36);
30932774f206SBjoern A. Zeeb 
30942774f206SBjoern A. Zeeb 	} else {
30952774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n");
30962774f206SBjoern A. Zeeb 
30972774f206SBjoern A. Zeeb 		/* set Rx filter corner RCK offset */
30982774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x20);
30992774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x0);
31002774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x20);
31012774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x0);
31022774f206SBjoern A. Zeeb 	}
31032774f206SBjoern A. Zeeb }
31042774f206SBjoern A. Zeeb 
31052774f206SBjoern A. Zeeb static void rtw8822c_bf_enable_bfee_su(struct rtw_dev *rtwdev,
31062774f206SBjoern A. Zeeb 				       struct rtw_vif *vif,
31072774f206SBjoern A. Zeeb 				       struct rtw_bfee *bfee)
31082774f206SBjoern A. Zeeb {
31092774f206SBjoern A. Zeeb 	u8 csi_rsc = 0;
31102774f206SBjoern A. Zeeb 	u32 tmp6dc;
31112774f206SBjoern A. Zeeb 
31122774f206SBjoern A. Zeeb 	rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
31132774f206SBjoern A. Zeeb 
31142774f206SBjoern A. Zeeb 	tmp6dc = rtw_read32(rtwdev, REG_BBPSF_CTRL) |
31152774f206SBjoern A. Zeeb 			    BIT_WMAC_USE_NDPARATE |
31162774f206SBjoern A. Zeeb 			    (csi_rsc << 13);
31172774f206SBjoern A. Zeeb 	if (vif->net_type == RTW_NET_AP_MODE)
31182774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc | BIT(12));
31192774f206SBjoern A. Zeeb 	else
31202774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc & ~BIT(12));
31212774f206SBjoern A. Zeeb 
31222774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_CSI_RRSR, 0x550);
31232774f206SBjoern A. Zeeb }
31242774f206SBjoern A. Zeeb 
31252774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee_su(struct rtw_dev *rtwdev,
31262774f206SBjoern A. Zeeb 				       struct rtw_vif *vif,
31272774f206SBjoern A. Zeeb 				       struct rtw_bfee *bfee, bool enable)
31282774f206SBjoern A. Zeeb {
31292774f206SBjoern A. Zeeb 	if (enable)
31302774f206SBjoern A. Zeeb 		rtw8822c_bf_enable_bfee_su(rtwdev, vif, bfee);
31312774f206SBjoern A. Zeeb 	else
31322774f206SBjoern A. Zeeb 		rtw_bf_remove_bfee_su(rtwdev, bfee);
31332774f206SBjoern A. Zeeb }
31342774f206SBjoern A. Zeeb 
31352774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee_mu(struct rtw_dev *rtwdev,
31362774f206SBjoern A. Zeeb 				       struct rtw_vif *vif,
31372774f206SBjoern A. Zeeb 				       struct rtw_bfee *bfee, bool enable)
31382774f206SBjoern A. Zeeb {
31392774f206SBjoern A. Zeeb 	if (enable)
31402774f206SBjoern A. Zeeb 		rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
31412774f206SBjoern A. Zeeb 	else
31422774f206SBjoern A. Zeeb 		rtw_bf_remove_bfee_mu(rtwdev, bfee);
31432774f206SBjoern A. Zeeb }
31442774f206SBjoern A. Zeeb 
31452774f206SBjoern A. Zeeb static void rtw8822c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
31462774f206SBjoern A. Zeeb 				    struct rtw_bfee *bfee, bool enable)
31472774f206SBjoern A. Zeeb {
31482774f206SBjoern A. Zeeb 	if (bfee->role == RTW_BFEE_SU)
31492774f206SBjoern A. Zeeb 		rtw8822c_bf_config_bfee_su(rtwdev, vif, bfee, enable);
31502774f206SBjoern A. Zeeb 	else if (bfee->role == RTW_BFEE_MU)
31512774f206SBjoern A. Zeeb 		rtw8822c_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
31522774f206SBjoern A. Zeeb 	else
31532774f206SBjoern A. Zeeb 		rtw_warn(rtwdev, "wrong bfee role\n");
31542774f206SBjoern A. Zeeb }
31552774f206SBjoern A. Zeeb 
31562774f206SBjoern A. Zeeb struct dpk_cfg_pair {
31572774f206SBjoern A. Zeeb 	u32 addr;
31582774f206SBjoern A. Zeeb 	u32 bitmask;
31592774f206SBjoern A. Zeeb 	u32 data;
31602774f206SBjoern A. Zeeb };
31612774f206SBjoern A. Zeeb 
31622774f206SBjoern A. Zeeb void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,
31632774f206SBjoern A. Zeeb 			    const struct rtw_table *tbl)
31642774f206SBjoern A. Zeeb {
31652774f206SBjoern A. Zeeb 	const struct dpk_cfg_pair *p = tbl->data;
31662774f206SBjoern A. Zeeb 	const struct dpk_cfg_pair *end = p + tbl->size / 3;
31672774f206SBjoern A. Zeeb 
31682774f206SBjoern A. Zeeb 	BUILD_BUG_ON(sizeof(struct dpk_cfg_pair) != sizeof(u32) * 3);
31692774f206SBjoern A. Zeeb 
31702774f206SBjoern A. Zeeb 	for (; p < end; p++)
31712774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, p->addr, p->bitmask, p->data);
31722774f206SBjoern A. Zeeb }
31732774f206SBjoern A. Zeeb 
31742774f206SBjoern A. Zeeb static void rtw8822c_dpk_set_gnt_wl(struct rtw_dev *rtwdev, bool is_before_k)
31752774f206SBjoern A. Zeeb {
31762774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
31772774f206SBjoern A. Zeeb 
31782774f206SBjoern A. Zeeb 	if (is_before_k) {
31792774f206SBjoern A. Zeeb 		dpk_info->gnt_control = rtw_read32(rtwdev, 0x70);
31802774f206SBjoern A. Zeeb 		dpk_info->gnt_value = rtw_coex_read_indirect_reg(rtwdev, 0x38);
31812774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x70, BIT(26), 0x1);
31822774f206SBjoern A. Zeeb 		rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKBYTE1, 0x77);
31832774f206SBjoern A. Zeeb 	} else {
31842774f206SBjoern A. Zeeb 		rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKDWORD,
31852774f206SBjoern A. Zeeb 					    dpk_info->gnt_value);
31862774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, 0x70, dpk_info->gnt_control);
31872774f206SBjoern A. Zeeb 	}
31882774f206SBjoern A. Zeeb }
31892774f206SBjoern A. Zeeb 
31902774f206SBjoern A. Zeeb static void
31912774f206SBjoern A. Zeeb rtw8822c_dpk_restore_registers(struct rtw_dev *rtwdev, u32 reg_num,
31922774f206SBjoern A. Zeeb 			       struct rtw_backup_info *bckp)
31932774f206SBjoern A. Zeeb {
31942774f206SBjoern A. Zeeb 	rtw_restore_reg(rtwdev, bckp, reg_num);
31952774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
31962774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0x4);
31972774f206SBjoern A. Zeeb }
31982774f206SBjoern A. Zeeb 
31992774f206SBjoern A. Zeeb static void
32002774f206SBjoern A. Zeeb rtw8822c_dpk_backup_registers(struct rtw_dev *rtwdev, u32 *reg,
32012774f206SBjoern A. Zeeb 			      u32 reg_num, struct rtw_backup_info *bckp)
32022774f206SBjoern A. Zeeb {
32032774f206SBjoern A. Zeeb 	u32 i;
32042774f206SBjoern A. Zeeb 
32052774f206SBjoern A. Zeeb 	for (i = 0; i < reg_num; i++) {
32062774f206SBjoern A. Zeeb 		bckp[i].len = 4;
32072774f206SBjoern A. Zeeb 		bckp[i].reg = reg[i];
32082774f206SBjoern A. Zeeb 		bckp[i].val = rtw_read32(rtwdev, reg[i]);
32092774f206SBjoern A. Zeeb 	}
32102774f206SBjoern A. Zeeb }
32112774f206SBjoern A. Zeeb 
32122774f206SBjoern A. Zeeb static void rtw8822c_dpk_backup_rf_registers(struct rtw_dev *rtwdev,
32132774f206SBjoern A. Zeeb 					     u32 *rf_reg,
32142774f206SBjoern A. Zeeb 					     u32 rf_reg_bak[][2])
32152774f206SBjoern A. Zeeb {
32162774f206SBjoern A. Zeeb 	u32 i;
32172774f206SBjoern A. Zeeb 
32182774f206SBjoern A. Zeeb 	for (i = 0; i < DPK_RF_REG_NUM; i++) {
32192774f206SBjoern A. Zeeb 		rf_reg_bak[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A,
32202774f206SBjoern A. Zeeb 						       rf_reg[i], RFREG_MASK);
32212774f206SBjoern A. Zeeb 		rf_reg_bak[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B,
32222774f206SBjoern A. Zeeb 						       rf_reg[i], RFREG_MASK);
32232774f206SBjoern A. Zeeb 	}
32242774f206SBjoern A. Zeeb }
32252774f206SBjoern A. Zeeb 
32262774f206SBjoern A. Zeeb static void rtw8822c_dpk_reload_rf_registers(struct rtw_dev *rtwdev,
32272774f206SBjoern A. Zeeb 					     u32 *rf_reg,
32282774f206SBjoern A. Zeeb 					     u32 rf_reg_bak[][2])
32292774f206SBjoern A. Zeeb {
32302774f206SBjoern A. Zeeb 	u32 i;
32312774f206SBjoern A. Zeeb 
32322774f206SBjoern A. Zeeb 	for (i = 0; i < DPK_RF_REG_NUM; i++) {
32332774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, rf_reg[i], RFREG_MASK,
32342774f206SBjoern A. Zeeb 			     rf_reg_bak[i][RF_PATH_A]);
32352774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, rf_reg[i], RFREG_MASK,
32362774f206SBjoern A. Zeeb 			     rf_reg_bak[i][RF_PATH_B]);
32372774f206SBjoern A. Zeeb 	}
32382774f206SBjoern A. Zeeb }
32392774f206SBjoern A. Zeeb 
32402774f206SBjoern A. Zeeb static void rtw8822c_dpk_information(struct rtw_dev *rtwdev)
32412774f206SBjoern A. Zeeb {
32422774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
32432774f206SBjoern A. Zeeb 	u32  reg;
32442774f206SBjoern A. Zeeb 	u8 band_shift;
32452774f206SBjoern A. Zeeb 
32464f3b2bbaSBjoern A. Zeeb #if defined(__linux__)
32472774f206SBjoern A. Zeeb 	reg = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
32484f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__)
32494f3b2bbaSBjoern A. Zeeb 	reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
32504f3b2bbaSBjoern A. Zeeb #endif
32512774f206SBjoern A. Zeeb 
32522774f206SBjoern A. Zeeb 	band_shift = FIELD_GET(BIT(16), reg);
32532774f206SBjoern A. Zeeb 	dpk_info->dpk_band = 1 << band_shift;
32542774f206SBjoern A. Zeeb 	dpk_info->dpk_ch = FIELD_GET(0xff, reg);
32552774f206SBjoern A. Zeeb 	dpk_info->dpk_bw = FIELD_GET(0x3000, reg);
32562774f206SBjoern A. Zeeb }
32572774f206SBjoern A. Zeeb 
32582774f206SBjoern A. Zeeb static void rtw8822c_dpk_rxbb_dc_cal(struct rtw_dev *rtwdev, u8 path)
32592774f206SBjoern A. Zeeb {
32602774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800);
32612774f206SBjoern A. Zeeb 	udelay(5);
32622774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84801);
32632774f206SBjoern A. Zeeb 	usleep_range(600, 610);
32642774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800);
32652774f206SBjoern A. Zeeb }
32662774f206SBjoern A. Zeeb 
32672774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_dc_corr_check(struct rtw_dev *rtwdev, u8 path)
32682774f206SBjoern A. Zeeb {
32692774f206SBjoern A. Zeeb 	u16 dc_i, dc_q;
32702774f206SBjoern A. Zeeb 	u8 corr_idx;
32712774f206SBjoern A. Zeeb 
32722774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000900f0);
32732774f206SBjoern A. Zeeb 	dc_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16));
32742774f206SBjoern A. Zeeb 	dc_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(11, 0));
32752774f206SBjoern A. Zeeb 
32762774f206SBjoern A. Zeeb 	if (dc_i & BIT(11))
32772774f206SBjoern A. Zeeb 		dc_i = 0x1000 - dc_i;
32782774f206SBjoern A. Zeeb 	if (dc_q & BIT(11))
32792774f206SBjoern A. Zeeb 		dc_q = 0x1000 - dc_q;
32802774f206SBjoern A. Zeeb 
32812774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0);
32822774f206SBjoern A. Zeeb 	corr_idx = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(7, 0));
32832774f206SBjoern A. Zeeb 	rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(15, 8));
32842774f206SBjoern A. Zeeb 
32852774f206SBjoern A. Zeeb 	if (dc_i > 200 || dc_q > 200 || corr_idx < 40 || corr_idx > 65)
32862774f206SBjoern A. Zeeb 		return 1;
32872774f206SBjoern A. Zeeb 	else
32882774f206SBjoern A. Zeeb 		return 0;
32892774f206SBjoern A. Zeeb 
32902774f206SBjoern A. Zeeb }
32912774f206SBjoern A. Zeeb 
32922774f206SBjoern A. Zeeb static void rtw8822c_dpk_tx_pause(struct rtw_dev *rtwdev)
32932774f206SBjoern A. Zeeb {
32942774f206SBjoern A. Zeeb 	u8 reg_a, reg_b;
32952774f206SBjoern A. Zeeb 	u16 count = 0;
32962774f206SBjoern A. Zeeb 
32972774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x522, 0xff);
32982774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1e70, 0xf, 0x2);
32992774f206SBjoern A. Zeeb 
33002774f206SBjoern A. Zeeb 	do {
33012774f206SBjoern A. Zeeb 		reg_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 0x00, 0xf0000);
33022774f206SBjoern A. Zeeb 		reg_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 0x00, 0xf0000);
33032774f206SBjoern A. Zeeb 		udelay(2);
33042774f206SBjoern A. Zeeb 		count++;
33052774f206SBjoern A. Zeeb 	} while ((reg_a == 2 || reg_b == 2) && count < 2500);
33062774f206SBjoern A. Zeeb }
33072774f206SBjoern A. Zeeb 
33082774f206SBjoern A. Zeeb static void rtw8822c_dpk_mac_bb_setting(struct rtw_dev *rtwdev)
33092774f206SBjoern A. Zeeb {
33102774f206SBjoern A. Zeeb 	rtw8822c_dpk_tx_pause(rtwdev);
33112774f206SBjoern A. Zeeb 	rtw_load_table(rtwdev, &rtw8822c_dpk_mac_bb_tbl);
33122774f206SBjoern A. Zeeb }
33132774f206SBjoern A. Zeeb 
33142774f206SBjoern A. Zeeb static void rtw8822c_dpk_afe_setting(struct rtw_dev *rtwdev, bool is_do_dpk)
33152774f206SBjoern A. Zeeb {
33162774f206SBjoern A. Zeeb 	if (is_do_dpk)
33172774f206SBjoern A. Zeeb 		rtw_load_table(rtwdev, &rtw8822c_dpk_afe_is_dpk_tbl);
33182774f206SBjoern A. Zeeb 	else
33192774f206SBjoern A. Zeeb 		rtw_load_table(rtwdev, &rtw8822c_dpk_afe_no_dpk_tbl);
33202774f206SBjoern A. Zeeb }
33212774f206SBjoern A. Zeeb 
33222774f206SBjoern A. Zeeb static void rtw8822c_dpk_pre_setting(struct rtw_dev *rtwdev)
33232774f206SBjoern A. Zeeb {
33242774f206SBjoern A. Zeeb 	u8 path;
33252774f206SBjoern A. Zeeb 
33262774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
33272774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_RXAGC_OFFSET, RFREG_MASK, 0x0);
33282774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1));
33292774f206SBjoern A. Zeeb 		if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G)
33302774f206SBjoern A. Zeeb 			rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000);
33312774f206SBjoern A. Zeeb 		else
33322774f206SBjoern A. Zeeb 			rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000);
33332774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_LUT0, BIT_GLOSS_DB, 0x4);
33342774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x3);
33352774f206SBjoern A. Zeeb 	}
33362774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
33372774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DPD_CTL11, 0x3b23170b);
33382774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DPD_CTL12, 0x775f5347);
33392774f206SBjoern A. Zeeb }
33402774f206SBjoern A. Zeeb 
33412774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_rf_setting(struct rtw_dev *rtwdev, u8 path)
33422774f206SBjoern A. Zeeb {
33432774f206SBjoern A. Zeeb 	u32 ori_txbb;
33442774f206SBjoern A. Zeeb 
33452774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50017);
33462774f206SBjoern A. Zeeb 	ori_txbb = rtw_read_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK);
33472774f206SBjoern A. Zeeb 
33482774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1);
33492774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_PWR_TRIM, 0x1);
33502774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_BB_GAIN, 0x0);
33512774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK, ori_txbb);
33522774f206SBjoern A. Zeeb 
33532774f206SBjoern A. Zeeb 	if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) {
33542774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x1);
33552774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x0);
33562774f206SBjoern A. Zeeb 	} else {
33572774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x0);
33582774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x6);
33592774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1);
33602774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0);
33612774f206SBjoern A. Zeeb 	}
33622774f206SBjoern A. Zeeb 
33632774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf);
33642774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1);
33652774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0);
33662774f206SBjoern A. Zeeb 
33672774f206SBjoern A. Zeeb 	if (rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80)
33682774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x2);
33692774f206SBjoern A. Zeeb 	else
33702774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1);
33712774f206SBjoern A. Zeeb 
33722774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT(1), 0x1);
33732774f206SBjoern A. Zeeb 
33742774f206SBjoern A. Zeeb 	usleep_range(100, 110);
33752774f206SBjoern A. Zeeb 
33762774f206SBjoern A. Zeeb 	return ori_txbb & 0x1f;
33772774f206SBjoern A. Zeeb }
33782774f206SBjoern A. Zeeb 
33792774f206SBjoern A. Zeeb static u16 rtw8822c_dpk_get_cmd(struct rtw_dev *rtwdev, u8 action, u8 path)
33802774f206SBjoern A. Zeeb {
33812774f206SBjoern A. Zeeb 	u16 cmd;
33822774f206SBjoern A. Zeeb 	u8 bw = rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80 ? 2 : 0;
33832774f206SBjoern A. Zeeb 
33842774f206SBjoern A. Zeeb 	switch (action) {
33852774f206SBjoern A. Zeeb 	case RTW_DPK_GAIN_LOSS:
33862774f206SBjoern A. Zeeb 		cmd = 0x14 + path;
33872774f206SBjoern A. Zeeb 		break;
33882774f206SBjoern A. Zeeb 	case RTW_DPK_DO_DPK:
33892774f206SBjoern A. Zeeb 		cmd = 0x16 + path + bw;
33902774f206SBjoern A. Zeeb 		break;
33912774f206SBjoern A. Zeeb 	case RTW_DPK_DPK_ON:
33922774f206SBjoern A. Zeeb 		cmd = 0x1a + path;
33932774f206SBjoern A. Zeeb 		break;
33942774f206SBjoern A. Zeeb 	case RTW_DPK_DAGC:
33952774f206SBjoern A. Zeeb 		cmd = 0x1c + path + bw;
33962774f206SBjoern A. Zeeb 		break;
33972774f206SBjoern A. Zeeb 	default:
33982774f206SBjoern A. Zeeb 		return 0;
33992774f206SBjoern A. Zeeb 	}
34002774f206SBjoern A. Zeeb 
34012774f206SBjoern A. Zeeb 	return (cmd << 8) | 0x48;
34022774f206SBjoern A. Zeeb }
34032774f206SBjoern A. Zeeb 
34042774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_one_shot(struct rtw_dev *rtwdev, u8 path, u8 action)
34052774f206SBjoern A. Zeeb {
34062774f206SBjoern A. Zeeb 	u16 dpk_cmd;
34072774f206SBjoern A. Zeeb 	u8 result = 0;
34082774f206SBjoern A. Zeeb 
34092774f206SBjoern A. Zeeb 	rtw8822c_dpk_set_gnt_wl(rtwdev, true);
34102774f206SBjoern A. Zeeb 
34112774f206SBjoern A. Zeeb 	if (action == RTW_DPK_CAL_PWR) {
34122774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x1);
34132774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x0);
34142774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0);
34152774f206SBjoern A. Zeeb 		msleep(10);
34162774f206SBjoern A. Zeeb 		if (!check_hw_ready(rtwdev, REG_STAT_RPT, BIT(31), 0x1)) {
34172774f206SBjoern A. Zeeb 			result = 1;
34182774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n");
34192774f206SBjoern A. Zeeb 		}
34202774f206SBjoern A. Zeeb 	} else {
34212774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE,
34222774f206SBjoern A. Zeeb 				 0x8 | (path << 1));
34232774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9);
34242774f206SBjoern A. Zeeb 
34252774f206SBjoern A. Zeeb 		dpk_cmd = rtw8822c_dpk_get_cmd(rtwdev, action, path);
34262774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_NCTL0, dpk_cmd);
34272774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_NCTL0, dpk_cmd + 1);
34282774f206SBjoern A. Zeeb 		msleep(10);
34292774f206SBjoern A. Zeeb 		if (!check_hw_ready(rtwdev, 0x2d9c, 0xff, 0x55)) {
34302774f206SBjoern A. Zeeb 			result = 1;
34312774f206SBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n");
34322774f206SBjoern A. Zeeb 		}
34332774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE,
34342774f206SBjoern A. Zeeb 				 0x8 | (path << 1));
34352774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0);
34362774f206SBjoern A. Zeeb 	}
34372774f206SBjoern A. Zeeb 
34382774f206SBjoern A. Zeeb 	rtw8822c_dpk_set_gnt_wl(rtwdev, false);
34392774f206SBjoern A. Zeeb 
34402774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1b10, 0x0);
34412774f206SBjoern A. Zeeb 
34422774f206SBjoern A. Zeeb 	return result;
34432774f206SBjoern A. Zeeb }
34442774f206SBjoern A. Zeeb 
34452774f206SBjoern A. Zeeb static u16 rtw8822c_dpk_dgain_read(struct rtw_dev *rtwdev, u8 path)
34462774f206SBjoern A. Zeeb {
34472774f206SBjoern A. Zeeb 	u16 dgain;
34482774f206SBjoern A. Zeeb 
34492774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
34502774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, 0x00ff0000, 0x0);
34512774f206SBjoern A. Zeeb 
34522774f206SBjoern A. Zeeb 	dgain = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16));
34532774f206SBjoern A. Zeeb 
34542774f206SBjoern A. Zeeb 	return dgain;
34552774f206SBjoern A. Zeeb }
34562774f206SBjoern A. Zeeb 
34572774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_thermal_read(struct rtw_dev *rtwdev, u8 path)
34582774f206SBjoern A. Zeeb {
34592774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1);
34602774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x0);
34612774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1);
34622774f206SBjoern A. Zeeb 	udelay(15);
34632774f206SBjoern A. Zeeb 
34642774f206SBjoern A. Zeeb 	return (u8)rtw_read_rf(rtwdev, path, RF_T_METER, 0x0007e);
34652774f206SBjoern A. Zeeb }
34662774f206SBjoern A. Zeeb 
34672774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_pas_read(struct rtw_dev *rtwdev, u8 path)
34682774f206SBjoern A. Zeeb {
34692774f206SBjoern A. Zeeb 	u32 i_val, q_val;
34702774f206SBjoern A. Zeeb 
34712774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1));
34722774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0);
34732774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060001);
34742774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b4c, 0x00000000);
34752774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b4c, 0x00080000);
34762774f206SBjoern A. Zeeb 
34772774f206SBjoern A. Zeeb 	q_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD);
34782774f206SBjoern A. Zeeb 	i_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD);
34792774f206SBjoern A. Zeeb 
34802774f206SBjoern A. Zeeb 	if (i_val & BIT(15))
34812774f206SBjoern A. Zeeb 		i_val = 0x10000 - i_val;
34822774f206SBjoern A. Zeeb 	if (q_val & BIT(15))
34832774f206SBjoern A. Zeeb 		q_val = 0x10000 - q_val;
34842774f206SBjoern A. Zeeb 
34852774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, 0x1b4c, 0x00000000);
34862774f206SBjoern A. Zeeb 
34872774f206SBjoern A. Zeeb 	return i_val * i_val + q_val * q_val;
34882774f206SBjoern A. Zeeb }
34892774f206SBjoern A. Zeeb 
34902774f206SBjoern A. Zeeb static u32 rtw8822c_psd_log2base(u32 val)
34912774f206SBjoern A. Zeeb {
34922774f206SBjoern A. Zeeb 	u32 tmp, val_integerd_b, tindex;
34932774f206SBjoern A. Zeeb 	u32 result, val_fractiond_b;
34942774f206SBjoern A. Zeeb 	u32 table_fraction[21] = {0, 432, 332, 274, 232, 200, 174,
34952774f206SBjoern A. Zeeb 				  151, 132, 115, 100, 86, 74, 62, 51,
34962774f206SBjoern A. Zeeb 				  42, 32, 23, 15, 7, 0};
34972774f206SBjoern A. Zeeb 
34982774f206SBjoern A. Zeeb 	if (val == 0)
34992774f206SBjoern A. Zeeb 		return 0;
35002774f206SBjoern A. Zeeb 
35012774f206SBjoern A. Zeeb 	val_integerd_b = __fls(val) + 1;
35022774f206SBjoern A. Zeeb 
35032774f206SBjoern A. Zeeb 	tmp = (val * 100) / (1 << val_integerd_b);
35042774f206SBjoern A. Zeeb 	tindex = tmp / 5;
35052774f206SBjoern A. Zeeb 
35062774f206SBjoern A. Zeeb 	if (tindex >= ARRAY_SIZE(table_fraction))
35072774f206SBjoern A. Zeeb 		tindex = ARRAY_SIZE(table_fraction) - 1;
35082774f206SBjoern A. Zeeb 
35092774f206SBjoern A. Zeeb 	val_fractiond_b = table_fraction[tindex];
35102774f206SBjoern A. Zeeb 
35112774f206SBjoern A. Zeeb 	result = val_integerd_b * 100 - val_fractiond_b;
35122774f206SBjoern A. Zeeb 
35132774f206SBjoern A. Zeeb 	return result;
35142774f206SBjoern A. Zeeb }
35152774f206SBjoern A. Zeeb 
35162774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_gainloss_result(struct rtw_dev *rtwdev, u8 path)
35172774f206SBjoern A. Zeeb {
35182774f206SBjoern A. Zeeb 	u8 result;
35192774f206SBjoern A. Zeeb 
35202774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
35212774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x1);
35222774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060000);
35232774f206SBjoern A. Zeeb 
35242774f206SBjoern A. Zeeb 	result = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, 0x000000f0);
35252774f206SBjoern A. Zeeb 
35262774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0);
35272774f206SBjoern A. Zeeb 
35282774f206SBjoern A. Zeeb 	return result;
35292774f206SBjoern A. Zeeb }
35302774f206SBjoern A. Zeeb 
35312774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_agc_gain_chk(struct rtw_dev *rtwdev, u8 path,
35322774f206SBjoern A. Zeeb 				    u8 limited_pga)
35332774f206SBjoern A. Zeeb {
35342774f206SBjoern A. Zeeb 	u8 result = 0;
35352774f206SBjoern A. Zeeb 	u16 dgain;
35362774f206SBjoern A. Zeeb 
35372774f206SBjoern A. Zeeb 	rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC);
35382774f206SBjoern A. Zeeb 	dgain = rtw8822c_dpk_dgain_read(rtwdev, path);
35392774f206SBjoern A. Zeeb 
35402774f206SBjoern A. Zeeb 	if (dgain > 1535 && !limited_pga)
35412774f206SBjoern A. Zeeb 		return RTW_DPK_GAIN_LESS;
35422774f206SBjoern A. Zeeb 	else if (dgain < 768 && !limited_pga)
35432774f206SBjoern A. Zeeb 		return RTW_DPK_GAIN_LARGE;
35442774f206SBjoern A. Zeeb 	else
35452774f206SBjoern A. Zeeb 		return result;
35462774f206SBjoern A. Zeeb }
35472774f206SBjoern A. Zeeb 
35482774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_agc_loss_chk(struct rtw_dev *rtwdev, u8 path)
35492774f206SBjoern A. Zeeb {
35502774f206SBjoern A. Zeeb 	u32 loss, loss_db;
35512774f206SBjoern A. Zeeb 
35522774f206SBjoern A. Zeeb 	loss = rtw8822c_dpk_pas_read(rtwdev, path);
35532774f206SBjoern A. Zeeb 	if (loss < 0x4000000)
35542774f206SBjoern A. Zeeb 		return RTW_DPK_GL_LESS;
35552774f206SBjoern A. Zeeb 	loss_db = 3 * rtw8822c_psd_log2base(loss >> 13) - 3870;
35562774f206SBjoern A. Zeeb 
35572774f206SBjoern A. Zeeb 	if (loss_db > 1000)
35582774f206SBjoern A. Zeeb 		return RTW_DPK_GL_LARGE;
35592774f206SBjoern A. Zeeb 	else if (loss_db < 250)
35602774f206SBjoern A. Zeeb 		return RTW_DPK_GL_LESS;
35612774f206SBjoern A. Zeeb 	else
35622774f206SBjoern A. Zeeb 		return RTW_DPK_AGC_OUT;
35632774f206SBjoern A. Zeeb }
35642774f206SBjoern A. Zeeb 
35652774f206SBjoern A. Zeeb struct rtw8822c_dpk_data {
35662774f206SBjoern A. Zeeb 	u8 txbb;
35672774f206SBjoern A. Zeeb 	u8 pga;
35682774f206SBjoern A. Zeeb 	u8 limited_pga;
35692774f206SBjoern A. Zeeb 	u8 agc_cnt;
35702774f206SBjoern A. Zeeb 	bool loss_only;
35712774f206SBjoern A. Zeeb 	bool gain_only;
35722774f206SBjoern A. Zeeb 	u8 path;
35732774f206SBjoern A. Zeeb };
35742774f206SBjoern A. Zeeb 
35752774f206SBjoern A. Zeeb static u8 rtw8822c_gain_check_state(struct rtw_dev *rtwdev,
35762774f206SBjoern A. Zeeb 				    struct rtw8822c_dpk_data *data)
35772774f206SBjoern A. Zeeb {
35782774f206SBjoern A. Zeeb 	u8 state;
35792774f206SBjoern A. Zeeb 
35802774f206SBjoern A. Zeeb 	data->txbb = (u8)rtw_read_rf(rtwdev, data->path, RF_TX_GAIN,
35812774f206SBjoern A. Zeeb 				     BIT_GAIN_TXBB);
35822774f206SBjoern A. Zeeb 	data->pga = (u8)rtw_read_rf(rtwdev, data->path, RF_MODE_TRXAGC,
35832774f206SBjoern A. Zeeb 				    BIT_RXAGC);
35842774f206SBjoern A. Zeeb 
35852774f206SBjoern A. Zeeb 	if (data->loss_only) {
35862774f206SBjoern A. Zeeb 		state = RTW_DPK_LOSS_CHECK;
35872774f206SBjoern A. Zeeb 		goto check_end;
35882774f206SBjoern A. Zeeb 	}
35892774f206SBjoern A. Zeeb 
35902774f206SBjoern A. Zeeb 	state = rtw8822c_dpk_agc_gain_chk(rtwdev, data->path,
35912774f206SBjoern A. Zeeb 					  data->limited_pga);
35922774f206SBjoern A. Zeeb 	if (state == RTW_DPK_GAIN_CHECK && data->gain_only)
35932774f206SBjoern A. Zeeb 		state = RTW_DPK_AGC_OUT;
35942774f206SBjoern A. Zeeb 	else if (state == RTW_DPK_GAIN_CHECK)
35952774f206SBjoern A. Zeeb 		state = RTW_DPK_LOSS_CHECK;
35962774f206SBjoern A. Zeeb 
35972774f206SBjoern A. Zeeb check_end:
35982774f206SBjoern A. Zeeb 	data->agc_cnt++;
35992774f206SBjoern A. Zeeb 	if (data->agc_cnt >= 6)
36002774f206SBjoern A. Zeeb 		state = RTW_DPK_AGC_OUT;
36012774f206SBjoern A. Zeeb 
36022774f206SBjoern A. Zeeb 	return state;
36032774f206SBjoern A. Zeeb }
36042774f206SBjoern A. Zeeb 
36052774f206SBjoern A. Zeeb static u8 rtw8822c_gain_large_state(struct rtw_dev *rtwdev,
36062774f206SBjoern A. Zeeb 				    struct rtw8822c_dpk_data *data)
36072774f206SBjoern A. Zeeb {
36082774f206SBjoern A. Zeeb 	u8 pga = data->pga;
36092774f206SBjoern A. Zeeb 
36102774f206SBjoern A. Zeeb 	if (pga > 0xe)
36112774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc);
36122774f206SBjoern A. Zeeb 	else if (pga > 0xb && pga < 0xf)
36132774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0);
36142774f206SBjoern A. Zeeb 	else if (pga < 0xc)
36152774f206SBjoern A. Zeeb 		data->limited_pga = 1;
36162774f206SBjoern A. Zeeb 
36172774f206SBjoern A. Zeeb 	return RTW_DPK_GAIN_CHECK;
36182774f206SBjoern A. Zeeb }
36192774f206SBjoern A. Zeeb 
36202774f206SBjoern A. Zeeb static u8 rtw8822c_gain_less_state(struct rtw_dev *rtwdev,
36212774f206SBjoern A. Zeeb 				   struct rtw8822c_dpk_data *data)
36222774f206SBjoern A. Zeeb {
36232774f206SBjoern A. Zeeb 	u8 pga = data->pga;
36242774f206SBjoern A. Zeeb 
36252774f206SBjoern A. Zeeb 	if (pga < 0xc)
36262774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc);
36272774f206SBjoern A. Zeeb 	else if (pga > 0xb && pga < 0xf)
36282774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf);
36292774f206SBjoern A. Zeeb 	else if (pga > 0xe)
36302774f206SBjoern A. Zeeb 		data->limited_pga = 1;
36312774f206SBjoern A. Zeeb 
36322774f206SBjoern A. Zeeb 	return RTW_DPK_GAIN_CHECK;
36332774f206SBjoern A. Zeeb }
36342774f206SBjoern A. Zeeb 
36352774f206SBjoern A. Zeeb static u8 rtw8822c_gl_state(struct rtw_dev *rtwdev,
36362774f206SBjoern A. Zeeb 			    struct rtw8822c_dpk_data *data, u8 is_large)
36372774f206SBjoern A. Zeeb {
36382774f206SBjoern A. Zeeb 	u8 txbb_bound[] = {0x1f, 0};
36392774f206SBjoern A. Zeeb 
36402774f206SBjoern A. Zeeb 	if (data->txbb == txbb_bound[is_large])
36412774f206SBjoern A. Zeeb 		return RTW_DPK_AGC_OUT;
36422774f206SBjoern A. Zeeb 
36432774f206SBjoern A. Zeeb 	if (is_large == 1)
36442774f206SBjoern A. Zeeb 		data->txbb -= 2;
36452774f206SBjoern A. Zeeb 	else
36462774f206SBjoern A. Zeeb 		data->txbb += 3;
36472774f206SBjoern A. Zeeb 
36482774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, data->path, RF_TX_GAIN, BIT_GAIN_TXBB, data->txbb);
36492774f206SBjoern A. Zeeb 	data->limited_pga = 0;
36502774f206SBjoern A. Zeeb 
36512774f206SBjoern A. Zeeb 	return RTW_DPK_GAIN_CHECK;
36522774f206SBjoern A. Zeeb }
36532774f206SBjoern A. Zeeb 
36542774f206SBjoern A. Zeeb static u8 rtw8822c_gl_large_state(struct rtw_dev *rtwdev,
36552774f206SBjoern A. Zeeb 				  struct rtw8822c_dpk_data *data)
36562774f206SBjoern A. Zeeb {
36572774f206SBjoern A. Zeeb 	return rtw8822c_gl_state(rtwdev, data, 1);
36582774f206SBjoern A. Zeeb }
36592774f206SBjoern A. Zeeb 
36602774f206SBjoern A. Zeeb static u8 rtw8822c_gl_less_state(struct rtw_dev *rtwdev,
36612774f206SBjoern A. Zeeb 				 struct rtw8822c_dpk_data *data)
36622774f206SBjoern A. Zeeb {
36632774f206SBjoern A. Zeeb 	return rtw8822c_gl_state(rtwdev, data, 0);
36642774f206SBjoern A. Zeeb }
36652774f206SBjoern A. Zeeb 
36662774f206SBjoern A. Zeeb static u8 rtw8822c_loss_check_state(struct rtw_dev *rtwdev,
36672774f206SBjoern A. Zeeb 				    struct rtw8822c_dpk_data *data)
36682774f206SBjoern A. Zeeb {
36692774f206SBjoern A. Zeeb 	u8 path = data->path;
36702774f206SBjoern A. Zeeb 	u8 state;
36712774f206SBjoern A. Zeeb 
36722774f206SBjoern A. Zeeb 	rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_GAIN_LOSS);
36732774f206SBjoern A. Zeeb 	state = rtw8822c_dpk_agc_loss_chk(rtwdev, path);
36742774f206SBjoern A. Zeeb 
36752774f206SBjoern A. Zeeb 	return state;
36762774f206SBjoern A. Zeeb }
36772774f206SBjoern A. Zeeb 
36782774f206SBjoern A. Zeeb static u8 (*dpk_state[])(struct rtw_dev *rtwdev,
36792774f206SBjoern A. Zeeb 			  struct rtw8822c_dpk_data *data) = {
36802774f206SBjoern A. Zeeb 	rtw8822c_gain_check_state, rtw8822c_gain_large_state,
36812774f206SBjoern A. Zeeb 	rtw8822c_gain_less_state, rtw8822c_gl_large_state,
36822774f206SBjoern A. Zeeb 	rtw8822c_gl_less_state, rtw8822c_loss_check_state };
36832774f206SBjoern A. Zeeb 
36842774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_pas_agc(struct rtw_dev *rtwdev, u8 path,
36852774f206SBjoern A. Zeeb 			       bool gain_only, bool loss_only)
36862774f206SBjoern A. Zeeb {
36872774f206SBjoern A. Zeeb 	struct rtw8822c_dpk_data data = {0};
36882774f206SBjoern A. Zeeb 	u8 (*func)(struct rtw_dev *rtwdev, struct rtw8822c_dpk_data *data);
36892774f206SBjoern A. Zeeb 	u8 state = RTW_DPK_GAIN_CHECK;
36902774f206SBjoern A. Zeeb 
36912774f206SBjoern A. Zeeb 	data.loss_only = loss_only;
36922774f206SBjoern A. Zeeb 	data.gain_only = gain_only;
36932774f206SBjoern A. Zeeb 	data.path = path;
36942774f206SBjoern A. Zeeb 
36952774f206SBjoern A. Zeeb 	for (;;) {
36962774f206SBjoern A. Zeeb 		func = dpk_state[state];
36972774f206SBjoern A. Zeeb 		state = func(rtwdev, &data);
36982774f206SBjoern A. Zeeb 		if (state == RTW_DPK_AGC_OUT)
36992774f206SBjoern A. Zeeb 			break;
37002774f206SBjoern A. Zeeb 	}
37012774f206SBjoern A. Zeeb 
37022774f206SBjoern A. Zeeb 	return data.txbb;
37032774f206SBjoern A. Zeeb }
37042774f206SBjoern A. Zeeb 
37052774f206SBjoern A. Zeeb static bool rtw8822c_dpk_coef_iq_check(struct rtw_dev *rtwdev,
37062774f206SBjoern A. Zeeb 				       u16 coef_i, u16 coef_q)
37072774f206SBjoern A. Zeeb {
37082774f206SBjoern A. Zeeb 	if (coef_i == 0x1000 || coef_i == 0x0fff ||
37092774f206SBjoern A. Zeeb 	    coef_q == 0x1000 || coef_q == 0x0fff)
37102774f206SBjoern A. Zeeb 		return true;
37112774f206SBjoern A. Zeeb 
37122774f206SBjoern A. Zeeb 	return false;
37132774f206SBjoern A. Zeeb }
37142774f206SBjoern A. Zeeb 
37152774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_coef_transfer(struct rtw_dev *rtwdev)
37162774f206SBjoern A. Zeeb {
37172774f206SBjoern A. Zeeb 	u32 reg = 0;
37182774f206SBjoern A. Zeeb 	u16 coef_i = 0, coef_q = 0;
37192774f206SBjoern A. Zeeb 
37202774f206SBjoern A. Zeeb 	reg = rtw_read32(rtwdev, REG_STAT_RPT);
37212774f206SBjoern A. Zeeb 
37222774f206SBjoern A. Zeeb 	coef_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD) & 0x1fff;
37232774f206SBjoern A. Zeeb 	coef_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD) & 0x1fff;
37242774f206SBjoern A. Zeeb 
37252774f206SBjoern A. Zeeb 	coef_q = ((0x2000 - coef_q) & 0x1fff) - 1;
37262774f206SBjoern A. Zeeb 
37272774f206SBjoern A. Zeeb 	reg = (coef_i << 16) | coef_q;
37282774f206SBjoern A. Zeeb 
37292774f206SBjoern A. Zeeb 	return reg;
37302774f206SBjoern A. Zeeb }
37312774f206SBjoern A. Zeeb 
37322774f206SBjoern A. Zeeb static const u32 rtw8822c_dpk_get_coef_tbl[] = {
37332774f206SBjoern A. Zeeb 	0x000400f0, 0x040400f0, 0x080400f0, 0x010400f0, 0x050400f0,
37342774f206SBjoern A. Zeeb 	0x090400f0, 0x020400f0, 0x060400f0, 0x0a0400f0, 0x030400f0,
37352774f206SBjoern A. Zeeb 	0x070400f0, 0x0b0400f0, 0x0c0400f0, 0x100400f0, 0x0d0400f0,
37362774f206SBjoern A. Zeeb 	0x110400f0, 0x0e0400f0, 0x120400f0, 0x0f0400f0, 0x130400f0,
37372774f206SBjoern A. Zeeb };
37382774f206SBjoern A. Zeeb 
37392774f206SBjoern A. Zeeb static void rtw8822c_dpk_coef_tbl_apply(struct rtw_dev *rtwdev, u8 path)
37402774f206SBjoern A. Zeeb {
37412774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
37422774f206SBjoern A. Zeeb 	int i;
37432774f206SBjoern A. Zeeb 
37442774f206SBjoern A. Zeeb 	for (i = 0; i < 20; i++) {
37452774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RXSRAM_CTL,
37462774f206SBjoern A. Zeeb 			    rtw8822c_dpk_get_coef_tbl[i]);
37472774f206SBjoern A. Zeeb 		dpk_info->coef[path][i] = rtw8822c_dpk_coef_transfer(rtwdev);
37482774f206SBjoern A. Zeeb 	}
37492774f206SBjoern A. Zeeb }
37502774f206SBjoern A. Zeeb 
37512774f206SBjoern A. Zeeb static void rtw8822c_dpk_get_coef(struct rtw_dev *rtwdev, u8 path)
37522774f206SBjoern A. Zeeb {
37532774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_NCTL0, 0x0000000c);
37542774f206SBjoern A. Zeeb 
37552774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
37562774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x0);
37572774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL0_S0, 0x30000080);
37582774f206SBjoern A. Zeeb 	} else if (path == RF_PATH_B) {
37592774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x1);
37602774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL0_S1, 0x30000080);
37612774f206SBjoern A. Zeeb 	}
37622774f206SBjoern A. Zeeb 
37632774f206SBjoern A. Zeeb 	rtw8822c_dpk_coef_tbl_apply(rtwdev, path);
37642774f206SBjoern A. Zeeb }
37652774f206SBjoern A. Zeeb 
37662774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_coef_read(struct rtw_dev *rtwdev, u8 path)
37672774f206SBjoern A. Zeeb {
37682774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
37692774f206SBjoern A. Zeeb 	u8 addr, result = 1;
37702774f206SBjoern A. Zeeb 	u16 coef_i, coef_q;
37712774f206SBjoern A. Zeeb 
37722774f206SBjoern A. Zeeb 	for (addr = 0; addr < 20; addr++) {
37732774f206SBjoern A. Zeeb 		coef_i = FIELD_GET(0x1fff0000, dpk_info->coef[path][addr]);
37742774f206SBjoern A. Zeeb 		coef_q = FIELD_GET(0x1fff, dpk_info->coef[path][addr]);
37752774f206SBjoern A. Zeeb 
37762774f206SBjoern A. Zeeb 		if (rtw8822c_dpk_coef_iq_check(rtwdev, coef_i, coef_q)) {
37772774f206SBjoern A. Zeeb 			result = 0;
37782774f206SBjoern A. Zeeb 			break;
37792774f206SBjoern A. Zeeb 		}
37802774f206SBjoern A. Zeeb 	}
37812774f206SBjoern A. Zeeb 	return result;
37822774f206SBjoern A. Zeeb }
37832774f206SBjoern A. Zeeb 
37842774f206SBjoern A. Zeeb static void rtw8822c_dpk_coef_write(struct rtw_dev *rtwdev, u8 path, u8 result)
37852774f206SBjoern A. Zeeb {
37862774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
37872774f206SBjoern A. Zeeb 	u16 reg[DPK_RF_PATH_NUM] = {0x1b0c, 0x1b64};
37882774f206SBjoern A. Zeeb 	u32 coef;
37892774f206SBjoern A. Zeeb 	u8 addr;
37902774f206SBjoern A. Zeeb 
37912774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_NCTL0, 0x0000000c);
37922774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0);
37932774f206SBjoern A. Zeeb 
37942774f206SBjoern A. Zeeb 	for (addr = 0; addr < 20; addr++) {
37952774f206SBjoern A. Zeeb 		if (result == 0) {
37962774f206SBjoern A. Zeeb 			if (addr == 3)
37972774f206SBjoern A. Zeeb 				coef = 0x04001fff;
37982774f206SBjoern A. Zeeb 			else
37992774f206SBjoern A. Zeeb 				coef = 0x00001fff;
38002774f206SBjoern A. Zeeb 		} else {
38012774f206SBjoern A. Zeeb 			coef = dpk_info->coef[path][addr];
38022774f206SBjoern A. Zeeb 		}
38032774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, reg[path] + addr * 4, coef);
38042774f206SBjoern A. Zeeb 	}
38052774f206SBjoern A. Zeeb }
38062774f206SBjoern A. Zeeb 
38072774f206SBjoern A. Zeeb static void rtw8822c_dpk_fill_result(struct rtw_dev *rtwdev, u32 dpk_txagc,
38082774f206SBjoern A. Zeeb 				     u8 path, u8 result)
38092774f206SBjoern A. Zeeb {
38102774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
38112774f206SBjoern A. Zeeb 
38122774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
38132774f206SBjoern A. Zeeb 
38142774f206SBjoern A. Zeeb 	if (result)
38152774f206SBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DPD_AGC, (u8)(dpk_txagc - 6));
38162774f206SBjoern A. Zeeb 	else
38172774f206SBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DPD_AGC, 0x00);
38182774f206SBjoern A. Zeeb 
38192774f206SBjoern A. Zeeb 	dpk_info->result[path] = result;
38202774f206SBjoern A. Zeeb 	dpk_info->dpk_txagc[path] = rtw_read8(rtwdev, REG_DPD_AGC);
38212774f206SBjoern A. Zeeb 
38222774f206SBjoern A. Zeeb 	rtw8822c_dpk_coef_write(rtwdev, path, result);
38232774f206SBjoern A. Zeeb }
38242774f206SBjoern A. Zeeb 
38252774f206SBjoern A. Zeeb static u32 rtw8822c_dpk_gainloss(struct rtw_dev *rtwdev, u8 path)
38262774f206SBjoern A. Zeeb {
38272774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
38282774f206SBjoern A. Zeeb 	u8 tx_agc, tx_bb, ori_txbb, ori_txagc, tx_agc_search, t1, t2;
38292774f206SBjoern A. Zeeb 
38302774f206SBjoern A. Zeeb 	ori_txbb = rtw8822c_dpk_rf_setting(rtwdev, path);
38312774f206SBjoern A. Zeeb 	ori_txagc = (u8)rtw_read_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_TXAGC);
38322774f206SBjoern A. Zeeb 
38332774f206SBjoern A. Zeeb 	rtw8822c_dpk_rxbb_dc_cal(rtwdev, path);
38342774f206SBjoern A. Zeeb 	rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC);
38352774f206SBjoern A. Zeeb 	rtw8822c_dpk_dgain_read(rtwdev, path);
38362774f206SBjoern A. Zeeb 
38372774f206SBjoern A. Zeeb 	if (rtw8822c_dpk_dc_corr_check(rtwdev, path)) {
38382774f206SBjoern A. Zeeb 		rtw8822c_dpk_rxbb_dc_cal(rtwdev, path);
38392774f206SBjoern A. Zeeb 		rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC);
38402774f206SBjoern A. Zeeb 		rtw8822c_dpk_dc_corr_check(rtwdev, path);
38412774f206SBjoern A. Zeeb 	}
38422774f206SBjoern A. Zeeb 
38432774f206SBjoern A. Zeeb 	t1 = rtw8822c_dpk_thermal_read(rtwdev, path);
38442774f206SBjoern A. Zeeb 	tx_bb = rtw8822c_dpk_pas_agc(rtwdev, path, false, true);
38452774f206SBjoern A. Zeeb 	tx_agc_search = rtw8822c_dpk_gainloss_result(rtwdev, path);
38462774f206SBjoern A. Zeeb 
38472774f206SBjoern A. Zeeb 	if (tx_bb < tx_agc_search)
38482774f206SBjoern A. Zeeb 		tx_bb = 0;
38492774f206SBjoern A. Zeeb 	else
38502774f206SBjoern A. Zeeb 		tx_bb = tx_bb - tx_agc_search;
38512774f206SBjoern A. Zeeb 
38522774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_TX_GAIN, BIT_GAIN_TXBB, tx_bb);
38532774f206SBjoern A. Zeeb 
38542774f206SBjoern A. Zeeb 	tx_agc = ori_txagc - (ori_txbb - tx_bb);
38552774f206SBjoern A. Zeeb 
38562774f206SBjoern A. Zeeb 	t2 = rtw8822c_dpk_thermal_read(rtwdev, path);
38572774f206SBjoern A. Zeeb 
38582774f206SBjoern A. Zeeb 	dpk_info->thermal_dpk_delta[path] = abs(t2 - t1);
38592774f206SBjoern A. Zeeb 
38602774f206SBjoern A. Zeeb 	return tx_agc;
38612774f206SBjoern A. Zeeb }
38622774f206SBjoern A. Zeeb 
38632774f206SBjoern A. Zeeb static u8 rtw8822c_dpk_by_path(struct rtw_dev *rtwdev, u32 tx_agc, u8 path)
38642774f206SBjoern A. Zeeb {
38652774f206SBjoern A. Zeeb 	u8 result;
38662774f206SBjoern A. Zeeb 
38672774f206SBjoern A. Zeeb 	result = rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DO_DPK);
38682774f206SBjoern A. Zeeb 
38692774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
38702774f206SBjoern A. Zeeb 
38712774f206SBjoern A. Zeeb 	result = result | (u8)rtw_read32_mask(rtwdev, REG_DPD_CTL1_S0, BIT(26));
38722774f206SBjoern A. Zeeb 
38732774f206SBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x33e14);
38742774f206SBjoern A. Zeeb 
38752774f206SBjoern A. Zeeb 	rtw8822c_dpk_get_coef(rtwdev, path);
38762774f206SBjoern A. Zeeb 
38772774f206SBjoern A. Zeeb 	return result;
38782774f206SBjoern A. Zeeb }
38792774f206SBjoern A. Zeeb 
38802774f206SBjoern A. Zeeb static void rtw8822c_dpk_cal_gs(struct rtw_dev *rtwdev, u8 path)
38812774f206SBjoern A. Zeeb {
38822774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
38832774f206SBjoern A. Zeeb 	u32 tmp_gs = 0;
38842774f206SBjoern A. Zeeb 
38852774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
38862774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_BYPASS_DPD, 0x0);
38872774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
38882774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9);
38892774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x1);
38902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
38912774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0xf);
38922774f206SBjoern A. Zeeb 
38932774f206SBjoern A. Zeeb 	if (path == RF_PATH_A) {
38942774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF,
38952774f206SBjoern A. Zeeb 				 0x1066680);
38962774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 0x1);
38972774f206SBjoern A. Zeeb 	} else {
38982774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF,
38992774f206SBjoern A. Zeeb 				 0x1066680);
39002774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 0x1);
39012774f206SBjoern A. Zeeb 	}
39022774f206SBjoern A. Zeeb 
39032774f206SBjoern A. Zeeb 	if (dpk_info->dpk_bw == DPK_CHANNEL_WIDTH_80) {
39042774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x80001310);
39052774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x00001310);
39062774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x810000db);
39072774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x010000db);
39082774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428);
39092774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL15,
39102774f206SBjoern A. Zeeb 			    0x05020000 | (BIT(path) << 28));
39112774f206SBjoern A. Zeeb 	} else {
39122774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x8200190c);
39132774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x0200190c);
39142774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x8301ee14);
39152774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x0301ee14);
39162774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428);
39172774f206SBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DPD_CTL15,
39182774f206SBjoern A. Zeeb 			    0x05020008 | (BIT(path) << 28));
39192774f206SBjoern A. Zeeb 	}
39202774f206SBjoern A. Zeeb 
39212774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DPD_CTL0, MASKBYTE3, 0x8 | path);
39222774f206SBjoern A. Zeeb 
39232774f206SBjoern A. Zeeb 	rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_CAL_PWR);
39242774f206SBjoern A. Zeeb 
39252774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DPD_CTL15, MASKBYTE3, 0x0);
39262774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
39272774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0);
39282774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x0);
39292774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
39302774f206SBjoern A. Zeeb 
39312774f206SBjoern A. Zeeb 	if (path == RF_PATH_A)
39322774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 0x5b);
39332774f206SBjoern A. Zeeb 	else
39342774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 0x5b);
39352774f206SBjoern A. Zeeb 
39362774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0);
39372774f206SBjoern A. Zeeb 
39382774f206SBjoern A. Zeeb 	tmp_gs = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, BIT_RPT_DGAIN);
39392774f206SBjoern A. Zeeb 	tmp_gs = (tmp_gs * 910) >> 10;
39402774f206SBjoern A. Zeeb 	tmp_gs = DIV_ROUND_CLOSEST(tmp_gs, 10);
39412774f206SBjoern A. Zeeb 
39422774f206SBjoern A. Zeeb 	if (path == RF_PATH_A)
39432774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, tmp_gs);
39442774f206SBjoern A. Zeeb 	else
39452774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, tmp_gs);
39462774f206SBjoern A. Zeeb 
39472774f206SBjoern A. Zeeb 	dpk_info->dpk_gs[path] = tmp_gs;
39482774f206SBjoern A. Zeeb }
39492774f206SBjoern A. Zeeb 
39502774f206SBjoern A. Zeeb static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev)
39512774f206SBjoern A. Zeeb {
39522774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
39532774f206SBjoern A. Zeeb 	u32 offset[DPK_RF_PATH_NUM] = {0, 0x58};
39542774f206SBjoern A. Zeeb 	u32 i_scaling;
39552774f206SBjoern A. Zeeb 	u8 path;
39562774f206SBjoern A. Zeeb 
39572774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c);
39582774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0);
39592774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_NCTL0, 0x00001148);
39602774f206SBjoern A. Zeeb 	rtw_write32(rtwdev, REG_NCTL0, 0x00001149);
39612774f206SBjoern A. Zeeb 
39622774f206SBjoern A. Zeeb 	check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55);
39632774f206SBjoern A. Zeeb 
39642774f206SBjoern A. Zeeb 	rtw_write8(rtwdev, 0x1b10, 0x0);
39652774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c);
39662774f206SBjoern A. Zeeb 
39672774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
39682774f206SBjoern A. Zeeb 		i_scaling = 0x16c00 / dpk_info->dpk_gs[path];
39692774f206SBjoern A. Zeeb 
39702774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x1b18 + offset[path], MASKHWORD,
39712774f206SBjoern A. Zeeb 				 i_scaling);
39722774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path],
39732774f206SBjoern A. Zeeb 				 GENMASK(31, 28), 0x9);
39742774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path],
39752774f206SBjoern A. Zeeb 				 GENMASK(31, 28), 0x1);
39762774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path],
39772774f206SBjoern A. Zeeb 				 GENMASK(31, 28), 0x0);
39782774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0 + offset[path],
39792774f206SBjoern A. Zeeb 				 BIT(14), 0x0);
39802774f206SBjoern A. Zeeb 	}
39812774f206SBjoern A. Zeeb }
39822774f206SBjoern A. Zeeb 
39832774f206SBjoern A. Zeeb static void rtw8822c_dpk_on(struct rtw_dev *rtwdev, u8 path)
39842774f206SBjoern A. Zeeb {
39852774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
39862774f206SBjoern A. Zeeb 
39872774f206SBjoern A. Zeeb 	rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON);
39882774f206SBjoern A. Zeeb 
39892774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1));
39902774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0);
39912774f206SBjoern A. Zeeb 
39922774f206SBjoern A. Zeeb 	if (test_bit(path, dpk_info->dpk_path_ok))
39932774f206SBjoern A. Zeeb 		rtw8822c_dpk_cal_gs(rtwdev, path);
39942774f206SBjoern A. Zeeb }
39952774f206SBjoern A. Zeeb 
39962774f206SBjoern A. Zeeb static bool rtw8822c_dpk_check_pass(struct rtw_dev *rtwdev, bool is_fail,
39972774f206SBjoern A. Zeeb 				    u32 dpk_txagc, u8 path)
39982774f206SBjoern A. Zeeb {
39992774f206SBjoern A. Zeeb 	bool result;
40002774f206SBjoern A. Zeeb 
40012774f206SBjoern A. Zeeb 	if (!is_fail) {
40022774f206SBjoern A. Zeeb 		if (rtw8822c_dpk_coef_read(rtwdev, path))
40032774f206SBjoern A. Zeeb 			result = true;
40042774f206SBjoern A. Zeeb 		else
40052774f206SBjoern A. Zeeb 			result = false;
40062774f206SBjoern A. Zeeb 	} else {
40072774f206SBjoern A. Zeeb 		result = false;
40082774f206SBjoern A. Zeeb 	}
40092774f206SBjoern A. Zeeb 
40102774f206SBjoern A. Zeeb 	rtw8822c_dpk_fill_result(rtwdev, dpk_txagc, path, result);
40112774f206SBjoern A. Zeeb 
40122774f206SBjoern A. Zeeb 	return result;
40132774f206SBjoern A. Zeeb }
40142774f206SBjoern A. Zeeb 
40152774f206SBjoern A. Zeeb static void rtw8822c_dpk_result_reset(struct rtw_dev *rtwdev)
40162774f206SBjoern A. Zeeb {
40172774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
40182774f206SBjoern A. Zeeb 	u8 path;
40192774f206SBjoern A. Zeeb 
40202774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
40212774f206SBjoern A. Zeeb 		clear_bit(path, dpk_info->dpk_path_ok);
40222774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE,
40232774f206SBjoern A. Zeeb 				 0x8 | (path << 1));
40242774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x1b58, 0x0000007f, 0x0);
40252774f206SBjoern A. Zeeb 
40262774f206SBjoern A. Zeeb 		dpk_info->dpk_txagc[path] = 0;
40272774f206SBjoern A. Zeeb 		dpk_info->result[path] = 0;
40282774f206SBjoern A. Zeeb 		dpk_info->dpk_gs[path] = 0x5b;
40292774f206SBjoern A. Zeeb 		dpk_info->pre_pwsf[path] = 0;
40302774f206SBjoern A. Zeeb 		dpk_info->thermal_dpk[path] = rtw8822c_dpk_thermal_read(rtwdev,
40312774f206SBjoern A. Zeeb 									path);
40322774f206SBjoern A. Zeeb 	}
40332774f206SBjoern A. Zeeb }
40342774f206SBjoern A. Zeeb 
40352774f206SBjoern A. Zeeb static void rtw8822c_dpk_calibrate(struct rtw_dev *rtwdev, u8 path)
40362774f206SBjoern A. Zeeb {
40372774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
40382774f206SBjoern A. Zeeb 	u32 dpk_txagc;
40392774f206SBjoern A. Zeeb 	u8 dpk_fail;
40402774f206SBjoern A. Zeeb 
40412774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk start\n", path);
40422774f206SBjoern A. Zeeb 
40432774f206SBjoern A. Zeeb 	dpk_txagc = rtw8822c_dpk_gainloss(rtwdev, path);
40442774f206SBjoern A. Zeeb 
40452774f206SBjoern A. Zeeb 	dpk_fail = rtw8822c_dpk_by_path(rtwdev, dpk_txagc, path);
40462774f206SBjoern A. Zeeb 
40472774f206SBjoern A. Zeeb 	if (!rtw8822c_dpk_check_pass(rtwdev, dpk_fail, dpk_txagc, path))
40482774f206SBjoern A. Zeeb 		rtw_err(rtwdev, "failed to do dpk calibration\n");
40492774f206SBjoern A. Zeeb 
40502774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk finish\n", path);
40512774f206SBjoern A. Zeeb 
40522774f206SBjoern A. Zeeb 	if (dpk_info->result[path])
40532774f206SBjoern A. Zeeb 		set_bit(path, dpk_info->dpk_path_ok);
40542774f206SBjoern A. Zeeb }
40552774f206SBjoern A. Zeeb 
40562774f206SBjoern A. Zeeb static void rtw8822c_dpk_path_select(struct rtw_dev *rtwdev)
40572774f206SBjoern A. Zeeb {
40582774f206SBjoern A. Zeeb 	rtw8822c_dpk_calibrate(rtwdev, RF_PATH_A);
40592774f206SBjoern A. Zeeb 	rtw8822c_dpk_calibrate(rtwdev, RF_PATH_B);
40602774f206SBjoern A. Zeeb 	rtw8822c_dpk_on(rtwdev, RF_PATH_A);
40612774f206SBjoern A. Zeeb 	rtw8822c_dpk_on(rtwdev, RF_PATH_B);
40622774f206SBjoern A. Zeeb 	rtw8822c_dpk_cal_coef1(rtwdev);
40632774f206SBjoern A. Zeeb }
40642774f206SBjoern A. Zeeb 
40652774f206SBjoern A. Zeeb static void rtw8822c_dpk_enable_disable(struct rtw_dev *rtwdev)
40662774f206SBjoern A. Zeeb {
40672774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
40682774f206SBjoern A. Zeeb 	u32 mask = BIT(15) | BIT(14);
40692774f206SBjoern A. Zeeb 
40702774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
40712774f206SBjoern A. Zeeb 
40722774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN,
40732774f206SBjoern A. Zeeb 			 dpk_info->is_dpk_pwr_on);
40742774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN,
40752774f206SBjoern A. Zeeb 			 dpk_info->is_dpk_pwr_on);
40762774f206SBjoern A. Zeeb 
40772774f206SBjoern A. Zeeb 	if (test_bit(RF_PATH_A, dpk_info->dpk_path_ok)) {
40782774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, mask, 0x0);
40792774f206SBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DPD_CTL0_S0, dpk_info->dpk_gs[RF_PATH_A]);
40802774f206SBjoern A. Zeeb 	}
40812774f206SBjoern A. Zeeb 	if (test_bit(RF_PATH_B, dpk_info->dpk_path_ok)) {
40822774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, mask, 0x0);
40832774f206SBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DPD_CTL0_S1, dpk_info->dpk_gs[RF_PATH_B]);
40842774f206SBjoern A. Zeeb 	}
40852774f206SBjoern A. Zeeb }
40862774f206SBjoern A. Zeeb 
40872774f206SBjoern A. Zeeb static void rtw8822c_dpk_reload_data(struct rtw_dev *rtwdev)
40882774f206SBjoern A. Zeeb {
40892774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
40902774f206SBjoern A. Zeeb 	u8 path;
40912774f206SBjoern A. Zeeb 
40922774f206SBjoern A. Zeeb 	if (!test_bit(RF_PATH_A, dpk_info->dpk_path_ok) &&
40932774f206SBjoern A. Zeeb 	    !test_bit(RF_PATH_B, dpk_info->dpk_path_ok) &&
40942774f206SBjoern A. Zeeb 	    dpk_info->dpk_ch == 0)
40952774f206SBjoern A. Zeeb 		return;
40962774f206SBjoern A. Zeeb 
40972774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
40982774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE,
40992774f206SBjoern A. Zeeb 				 0x8 | (path << 1));
41002774f206SBjoern A. Zeeb 		if (dpk_info->dpk_band == RTW_BAND_2G)
41012774f206SBjoern A. Zeeb 			rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000);
41022774f206SBjoern A. Zeeb 		else
41032774f206SBjoern A. Zeeb 			rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000);
41042774f206SBjoern A. Zeeb 
41052774f206SBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DPD_AGC, dpk_info->dpk_txagc[path]);
41062774f206SBjoern A. Zeeb 
41072774f206SBjoern A. Zeeb 		rtw8822c_dpk_coef_write(rtwdev, path,
41082774f206SBjoern A. Zeeb 					test_bit(path, dpk_info->dpk_path_ok));
41092774f206SBjoern A. Zeeb 
41102774f206SBjoern A. Zeeb 		rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON);
41112774f206SBjoern A. Zeeb 
41122774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc);
41132774f206SBjoern A. Zeeb 
41142774f206SBjoern A. Zeeb 		if (path == RF_PATH_A)
41152774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF,
41162774f206SBjoern A. Zeeb 					 dpk_info->dpk_gs[path]);
41172774f206SBjoern A. Zeeb 		else
41182774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF,
41192774f206SBjoern A. Zeeb 					 dpk_info->dpk_gs[path]);
41202774f206SBjoern A. Zeeb 	}
41212774f206SBjoern A. Zeeb 	rtw8822c_dpk_cal_coef1(rtwdev);
41222774f206SBjoern A. Zeeb }
41232774f206SBjoern A. Zeeb 
41242774f206SBjoern A. Zeeb static bool rtw8822c_dpk_reload(struct rtw_dev *rtwdev)
41252774f206SBjoern A. Zeeb {
41262774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
41272774f206SBjoern A. Zeeb 	u8 channel;
41282774f206SBjoern A. Zeeb 
41292774f206SBjoern A. Zeeb 	dpk_info->is_reload = false;
41302774f206SBjoern A. Zeeb 
41314f3b2bbaSBjoern A. Zeeb #if defined(__linux__)
41322774f206SBjoern A. Zeeb 	channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK) & 0xff);
41334f3b2bbaSBjoern A. Zeeb #elif defined(__FreeBSD__)
41344f3b2bbaSBjoern A. Zeeb 	channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK) & 0xff);
41354f3b2bbaSBjoern A. Zeeb #endif
41362774f206SBjoern A. Zeeb 
41372774f206SBjoern A. Zeeb 	if (channel == dpk_info->dpk_ch) {
41382774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
41392774f206SBjoern A. Zeeb 			"[DPK] DPK reload for CH%d!!\n", dpk_info->dpk_ch);
41402774f206SBjoern A. Zeeb 		rtw8822c_dpk_reload_data(rtwdev);
41412774f206SBjoern A. Zeeb 		dpk_info->is_reload = true;
41422774f206SBjoern A. Zeeb 	}
41432774f206SBjoern A. Zeeb 
41442774f206SBjoern A. Zeeb 	return dpk_info->is_reload;
41452774f206SBjoern A. Zeeb }
41462774f206SBjoern A. Zeeb 
41472774f206SBjoern A. Zeeb static void rtw8822c_do_dpk(struct rtw_dev *rtwdev)
41482774f206SBjoern A. Zeeb {
41492774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
41502774f206SBjoern A. Zeeb 	struct rtw_backup_info bckp[DPK_BB_REG_NUM];
41512774f206SBjoern A. Zeeb 	u32 rf_reg_backup[DPK_RF_REG_NUM][DPK_RF_PATH_NUM];
41522774f206SBjoern A. Zeeb 	u32 bb_reg[DPK_BB_REG_NUM] = {
41532774f206SBjoern A. Zeeb 		0x520, 0x820, 0x824, 0x1c3c, 0x1d58, 0x1864,
41542774f206SBjoern A. Zeeb 		0x4164, 0x180c, 0x410c, 0x186c, 0x416c,
41552774f206SBjoern A. Zeeb 		0x1a14, 0x1e70, 0x80c, 0x1d70, 0x1e7c, 0x18a4, 0x41a4};
41562774f206SBjoern A. Zeeb 	u32 rf_reg[DPK_RF_REG_NUM] = {
41572774f206SBjoern A. Zeeb 		0x0, 0x1a, 0x55, 0x63, 0x87, 0x8f, 0xde};
41582774f206SBjoern A. Zeeb 	u8 path;
41592774f206SBjoern A. Zeeb 
41602774f206SBjoern A. Zeeb 	if (!dpk_info->is_dpk_pwr_on) {
41612774f206SBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] Skip DPK due to DPD PWR off\n");
41622774f206SBjoern A. Zeeb 		return;
41632774f206SBjoern A. Zeeb 	} else if (rtw8822c_dpk_reload(rtwdev)) {
41642774f206SBjoern A. Zeeb 		return;
41652774f206SBjoern A. Zeeb 	}
41662774f206SBjoern A. Zeeb 
41672774f206SBjoern A. Zeeb 	for (path = RF_PATH_A; path < DPK_RF_PATH_NUM; path++)
41682774f206SBjoern A. Zeeb 		ewma_thermal_init(&dpk_info->avg_thermal[path]);
41692774f206SBjoern A. Zeeb 
41702774f206SBjoern A. Zeeb 	rtw8822c_dpk_information(rtwdev);
41712774f206SBjoern A. Zeeb 
41722774f206SBjoern A. Zeeb 	rtw8822c_dpk_backup_registers(rtwdev, bb_reg, DPK_BB_REG_NUM, bckp);
41732774f206SBjoern A. Zeeb 	rtw8822c_dpk_backup_rf_registers(rtwdev, rf_reg, rf_reg_backup);
41742774f206SBjoern A. Zeeb 
41752774f206SBjoern A. Zeeb 	rtw8822c_dpk_mac_bb_setting(rtwdev);
41762774f206SBjoern A. Zeeb 	rtw8822c_dpk_afe_setting(rtwdev, true);
41772774f206SBjoern A. Zeeb 	rtw8822c_dpk_pre_setting(rtwdev);
41782774f206SBjoern A. Zeeb 	rtw8822c_dpk_result_reset(rtwdev);
41792774f206SBjoern A. Zeeb 	rtw8822c_dpk_path_select(rtwdev);
41802774f206SBjoern A. Zeeb 	rtw8822c_dpk_afe_setting(rtwdev, false);
41812774f206SBjoern A. Zeeb 	rtw8822c_dpk_enable_disable(rtwdev);
41822774f206SBjoern A. Zeeb 
41832774f206SBjoern A. Zeeb 	rtw8822c_dpk_reload_rf_registers(rtwdev, rf_reg, rf_reg_backup);
41842774f206SBjoern A. Zeeb 	for (path = 0; path < rtwdev->hal.rf_path_num; path++)
41852774f206SBjoern A. Zeeb 		rtw8822c_dpk_rxbb_dc_cal(rtwdev, path);
41862774f206SBjoern A. Zeeb 	rtw8822c_dpk_restore_registers(rtwdev, DPK_BB_REG_NUM, bckp);
41872774f206SBjoern A. Zeeb }
41882774f206SBjoern A. Zeeb 
41892774f206SBjoern A. Zeeb static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev)
41902774f206SBjoern A. Zeeb {
41912774f206SBjoern A. Zeeb 	rtw8822c_rfk_power_save(rtwdev, false);
41922774f206SBjoern A. Zeeb 	rtw8822c_do_gapk(rtwdev);
41932774f206SBjoern A. Zeeb 	rtw8822c_do_iqk(rtwdev);
41942774f206SBjoern A. Zeeb 	rtw8822c_do_dpk(rtwdev);
41952774f206SBjoern A. Zeeb 	rtw8822c_rfk_power_save(rtwdev, true);
41962774f206SBjoern A. Zeeb }
41972774f206SBjoern A. Zeeb 
41982774f206SBjoern A. Zeeb static void rtw8822c_dpk_track(struct rtw_dev *rtwdev)
41992774f206SBjoern A. Zeeb {
42002774f206SBjoern A. Zeeb 	struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
42012774f206SBjoern A. Zeeb 	u8 path;
42022774f206SBjoern A. Zeeb 	u8 thermal_value[DPK_RF_PATH_NUM] = {0};
42032774f206SBjoern A. Zeeb 	s8 offset[DPK_RF_PATH_NUM], delta_dpk[DPK_RF_PATH_NUM];
42042774f206SBjoern A. Zeeb 
42052774f206SBjoern A. Zeeb 	if (dpk_info->thermal_dpk[0] == 0 && dpk_info->thermal_dpk[1] == 0)
42062774f206SBjoern A. Zeeb 		return;
42072774f206SBjoern A. Zeeb 
42082774f206SBjoern A. Zeeb 	for (path = 0; path < DPK_RF_PATH_NUM; path++) {
42092774f206SBjoern A. Zeeb 		thermal_value[path] = rtw8822c_dpk_thermal_read(rtwdev, path);
42102774f206SBjoern A. Zeeb 		ewma_thermal_add(&dpk_info->avg_thermal[path],
42112774f206SBjoern A. Zeeb 				 thermal_value[path]);
42122774f206SBjoern A. Zeeb 		thermal_value[path] =
42132774f206SBjoern A. Zeeb 			ewma_thermal_read(&dpk_info->avg_thermal[path]);
42142774f206SBjoern A. Zeeb 		delta_dpk[path] = dpk_info->thermal_dpk[path] -
42152774f206SBjoern A. Zeeb 				  thermal_value[path];
42162774f206SBjoern A. Zeeb 		offset[path] = delta_dpk[path] -
42172774f206SBjoern A. Zeeb 			       dpk_info->thermal_dpk_delta[path];
42182774f206SBjoern A. Zeeb 		offset[path] &= 0x7f;
42192774f206SBjoern A. Zeeb 
42202774f206SBjoern A. Zeeb 		if (offset[path] != dpk_info->pre_pwsf[path]) {
42212774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE,
42222774f206SBjoern A. Zeeb 					 0x8 | (path << 1));
42232774f206SBjoern A. Zeeb 			rtw_write32_mask(rtwdev, 0x1b58, GENMASK(6, 0),
42242774f206SBjoern A. Zeeb 					 offset[path]);
42252774f206SBjoern A. Zeeb 			dpk_info->pre_pwsf[path] = offset[path];
42262774f206SBjoern A. Zeeb 		}
42272774f206SBjoern A. Zeeb 	}
42282774f206SBjoern A. Zeeb }
42292774f206SBjoern A. Zeeb 
42302774f206SBjoern A. Zeeb #define XCAP_EXTEND(val) ({typeof(val) _v = (val); _v | _v << 7; })
42312774f206SBjoern A. Zeeb static void rtw8822c_set_crystal_cap_reg(struct rtw_dev *rtwdev, u8 crystal_cap)
42322774f206SBjoern A. Zeeb {
42332774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
42342774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
42352774f206SBjoern A. Zeeb 	u32 val = 0;
42362774f206SBjoern A. Zeeb 
42372774f206SBjoern A. Zeeb 	val = XCAP_EXTEND(crystal_cap);
42382774f206SBjoern A. Zeeb 	cfo->crystal_cap = crystal_cap;
42392774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, BIT_XCAP_0, val);
42402774f206SBjoern A. Zeeb }
42412774f206SBjoern A. Zeeb 
42422774f206SBjoern A. Zeeb static void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap)
42432774f206SBjoern A. Zeeb {
42442774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
42452774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
42462774f206SBjoern A. Zeeb 
42472774f206SBjoern A. Zeeb 	if (cfo->crystal_cap == crystal_cap)
42482774f206SBjoern A. Zeeb 		return;
42492774f206SBjoern A. Zeeb 
42502774f206SBjoern A. Zeeb 	rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap);
42512774f206SBjoern A. Zeeb }
42522774f206SBjoern A. Zeeb 
42532774f206SBjoern A. Zeeb static void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev)
42542774f206SBjoern A. Zeeb {
42552774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
42562774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
42572774f206SBjoern A. Zeeb 
42582774f206SBjoern A. Zeeb 	cfo->is_adjust = true;
42592774f206SBjoern A. Zeeb 
42602774f206SBjoern A. Zeeb 	if (cfo->crystal_cap > rtwdev->efuse.crystal_cap)
42612774f206SBjoern A. Zeeb 		rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1);
42622774f206SBjoern A. Zeeb 	else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap)
42632774f206SBjoern A. Zeeb 		rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1);
42642774f206SBjoern A. Zeeb }
42652774f206SBjoern A. Zeeb 
42662774f206SBjoern A. Zeeb static void rtw8822c_cfo_init(struct rtw_dev *rtwdev)
42672774f206SBjoern A. Zeeb {
42682774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
42692774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
42702774f206SBjoern A. Zeeb 
42712774f206SBjoern A. Zeeb 	cfo->crystal_cap = rtwdev->efuse.crystal_cap;
42722774f206SBjoern A. Zeeb 	cfo->is_adjust = true;
42732774f206SBjoern A. Zeeb }
42742774f206SBjoern A. Zeeb 
42752774f206SBjoern A. Zeeb #define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); })
42762774f206SBjoern A. Zeeb static s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num)
42772774f206SBjoern A. Zeeb {
42782774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
42792774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
42802774f206SBjoern A. Zeeb 	s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum;
42812774f206SBjoern A. Zeeb 	u8 i;
42822774f206SBjoern A. Zeeb 
42832774f206SBjoern A. Zeeb 	for (i = 0; i < path_num; i++) {
42842774f206SBjoern A. Zeeb 		cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]);
42852774f206SBjoern A. Zeeb 
42862774f206SBjoern A. Zeeb 		if (cfo->cfo_cnt[i])
42872774f206SBjoern A. Zeeb 			cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i];
42882774f206SBjoern A. Zeeb 		else
42892774f206SBjoern A. Zeeb 			cfo_avg = 0;
42902774f206SBjoern A. Zeeb 
42912774f206SBjoern A. Zeeb 		cfo_path_sum += cfo_avg;
42922774f206SBjoern A. Zeeb 	}
42932774f206SBjoern A. Zeeb 
42942774f206SBjoern A. Zeeb 	for (i = 0; i < path_num; i++) {
42952774f206SBjoern A. Zeeb 		cfo->cfo_tail[i] = 0;
42962774f206SBjoern A. Zeeb 		cfo->cfo_cnt[i] = 0;
42972774f206SBjoern A. Zeeb 	}
42982774f206SBjoern A. Zeeb 
42992774f206SBjoern A. Zeeb 	return cfo_path_sum / path_num;
43002774f206SBjoern A. Zeeb }
43012774f206SBjoern A. Zeeb 
43022774f206SBjoern A. Zeeb static void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg)
43032774f206SBjoern A. Zeeb {
43042774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
43052774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
43062774f206SBjoern A. Zeeb 
43072774f206SBjoern A. Zeeb 	if (!cfo->is_adjust) {
43082774f206SBjoern A. Zeeb 		if (abs(cfo_avg) > CFO_TRK_ENABLE_TH)
43092774f206SBjoern A. Zeeb 			cfo->is_adjust = true;
43102774f206SBjoern A. Zeeb 	} else {
43112774f206SBjoern A. Zeeb 		if (abs(cfo_avg) <= CFO_TRK_STOP_TH)
43122774f206SBjoern A. Zeeb 			cfo->is_adjust = false;
43132774f206SBjoern A. Zeeb 	}
43142774f206SBjoern A. Zeeb 
43152774f206SBjoern A. Zeeb 	if (!rtw_coex_disabled(rtwdev)) {
43162774f206SBjoern A. Zeeb 		cfo->is_adjust = false;
43172774f206SBjoern A. Zeeb 		rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap);
43182774f206SBjoern A. Zeeb 	}
43192774f206SBjoern A. Zeeb }
43202774f206SBjoern A. Zeeb 
43212774f206SBjoern A. Zeeb static void rtw8822c_cfo_track(struct rtw_dev *rtwdev)
43222774f206SBjoern A. Zeeb {
43232774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
43242774f206SBjoern A. Zeeb 	struct rtw_cfo_track *cfo = &dm_info->cfo_track;
43252774f206SBjoern A. Zeeb 	u8 path_num = rtwdev->hal.rf_path_num;
43262774f206SBjoern A. Zeeb 	s8 crystal_cap = cfo->crystal_cap;
43272774f206SBjoern A. Zeeb 	s32 cfo_avg = 0;
43282774f206SBjoern A. Zeeb 
43292774f206SBjoern A. Zeeb 	if (rtwdev->sta_cnt != 1) {
43302774f206SBjoern A. Zeeb 		rtw8822c_cfo_tracking_reset(rtwdev);
43312774f206SBjoern A. Zeeb 		return;
43322774f206SBjoern A. Zeeb 	}
43332774f206SBjoern A. Zeeb 
43342774f206SBjoern A. Zeeb 	if (cfo->packet_count == cfo->packet_count_pre)
43352774f206SBjoern A. Zeeb 		return;
43362774f206SBjoern A. Zeeb 
43372774f206SBjoern A. Zeeb 	cfo->packet_count_pre = cfo->packet_count;
43382774f206SBjoern A. Zeeb 	cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num);
43392774f206SBjoern A. Zeeb 	rtw8822c_cfo_need_adjust(rtwdev, cfo_avg);
43402774f206SBjoern A. Zeeb 
43412774f206SBjoern A. Zeeb 	if (cfo->is_adjust) {
43422774f206SBjoern A. Zeeb 		if (cfo_avg > CFO_TRK_ADJ_TH)
43432774f206SBjoern A. Zeeb 			crystal_cap++;
43442774f206SBjoern A. Zeeb 		else if (cfo_avg < -CFO_TRK_ADJ_TH)
43452774f206SBjoern A. Zeeb 			crystal_cap--;
43462774f206SBjoern A. Zeeb 
43472774f206SBjoern A. Zeeb 		crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK);
43482774f206SBjoern A. Zeeb 		rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap);
43492774f206SBjoern A. Zeeb 	}
43502774f206SBjoern A. Zeeb }
43512774f206SBjoern A. Zeeb 
43522774f206SBjoern A. Zeeb static const struct rtw_phy_cck_pd_reg
43532774f206SBjoern A. Zeeb rtw8822c_cck_pd_reg[RTW_CHANNEL_WIDTH_40 + 1][RTW_RF_PATH_MAX] = {
43542774f206SBjoern A. Zeeb 	{
43552774f206SBjoern A. Zeeb 		{0x1ac8, 0x00ff, 0x1ad0, 0x01f},
43562774f206SBjoern A. Zeeb 		{0x1ac8, 0xff00, 0x1ad0, 0x3e0}
43572774f206SBjoern A. Zeeb 	},
43582774f206SBjoern A. Zeeb 	{
43592774f206SBjoern A. Zeeb 		{0x1acc, 0x00ff, 0x1ad0, 0x01F00000},
43602774f206SBjoern A. Zeeb 		{0x1acc, 0xff00, 0x1ad0, 0x3E000000}
43612774f206SBjoern A. Zeeb 	},
43622774f206SBjoern A. Zeeb };
43632774f206SBjoern A. Zeeb 
43642774f206SBjoern A. Zeeb #define RTW_CCK_PD_MAX 255
43652774f206SBjoern A. Zeeb #define RTW_CCK_CS_MAX 31
43662774f206SBjoern A. Zeeb #define RTW_CCK_CS_ERR1 27
43672774f206SBjoern A. Zeeb #define RTW_CCK_CS_ERR2 29
43682774f206SBjoern A. Zeeb static void
43692774f206SBjoern A. Zeeb rtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev,
43702774f206SBjoern A. Zeeb 			    s8 pd_diff, s8 cs_diff, u8 bw, u8 nrx)
43712774f206SBjoern A. Zeeb {
43722774f206SBjoern A. Zeeb 	u32 pd, cs;
43732774f206SBjoern A. Zeeb 
43742774f206SBjoern A. Zeeb 	if (WARN_ON(bw > RTW_CHANNEL_WIDTH_40 || nrx >= RTW_RF_PATH_MAX))
43752774f206SBjoern A. Zeeb 		return;
43762774f206SBjoern A. Zeeb 
43772774f206SBjoern A. Zeeb 	pd = rtw_read32_mask(rtwdev,
43782774f206SBjoern A. Zeeb 			     rtw8822c_cck_pd_reg[bw][nrx].reg_pd,
43792774f206SBjoern A. Zeeb 			     rtw8822c_cck_pd_reg[bw][nrx].mask_pd);
43802774f206SBjoern A. Zeeb 	cs = rtw_read32_mask(rtwdev,
43812774f206SBjoern A. Zeeb 			     rtw8822c_cck_pd_reg[bw][nrx].reg_cs,
43822774f206SBjoern A. Zeeb 			     rtw8822c_cck_pd_reg[bw][nrx].mask_cs);
43832774f206SBjoern A. Zeeb 	pd += pd_diff;
43842774f206SBjoern A. Zeeb 	cs += cs_diff;
43852774f206SBjoern A. Zeeb 	if (pd > RTW_CCK_PD_MAX)
43862774f206SBjoern A. Zeeb 		pd = RTW_CCK_PD_MAX;
43872774f206SBjoern A. Zeeb 	if (cs == RTW_CCK_CS_ERR1 || cs == RTW_CCK_CS_ERR2)
43882774f206SBjoern A. Zeeb 		cs++;
43892774f206SBjoern A. Zeeb 	else if (cs > RTW_CCK_CS_MAX)
43902774f206SBjoern A. Zeeb 		cs = RTW_CCK_CS_MAX;
43912774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev,
43922774f206SBjoern A. Zeeb 			 rtw8822c_cck_pd_reg[bw][nrx].reg_pd,
43932774f206SBjoern A. Zeeb 			 rtw8822c_cck_pd_reg[bw][nrx].mask_pd,
43942774f206SBjoern A. Zeeb 			 pd);
43952774f206SBjoern A. Zeeb 	rtw_write32_mask(rtwdev,
43962774f206SBjoern A. Zeeb 			 rtw8822c_cck_pd_reg[bw][nrx].reg_cs,
43972774f206SBjoern A. Zeeb 			 rtw8822c_cck_pd_reg[bw][nrx].mask_cs,
43982774f206SBjoern A. Zeeb 			 cs);
43992774f206SBjoern A. Zeeb 
44002774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_PHY,
44012774f206SBjoern A. Zeeb 		"is_linked=%d, bw=%d, nrx=%d, cs_ratio=0x%x, pd_th=0x%x\n",
44022774f206SBjoern A. Zeeb 		rtw_is_assoc(rtwdev), bw, nrx, cs, pd);
44032774f206SBjoern A. Zeeb }
44042774f206SBjoern A. Zeeb 
44052774f206SBjoern A. Zeeb static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
44062774f206SBjoern A. Zeeb {
44072774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
44082774f206SBjoern A. Zeeb 	s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8};
44092774f206SBjoern A. Zeeb 	s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4};
44102774f206SBjoern A. Zeeb 	u8 cur_lvl;
44112774f206SBjoern A. Zeeb 	u8 nrx, bw;
44122774f206SBjoern A. Zeeb 
44132774f206SBjoern A. Zeeb 	nrx = (u8)rtw_read32_mask(rtwdev, 0x1a2c, 0x60000);
44142774f206SBjoern A. Zeeb 	bw = (u8)rtw_read32_mask(rtwdev, 0x9b0, 0xc);
44152774f206SBjoern A. Zeeb 
44162774f206SBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d) bw=%d nr=%d cck_fa_avg=%d\n",
44172774f206SBjoern A. Zeeb 		dm_info->cck_pd_lv[bw][nrx], new_lvl, bw, nrx,
44182774f206SBjoern A. Zeeb 		dm_info->cck_fa_avg);
44192774f206SBjoern A. Zeeb 
44202774f206SBjoern A. Zeeb 	if (dm_info->cck_pd_lv[bw][nrx] == new_lvl)
44212774f206SBjoern A. Zeeb 		return;
44222774f206SBjoern A. Zeeb 
44232774f206SBjoern A. Zeeb 	cur_lvl = dm_info->cck_pd_lv[bw][nrx];
44242774f206SBjoern A. Zeeb 
44252774f206SBjoern A. Zeeb 	/* update cck pd info */
44262774f206SBjoern A. Zeeb 	dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
44272774f206SBjoern A. Zeeb 
44282774f206SBjoern A. Zeeb 	rtw8822c_phy_cck_pd_set_reg(rtwdev,
44292774f206SBjoern A. Zeeb 				    pd_lvl[new_lvl] - pd_lvl[cur_lvl],
44302774f206SBjoern A. Zeeb 				    cs_lvl[new_lvl] - cs_lvl[cur_lvl],
44312774f206SBjoern A. Zeeb 				    bw, nrx);
44322774f206SBjoern A. Zeeb 	dm_info->cck_pd_lv[bw][nrx] = new_lvl;
44332774f206SBjoern A. Zeeb }
44342774f206SBjoern A. Zeeb 
44352774f206SBjoern A. Zeeb #define PWR_TRACK_MASK 0x7f
44362774f206SBjoern A. Zeeb static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path)
44372774f206SBjoern A. Zeeb {
44382774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
44392774f206SBjoern A. Zeeb 
44402774f206SBjoern A. Zeeb 	switch (rf_path) {
44412774f206SBjoern A. Zeeb 	case RF_PATH_A:
44422774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK,
44432774f206SBjoern A. Zeeb 				 dm_info->delta_power_index[rf_path]);
44442774f206SBjoern A. Zeeb 		break;
44452774f206SBjoern A. Zeeb 	case RF_PATH_B:
44462774f206SBjoern A. Zeeb 		rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK,
44472774f206SBjoern A. Zeeb 				 dm_info->delta_power_index[rf_path]);
44482774f206SBjoern A. Zeeb 		break;
44492774f206SBjoern A. Zeeb 	default:
44502774f206SBjoern A. Zeeb 		break;
44512774f206SBjoern A. Zeeb 	}
44522774f206SBjoern A. Zeeb }
44532774f206SBjoern A. Zeeb 
44542774f206SBjoern A. Zeeb static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path)
44552774f206SBjoern A. Zeeb {
44562774f206SBjoern A. Zeeb 	u8 thermal_value;
44572774f206SBjoern A. Zeeb 
44582774f206SBjoern A. Zeeb 	if (rtwdev->efuse.thermal_meter[path] == 0xff)
44592774f206SBjoern A. Zeeb 		return;
44602774f206SBjoern A. Zeeb 
44612774f206SBjoern A. Zeeb 	thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e);
44622774f206SBjoern A. Zeeb 	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path);
44632774f206SBjoern A. Zeeb }
44642774f206SBjoern A. Zeeb 
44652774f206SBjoern A. Zeeb static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev,
44662774f206SBjoern A. Zeeb 				    struct rtw_swing_table *swing_table,
44672774f206SBjoern A. Zeeb 				    u8 path)
44682774f206SBjoern A. Zeeb {
44692774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
44702774f206SBjoern A. Zeeb 	u8 delta;
44712774f206SBjoern A. Zeeb 
44722774f206SBjoern A. Zeeb 	delta = rtw_phy_pwrtrack_get_delta(rtwdev, path);
44732774f206SBjoern A. Zeeb 	dm_info->delta_power_index[path] =
44742774f206SBjoern A. Zeeb 		rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path,
44752774f206SBjoern A. Zeeb 					    delta);
44762774f206SBjoern A. Zeeb 	rtw8822c_pwrtrack_set(rtwdev, path);
44772774f206SBjoern A. Zeeb }
44782774f206SBjoern A. Zeeb 
44792774f206SBjoern A. Zeeb static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev)
44802774f206SBjoern A. Zeeb {
44812774f206SBjoern A. Zeeb 	struct rtw_swing_table swing_table;
44822774f206SBjoern A. Zeeb 	u8 i;
44832774f206SBjoern A. Zeeb 
44842774f206SBjoern A. Zeeb 	rtw_phy_config_swing_table(rtwdev, &swing_table);
44852774f206SBjoern A. Zeeb 
44862774f206SBjoern A. Zeeb 	for (i = 0; i < rtwdev->hal.rf_path_num; i++)
44872774f206SBjoern A. Zeeb 		rtw8822c_pwr_track_stats(rtwdev, i);
44882774f206SBjoern A. Zeeb 	if (rtw_phy_pwrtrack_need_lck(rtwdev))
44892774f206SBjoern A. Zeeb 		rtw8822c_do_lck(rtwdev);
44902774f206SBjoern A. Zeeb 	for (i = 0; i < rtwdev->hal.rf_path_num; i++)
44912774f206SBjoern A. Zeeb 		rtw8822c_pwr_track_path(rtwdev, &swing_table, i);
44922774f206SBjoern A. Zeeb }
44932774f206SBjoern A. Zeeb 
44942774f206SBjoern A. Zeeb static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
44952774f206SBjoern A. Zeeb {
44962774f206SBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
44972774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
44982774f206SBjoern A. Zeeb 
44992774f206SBjoern A. Zeeb 	if (efuse->power_track_type != 0)
45002774f206SBjoern A. Zeeb 		return;
45012774f206SBjoern A. Zeeb 
45022774f206SBjoern A. Zeeb 	if (!dm_info->pwr_trk_triggered) {
45032774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01);
45042774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00);
45052774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01);
45062774f206SBjoern A. Zeeb 
45072774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01);
45082774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00);
45092774f206SBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01);
45102774f206SBjoern A. Zeeb 
45112774f206SBjoern A. Zeeb 		dm_info->pwr_trk_triggered = true;
45122774f206SBjoern A. Zeeb 		return;
45132774f206SBjoern A. Zeeb 	}
45142774f206SBjoern A. Zeeb 
45152774f206SBjoern A. Zeeb 	__rtw8822c_pwr_track(rtwdev);
45162774f206SBjoern A. Zeeb 	dm_info->pwr_trk_triggered = false;
45172774f206SBjoern A. Zeeb }
45182774f206SBjoern A. Zeeb 
45192774f206SBjoern A. Zeeb static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev)
45202774f206SBjoern A. Zeeb {
45212774f206SBjoern A. Zeeb 	rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX);
45222774f206SBjoern A. Zeeb 
45232774f206SBjoern A. Zeeb 	/* mac edcca state setting */
45242774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
45252774f206SBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
45262774f206SBjoern A. Zeeb 
45272774f206SBjoern A. Zeeb 	/* edcca decistion opt */
45282774f206SBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
45292774f206SBjoern A. Zeeb }
45302774f206SBjoern A. Zeeb 
45312774f206SBjoern A. Zeeb static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
45322774f206SBjoern A. Zeeb {
45332774f206SBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
45342774f206SBjoern A. Zeeb 	s8 l2h, h2l;
45352774f206SBjoern A. Zeeb 	u8 igi;
45362774f206SBjoern A. Zeeb 
45372774f206SBjoern A. Zeeb 	igi = dm_info->igi_history[0];
45382774f206SBjoern A. Zeeb 	if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
45392774f206SBjoern A. Zeeb 		l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
45402774f206SBjoern A. Zeeb 		h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
45412774f206SBjoern A. Zeeb 	} else {
45422774f206SBjoern A. Zeeb 		if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF)
45432774f206SBjoern A. Zeeb 			l2h = igi + EDCCA_ADC_BACKOFF;
45442774f206SBjoern A. Zeeb 		else
45452774f206SBjoern A. Zeeb 			l2h = dm_info->l2h_th_ini;
45462774f206SBjoern A. Zeeb 		h2l = l2h - EDCCA_L2H_H2L_DIFF;
45472774f206SBjoern A. Zeeb 	}
45482774f206SBjoern A. Zeeb 
45492774f206SBjoern A. Zeeb 	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
45502774f206SBjoern A. Zeeb }
45512774f206SBjoern A. Zeeb 
4552*a0ccc12fSBjoern A. Zeeb static void rtw8822c_led_set(struct led_classdev *led,
4553*a0ccc12fSBjoern A. Zeeb 			     enum led_brightness brightness)
4554*a0ccc12fSBjoern A. Zeeb {
4555*a0ccc12fSBjoern A. Zeeb 	struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
4556*a0ccc12fSBjoern A. Zeeb 	u32 ledcfg;
4557*a0ccc12fSBjoern A. Zeeb 
4558*a0ccc12fSBjoern A. Zeeb 	ledcfg = rtw_read32(rtwdev, REG_LED_CFG);
4559*a0ccc12fSBjoern A. Zeeb 	u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM);
4560*a0ccc12fSBjoern A. Zeeb 	ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN;
4561*a0ccc12fSBjoern A. Zeeb 
4562*a0ccc12fSBjoern A. Zeeb 	if (brightness == LED_OFF)
4563*a0ccc12fSBjoern A. Zeeb 		ledcfg |= BIT_LED2_SV;
4564*a0ccc12fSBjoern A. Zeeb 	else
4565*a0ccc12fSBjoern A. Zeeb 		ledcfg &= ~BIT_LED2_SV;
4566*a0ccc12fSBjoern A. Zeeb 
4567*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_LED_CFG, ledcfg);
4568*a0ccc12fSBjoern A. Zeeb }
4569*a0ccc12fSBjoern A. Zeeb 
457090aac0d8SBjoern A. Zeeb static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
457190aac0d8SBjoern A. Zeeb 					  struct rtw_tx_pkt_info *pkt_info,
457290aac0d8SBjoern A. Zeeb 					  u8 *txdesc)
457390aac0d8SBjoern A. Zeeb {
457490aac0d8SBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
457590aac0d8SBjoern A. Zeeb 	size_t words;
457690aac0d8SBjoern A. Zeeb 
457790aac0d8SBjoern A. Zeeb 	words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2;
457890aac0d8SBjoern A. Zeeb 
457990aac0d8SBjoern A. Zeeb 	fill_txdesc_checksum_common(txdesc, words);
458090aac0d8SBjoern A. Zeeb }
458190aac0d8SBjoern A. Zeeb 
45822774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
45832774f206SBjoern A. Zeeb 	{0x0086,
45842774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
45852774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_SDIO_MSK,
45862774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_SDIO,
45872774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
45882774f206SBjoern A. Zeeb 	{0x0086,
45892774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
45902774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_SDIO_MSK,
45912774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_SDIO,
45922774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
45932774f206SBjoern A. Zeeb 	{0x002E,
45942774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
45952774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
45962774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
45972774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
45982774f206SBjoern A. Zeeb 	{0x002D,
45992774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46002774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46012774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46022774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
46032774f206SBjoern A. Zeeb 	{0x007F,
46042774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46052774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46062774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46072774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(7), 0},
46082774f206SBjoern A. Zeeb 	{0x004A,
46092774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46102774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK,
46112774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46122774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
46132774f206SBjoern A. Zeeb 	{0x0005,
46142774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46152774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46162774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46172774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
46182774f206SBjoern A. Zeeb 	{0xFFFF,
46192774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46202774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46212774f206SBjoern A. Zeeb 	 0,
46222774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_END, 0, 0},
46232774f206SBjoern A. Zeeb };
46242774f206SBjoern A. Zeeb 
46252774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822c[] = {
46262774f206SBjoern A. Zeeb 	{0x0000,
46272774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46282774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
46292774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46302774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(5), 0},
46312774f206SBjoern A. Zeeb 	{0x0005,
46322774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46332774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46342774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46352774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
46362774f206SBjoern A. Zeeb 	{0x0075,
46372774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46382774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
46392774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46402774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
46412774f206SBjoern A. Zeeb 	{0x0006,
46422774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46432774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46442774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46452774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
46462774f206SBjoern A. Zeeb 	{0x0075,
46472774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46482774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
46492774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46502774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
46512774f206SBjoern A. Zeeb 	{0xFF1A,
46522774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46532774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK,
46542774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46552774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
46562774f206SBjoern A. Zeeb 	{0x002E,
46572774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46582774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46592774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46602774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(3), 0},
46612774f206SBjoern A. Zeeb 	{0x0006,
46622774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46632774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46642774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46652774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
46662774f206SBjoern A. Zeeb 	{0x0005,
46672774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46682774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46692774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46702774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
46712774f206SBjoern A. Zeeb 	{0x1018,
46722774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46732774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46742774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46752774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
46762774f206SBjoern A. Zeeb 	{0x0005,
46772774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46782774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46792774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46802774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
46812774f206SBjoern A. Zeeb 	{0x0005,
46822774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46832774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
46842774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46852774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_POLLING, BIT(0), 0},
46862774f206SBjoern A. Zeeb 	{0x0074,
46872774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46882774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
46892774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46902774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
46912774f206SBjoern A. Zeeb 	{0x0071,
46922774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46932774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
46942774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
46952774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(4), 0},
46962774f206SBjoern A. Zeeb 	{0x0062,
46972774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
46982774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
46992774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47002774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)),
47012774f206SBjoern A. Zeeb 	 (BIT(7) | BIT(6) | BIT(5))},
47022774f206SBjoern A. Zeeb 	{0x0061,
47032774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47042774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
47052774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47062774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0},
47072774f206SBjoern A. Zeeb 	{0x001F,
47082774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47092774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47102774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47112774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)},
47122774f206SBjoern A. Zeeb 	{0x00EF,
47132774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47142774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47152774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47162774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)},
47172774f206SBjoern A. Zeeb 	{0x1045,
47182774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47192774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47202774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47212774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
47222774f206SBjoern A. Zeeb 	{0x0010,
47232774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47242774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47252774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47262774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
47272774f206SBjoern A. Zeeb 	{0x1064,
47282774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47292774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47302774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47312774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
47322774f206SBjoern A. Zeeb 	{0xFFFF,
47332774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47342774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47352774f206SBjoern A. Zeeb 	 0,
47362774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_END, 0, 0},
47372774f206SBjoern A. Zeeb };
47382774f206SBjoern A. Zeeb 
47392774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822c[] = {
47402774f206SBjoern A. Zeeb 	{0x0093,
47412774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47422774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47432774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47442774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(3), 0},
47452774f206SBjoern A. Zeeb 	{0x001F,
47462774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47472774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47482774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47492774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
47502774f206SBjoern A. Zeeb 	{0x00EF,
47512774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47522774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47532774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47542774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
47552774f206SBjoern A. Zeeb 	{0x1045,
47562774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47572774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47582774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47592774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(4), 0},
47602774f206SBjoern A. Zeeb 	{0xFF1A,
47612774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47622774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK,
47632774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47642774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0x30},
47652774f206SBjoern A. Zeeb 	{0x0049,
47662774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47672774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47682774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47692774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
47702774f206SBjoern A. Zeeb 	{0x0006,
47712774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47722774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47732774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47742774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
47752774f206SBjoern A. Zeeb 	{0x0002,
47762774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47772774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47782774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47792774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
47802774f206SBjoern A. Zeeb 	{0x0005,
47812774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47822774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47832774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47842774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
47852774f206SBjoern A. Zeeb 	{0x0005,
47862774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47872774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47882774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47892774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_POLLING, BIT(1), 0},
47902774f206SBjoern A. Zeeb 	{0x0000,
47912774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47922774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
47932774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
47942774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
47952774f206SBjoern A. Zeeb 	{0xFFFF,
47962774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
47972774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
47982774f206SBjoern A. Zeeb 	 0,
47992774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_END, 0, 0},
48002774f206SBjoern A. Zeeb };
48012774f206SBjoern A. Zeeb 
48022774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = {
48032774f206SBjoern A. Zeeb 	{0x0005,
48042774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48052774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_SDIO_MSK,
48062774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48072774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
48082774f206SBjoern A. Zeeb 	{0x0007,
48092774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48102774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
48112774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48122774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
48132774f206SBjoern A. Zeeb 	{0x0067,
48142774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48152774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
48162774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48172774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(5), 0},
48182774f206SBjoern A. Zeeb 	{0x004A,
48192774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48202774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK,
48212774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48222774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
48232774f206SBjoern A. Zeeb 	{0x0081,
48242774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48252774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
48262774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48272774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
48282774f206SBjoern A. Zeeb 	{0x0090,
48292774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48302774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
48312774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48322774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
48332774f206SBjoern A. Zeeb 	{0x0092,
48342774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48352774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
48362774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48372774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
48382774f206SBjoern A. Zeeb 	{0x0093,
48392774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48402774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
48412774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48422774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, 0xFF, 0x04},
48432774f206SBjoern A. Zeeb 	{0x0005,
48442774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48452774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
48462774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48472774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
48482774f206SBjoern A. Zeeb 	{0x0005,
48492774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48502774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_PCI_MSK,
48512774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_MAC,
48522774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
48532774f206SBjoern A. Zeeb 	{0x0086,
48542774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48552774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_SDIO_MSK,
48562774f206SBjoern A. Zeeb 	 RTW_PWR_ADDR_SDIO,
48572774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
48582774f206SBjoern A. Zeeb 	{0xFFFF,
48592774f206SBjoern A. Zeeb 	 RTW_PWR_CUT_ALL_MSK,
48602774f206SBjoern A. Zeeb 	 RTW_PWR_INTF_ALL_MSK,
48612774f206SBjoern A. Zeeb 	 0,
48622774f206SBjoern A. Zeeb 	 RTW_PWR_CMD_END, 0, 0},
48632774f206SBjoern A. Zeeb };
48642774f206SBjoern A. Zeeb 
4865*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = {
48662774f206SBjoern A. Zeeb 	trans_carddis_to_cardemu_8822c,
48672774f206SBjoern A. Zeeb 	trans_cardemu_to_act_8822c,
48682774f206SBjoern A. Zeeb 	NULL
48692774f206SBjoern A. Zeeb };
48702774f206SBjoern A. Zeeb 
4871*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = {
48722774f206SBjoern A. Zeeb 	trans_act_to_cardemu_8822c,
48732774f206SBjoern A. Zeeb 	trans_cardemu_to_carddis_8822c,
48742774f206SBjoern A. Zeeb 	NULL
48752774f206SBjoern A. Zeeb };
48762774f206SBjoern A. Zeeb 
48772774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb2_param_8822c[] = {
48782774f206SBjoern A. Zeeb 	{0xFFFF, 0x00,
48792774f206SBjoern A. Zeeb 	 RTW_IP_SEL_PHY,
48802774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_CUT_ALL,
48812774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_PLATFORM_ALL},
48822774f206SBjoern A. Zeeb };
48832774f206SBjoern A. Zeeb 
48842774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb3_param_8822c[] = {
48852774f206SBjoern A. Zeeb 	{0xFFFF, 0x0000,
48862774f206SBjoern A. Zeeb 	 RTW_IP_SEL_PHY,
48872774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_CUT_ALL,
48882774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_PLATFORM_ALL},
48892774f206SBjoern A. Zeeb };
48902774f206SBjoern A. Zeeb 
48912774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen1_param_8822c[] = {
48922774f206SBjoern A. Zeeb 	{0xFFFF, 0x0000,
48932774f206SBjoern A. Zeeb 	 RTW_IP_SEL_PHY,
48942774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_CUT_ALL,
48952774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_PLATFORM_ALL},
48962774f206SBjoern A. Zeeb };
48972774f206SBjoern A. Zeeb 
48982774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen2_param_8822c[] = {
48992774f206SBjoern A. Zeeb 	{0xFFFF, 0x0000,
49002774f206SBjoern A. Zeeb 	 RTW_IP_SEL_PHY,
49012774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_CUT_ALL,
49022774f206SBjoern A. Zeeb 	 RTW_INTF_PHY_PLATFORM_ALL},
49032774f206SBjoern A. Zeeb };
49042774f206SBjoern A. Zeeb 
49052774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para_table phy_para_table_8822c = {
49062774f206SBjoern A. Zeeb 	.usb2_para	= usb2_param_8822c,
49072774f206SBjoern A. Zeeb 	.usb3_para	= usb3_param_8822c,
49082774f206SBjoern A. Zeeb 	.gen1_para	= pcie_gen1_param_8822c,
49092774f206SBjoern A. Zeeb 	.gen2_para	= pcie_gen2_param_8822c,
49102774f206SBjoern A. Zeeb 	.n_usb2_para	= ARRAY_SIZE(usb2_param_8822c),
49112774f206SBjoern A. Zeeb 	.n_usb3_para	= ARRAY_SIZE(usb2_param_8822c),
49122774f206SBjoern A. Zeeb 	.n_gen1_para	= ARRAY_SIZE(pcie_gen1_param_8822c),
49132774f206SBjoern A. Zeeb 	.n_gen2_para	= ARRAY_SIZE(pcie_gen2_param_8822c),
49142774f206SBjoern A. Zeeb };
49152774f206SBjoern A. Zeeb 
49162774f206SBjoern A. Zeeb static const struct rtw_hw_reg rtw8822c_dig[] = {
49172774f206SBjoern A. Zeeb 	[0] = { .addr = 0x1d70, .mask = 0x7f },
49182774f206SBjoern A. Zeeb 	[1] = { .addr = 0x1d70, .mask = 0x7f00 },
49192774f206SBjoern A. Zeeb };
49202774f206SBjoern A. Zeeb 
49212774f206SBjoern A. Zeeb static const struct rtw_ltecoex_addr rtw8822c_ltecoex_addr = {
49222774f206SBjoern A. Zeeb 	.ctrl = LTECOEX_ACCESS_CTRL,
49232774f206SBjoern A. Zeeb 	.wdata = LTECOEX_WRITE_DATA,
49242774f206SBjoern A. Zeeb 	.rdata = LTECOEX_READ_DATA,
49252774f206SBjoern A. Zeeb };
49262774f206SBjoern A. Zeeb 
49272774f206SBjoern A. Zeeb static const struct rtw_page_table page_table_8822c[] = {
49282774f206SBjoern A. Zeeb 	{64, 64, 64, 64, 1},
49292774f206SBjoern A. Zeeb 	{64, 64, 64, 64, 1},
49302774f206SBjoern A. Zeeb 	{64, 64, 0, 0, 1},
49312774f206SBjoern A. Zeeb 	{64, 64, 64, 0, 1},
49322774f206SBjoern A. Zeeb 	{64, 64, 64, 64, 1},
49332774f206SBjoern A. Zeeb };
49342774f206SBjoern A. Zeeb 
49352774f206SBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8822c[] = {
49362774f206SBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
49372774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
49382774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
49392774f206SBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
49402774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
49412774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
49422774f206SBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
49432774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
49442774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
49452774f206SBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
49462774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
49472774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
49482774f206SBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
49492774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
49502774f206SBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
49512774f206SBjoern A. Zeeb };
49522774f206SBjoern A. Zeeb 
4953*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8822c = {
49542774f206SBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_EXTRA] = {
49552774f206SBjoern A. Zeeb 		.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
49562774f206SBjoern A. Zeeb 	},
49572774f206SBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_LOW] = {
49582774f206SBjoern A. Zeeb 		.rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
49592774f206SBjoern A. Zeeb 	},
49602774f206SBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_NORMAL] = {
49612774f206SBjoern A. Zeeb 		.rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
49622774f206SBjoern A. Zeeb 	},
49632774f206SBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_HIGH] = {
49642774f206SBjoern A. Zeeb 		.rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
49652774f206SBjoern A. Zeeb 	},
49662774f206SBjoern A. Zeeb 	.wsize = true,
49672774f206SBjoern A. Zeeb };
49682774f206SBjoern A. Zeeb 
4969*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8822c_ops = {
4970*a0ccc12fSBjoern A. Zeeb 	.power_on		= rtw_power_on,
4971*a0ccc12fSBjoern A. Zeeb 	.power_off		= rtw_power_off,
49722774f206SBjoern A. Zeeb 	.phy_set_param		= rtw8822c_phy_set_param,
49732774f206SBjoern A. Zeeb 	.read_efuse		= rtw8822c_read_efuse,
4974*a0ccc12fSBjoern A. Zeeb 	.query_phy_status	= query_phy_status,
49752774f206SBjoern A. Zeeb 	.set_channel		= rtw8822c_set_channel,
49762774f206SBjoern A. Zeeb 	.mac_init		= rtw8822c_mac_init,
49772774f206SBjoern A. Zeeb 	.dump_fw_crash		= rtw8822c_dump_fw_crash,
49782774f206SBjoern A. Zeeb 	.read_rf		= rtw_phy_read_rf,
49792774f206SBjoern A. Zeeb 	.write_rf		= rtw_phy_write_rf_reg_mix,
49802774f206SBjoern A. Zeeb 	.set_tx_power_index	= rtw8822c_set_tx_power_index,
49812774f206SBjoern A. Zeeb 	.set_antenna		= rtw8822c_set_antenna,
49822774f206SBjoern A. Zeeb 	.cfg_ldo25		= rtw8822c_cfg_ldo25,
49832774f206SBjoern A. Zeeb 	.false_alarm_statistics	= rtw8822c_false_alarm_statistics,
49842774f206SBjoern A. Zeeb 	.dpk_track		= rtw8822c_dpk_track,
49852774f206SBjoern A. Zeeb 	.phy_calibration	= rtw8822c_phy_calibration,
49862774f206SBjoern A. Zeeb 	.cck_pd_set		= rtw8822c_phy_cck_pd_set,
49872774f206SBjoern A. Zeeb 	.pwr_track		= rtw8822c_pwr_track,
49882774f206SBjoern A. Zeeb 	.config_bfee		= rtw8822c_bf_config_bfee,
49892774f206SBjoern A. Zeeb 	.set_gid_table		= rtw_bf_set_gid_table,
49902774f206SBjoern A. Zeeb 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
49912774f206SBjoern A. Zeeb 	.adaptivity_init	= rtw8822c_adaptivity_init,
49922774f206SBjoern A. Zeeb 	.adaptivity		= rtw8822c_adaptivity,
49932774f206SBjoern A. Zeeb 	.cfo_init		= rtw8822c_cfo_init,
49942774f206SBjoern A. Zeeb 	.cfo_track		= rtw8822c_cfo_track,
49952774f206SBjoern A. Zeeb 	.config_tx_path		= rtw8822c_config_tx_path,
49969c951734SBjoern A. Zeeb 	.config_txrx_mode	= rtw8822c_config_trx_mode,
4997*a0ccc12fSBjoern A. Zeeb 	.led_set		= rtw8822c_led_set,
499890aac0d8SBjoern A. Zeeb 	.fill_txdesc_checksum	= rtw8822c_fill_txdesc_checksum,
49992774f206SBjoern A. Zeeb 
50002774f206SBjoern A. Zeeb 	.coex_set_init		= rtw8822c_coex_cfg_init,
50012774f206SBjoern A. Zeeb 	.coex_set_ant_switch	= NULL,
50022774f206SBjoern A. Zeeb 	.coex_set_gnt_fix	= rtw8822c_coex_cfg_gnt_fix,
50032774f206SBjoern A. Zeeb 	.coex_set_gnt_debug	= rtw8822c_coex_cfg_gnt_debug,
50042774f206SBjoern A. Zeeb 	.coex_set_rfe_type	= rtw8822c_coex_cfg_rfe_type,
50052774f206SBjoern A. Zeeb 	.coex_set_wl_tx_power	= rtw8822c_coex_cfg_wl_tx_power,
50062774f206SBjoern A. Zeeb 	.coex_set_wl_rx_gain	= rtw8822c_coex_cfg_wl_rx_gain,
50072774f206SBjoern A. Zeeb };
50082774f206SBjoern A. Zeeb 
50092774f206SBjoern A. Zeeb /* Shared-Antenna Coex Table */
50102774f206SBjoern A. Zeeb static const struct coex_table_para table_sant_8822c[] = {
50112774f206SBjoern A. Zeeb 	{0xffffffff, 0xffffffff}, /* case-0 */
50122774f206SBjoern A. Zeeb 	{0x55555555, 0x55555555},
50132774f206SBjoern A. Zeeb 	{0x66555555, 0x66555555},
50142774f206SBjoern A. Zeeb 	{0xaaaaaaaa, 0xaaaaaaaa},
50152774f206SBjoern A. Zeeb 	{0x5a5a5a5a, 0x5a5a5a5a},
50162774f206SBjoern A. Zeeb 	{0xfafafafa, 0xfafafafa}, /* case-5 */
50172774f206SBjoern A. Zeeb 	{0x6a5a5555, 0xaaaaaaaa},
50182774f206SBjoern A. Zeeb 	{0x6a5a56aa, 0x6a5a56aa},
50192774f206SBjoern A. Zeeb 	{0x6a5a5a5a, 0x6a5a5a5a},
50202774f206SBjoern A. Zeeb 	{0x66555555, 0x5a5a5a5a},
50212774f206SBjoern A. Zeeb 	{0x66555555, 0x6a5a5a5a}, /* case-10 */
50222774f206SBjoern A. Zeeb 	{0x66555555, 0x6a5a5aaa},
50232774f206SBjoern A. Zeeb 	{0x66555555, 0x5a5a5aaa},
50242774f206SBjoern A. Zeeb 	{0x66555555, 0x6aaa5aaa},
50252774f206SBjoern A. Zeeb 	{0x66555555, 0xaaaa5aaa},
50262774f206SBjoern A. Zeeb 	{0x66555555, 0xaaaaaaaa}, /* case-15 */
50272774f206SBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
50282774f206SBjoern A. Zeeb 	{0xffff55ff, 0x6afa5afa},
50292774f206SBjoern A. Zeeb 	{0xaaffffaa, 0xfafafafa},
50302774f206SBjoern A. Zeeb 	{0xaa5555aa, 0x5a5a5a5a},
50312774f206SBjoern A. Zeeb 	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
50322774f206SBjoern A. Zeeb 	{0xaa5555aa, 0xaaaaaaaa},
50332774f206SBjoern A. Zeeb 	{0xffffffff, 0x5a5a5a5a},
50342774f206SBjoern A. Zeeb 	{0xffffffff, 0x5a5a5a5a},
50352774f206SBjoern A. Zeeb 	{0xffffffff, 0x55555555},
50362774f206SBjoern A. Zeeb 	{0xffffffff, 0x5a5a5aaa}, /* case-25 */
50372774f206SBjoern A. Zeeb 	{0x55555555, 0x5a5a5a5a},
50382774f206SBjoern A. Zeeb 	{0x55555555, 0xaaaaaaaa},
50392774f206SBjoern A. Zeeb 	{0x55555555, 0x6a5a6a5a},
50402774f206SBjoern A. Zeeb 	{0x66556655, 0x66556655},
50412774f206SBjoern A. Zeeb 	{0x66556aaa, 0x6a5a6aaa}, /*case-30*/
50422774f206SBjoern A. Zeeb 	{0xffffffff, 0x5aaa5aaa},
50432774f206SBjoern A. Zeeb 	{0x56555555, 0x5a5a5aaa},
50449c951734SBjoern A. Zeeb 	{0xdaffdaff, 0xdaffdaff},
50459c951734SBjoern A. Zeeb 	{0xddffddff, 0xddffddff},
50462774f206SBjoern A. Zeeb };
50472774f206SBjoern A. Zeeb 
50482774f206SBjoern A. Zeeb /* Non-Shared-Antenna Coex Table */
50492774f206SBjoern A. Zeeb static const struct coex_table_para table_nsant_8822c[] = {
50502774f206SBjoern A. Zeeb 	{0xffffffff, 0xffffffff}, /* case-100 */
50512774f206SBjoern A. Zeeb 	{0x55555555, 0x55555555},
50522774f206SBjoern A. Zeeb 	{0x66555555, 0x66555555},
50532774f206SBjoern A. Zeeb 	{0xaaaaaaaa, 0xaaaaaaaa},
50542774f206SBjoern A. Zeeb 	{0x5a5a5a5a, 0x5a5a5a5a},
50552774f206SBjoern A. Zeeb 	{0xfafafafa, 0xfafafafa}, /* case-105 */
50562774f206SBjoern A. Zeeb 	{0x5afa5afa, 0x5afa5afa},
50572774f206SBjoern A. Zeeb 	{0x55555555, 0xfafafafa},
50582774f206SBjoern A. Zeeb 	{0x66555555, 0xfafafafa},
50592774f206SBjoern A. Zeeb 	{0x66555555, 0x5a5a5a5a},
50602774f206SBjoern A. Zeeb 	{0x66555555, 0x6a5a5a5a}, /* case-110 */
50612774f206SBjoern A. Zeeb 	{0x66555555, 0xaaaaaaaa},
50622774f206SBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
50632774f206SBjoern A. Zeeb 	{0xffff55ff, 0x5afa5afa},
50642774f206SBjoern A. Zeeb 	{0xffff55ff, 0xaaaaaaaa},
50652774f206SBjoern A. Zeeb 	{0xffff55ff, 0xffff55ff}, /* case-115 */
50662774f206SBjoern A. Zeeb 	{0xaaffffaa, 0x5afa5afa},
50672774f206SBjoern A. Zeeb 	{0xaaffffaa, 0xaaaaaaaa},
50682774f206SBjoern A. Zeeb 	{0xffffffff, 0xfafafafa},
50692774f206SBjoern A. Zeeb 	{0xffffffff, 0x5afa5afa},
50702774f206SBjoern A. Zeeb 	{0xffffffff, 0xaaaaaaaa}, /* case-120 */
50712774f206SBjoern A. Zeeb 	{0x55ff55ff, 0x5afa5afa},
50722774f206SBjoern A. Zeeb 	{0x55ff55ff, 0xaaaaaaaa},
50732774f206SBjoern A. Zeeb 	{0x55ff55ff, 0x55ff55ff}
50742774f206SBjoern A. Zeeb };
50752774f206SBjoern A. Zeeb 
50762774f206SBjoern A. Zeeb /* Shared-Antenna TDMA */
50772774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_sant_8822c[] = {
50782774f206SBjoern A. Zeeb 	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
50792774f206SBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
50802774f206SBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
50812774f206SBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
50822774f206SBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
50832774f206SBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
50842774f206SBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
50852774f206SBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
50862774f206SBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
50872774f206SBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
50882774f206SBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
50892774f206SBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
50902774f206SBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
50912774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
50922774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
50932774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
50942774f206SBjoern A. Zeeb 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
50952774f206SBjoern A. Zeeb 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
50962774f206SBjoern A. Zeeb 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
50972774f206SBjoern A. Zeeb 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
50982774f206SBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
50992774f206SBjoern A. Zeeb 	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
51002774f206SBjoern A. Zeeb 	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
51012774f206SBjoern A. Zeeb 	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
51022774f206SBjoern A. Zeeb 	{ {0x65, 0x10, 0x03, 0x11, 0x10} },
51032774f206SBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
51042774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x50} },
51052774f206SBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x11, 0x11} }
51062774f206SBjoern A. Zeeb };
51072774f206SBjoern A. Zeeb 
51082774f206SBjoern A. Zeeb /* Non-Shared-Antenna TDMA */
51092774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_nsant_8822c[] = {
51102774f206SBjoern A. Zeeb 	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */
51112774f206SBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
51122774f206SBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
51132774f206SBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
51142774f206SBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
51152774f206SBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
51162774f206SBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
51172774f206SBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
51182774f206SBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
51192774f206SBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
51202774f206SBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
51212774f206SBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
51222774f206SBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
51232774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
51242774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
51252774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
51262774f206SBjoern A. Zeeb 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
51272774f206SBjoern A. Zeeb 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
51282774f206SBjoern A. Zeeb 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
51292774f206SBjoern A. Zeeb 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
51302774f206SBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */
51312774f206SBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x50} }
51322774f206SBjoern A. Zeeb };
51332774f206SBjoern A. Zeeb 
51342774f206SBjoern A. Zeeb /* rssi in percentage % (dbm = % - 100) */
51352774f206SBjoern A. Zeeb static const u8 wl_rssi_step_8822c[] = {60, 50, 44, 30};
51362774f206SBjoern A. Zeeb static const u8 bt_rssi_step_8822c[] = {8, 15, 20, 25};
51372774f206SBjoern A. Zeeb static const struct coex_5g_afh_map afh_5g_8822c[] = { {0, 0, 0} };
51382774f206SBjoern A. Zeeb 
51392774f206SBjoern A. Zeeb /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
51402774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8822c[] = {
51412774f206SBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
51422774f206SBjoern A. Zeeb 	{0, 16, false, 7}, /* for WL-CPT */
51432774f206SBjoern A. Zeeb 	{8, 17, true, 4},
51442774f206SBjoern A. Zeeb 	{7, 18, true, 4},
51452774f206SBjoern A. Zeeb 	{6, 19, true, 4},
51469c951734SBjoern A. Zeeb 	{5, 20, true, 4},
51479c951734SBjoern A. Zeeb 	{0, 21, true, 4}   /* for gamg hid */
51482774f206SBjoern A. Zeeb };
51492774f206SBjoern A. Zeeb 
51502774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8822c[] = {
51512774f206SBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
51522774f206SBjoern A. Zeeb 	{0, 16, false, 7}, /* for WL-CPT */
51532774f206SBjoern A. Zeeb 	{3, 24, true, 5},
51542774f206SBjoern A. Zeeb 	{2, 26, true, 5},
51552774f206SBjoern A. Zeeb 	{1, 27, true, 5},
51569c951734SBjoern A. Zeeb 	{0, 28, true, 5},
51579c951734SBjoern A. Zeeb 	{0, 28, true, 5}   /* for gamg hid */
51582774f206SBjoern A. Zeeb };
51592774f206SBjoern A. Zeeb 
51602774f206SBjoern A. Zeeb #if defined(__linux__)
51612774f206SBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c));
51622774f206SBjoern A. Zeeb #elif defined(__FreeBSD__)
51632774f206SBjoern A. Zeeb rtw88_static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c));
51642774f206SBjoern A. Zeeb #endif
51652774f206SBjoern A. Zeeb 
51662774f206SBjoern A. Zeeb static const u8
51672774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
51682774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  5,  6,  7,  8,  9, 10,
51692774f206SBjoern A. Zeeb 	 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
51702774f206SBjoern A. Zeeb 	 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 },
51712774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  5,  6,  7,  8,  9, 10,
51722774f206SBjoern A. Zeeb 	 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
51732774f206SBjoern A. Zeeb 	 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 },
51742774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  5,  6,  7,  8,  9, 10,
51752774f206SBjoern A. Zeeb 	 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
51762774f206SBjoern A. Zeeb 	 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 },
51772774f206SBjoern A. Zeeb };
51782774f206SBjoern A. Zeeb 
51792774f206SBjoern A. Zeeb static const u8
51802774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
51812774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
51822774f206SBjoern A. Zeeb 	 10, 10, 11, 12, 13, 14, 15, 16, 17, 18,
51832774f206SBjoern A. Zeeb 	 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 },
51842774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
51852774f206SBjoern A. Zeeb 	 10, 10, 11, 12, 13, 14, 15, 16, 17, 18,
51862774f206SBjoern A. Zeeb 	 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 },
51872774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
51882774f206SBjoern A. Zeeb 	 10, 10, 11, 12, 13, 14, 15, 16, 17, 18,
51892774f206SBjoern A. Zeeb 	 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 },
51902774f206SBjoern A. Zeeb };
51912774f206SBjoern A. Zeeb 
51922774f206SBjoern A. Zeeb static const u8
51932774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
51942774f206SBjoern A. Zeeb 	{ 0,  1,  2,  4,  5,  6,  7,  8,  9, 10,
51952774f206SBjoern A. Zeeb 	 11, 13, 14, 15, 16, 17, 18, 19, 20, 21,
51962774f206SBjoern A. Zeeb 	 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 },
51972774f206SBjoern A. Zeeb 	{ 0,  1,  2,  4,  5,  6,  7,  8,  9, 10,
51982774f206SBjoern A. Zeeb 	 11, 13, 14, 15, 16, 17, 18, 19, 20, 21,
51992774f206SBjoern A. Zeeb 	 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 },
52002774f206SBjoern A. Zeeb 	{ 0,  1,  2,  4,  5,  6,  7,  8,  9, 10,
52012774f206SBjoern A. Zeeb 	 11, 13, 14, 15, 16, 17, 18, 19, 20, 21,
52022774f206SBjoern A. Zeeb 	 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 },
52032774f206SBjoern A. Zeeb };
52042774f206SBjoern A. Zeeb 
52052774f206SBjoern A. Zeeb static const u8
52062774f206SBjoern A. Zeeb rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
52072774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52082774f206SBjoern A. Zeeb 	 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
52092774f206SBjoern A. Zeeb 	 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
52102774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52112774f206SBjoern A. Zeeb 	 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
52122774f206SBjoern A. Zeeb 	 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
52132774f206SBjoern A. Zeeb 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52142774f206SBjoern A. Zeeb 	 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
52152774f206SBjoern A. Zeeb 	 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
52162774f206SBjoern A. Zeeb };
52172774f206SBjoern A. Zeeb 
52182774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = {
52192774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  4,  5,  6,  7,  8,
52202774f206SBjoern A. Zeeb 	 9,  9, 10, 11, 12, 13, 14, 15, 15, 16,
52212774f206SBjoern A. Zeeb 	17, 18, 19, 20, 20, 21, 22, 23, 24, 25
52222774f206SBjoern A. Zeeb };
52232774f206SBjoern A. Zeeb 
52242774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = {
52252774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52262774f206SBjoern A. Zeeb 	10, 11, 12, 13, 14, 14, 15, 16, 17, 18,
52272774f206SBjoern A. Zeeb 	19, 20, 21, 22, 23, 24, 25, 26, 27, 28
52282774f206SBjoern A. Zeeb };
52292774f206SBjoern A. Zeeb 
52302774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = {
52312774f206SBjoern A. Zeeb 	 0,  1,  2,  2,  3,  4,  4,  5,  6,  6,
52322774f206SBjoern A. Zeeb 	 7,  8,  8,  9,  9, 10, 11, 11, 12, 13,
52332774f206SBjoern A. Zeeb 	13, 14, 15, 15, 16, 17, 17, 18, 19, 19
52342774f206SBjoern A. Zeeb };
52352774f206SBjoern A. Zeeb 
52362774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = {
52372774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52382774f206SBjoern A. Zeeb 	10, 11, 11, 12, 13, 14, 15, 16, 17, 18,
52392774f206SBjoern A. Zeeb 	19, 20, 21, 22, 23, 24, 25, 25, 26, 27
52402774f206SBjoern A. Zeeb };
52412774f206SBjoern A. Zeeb 
52422774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = {
52432774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  5,  5,  6,  7,  8,
52442774f206SBjoern A. Zeeb 	 9, 10, 11, 11, 12, 13, 14, 15, 16, 17,
52452774f206SBjoern A. Zeeb 	17, 18, 19, 20, 21, 22, 23, 23, 24, 25
52462774f206SBjoern A. Zeeb };
52472774f206SBjoern A. Zeeb 
52482774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = {
52492774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
52502774f206SBjoern A. Zeeb 	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
52512774f206SBjoern A. Zeeb 	20, 21, 22, 23, 24, 25, 26, 27, 28, 29
52522774f206SBjoern A. Zeeb };
52532774f206SBjoern A. Zeeb 
52542774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = {
52552774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  3,  4,  5,  6,  6,  7,
52562774f206SBjoern A. Zeeb 	 8,  9,  9, 10, 11, 12, 12, 13, 14, 15,
52572774f206SBjoern A. Zeeb 	15, 16, 17, 18, 18, 19, 20, 21, 21, 22
52582774f206SBjoern A. Zeeb };
52592774f206SBjoern A. Zeeb 
52602774f206SBjoern A. Zeeb static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
52612774f206SBjoern A. Zeeb 	 0,  1,  2,  3,  4,  5,  5,  6,  7,  8,
52622774f206SBjoern A. Zeeb 	 9, 10, 11, 11, 12, 13, 14, 15, 16, 17,
52632774f206SBjoern A. Zeeb 	18, 18, 19, 20, 21, 22, 23, 24, 24, 25
52642774f206SBjoern A. Zeeb };
52652774f206SBjoern A. Zeeb 
5266*a0ccc12fSBjoern A. Zeeb static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = {
52672774f206SBjoern A. Zeeb 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
52682774f206SBjoern A. Zeeb 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
52692774f206SBjoern A. Zeeb 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
52702774f206SBjoern A. Zeeb 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],
52712774f206SBjoern A. Zeeb 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],
52722774f206SBjoern A. Zeeb 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],
52732774f206SBjoern A. Zeeb 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],
52742774f206SBjoern A. Zeeb 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],
52752774f206SBjoern A. Zeeb 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],
52762774f206SBjoern A. Zeeb 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],
52772774f206SBjoern A. Zeeb 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],
52782774f206SBjoern A. Zeeb 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],
52792774f206SBjoern A. Zeeb 	.pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n,
52802774f206SBjoern A. Zeeb 	.pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p,
52812774f206SBjoern A. Zeeb 	.pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n,
52822774f206SBjoern A. Zeeb 	.pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p,
52832774f206SBjoern A. Zeeb 	.pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n,
52842774f206SBjoern A. Zeeb 	.pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p,
52852774f206SBjoern A. Zeeb 	.pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n,
52862774f206SBjoern A. Zeeb 	.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
52872774f206SBjoern A. Zeeb };
52882774f206SBjoern A. Zeeb 
5289*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
5290*a0ccc12fSBjoern A. Zeeb 	[0] = RTW_DEF_RFE(8822c, 0, 0, 0),
5291*a0ccc12fSBjoern A. Zeeb 	[1] = RTW_DEF_RFE(8822c, 0, 0, 0),
5292*a0ccc12fSBjoern A. Zeeb 	[2] = RTW_DEF_RFE(8822c, 0, 0, 0),
5293*a0ccc12fSBjoern A. Zeeb 	[3] = RTW_DEF_RFE(8822c, 0, 0, 0),
5294*a0ccc12fSBjoern A. Zeeb 	[4] = RTW_DEF_RFE(8822c, 0, 0, 0),
5295*a0ccc12fSBjoern A. Zeeb 	[5] = RTW_DEF_RFE(8822c, 0, 5, 0),
5296*a0ccc12fSBjoern A. Zeeb 	[6] = RTW_DEF_RFE(8822c, 0, 0, 0),
5297*a0ccc12fSBjoern A. Zeeb };
5298*a0ccc12fSBjoern A. Zeeb 
5299*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
53002774f206SBjoern A. Zeeb 	[EDCCA_TH_L2H_IDX] = {
53012774f206SBjoern A. Zeeb 		{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
53022774f206SBjoern A. Zeeb 	},
53032774f206SBjoern A. Zeeb 	[EDCCA_TH_H2L_IDX] = {
53042774f206SBjoern A. Zeeb 		{.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80
53052774f206SBjoern A. Zeeb 	},
53062774f206SBjoern A. Zeeb };
53072774f206SBjoern A. Zeeb 
53082774f206SBjoern A. Zeeb #ifdef CONFIG_PM
53092774f206SBjoern A. Zeeb static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = {
53102774f206SBjoern A. Zeeb 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
53112774f206SBjoern A. Zeeb 		 WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
53122774f206SBjoern A. Zeeb 		 WIPHY_WOWLAN_NET_DETECT,
53132774f206SBjoern A. Zeeb 	.n_patterns = RTW_MAX_PATTERN_NUM,
53142774f206SBjoern A. Zeeb 	.pattern_max_len = RTW_MAX_PATTERN_SIZE,
53152774f206SBjoern A. Zeeb 	.pattern_min_len = 1,
53162774f206SBjoern A. Zeeb 	.max_nd_match_sets = 4,
53172774f206SBjoern A. Zeeb };
53182774f206SBjoern A. Zeeb #endif
53192774f206SBjoern A. Zeeb 
53202774f206SBjoern A. Zeeb static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = {
53212774f206SBjoern A. Zeeb 	{0x1860, BIT(3), RTW_REG_DOMAIN_MAC8},
53222774f206SBjoern A. Zeeb 	{0x4160, BIT(3), RTW_REG_DOMAIN_MAC8},
53232774f206SBjoern A. Zeeb 	{0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8},
53242774f206SBjoern A. Zeeb 	{0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32},
53252774f206SBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
53262774f206SBjoern A. Zeeb 	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
53272774f206SBjoern A. Zeeb 	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
53282774f206SBjoern A. Zeeb 	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
53292774f206SBjoern A. Zeeb 	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
53302774f206SBjoern A. Zeeb 	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
53312774f206SBjoern A. Zeeb 	{0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
53322774f206SBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
53332774f206SBjoern A. Zeeb 	{0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
53342774f206SBjoern A. Zeeb 	{0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
53352774f206SBjoern A. Zeeb 	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
53362774f206SBjoern A. Zeeb 	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
53372774f206SBjoern A. Zeeb 	{0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B},
53382774f206SBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
53392774f206SBjoern A. Zeeb 	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
53402774f206SBjoern A. Zeeb 	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
53412774f206SBjoern A. Zeeb 	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
53422774f206SBjoern A. Zeeb 	{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
53432774f206SBjoern A. Zeeb };
53442774f206SBjoern A. Zeeb 
53459c951734SBjoern A. Zeeb const struct rtw_chip_info rtw8822c_hw_spec = {
53462774f206SBjoern A. Zeeb 	.ops = &rtw8822c_ops,
53472774f206SBjoern A. Zeeb 	.id = RTW_CHIP_TYPE_8822C,
53482774f206SBjoern A. Zeeb 	.fw_name = "rtw88/rtw8822c_fw.bin",
53492774f206SBjoern A. Zeeb 	.wlan_cpu = RTW_WCPU_11AC,
53502774f206SBjoern A. Zeeb 	.tx_pkt_desc_sz = 48,
53512774f206SBjoern A. Zeeb 	.tx_buf_desc_sz = 16,
53522774f206SBjoern A. Zeeb 	.rx_pkt_desc_sz = 24,
53532774f206SBjoern A. Zeeb 	.rx_buf_desc_sz = 8,
53542774f206SBjoern A. Zeeb 	.phy_efuse_size = 512,
53552774f206SBjoern A. Zeeb 	.log_efuse_size = 768,
53562774f206SBjoern A. Zeeb 	.ptct_efuse_size = 124,
53572774f206SBjoern A. Zeeb 	.txff_size = 262144,
53582774f206SBjoern A. Zeeb 	.rxff_size = 24576,
53592774f206SBjoern A. Zeeb 	.fw_rxff_size = 12288,
536090aac0d8SBjoern A. Zeeb 	.rsvd_drv_pg_num = 16,
53612774f206SBjoern A. Zeeb 	.txgi_factor = 2,
53622774f206SBjoern A. Zeeb 	.is_pwr_by_rate_dec = false,
53632774f206SBjoern A. Zeeb 	.max_power_index = 0x7f,
53642774f206SBjoern A. Zeeb 	.csi_buf_pg_num = 50,
53652774f206SBjoern A. Zeeb 	.band = RTW_BAND_2G | RTW_BAND_5G,
536690aac0d8SBjoern A. Zeeb 	.page_size = TX_PAGE_SIZE,
53672774f206SBjoern A. Zeeb 	.dig_min = 0x20,
536811c53278SBjoern A. Zeeb 	.usb_tx_agg_desc_num = 3,
5369*a0ccc12fSBjoern A. Zeeb 	.hw_feature_report = true,
5370*a0ccc12fSBjoern A. Zeeb 	.c2h_ra_report_size = 7,
5371*a0ccc12fSBjoern A. Zeeb 	.old_datarate_fb_limit = false,
53722774f206SBjoern A. Zeeb 	.default_1ss_tx_path = BB_PATH_A,
53732774f206SBjoern A. Zeeb 	.path_div_supported = true,
53742774f206SBjoern A. Zeeb 	.ht_supported = true,
53752774f206SBjoern A. Zeeb 	.vht_supported = true,
53762774f206SBjoern A. Zeeb 	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK) | BIT(LPS_DEEP_MODE_PG),
53772774f206SBjoern A. Zeeb 	.sys_func_en = 0xD8,
53782774f206SBjoern A. Zeeb 	.pwr_on_seq = card_enable_flow_8822c,
53792774f206SBjoern A. Zeeb 	.pwr_off_seq = card_disable_flow_8822c,
53802774f206SBjoern A. Zeeb 	.page_table = page_table_8822c,
53812774f206SBjoern A. Zeeb 	.rqpn_table = rqpn_table_8822c,
53822774f206SBjoern A. Zeeb 	.prioq_addrs = &prioq_addrs_8822c,
53832774f206SBjoern A. Zeeb 	.intf_table = &phy_para_table_8822c,
53842774f206SBjoern A. Zeeb 	.dig = rtw8822c_dig,
53852774f206SBjoern A. Zeeb 	.dig_cck = NULL,
53862774f206SBjoern A. Zeeb 	.rf_base_addr = {0x3c00, 0x4c00},
53872774f206SBjoern A. Zeeb 	.rf_sipi_addr = {0x1808, 0x4108},
53882774f206SBjoern A. Zeeb 	.ltecoex_addr = &rtw8822c_ltecoex_addr,
53892774f206SBjoern A. Zeeb 	.mac_tbl = &rtw8822c_mac_tbl,
53902774f206SBjoern A. Zeeb 	.agc_tbl = &rtw8822c_agc_tbl,
53912774f206SBjoern A. Zeeb 	.bb_tbl = &rtw8822c_bb_tbl,
53922774f206SBjoern A. Zeeb 	.rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl,
53932774f206SBjoern A. Zeeb 	.rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl},
53942774f206SBjoern A. Zeeb 	.rfe_defs = rtw8822c_rfe_defs,
53952774f206SBjoern A. Zeeb 	.rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs),
53962774f206SBjoern A. Zeeb 	.en_dis_dpd = true,
53972774f206SBjoern A. Zeeb 	.dpd_ratemask = DIS_DPD_RATEALL,
53982774f206SBjoern A. Zeeb 	.iqk_threshold = 8,
53992774f206SBjoern A. Zeeb 	.lck_threshold = 8,
54002774f206SBjoern A. Zeeb 	.bfer_su_max_num = 2,
54012774f206SBjoern A. Zeeb 	.bfer_mu_max_num = 1,
54022774f206SBjoern A. Zeeb 	.rx_ldpc = true,
54032774f206SBjoern A. Zeeb 	.tx_stbc = true,
54042774f206SBjoern A. Zeeb 	.edcca_th = rtw8822c_edcca_th,
54052774f206SBjoern A. Zeeb 	.l2h_th_ini_cs = 60,
54062774f206SBjoern A. Zeeb 	.l2h_th_ini_ad = 45,
54079c951734SBjoern A. Zeeb 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
54082774f206SBjoern A. Zeeb 
54092774f206SBjoern A. Zeeb #ifdef CONFIG_PM
54102774f206SBjoern A. Zeeb 	.wow_fw_name = "rtw88/rtw8822c_wow_fw.bin",
54112774f206SBjoern A. Zeeb 	.wowlan_stub = &rtw_wowlan_stub_8822c,
54122774f206SBjoern A. Zeeb 	.max_sched_scan_ssids = 4,
54132774f206SBjoern A. Zeeb #endif
541490aac0d8SBjoern A. Zeeb 	.max_scan_ie_len = (RTW_PROBE_PG_CNT - 1) * TX_PAGE_SIZE,
54159c951734SBjoern A. Zeeb 	.coex_para_ver = 0x22020720,
54169c951734SBjoern A. Zeeb 	.bt_desired_ver = 0x20,
54172774f206SBjoern A. Zeeb 	.scbd_support = true,
54182774f206SBjoern A. Zeeb 	.new_scbd10_def = true,
54192774f206SBjoern A. Zeeb 	.ble_hid_profile_support = true,
54209c951734SBjoern A. Zeeb 	.wl_mimo_ps_support = true,
54212774f206SBjoern A. Zeeb 	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
54222774f206SBjoern A. Zeeb 	.bt_rssi_type = COEX_BTRSSI_DBM,
54232774f206SBjoern A. Zeeb 	.ant_isolation = 15,
54242774f206SBjoern A. Zeeb 	.rssi_tolerance = 2,
54252774f206SBjoern A. Zeeb 	.wl_rssi_step = wl_rssi_step_8822c,
54262774f206SBjoern A. Zeeb 	.bt_rssi_step = bt_rssi_step_8822c,
54272774f206SBjoern A. Zeeb 	.table_sant_num = ARRAY_SIZE(table_sant_8822c),
54282774f206SBjoern A. Zeeb 	.table_sant = table_sant_8822c,
54292774f206SBjoern A. Zeeb 	.table_nsant_num = ARRAY_SIZE(table_nsant_8822c),
54302774f206SBjoern A. Zeeb 	.table_nsant = table_nsant_8822c,
54312774f206SBjoern A. Zeeb 	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8822c),
54322774f206SBjoern A. Zeeb 	.tdma_sant = tdma_sant_8822c,
54332774f206SBjoern A. Zeeb 	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822c),
54342774f206SBjoern A. Zeeb 	.tdma_nsant = tdma_nsant_8822c,
54352774f206SBjoern A. Zeeb 	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822c),
54362774f206SBjoern A. Zeeb 	.wl_rf_para_tx = rf_para_tx_8822c,
54372774f206SBjoern A. Zeeb 	.wl_rf_para_rx = rf_para_rx_8822c,
54382774f206SBjoern A. Zeeb 	.bt_afh_span_bw20 = 0x24,
54392774f206SBjoern A. Zeeb 	.bt_afh_span_bw40 = 0x36,
54402774f206SBjoern A. Zeeb 	.afh_5g_num = ARRAY_SIZE(afh_5g_8822c),
54412774f206SBjoern A. Zeeb 	.afh_5g = afh_5g_8822c,
54422774f206SBjoern A. Zeeb 
54432774f206SBjoern A. Zeeb 	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c),
54442774f206SBjoern A. Zeeb 	.coex_info_hw_regs = coex_info_hw_regs_8822c,
54452774f206SBjoern A. Zeeb 
54462774f206SBjoern A. Zeeb 	.fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680},
54472774f206SBjoern A. Zeeb 	.fwcd_segs = &rtw8822c_fwcd_segs,
54482774f206SBjoern A. Zeeb };
54492774f206SBjoern A. Zeeb EXPORT_SYMBOL(rtw8822c_hw_spec);
54502774f206SBjoern A. Zeeb 
54512774f206SBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8822c_fw.bin");
54522774f206SBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8822c_wow_fw.bin");
54532774f206SBjoern A. Zeeb 
54542774f206SBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation");
54552774f206SBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822c driver");
54562774f206SBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
5457