cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtw8822b.c (78612B)


      1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
      2/* Copyright(c) 2018-2019  Realtek Corporation
      3 */
      4
      5#include <linux/module.h>
      6#include "main.h"
      7#include "coex.h"
      8#include "fw.h"
      9#include "tx.h"
     10#include "rx.h"
     11#include "phy.h"
     12#include "rtw8822b.h"
     13#include "rtw8822b_table.h"
     14#include "mac.h"
     15#include "reg.h"
     16#include "debug.h"
     17#include "bf.h"
     18#include "regd.h"
     19
     20static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
     21				     u8 rx_path, bool is_tx2_path);
     22
     23static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
     24				    struct rtw8822b_efuse *map)
     25{
     26	ether_addr_copy(efuse->addr, map->e.mac_addr);
     27}
     28
     29static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
     30{
     31	struct rtw_efuse *efuse = &rtwdev->efuse;
     32	struct rtw8822b_efuse *map;
     33	int i;
     34
     35	map = (struct rtw8822b_efuse *)log_map;
     36
     37	efuse->rfe_option = map->rfe_option;
     38	efuse->rf_board_option = map->rf_board_option;
     39	efuse->crystal_cap = map->xtal_k;
     40	efuse->pa_type_2g = map->pa_type;
     41	efuse->pa_type_5g = map->pa_type;
     42	efuse->lna_type_2g = map->lna_type_2g[0];
     43	efuse->lna_type_5g = map->lna_type_5g[0];
     44	efuse->channel_plan = map->channel_plan;
     45	efuse->country_code[0] = map->country_code[0];
     46	efuse->country_code[1] = map->country_code[1];
     47	efuse->bt_setting = map->rf_bt_setting;
     48	efuse->regd = map->rf_board_option & 0x7;
     49	efuse->thermal_meter[RF_PATH_A] = map->thermal_meter;
     50	efuse->thermal_meter_k = map->thermal_meter;
     51
     52	for (i = 0; i < 4; i++)
     53		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
     54
     55	switch (rtw_hci_type(rtwdev)) {
     56	case RTW_HCI_TYPE_PCIE:
     57		rtw8822be_efuse_parsing(efuse, map);
     58		break;
     59	default:
     60		/* unsupported now */
     61		return -ENOTSUPP;
     62	}
     63
     64	return 0;
     65}
     66
     67static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev)
     68{
     69	/* chip top mux */
     70	rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3);
     71	rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0);
     72	rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1);
     73
     74	/* from s0 or s1 */
     75	rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30);
     76	rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3);
     77
     78	/* input or output */
     79	rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f);
     80	rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3);
     81}
     82
     83#define RTW_TXSCALE_SIZE 37
     84static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = {
     85	0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
     86	0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
     87	0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
     88	0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
     89};
     90
     91static u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev)
     92{
     93	u8 i = 0;
     94	u32 swing, table_value;
     95
     96	swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000);
     97	for (i = 0; i < RTW_TXSCALE_SIZE; i++) {
     98		table_value = rtw8822b_txscale_tbl[i];
     99		if (swing == table_value)
    100			break;
    101	}
    102
    103	return i;
    104}
    105
    106static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev)
    107{
    108	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
    109	u8 swing_idx = rtw8822b_get_swing_index(rtwdev);
    110	u8 path;
    111
    112	if (swing_idx >= RTW_TXSCALE_SIZE)
    113		dm_info->default_ofdm_index = 24;
    114	else
    115		dm_info->default_ofdm_index = swing_idx;
    116
    117	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
    118		ewma_thermal_init(&dm_info->avg_thermal[path]);
    119		dm_info->delta_power_index[path] = 0;
    120	}
    121	dm_info->pwr_trk_triggered = false;
    122	dm_info->pwr_trk_init_trigger = true;
    123	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
    124}
    125
    126static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev)
    127{
    128	rtw_bf_phy_init(rtwdev);
    129	/* Grouping bitmap parameters */
    130	rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF);
    131}
    132
    133static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
    134{
    135	struct rtw_hal *hal = &rtwdev->hal;
    136	u8 crystal_cap;
    137	bool is_tx2_path;
    138
    139	/* power on BB/RF domain */
    140	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
    141		       BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
    142	rtw_write8_set(rtwdev, REG_RF_CTRL,
    143		       BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
    144	rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
    145
    146	/* pre init before header files config */
    147	rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
    148
    149	rtw_phy_load_tables(rtwdev);
    150
    151	crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
    152	rtw_write32_mask(rtwdev, 0x24, 0x7e000000, crystal_cap);
    153	rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap);
    154
    155	/* post init after header files config */
    156	rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
    157
    158	is_tx2_path = false;
    159	rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
    160				 is_tx2_path);
    161	rtw_phy_init(rtwdev);
    162
    163	rtw8822b_phy_rfe_init(rtwdev);
    164	rtw8822b_pwrtrack_init(rtwdev);
    165
    166	rtw8822b_phy_bf_init(rtwdev);
    167}
    168
    169#define WLAN_SLOT_TIME		0x09
    170#define WLAN_PIFS_TIME		0x19
    171#define WLAN_SIFS_CCK_CONT_TX	0xA
    172#define WLAN_SIFS_OFDM_CONT_TX	0xE
    173#define WLAN_SIFS_CCK_TRX	0x10
    174#define WLAN_SIFS_OFDM_TRX	0x10
    175#define WLAN_VO_TXOP_LIMIT	0x186 /* unit : 32us */
    176#define WLAN_VI_TXOP_LIMIT	0x3BC /* unit : 32us */
    177#define WLAN_RDG_NAV		0x05
    178#define WLAN_TXOP_NAV		0x1B
    179#define WLAN_CCK_RX_TSF		0x30
    180#define WLAN_OFDM_RX_TSF	0x30
    181#define WLAN_TBTT_PROHIBIT	0x04 /* unit : 32us */
    182#define WLAN_TBTT_HOLD_TIME	0x064 /* unit : 32us */
    183#define WLAN_DRV_EARLY_INT	0x04
    184#define WLAN_BCN_DMA_TIME	0x02
    185
    186#define WLAN_RX_FILTER0		0x0FFFFFFF
    187#define WLAN_RX_FILTER2		0xFFFF
    188#define WLAN_RCR_CFG		0xE400220E
    189#define WLAN_RXPKT_MAX_SZ	12288
    190#define WLAN_RXPKT_MAX_SZ_512	(WLAN_RXPKT_MAX_SZ >> 9)
    191
    192#define WLAN_AMPDU_MAX_TIME		0x70
    193#define WLAN_RTS_LEN_TH			0xFF
    194#define WLAN_RTS_TX_TIME_TH		0x08
    195#define WLAN_MAX_AGG_PKT_LIMIT		0x20
    196#define WLAN_RTS_MAX_AGG_PKT_LIMIT	0x20
    197#define FAST_EDCA_VO_TH		0x06
    198#define FAST_EDCA_VI_TH		0x06
    199#define FAST_EDCA_BE_TH		0x06
    200#define FAST_EDCA_BK_TH		0x06
    201#define WLAN_BAR_RETRY_LIMIT		0x01
    202#define WLAN_RA_TRY_RATE_AGG_LIMIT	0x08
    203
    204#define WLAN_TX_FUNC_CFG1		0x30
    205#define WLAN_TX_FUNC_CFG2		0x30
    206#define WLAN_MAC_OPT_NORM_FUNC1		0x98
    207#define WLAN_MAC_OPT_LB_FUNC1		0x80
    208#define WLAN_MAC_OPT_FUNC2		0xb0810041
    209
    210#define WLAN_SIFS_CFG	(WLAN_SIFS_CCK_CONT_TX | \
    211			(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
    212			(WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
    213			(WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
    214
    215#define WLAN_TBTT_TIME	(WLAN_TBTT_PROHIBIT |\
    216			(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
    217
    218#define WLAN_NAV_CFG		(WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
    219#define WLAN_RX_TSF_CFG		(WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
    220
    221static int rtw8822b_mac_init(struct rtw_dev *rtwdev)
    222{
    223	u32 value32;
    224
    225	/* protocol configuration */
    226	rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, BIT_PRE_TX_CMD);
    227	rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
    228	rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
    229	value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
    230		  (WLAN_MAX_AGG_PKT_LIMIT << 16) |
    231		  (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
    232	rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
    233	rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
    234		    WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
    235	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
    236	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
    237	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
    238	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
    239	/* EDCA configuration */
    240	rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
    241	rtw_write16(rtwdev, REG_TXPAUSE, 0x0000);
    242	rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
    243	rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
    244	rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
    245	rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
    246	rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
    247	rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
    248	rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
    249	/* Set beacon cotnrol - enable TSF and other related functions */
    250	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
    251	/* Set send beacon related registers */
    252	rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
    253	rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
    254	rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
    255	rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
    256	/* WMAC configuration */
    257	rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
    258	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
    259	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
    260	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
    261	rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
    262	rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
    263	rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
    264	rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
    265	rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL,
    266		       BIT_DIS_CHK_VHTSIGB_CRC);
    267
    268	return 0;
    269}
    270
    271static void rtw8822b_set_channel_rfe_efem(struct rtw_dev *rtwdev, u8 channel)
    272{
    273	struct rtw_hal *hal = &rtwdev->hal;
    274
    275	if (IS_CH_2G_BAND(channel)) {
    276		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x705770);
    277		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
    278		rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(4), 0);
    279	} else {
    280		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x177517);
    281		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
    282		rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(5), 0);
    283	}
    284
    285	rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
    286
    287	if (hal->antenna_rx == BB_PATH_AB ||
    288	    hal->antenna_tx == BB_PATH_AB) {
    289		/* 2TX or 2RX */
    290		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
    291	} else if (hal->antenna_rx == hal->antenna_tx) {
    292		/* TXA+RXA or TXB+RXB */
    293		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
    294	} else {
    295		/* TXB+RXA or TXA+RXB */
    296		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
    297	}
    298}
    299
    300static void rtw8822b_set_channel_rfe_ifem(struct rtw_dev *rtwdev, u8 channel)
    301{
    302	struct rtw_hal *hal = &rtwdev->hal;
    303
    304	if (IS_CH_2G_BAND(channel)) {
    305		/* signal source */
    306		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x745774);
    307		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
    308	} else {
    309		/* signal source */
    310		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x477547);
    311		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
    312	}
    313
    314	rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
    315
    316	if (IS_CH_2G_BAND(channel)) {
    317		if (hal->antenna_rx == BB_PATH_AB ||
    318		    hal->antenna_tx == BB_PATH_AB) {
    319			/* 2TX or 2RX */
    320			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
    321		} else if (hal->antenna_rx == hal->antenna_tx) {
    322			/* TXA+RXA or TXB+RXB */
    323			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
    324		} else {
    325			/* TXB+RXA or TXA+RXB */
    326			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
    327		}
    328	} else {
    329		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa5a5);
    330	}
    331}
    332
    333enum {
    334	CCUT_IDX_1R_2G,
    335	CCUT_IDX_2R_2G,
    336	CCUT_IDX_1R_5G,
    337	CCUT_IDX_2R_5G,
    338	CCUT_IDX_NR,
    339};
    340
    341struct cca_ccut {
    342	u32 reg82c[CCUT_IDX_NR];
    343	u32 reg830[CCUT_IDX_NR];
    344	u32 reg838[CCUT_IDX_NR];
    345};
    346
    347static const struct cca_ccut cca_ifem_ccut = {
    348	{0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
    349	{0x79a0eaaa, 0x79A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
    350	{0x87765541, 0x87746341, 0x87765541, 0x87746341}, /*Reg838*/
    351};
    352
    353static const struct cca_ccut cca_efem_ccut = {
    354	{0x75B86010, 0x75B76010, 0x75B86010, 0x75B76010}, /*Reg82C*/
    355	{0x79A0EAA8, 0x79A0EAAC, 0x79A0EAA8, 0x79a0eaaa}, /*Reg830*/
    356	{0x87766451, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/
    357};
    358
    359static const struct cca_ccut cca_ifem_ccut_ext = {
    360	{0x75da8010, 0x75da8010, 0x75da8010, 0x75da8010}, /*Reg82C*/
    361	{0x79a0eaaa, 0x97A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
    362	{0x87765541, 0x86666341, 0x87765561, 0x86666361}, /*Reg838*/
    363};
    364
    365static void rtw8822b_get_cca_val(const struct cca_ccut *cca_ccut, u8 col,
    366				 u32 *reg82c, u32 *reg830, u32 *reg838)
    367{
    368	*reg82c = cca_ccut->reg82c[col];
    369	*reg830 = cca_ccut->reg830[col];
    370	*reg838 = cca_ccut->reg838[col];
    371}
    372
    373struct rtw8822b_rfe_info {
    374	const struct cca_ccut *cca_ccut_2g;
    375	const struct cca_ccut *cca_ccut_5g;
    376	enum rtw_rfe_fem fem;
    377	bool ifem_ext;
    378	void (*rtw_set_channel_rfe)(struct rtw_dev *rtwdev, u8 channel);
    379};
    380
    381#define I2GE5G_CCUT(set_ch) {						\
    382	.cca_ccut_2g = &cca_ifem_ccut,					\
    383	.cca_ccut_5g = &cca_efem_ccut,					\
    384	.fem = RTW_RFE_IFEM2G_EFEM5G,					\
    385	.ifem_ext = false,						\
    386	.rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch,	\
    387	}
    388#define IFEM_EXT_CCUT(set_ch) {						\
    389	.cca_ccut_2g = &cca_ifem_ccut_ext,				\
    390	.cca_ccut_5g = &cca_ifem_ccut_ext,				\
    391	.fem = RTW_RFE_IFEM,						\
    392	.ifem_ext = true,						\
    393	.rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch,	\
    394	}
    395
    396static const struct rtw8822b_rfe_info rtw8822b_rfe_info[] = {
    397	[2] = I2GE5G_CCUT(efem),
    398	[3] = IFEM_EXT_CCUT(ifem),
    399	[5] = IFEM_EXT_CCUT(ifem),
    400};
    401
    402static void rtw8822b_set_channel_cca(struct rtw_dev *rtwdev, u8 channel, u8 bw,
    403				     const struct rtw8822b_rfe_info *rfe_info)
    404{
    405	struct rtw_hal *hal = &rtwdev->hal;
    406	struct rtw_efuse *efuse = &rtwdev->efuse;
    407	const struct cca_ccut *cca_ccut;
    408	u8 col;
    409	u32 reg82c, reg830, reg838;
    410	bool is_efem_cca = false, is_ifem_cca = false, is_rfe_type = false;
    411
    412	if (IS_CH_2G_BAND(channel)) {
    413		cca_ccut = rfe_info->cca_ccut_2g;
    414
    415		if (hal->antenna_rx == BB_PATH_A ||
    416		    hal->antenna_rx == BB_PATH_B)
    417			col = CCUT_IDX_1R_2G;
    418		else
    419			col = CCUT_IDX_2R_2G;
    420	} else {
    421		cca_ccut = rfe_info->cca_ccut_5g;
    422
    423		if (hal->antenna_rx == BB_PATH_A ||
    424		    hal->antenna_rx == BB_PATH_B)
    425			col = CCUT_IDX_1R_5G;
    426		else
    427			col = CCUT_IDX_2R_5G;
    428	}
    429
    430	rtw8822b_get_cca_val(cca_ccut, col, &reg82c, &reg830, &reg838);
    431
    432	switch (rfe_info->fem) {
    433	case RTW_RFE_IFEM:
    434	default:
    435		is_ifem_cca = true;
    436		if (rfe_info->ifem_ext)
    437			is_rfe_type = true;
    438		break;
    439	case RTW_RFE_EFEM:
    440		is_efem_cca = true;
    441		break;
    442	case RTW_RFE_IFEM2G_EFEM5G:
    443		if (IS_CH_2G_BAND(channel))
    444			is_ifem_cca = true;
    445		else
    446			is_efem_cca = true;
    447		break;
    448	}
    449
    450	if (is_ifem_cca) {
    451		if ((hal->cut_version == RTW_CHIP_VER_CUT_B &&
    452		     (col == CCUT_IDX_2R_2G || col == CCUT_IDX_2R_5G) &&
    453		     bw == RTW_CHANNEL_WIDTH_40) ||
    454		    (!is_rfe_type && col == CCUT_IDX_2R_5G &&
    455		     bw == RTW_CHANNEL_WIDTH_40) ||
    456		    (efuse->rfe_option == 5 && col == CCUT_IDX_2R_5G))
    457			reg830 = 0x79a0ea28;
    458	}
    459
    460	rtw_write32_mask(rtwdev, REG_CCASEL, MASKDWORD, reg82c);
    461	rtw_write32_mask(rtwdev, REG_PDMFTH, MASKDWORD, reg830);
    462	rtw_write32_mask(rtwdev, REG_CCA2ND, MASKDWORD, reg838);
    463
    464	if (is_efem_cca && !(hal->cut_version == RTW_CHIP_VER_CUT_B))
    465		rtw_write32_mask(rtwdev, REG_L1WT, MASKDWORD, 0x9194b2b9);
    466
    467	if (bw == RTW_CHANNEL_WIDTH_20 && IS_CH_5G_BAND_MID(channel))
    468		rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0, 0x4);
    469}
    470
    471static const u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, 0x6,
    472				0x5, 0x0, 0x0, 0x7, 0x6, 0x6};
    473static const u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, 0x0,
    474				   0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, 0x7, 0x6,
    475				   0x6, 0x5, 0x0, 0x0, 0x7};
    476static const u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, 0x0,
    477				 0x7, 0x7, 0x6, 0x5, 0x5, 0x0};
    478
    479static void rtw8822b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
    480{
    481#define RF18_BAND_MASK		(BIT(16) | BIT(9) | BIT(8))
    482#define RF18_BAND_2G		(0)
    483#define RF18_BAND_5G		(BIT(16) | BIT(8))
    484#define RF18_CHANNEL_MASK	(MASKBYTE0)
    485#define RF18_RFSI_MASK		(BIT(18) | BIT(17))
    486#define RF18_RFSI_GE_CH80	(BIT(17))
    487#define RF18_RFSI_GT_CH144	(BIT(18))
    488#define RF18_BW_MASK		(BIT(11) | BIT(10))
    489#define RF18_BW_20M		(BIT(11) | BIT(10))
    490#define RF18_BW_40M		(BIT(11))
    491#define RF18_BW_80M		(BIT(10))
    492#define RFBE_MASK		(BIT(17) | BIT(16) | BIT(15))
    493
    494	struct rtw_hal *hal = &rtwdev->hal;
    495	u32 rf_reg18, rf_reg_be;
    496
    497	rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
    498
    499	rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
    500		      RF18_BW_MASK);
    501
    502	rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G);
    503	rf_reg18 |= (channel & RF18_CHANNEL_MASK);
    504	if (channel > 144)
    505		rf_reg18 |= RF18_RFSI_GT_CH144;
    506	else if (channel >= 80)
    507		rf_reg18 |= RF18_RFSI_GE_CH80;
    508
    509	switch (bw) {
    510	case RTW_CHANNEL_WIDTH_5:
    511	case RTW_CHANNEL_WIDTH_10:
    512	case RTW_CHANNEL_WIDTH_20:
    513	default:
    514		rf_reg18 |= RF18_BW_20M;
    515		break;
    516	case RTW_CHANNEL_WIDTH_40:
    517		rf_reg18 |= RF18_BW_40M;
    518		break;
    519	case RTW_CHANNEL_WIDTH_80:
    520		rf_reg18 |= RF18_BW_80M;
    521		break;
    522	}
    523
    524	if (IS_CH_2G_BAND(channel))
    525		rf_reg_be = 0x0;
    526	else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
    527		rf_reg_be = low_band[(channel - 36) >> 1];
    528	else if (IS_CH_5G_BAND_3(channel))
    529		rf_reg_be = middle_band[(channel - 100) >> 1];
    530	else if (IS_CH_5G_BAND_4(channel))
    531		rf_reg_be = high_band[(channel - 149) >> 1];
    532	else
    533		goto err;
    534
    535	rtw_write_rf(rtwdev, RF_PATH_A, RF_MALSEL, RFBE_MASK, rf_reg_be);
    536
    537	/* need to set 0xdf[18]=1 before writing RF18 when channel 144 */
    538	if (channel == 144)
    539		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x1);
    540	else
    541		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x0);
    542
    543	rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18);
    544	if (hal->rf_type > RF_1T1R)
    545		rtw_write_rf(rtwdev, RF_PATH_B, 0x18, RFREG_MASK, rf_reg18);
    546
    547	rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0);
    548	rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1);
    549
    550	return;
    551
    552err:
    553	WARN_ON(1);
    554}
    555
    556static void rtw8822b_toggle_igi(struct rtw_dev *rtwdev)
    557{
    558	struct rtw_hal *hal = &rtwdev->hal;
    559	u32 igi;
    560
    561	igi = rtw_read32_mask(rtwdev, REG_RXIGI_A, 0x7f);
    562	rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi - 2);
    563	rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi);
    564	rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi - 2);
    565	rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi);
    566
    567	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, 0x0);
    568	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0,
    569			 hal->antenna_rx | (hal->antenna_rx << 4));
    570}
    571
    572static void rtw8822b_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
    573{
    574	if (bw == RTW_CHANNEL_WIDTH_40) {
    575		/* RX DFIR for BW40 */
    576		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x1);
    577		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x0);
    578		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
    579	} else if (bw == RTW_CHANNEL_WIDTH_80) {
    580		/* RX DFIR for BW80 */
    581		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
    582		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1);
    583		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
    584	} else {
    585		/* RX DFIR for BW20, BW10 and BW5*/
    586		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
    587		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
    588		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1);
    589	}
    590}
    591
    592static void rtw8822b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
    593				    u8 primary_ch_idx)
    594{
    595	struct rtw_efuse *efuse = &rtwdev->efuse;
    596	u8 rfe_option = efuse->rfe_option;
    597	u32 val32;
    598
    599	if (IS_CH_2G_BAND(channel)) {
    600		rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1);
    601		rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0);
    602		rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0);
    603		rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
    604
    605		rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x0);
    606		rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
    607		if (channel == 14) {
    608			rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x00006577);
    609			rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
    610		} else {
    611			rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x384f6577);
    612			rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x1525);
    613		}
    614
    615		rtw_write32_mask(rtwdev, REG_RFEINV, 0x300, 0x2);
    616	} else if (IS_CH_5G_BAND(channel)) {
    617		rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
    618		rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1);
    619		rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0);
    620		rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 34);
    621
    622		if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
    623			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x1);
    624		else if (IS_CH_5G_BAND_3(channel))
    625			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x2);
    626		else if (IS_CH_5G_BAND_4(channel))
    627			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x3);
    628
    629		if (IS_CH_5G_BAND_1(channel))
    630			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494);
    631		else if (IS_CH_5G_BAND_2(channel))
    632			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453);
    633		else if (channel >= 100 && channel <= 116)
    634			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452);
    635		else if (channel >= 118 && channel <= 177)
    636			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
    637
    638		rtw_write32_mask(rtwdev, 0xcbc, 0x300, 0x1);
    639	}
    640
    641	switch (bw) {
    642	case RTW_CHANNEL_WIDTH_20:
    643	default:
    644		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
    645		val32 &= 0xFFCFFC00;
    646		val32 |= (RTW_CHANNEL_WIDTH_20);
    647		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
    648
    649		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
    650		break;
    651	case RTW_CHANNEL_WIDTH_40:
    652		if (primary_ch_idx == RTW_SC_20_UPPER)
    653			rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
    654		else
    655			rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
    656
    657		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
    658		val32 &= 0xFF3FF300;
    659		val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_40);
    660		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
    661
    662		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
    663		break;
    664	case RTW_CHANNEL_WIDTH_80:
    665		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
    666		val32 &= 0xFCEFCF00;
    667		val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_80);
    668		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
    669
    670		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
    671
    672		if (rfe_option == 2 || rfe_option == 3) {
    673			rtw_write32_mask(rtwdev, REG_L1PKWT, 0x0000f000, 0x6);
    674			rtw_write32_mask(rtwdev, REG_ADC40, BIT(10), 0x1);
    675		}
    676		break;
    677	case RTW_CHANNEL_WIDTH_5:
    678		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
    679		val32 &= 0xEFEEFE00;
    680		val32 |= ((BIT(6) | RTW_CHANNEL_WIDTH_20));
    681		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
    682
    683		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
    684		rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
    685		break;
    686	case RTW_CHANNEL_WIDTH_10:
    687		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
    688		val32 &= 0xEFFEFF00;
    689		val32 |= ((BIT(7) | RTW_CHANNEL_WIDTH_20));
    690		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
    691
    692		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
    693		rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
    694		break;
    695	}
    696}
    697
    698static void rtw8822b_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
    699				 u8 primary_chan_idx)
    700{
    701	struct rtw_efuse *efuse = &rtwdev->efuse;
    702	const struct rtw8822b_rfe_info *rfe_info;
    703
    704	if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
    705		 "rfe_option %d is out of boundary\n", efuse->rfe_option))
    706		return;
    707
    708	rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
    709
    710	rtw8822b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
    711	rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
    712	rtw8822b_set_channel_rf(rtwdev, channel, bw);
    713	rtw8822b_set_channel_rxdfir(rtwdev, bw);
    714	rtw8822b_toggle_igi(rtwdev);
    715	rtw8822b_set_channel_cca(rtwdev, channel, bw, rfe_info);
    716	(*rfe_info->rtw_set_channel_rfe)(rtwdev, channel);
    717}
    718
    719static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
    720				     u8 rx_path, bool is_tx2_path)
    721{
    722	struct rtw_efuse *efuse = &rtwdev->efuse;
    723	const struct rtw8822b_rfe_info *rfe_info;
    724	u8 ch = rtwdev->hal.current_channel;
    725	u8 tx_path_sel, rx_path_sel;
    726	int counter;
    727
    728	if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
    729		 "rfe_option %d is out of boundary\n", efuse->rfe_option))
    730		return;
    731
    732	rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
    733
    734	if ((tx_path | rx_path) & BB_PATH_A)
    735		rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x3231);
    736	else
    737		rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x1111);
    738
    739	if ((tx_path | rx_path) & BB_PATH_B)
    740		rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x3231);
    741	else
    742		rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x1111);
    743
    744	rtw_write32_mask(rtwdev, REG_CDDTXP, (BIT(19) | BIT(18)), 0x3);
    745	rtw_write32_mask(rtwdev, REG_TXPSEL, (BIT(29) | BIT(28)), 0x1);
    746	rtw_write32_mask(rtwdev, REG_TXPSEL, BIT(30), 0x1);
    747
    748	if (tx_path & BB_PATH_A) {
    749		rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x001);
    750		rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x8);
    751	} else if (tx_path & BB_PATH_B) {
    752		rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x002);
    753		rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x4);
    754	}
    755
    756	if (tx_path == BB_PATH_A || tx_path == BB_PATH_B)
    757		rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x01);
    758	else
    759		rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x43);
    760
    761	tx_path_sel = (tx_path << 4) | tx_path;
    762	rtw_write32_mask(rtwdev, REG_TXPSEL, MASKBYTE0, tx_path_sel);
    763
    764	if (tx_path != BB_PATH_A && tx_path != BB_PATH_B) {
    765		if (is_tx2_path || rtwdev->mp_mode) {
    766			rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x043);
    767			rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0xc);
    768		}
    769	}
    770
    771	rtw_write32_mask(rtwdev, REG_RXDESC, BIT(22), 0x0);
    772	rtw_write32_mask(rtwdev, REG_RXDESC, BIT(18), 0x0);
    773
    774	if (rx_path & BB_PATH_A)
    775		rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x0);
    776	else if (rx_path & BB_PATH_B)
    777		rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x5);
    778
    779	rx_path_sel = (rx_path << 4) | rx_path;
    780	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, rx_path_sel);
    781
    782	if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) {
    783		rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x0);
    784		rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x0);
    785		rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x0);
    786	} else {
    787		rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x1);
    788		rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x1);
    789		rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x1);
    790	}
    791
    792	for (counter = 100; counter > 0; counter--) {
    793		u32 rf_reg33;
    794
    795		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
    796		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
    797
    798		udelay(2);
    799		rf_reg33 = rtw_read_rf(rtwdev, RF_PATH_A, 0x33, RFREG_MASK);
    800
    801		if (rf_reg33 == 0x00001)
    802			break;
    803	}
    804
    805	if (WARN(counter <= 0, "write RF mode table fail\n"))
    806		return;
    807
    808	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
    809	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
    810	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x00034);
    811	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x4080c);
    812	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
    813	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
    814
    815	rtw8822b_toggle_igi(rtwdev);
    816	rtw8822b_set_channel_cca(rtwdev, 1, RTW_CHANNEL_WIDTH_20, rfe_info);
    817	(*rfe_info->rtw_set_channel_rfe)(rtwdev, ch);
    818}
    819
    820static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
    821				   struct rtw_rx_pkt_stat *pkt_stat)
    822{
    823	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
    824	s8 min_rx_power = -120;
    825	u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
    826
    827	/* 8822B uses only 1 antenna to RX CCK rates */
    828	pkt_stat->rx_power[RF_PATH_A] = pwdb - 110;
    829	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
    830	pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
    831	pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
    832				     min_rx_power);
    833	dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
    834}
    835
    836static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
    837				   struct rtw_rx_pkt_stat *pkt_stat)
    838{
    839	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
    840	u8 rxsc, bw;
    841	s8 min_rx_power = -120;
    842	s8 rx_evm;
    843	u8 evm_dbm = 0;
    844	u8 rssi;
    845	int path;
    846
    847	if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
    848		rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
    849	else
    850		rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
    851
    852	if (rxsc >= 1 && rxsc <= 8)
    853		bw = RTW_CHANNEL_WIDTH_20;
    854	else if (rxsc >= 9 && rxsc <= 12)
    855		bw = RTW_CHANNEL_WIDTH_40;
    856	else if (rxsc >= 13)
    857		bw = RTW_CHANNEL_WIDTH_80;
    858	else
    859		bw = GET_PHY_STAT_P1_RF_MODE(phy_status);
    860
    861	pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
    862	pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110;
    863	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2);
    864	pkt_stat->bw = bw;
    865	pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A],
    866				      pkt_stat->rx_power[RF_PATH_B],
    867				      min_rx_power);
    868
    869	dm_info->curr_rx_rate = pkt_stat->rate;
    870
    871	pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
    872	pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status);
    873
    874	pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
    875	pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status);
    876
    877	pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
    878	pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status);
    879
    880	for (path = 0; path <= rtwdev->hal.rf_path_num; path++) {
    881		rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1);
    882		dm_info->rssi[path] = rssi;
    883		dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1;
    884		dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1;
    885
    886		rx_evm = pkt_stat->rx_evm[path];
    887
    888		if (rx_evm < 0) {
    889			if (rx_evm == S8_MIN)
    890				evm_dbm = 0;
    891			else
    892				evm_dbm = ((u8)-rx_evm >> 1);
    893		}
    894		dm_info->rx_evm_dbm[path] = evm_dbm;
    895	}
    896}
    897
    898static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
    899			     struct rtw_rx_pkt_stat *pkt_stat)
    900{
    901	u8 page;
    902
    903	page = *phy_status & 0xf;
    904
    905	switch (page) {
    906	case 0:
    907		query_phy_status_page0(rtwdev, phy_status, pkt_stat);
    908		break;
    909	case 1:
    910		query_phy_status_page1(rtwdev, phy_status, pkt_stat);
    911		break;
    912	default:
    913		rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
    914		return;
    915	}
    916}
    917
    918static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
    919				   struct rtw_rx_pkt_stat *pkt_stat,
    920				   struct ieee80211_rx_status *rx_status)
    921{
    922	struct ieee80211_hdr *hdr;
    923	u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
    924	u8 *phy_status = NULL;
    925
    926	memset(pkt_stat, 0, sizeof(*pkt_stat));
    927
    928	pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
    929	pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
    930	pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
    931	pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
    932			      GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
    933	pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
    934	pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
    935	pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
    936	pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
    937	pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
    938	pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
    939	pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
    940	pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
    941
    942	/* drv_info_sz is in unit of 8-bytes */
    943	pkt_stat->drv_info_sz *= 8;
    944
    945	/* c2h cmd pkt's rx/phy status is not interested */
    946	if (pkt_stat->is_c2h)
    947		return;
    948
    949	hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
    950				       pkt_stat->drv_info_sz);
    951	if (pkt_stat->phy_status) {
    952		phy_status = rx_desc + desc_sz + pkt_stat->shift;
    953		query_phy_status(rtwdev, phy_status, pkt_stat);
    954	}
    955
    956	rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
    957}
    958
    959static void
    960rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
    961{
    962	struct rtw_hal *hal = &rtwdev->hal;
    963	static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
    964	static u32 phy_pwr_idx;
    965	u8 rate, rate_idx, pwr_index, shift;
    966	int j;
    967
    968	for (j = 0; j < rtw_rate_size[rs]; j++) {
    969		rate = rtw_rate_section[rs][j];
    970		pwr_index = hal->tx_pwr_tbl[path][rate];
    971		shift = rate & 0x3;
    972		phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
    973		if (shift == 0x3) {
    974			rate_idx = rate & 0xfc;
    975			rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
    976				    phy_pwr_idx);
    977			phy_pwr_idx = 0;
    978		}
    979	}
    980}
    981
    982static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev)
    983{
    984	struct rtw_hal *hal = &rtwdev->hal;
    985	int rs, path;
    986
    987	for (path = 0; path < hal->rf_path_num; path++) {
    988		for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
    989			rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs);
    990	}
    991}
    992
    993static bool rtw8822b_check_rf_path(u8 antenna)
    994{
    995	switch (antenna) {
    996	case BB_PATH_A:
    997	case BB_PATH_B:
    998	case BB_PATH_AB:
    999		return true;
   1000	default:
   1001		return false;
   1002	}
   1003}
   1004
   1005static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
   1006				u32 antenna_tx,
   1007				u32 antenna_rx)
   1008{
   1009	struct rtw_hal *hal = &rtwdev->hal;
   1010
   1011	rtw_dbg(rtwdev, RTW_DBG_PHY, "config RF path, tx=0x%x rx=0x%x\n",
   1012		antenna_tx, antenna_rx);
   1013
   1014	if (!rtw8822b_check_rf_path(antenna_tx)) {
   1015		rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
   1016		return -EINVAL;
   1017	}
   1018
   1019	if (!rtw8822b_check_rf_path(antenna_rx)) {
   1020		rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
   1021		return -EINVAL;
   1022	}
   1023
   1024	hal->antenna_tx = antenna_tx;
   1025	hal->antenna_rx = antenna_rx;
   1026
   1027	rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
   1028
   1029	return 0;
   1030}
   1031
   1032static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
   1033{
   1034	u8 ldo_pwr;
   1035
   1036	ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
   1037	ldo_pwr = enable ? ldo_pwr | BIT_LDO25_EN : ldo_pwr & ~BIT_LDO25_EN;
   1038	rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
   1039}
   1040
   1041static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev)
   1042{
   1043	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1044	u32 cck_enable;
   1045	u32 cck_fa_cnt;
   1046	u32 ofdm_fa_cnt;
   1047	u32 crc32_cnt;
   1048	u32 cca32_cnt;
   1049
   1050	cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28);
   1051	cck_fa_cnt = rtw_read16(rtwdev, 0xa5c);
   1052	ofdm_fa_cnt = rtw_read16(rtwdev, 0xf48);
   1053
   1054	dm_info->cck_fa_cnt = cck_fa_cnt;
   1055	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
   1056	dm_info->total_fa_cnt = ofdm_fa_cnt;
   1057	dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0;
   1058
   1059	crc32_cnt = rtw_read32(rtwdev, 0xf04);
   1060	dm_info->cck_ok_cnt = crc32_cnt & 0xffff;
   1061	dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
   1062	crc32_cnt = rtw_read32(rtwdev, 0xf14);
   1063	dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff;
   1064	dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
   1065	crc32_cnt = rtw_read32(rtwdev, 0xf10);
   1066	dm_info->ht_ok_cnt = crc32_cnt & 0xffff;
   1067	dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
   1068	crc32_cnt = rtw_read32(rtwdev, 0xf0c);
   1069	dm_info->vht_ok_cnt = crc32_cnt & 0xffff;
   1070	dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
   1071
   1072	cca32_cnt = rtw_read32(rtwdev, 0xf08);
   1073	dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16);
   1074	dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
   1075	if (cck_enable) {
   1076		cca32_cnt = rtw_read32(rtwdev, 0xfcc);
   1077		dm_info->cck_cca_cnt = cca32_cnt & 0xffff;
   1078		dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
   1079	}
   1080
   1081	rtw_write32_set(rtwdev, 0x9a4, BIT(17));
   1082	rtw_write32_clr(rtwdev, 0x9a4, BIT(17));
   1083	rtw_write32_clr(rtwdev, 0xa2c, BIT(15));
   1084	rtw_write32_set(rtwdev, 0xa2c, BIT(15));
   1085	rtw_write32_set(rtwdev, 0xb58, BIT(0));
   1086	rtw_write32_clr(rtwdev, 0xb58, BIT(0));
   1087}
   1088
   1089static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
   1090{
   1091	static int do_iqk_cnt;
   1092	struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
   1093	u32 rf_reg, iqk_fail_mask;
   1094	int counter;
   1095	bool reload;
   1096
   1097	rtw_fw_do_iqk(rtwdev, &para);
   1098
   1099	for (counter = 0; counter < 300; counter++) {
   1100		rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
   1101		if (rf_reg == 0xabcde)
   1102			break;
   1103		msleep(20);
   1104	}
   1105	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
   1106
   1107	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
   1108	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
   1109	rtw_dbg(rtwdev, RTW_DBG_PHY,
   1110		"iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
   1111		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
   1112}
   1113
   1114static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)
   1115{
   1116	rtw8822b_do_iqk(rtwdev);
   1117}
   1118
   1119static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev)
   1120{
   1121	/* enable TBTT nterrupt */
   1122	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
   1123
   1124	/* BT report packet sample rate */
   1125	/* 0x790[5:0]=0x5 */
   1126	rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
   1127
   1128	/* enable BT counter statistics */
   1129	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
   1130
   1131	/* enable PTA (3-wire function form BT side) */
   1132	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
   1133	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
   1134
   1135	/* enable PTA (tx/rx signal form WiFi side) */
   1136	rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
   1137	/* wl tx signal to PTA not case EDCCA */
   1138	rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
   1139	/* GNT_BT=1 while select both */
   1140	rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
   1141}
   1142
   1143static void rtw8822b_coex_cfg_ant_switch(struct rtw_dev *rtwdev,
   1144					 u8 ctrl_type, u8 pos_type)
   1145{
   1146	struct rtw_coex *coex = &rtwdev->coex;
   1147	struct rtw_coex_dm *coex_dm = &coex->dm;
   1148	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
   1149	bool polarity_inverse;
   1150	u8 regval = 0;
   1151
   1152	if (((ctrl_type << 8) + pos_type) == coex_dm->cur_switch_status)
   1153		return;
   1154
   1155	coex_dm->cur_switch_status = (ctrl_type << 8) + pos_type;
   1156
   1157	if (coex_rfe->ant_switch_diversity &&
   1158	    ctrl_type == COEX_SWITCH_CTRL_BY_BBSW)
   1159		ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV;
   1160
   1161	polarity_inverse = (coex_rfe->ant_switch_polarity == 1);
   1162
   1163	switch (ctrl_type) {
   1164	default:
   1165	case COEX_SWITCH_CTRL_BY_BBSW:
   1166		/* 0x4c[23] = 0 */
   1167		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
   1168		/* 0x4c[24] = 1 */
   1169		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
   1170		/* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
   1171		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x77);
   1172
   1173		if (pos_type == COEX_SWITCH_TO_WLG_BT) {
   1174			if (coex_rfe->rfe_module_type != 0x4 &&
   1175			    coex_rfe->rfe_module_type != 0x2)
   1176				regval = 0x3;
   1177			else
   1178				regval = (!polarity_inverse ? 0x2 : 0x1);
   1179		} else if (pos_type == COEX_SWITCH_TO_WLG) {
   1180			regval = (!polarity_inverse ? 0x2 : 0x1);
   1181		} else {
   1182			regval = (!polarity_inverse ? 0x1 : 0x2);
   1183		}
   1184
   1185		rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
   1186		break;
   1187	case COEX_SWITCH_CTRL_BY_PTA:
   1188		/* 0x4c[23] = 0 */
   1189		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
   1190		/* 0x4c[24] = 1 */
   1191		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
   1192		/* PTA,  DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
   1193		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x66);
   1194
   1195		regval = (!polarity_inverse ? 0x2 : 0x1);
   1196		rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
   1197		break;
   1198	case COEX_SWITCH_CTRL_BY_ANTDIV:
   1199		/* 0x4c[23] = 0 */
   1200		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
   1201		/* 0x4c[24] = 1 */
   1202		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
   1203		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x88);
   1204		break;
   1205	case COEX_SWITCH_CTRL_BY_MAC:
   1206		/* 0x4c[23] = 1 */
   1207		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x1);
   1208
   1209		regval = (!polarity_inverse ? 0x0 : 0x1);
   1210		rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, regval);
   1211		break;
   1212	case COEX_SWITCH_CTRL_BY_FW:
   1213		/* 0x4c[23] = 0 */
   1214		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
   1215		/* 0x4c[24] = 1 */
   1216		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
   1217		break;
   1218	case COEX_SWITCH_CTRL_BY_BT:
   1219		/* 0x4c[23] = 0 */
   1220		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
   1221		/* 0x4c[24] = 0 */
   1222		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x0);
   1223		break;
   1224	}
   1225}
   1226
   1227static void rtw8822b_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
   1228{
   1229}
   1230
   1231static void rtw8822b_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
   1232{
   1233	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0);
   1234	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0);
   1235	rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0);
   1236	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0);
   1237	rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0);
   1238}
   1239
   1240static void rtw8822b_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
   1241{
   1242	struct rtw_coex *coex = &rtwdev->coex;
   1243	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
   1244	struct rtw_efuse *efuse = &rtwdev->efuse;
   1245	bool is_ext_fem = false;
   1246
   1247	coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
   1248	coex_rfe->ant_switch_polarity = 0;
   1249	coex_rfe->ant_switch_diversity = false;
   1250	if (coex_rfe->rfe_module_type == 0x12 ||
   1251	    coex_rfe->rfe_module_type == 0x15 ||
   1252	    coex_rfe->rfe_module_type == 0x16)
   1253		coex_rfe->ant_switch_exist = false;
   1254	else
   1255		coex_rfe->ant_switch_exist = true;
   1256
   1257	if (coex_rfe->rfe_module_type == 2 ||
   1258	    coex_rfe->rfe_module_type == 4) {
   1259		rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, true);
   1260		is_ext_fem = true;
   1261	} else {
   1262		rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, false);
   1263	}
   1264
   1265	coex_rfe->wlg_at_btg = false;
   1266
   1267	if (efuse->share_ant &&
   1268	    coex_rfe->ant_switch_exist && !is_ext_fem)
   1269		coex_rfe->ant_switch_with_bt = true;
   1270	else
   1271		coex_rfe->ant_switch_with_bt = false;
   1272
   1273	/* Ext switch buffer mux */
   1274	rtw_write8(rtwdev, REG_RFE_CTRL_E, 0xff);
   1275	rtw_write8_mask(rtwdev, REG_RFESEL_CTRL + 1, 0x3, 0x0);
   1276	rtw_write8_mask(rtwdev, REG_RFE_INV16, BIT_RFE_BUF_EN, 0x0);
   1277
   1278	/* Disable LTE Coex Function in WiFi side */
   1279	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0);
   1280
   1281	/* BTC_CTT_WL_VS_LTE */
   1282	rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
   1283
   1284	/* BTC_CTT_BT_VS_LTE */
   1285	rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
   1286}
   1287
   1288static void rtw8822b_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
   1289{
   1290	struct rtw_coex *coex = &rtwdev->coex;
   1291	struct rtw_coex_dm *coex_dm = &coex->dm;
   1292	static const u16 reg_addr[] = {0xc58, 0xe58};
   1293	static const u8	wl_tx_power[] = {0xd8, 0xd4, 0xd0, 0xcc, 0xc8};
   1294	u8 i, pwr;
   1295
   1296	if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
   1297		return;
   1298
   1299	coex_dm->cur_wl_pwr_lvl = wl_pwr;
   1300
   1301	if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power))
   1302		coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1;
   1303
   1304	pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl];
   1305
   1306	for (i = 0; i < ARRAY_SIZE(reg_addr); i++)
   1307		rtw_write8_mask(rtwdev, reg_addr[i], 0xff, pwr);
   1308}
   1309
   1310static void rtw8822b_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
   1311{
   1312	struct rtw_coex *coex = &rtwdev->coex;
   1313	struct rtw_coex_dm *coex_dm = &coex->dm;
   1314	/* WL Rx Low gain on */
   1315	static const u32 wl_rx_low_gain_on[] = {
   1316		0xff000003, 0xbd120003, 0xbe100003, 0xbf080003, 0xbf060003,
   1317		0xbf050003, 0xbc140003, 0xbb160003, 0xba180003, 0xb91a0003,
   1318		0xb81c0003, 0xb71e0003, 0xb4200003, 0xb5220003, 0xb4240003,
   1319		0xb3260003, 0xb2280003, 0xb12a0003, 0xb02c0003, 0xaf2e0003,
   1320		0xae300003, 0xad320003, 0xac340003, 0xab360003, 0x8d380003,
   1321		0x8c3a0003, 0x8b3c0003, 0x8a3e0003, 0x6e400003, 0x6d420003,
   1322		0x6c440003, 0x6b460003, 0x6a480003, 0x694a0003, 0x684c0003,
   1323		0x674e0003, 0x66500003, 0x65520003, 0x64540003, 0x64560003,
   1324		0x007e0403
   1325	};
   1326
   1327	/* WL Rx Low gain off */
   1328	static const u32 wl_rx_low_gain_off[] = {
   1329		0xff000003, 0xf4120003, 0xf5100003, 0xf60e0003, 0xf70c0003,
   1330		0xf80a0003, 0xf3140003, 0xf2160003, 0xf1180003, 0xf01a0003,
   1331		0xef1c0003, 0xee1e0003, 0xed200003, 0xec220003, 0xeb240003,
   1332		0xea260003, 0xe9280003, 0xe82a0003, 0xe72c0003, 0xe62e0003,
   1333		0xe5300003, 0xc8320003, 0xc7340003, 0xc6360003, 0xc5380003,
   1334		0xc43a0003, 0xc33c0003, 0xc23e0003, 0xc1400003, 0xc0420003,
   1335		0xa5440003, 0xa4460003, 0xa3480003, 0xa24a0003, 0xa14c0003,
   1336		0x834e0003, 0x82500003, 0x81520003, 0x80540003, 0x65560003,
   1337		0x007e0403
   1338	};
   1339	u8 i;
   1340
   1341	if (low_gain == coex_dm->cur_wl_rx_low_gain_en)
   1342		return;
   1343
   1344	coex_dm->cur_wl_rx_low_gain_en = low_gain;
   1345
   1346	if (coex_dm->cur_wl_rx_low_gain_en) {
   1347		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n");
   1348		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++)
   1349			rtw_write32(rtwdev, REG_RX_GAIN_EN, wl_rx_low_gain_on[i]);
   1350
   1351		/* set Rx filter corner RCK offset */
   1352		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x1);
   1353		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x3f);
   1354		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x1);
   1355		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x3f);
   1356	} else {
   1357		rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n");
   1358		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++)
   1359			rtw_write32(rtwdev, 0x81c, wl_rx_low_gain_off[i]);
   1360
   1361		/* set Rx filter corner RCK offset */
   1362		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x4);
   1363		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x0);
   1364		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x4);
   1365		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x0);
   1366	}
   1367}
   1368
   1369static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path,
   1370					u8 tx_pwr_idx_offset,
   1371					s8 *txagc_idx, u8 *swing_idx)
   1372{
   1373	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1374	s8 delta_pwr_idx = dm_info->delta_power_index[path];
   1375	u8 swing_upper_bound = dm_info->default_ofdm_index + 10;
   1376	u8 swing_lower_bound = 0;
   1377	u8 max_tx_pwr_idx_offset = 0xf;
   1378	s8 agc_index = 0;
   1379	u8 swing_index = dm_info->default_ofdm_index;
   1380
   1381	tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset);
   1382
   1383	if (delta_pwr_idx >= 0) {
   1384		if (delta_pwr_idx <= tx_pwr_idx_offset) {
   1385			agc_index = delta_pwr_idx;
   1386			swing_index = dm_info->default_ofdm_index;
   1387		} else if (delta_pwr_idx > tx_pwr_idx_offset) {
   1388			agc_index = tx_pwr_idx_offset;
   1389			swing_index = dm_info->default_ofdm_index +
   1390					delta_pwr_idx - tx_pwr_idx_offset;
   1391			swing_index = min_t(u8, swing_index, swing_upper_bound);
   1392		}
   1393	} else {
   1394		if (dm_info->default_ofdm_index > abs(delta_pwr_idx))
   1395			swing_index =
   1396				dm_info->default_ofdm_index + delta_pwr_idx;
   1397		else
   1398			swing_index = swing_lower_bound;
   1399		swing_index = max_t(u8, swing_index, swing_lower_bound);
   1400
   1401		agc_index = 0;
   1402	}
   1403
   1404	if (swing_index >= RTW_TXSCALE_SIZE) {
   1405		rtw_warn(rtwdev, "swing index overflow\n");
   1406		swing_index = RTW_TXSCALE_SIZE - 1;
   1407	}
   1408	*txagc_idx = agc_index;
   1409	*swing_idx = swing_index;
   1410}
   1411
   1412static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path,
   1413				      u8 pwr_idx_offset)
   1414{
   1415	s8 txagc_idx;
   1416	u8 swing_idx;
   1417	u32 reg1, reg2;
   1418
   1419	if (path == RF_PATH_A) {
   1420		reg1 = 0xc94;
   1421		reg2 = 0xc1c;
   1422	} else if (path == RF_PATH_B) {
   1423		reg1 = 0xe94;
   1424		reg2 = 0xe1c;
   1425	} else {
   1426		return;
   1427	}
   1428
   1429	rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset,
   1430				    &txagc_idx, &swing_idx);
   1431	rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx);
   1432	rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21),
   1433			 rtw8822b_txscale_tbl[swing_idx]);
   1434}
   1435
   1436static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
   1437{
   1438	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1439	u8 pwr_idx_offset, tx_pwr_idx;
   1440	u8 channel = rtwdev->hal.current_channel;
   1441	u8 band_width = rtwdev->hal.current_band_width;
   1442	u8 regd = rtw_regd_get(rtwdev);
   1443	u8 tx_rate = dm_info->tx_rate;
   1444	u8 max_pwr_idx = rtwdev->chip->max_power_index;
   1445
   1446	tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate,
   1447						band_width, channel, regd);
   1448
   1449	tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx);
   1450
   1451	pwr_idx_offset = max_pwr_idx - tx_pwr_idx;
   1452
   1453	rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset);
   1454}
   1455
   1456static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev,
   1457				       struct rtw_swing_table *swing_table,
   1458				       u8 path)
   1459{
   1460	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1461	u8 power_idx_cur, power_idx_last;
   1462	u8 delta;
   1463
   1464	/* 8822B only has one thermal meter at PATH A */
   1465	delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
   1466
   1467	power_idx_last = dm_info->delta_power_index[path];
   1468	power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table,
   1469						    path, RF_PATH_A, delta);
   1470
   1471	/* if delta of power indexes are the same, just skip */
   1472	if (power_idx_cur == power_idx_last)
   1473		return;
   1474
   1475	dm_info->delta_power_index[path] = power_idx_cur;
   1476	rtw8822b_pwrtrack_set(rtwdev, path);
   1477}
   1478
   1479static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev)
   1480{
   1481	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1482	struct rtw_swing_table swing_table;
   1483	u8 thermal_value, path;
   1484
   1485	rtw_phy_config_swing_table(rtwdev, &swing_table);
   1486
   1487	if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff)
   1488		return;
   1489
   1490	thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
   1491
   1492	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
   1493
   1494	if (dm_info->pwr_trk_init_trigger)
   1495		dm_info->pwr_trk_init_trigger = false;
   1496	else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
   1497						   RF_PATH_A))
   1498		goto iqk;
   1499
   1500	for (path = 0; path < rtwdev->hal.rf_path_num; path++)
   1501		rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path);
   1502
   1503iqk:
   1504	if (rtw_phy_pwrtrack_need_iqk(rtwdev))
   1505		rtw8822b_do_iqk(rtwdev);
   1506}
   1507
   1508static void rtw8822b_pwr_track(struct rtw_dev *rtwdev)
   1509{
   1510	struct rtw_efuse *efuse = &rtwdev->efuse;
   1511	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1512
   1513	if (efuse->power_track_type != 0)
   1514		return;
   1515
   1516	if (!dm_info->pwr_trk_triggered) {
   1517		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
   1518			     GENMASK(17, 16), 0x03);
   1519		dm_info->pwr_trk_triggered = true;
   1520		return;
   1521	}
   1522
   1523	rtw8822b_phy_pwrtrack(rtwdev);
   1524	dm_info->pwr_trk_triggered = false;
   1525}
   1526
   1527static void rtw8822b_bf_config_bfee_su(struct rtw_dev *rtwdev,
   1528				       struct rtw_vif *vif,
   1529				       struct rtw_bfee *bfee, bool enable)
   1530{
   1531	if (enable)
   1532		rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
   1533	else
   1534		rtw_bf_remove_bfee_su(rtwdev, bfee);
   1535}
   1536
   1537static void rtw8822b_bf_config_bfee_mu(struct rtw_dev *rtwdev,
   1538				       struct rtw_vif *vif,
   1539				       struct rtw_bfee *bfee, bool enable)
   1540{
   1541	if (enable)
   1542		rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
   1543	else
   1544		rtw_bf_remove_bfee_mu(rtwdev, bfee);
   1545}
   1546
   1547static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
   1548				    struct rtw_bfee *bfee, bool enable)
   1549{
   1550	if (bfee->role == RTW_BFEE_SU)
   1551		rtw8822b_bf_config_bfee_su(rtwdev, vif, bfee, enable);
   1552	else if (bfee->role == RTW_BFEE_MU)
   1553		rtw8822b_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
   1554	else
   1555		rtw_warn(rtwdev, "wrong bfee role\n");
   1556}
   1557
   1558static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev)
   1559{
   1560	rtw_phy_set_edcca_th(rtwdev, RTW8822B_EDCCA_MAX, RTW8822B_EDCCA_MAX);
   1561
   1562	/* mac edcca state setting */
   1563	rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
   1564	rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
   1565	rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION,
   1566			 RTW8822B_EDCCA_SRC_DEF);
   1567	rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0);
   1568
   1569	/* edcca decision opt */
   1570	rtw_write32_set(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
   1571}
   1572
   1573static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
   1574{
   1575	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   1576	s8 l2h, h2l;
   1577	u8 igi;
   1578
   1579	igi = dm_info->igi_history[0];
   1580	if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
   1581		l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
   1582		h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
   1583	} else {
   1584		l2h = min_t(s8, igi, dm_info->l2h_th_ini);
   1585		h2l = l2h - EDCCA_L2H_H2L_DIFF;
   1586	}
   1587
   1588	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
   1589}
   1590
   1591static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
   1592	{0x0086,
   1593	 RTW_PWR_CUT_ALL_MSK,
   1594	 RTW_PWR_INTF_SDIO_MSK,
   1595	 RTW_PWR_ADDR_SDIO,
   1596	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1597	{0x0086,
   1598	 RTW_PWR_CUT_ALL_MSK,
   1599	 RTW_PWR_INTF_SDIO_MSK,
   1600	 RTW_PWR_ADDR_SDIO,
   1601	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
   1602	{0x004A,
   1603	 RTW_PWR_CUT_ALL_MSK,
   1604	 RTW_PWR_INTF_USB_MSK,
   1605	 RTW_PWR_ADDR_MAC,
   1606	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1607	{0x0005,
   1608	 RTW_PWR_CUT_ALL_MSK,
   1609	 RTW_PWR_INTF_ALL_MSK,
   1610	 RTW_PWR_ADDR_MAC,
   1611	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
   1612	{0x0300,
   1613	 RTW_PWR_CUT_ALL_MSK,
   1614	 RTW_PWR_INTF_PCI_MSK,
   1615	 RTW_PWR_ADDR_MAC,
   1616	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1617	{0x0301,
   1618	 RTW_PWR_CUT_ALL_MSK,
   1619	 RTW_PWR_INTF_PCI_MSK,
   1620	 RTW_PWR_ADDR_MAC,
   1621	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1622	{0xFFFF,
   1623	 RTW_PWR_CUT_ALL_MSK,
   1624	 RTW_PWR_INTF_ALL_MSK,
   1625	 0,
   1626	 RTW_PWR_CMD_END, 0, 0},
   1627};
   1628
   1629static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822b[] = {
   1630	{0x0012,
   1631	 RTW_PWR_CUT_ALL_MSK,
   1632	 RTW_PWR_INTF_ALL_MSK,
   1633	 RTW_PWR_ADDR_MAC,
   1634	 RTW_PWR_CMD_WRITE, BIT(1), 0},
   1635	{0x0012,
   1636	 RTW_PWR_CUT_ALL_MSK,
   1637	 RTW_PWR_INTF_ALL_MSK,
   1638	 RTW_PWR_ADDR_MAC,
   1639	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1640	{0x0020,
   1641	 RTW_PWR_CUT_ALL_MSK,
   1642	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1643	 RTW_PWR_ADDR_MAC,
   1644	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1645	{0x0001,
   1646	 RTW_PWR_CUT_ALL_MSK,
   1647	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1648	 RTW_PWR_ADDR_MAC,
   1649	 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
   1650	{0x0000,
   1651	 RTW_PWR_CUT_ALL_MSK,
   1652	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1653	 RTW_PWR_ADDR_MAC,
   1654	 RTW_PWR_CMD_WRITE, BIT(5), 0},
   1655	{0x0005,
   1656	 RTW_PWR_CUT_ALL_MSK,
   1657	 RTW_PWR_INTF_ALL_MSK,
   1658	 RTW_PWR_ADDR_MAC,
   1659	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
   1660	{0x0075,
   1661	 RTW_PWR_CUT_ALL_MSK,
   1662	 RTW_PWR_INTF_PCI_MSK,
   1663	 RTW_PWR_ADDR_MAC,
   1664	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1665	{0x0006,
   1666	 RTW_PWR_CUT_ALL_MSK,
   1667	 RTW_PWR_INTF_ALL_MSK,
   1668	 RTW_PWR_ADDR_MAC,
   1669	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
   1670	{0x0075,
   1671	 RTW_PWR_CUT_ALL_MSK,
   1672	 RTW_PWR_INTF_PCI_MSK,
   1673	 RTW_PWR_ADDR_MAC,
   1674	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1675	{0xFF1A,
   1676	 RTW_PWR_CUT_ALL_MSK,
   1677	 RTW_PWR_INTF_USB_MSK,
   1678	 RTW_PWR_ADDR_MAC,
   1679	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1680	{0x0006,
   1681	 RTW_PWR_CUT_ALL_MSK,
   1682	 RTW_PWR_INTF_ALL_MSK,
   1683	 RTW_PWR_ADDR_MAC,
   1684	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1685	{0x0005,
   1686	 RTW_PWR_CUT_ALL_MSK,
   1687	 RTW_PWR_INTF_ALL_MSK,
   1688	 RTW_PWR_ADDR_MAC,
   1689	 RTW_PWR_CMD_WRITE, BIT(7), 0},
   1690	{0x0005,
   1691	 RTW_PWR_CUT_ALL_MSK,
   1692	 RTW_PWR_INTF_ALL_MSK,
   1693	 RTW_PWR_ADDR_MAC,
   1694	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
   1695	{0x10C3,
   1696	 RTW_PWR_CUT_ALL_MSK,
   1697	 RTW_PWR_INTF_USB_MSK,
   1698	 RTW_PWR_ADDR_MAC,
   1699	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1700	{0x0005,
   1701	 RTW_PWR_CUT_ALL_MSK,
   1702	 RTW_PWR_INTF_ALL_MSK,
   1703	 RTW_PWR_ADDR_MAC,
   1704	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1705	{0x0005,
   1706	 RTW_PWR_CUT_ALL_MSK,
   1707	 RTW_PWR_INTF_ALL_MSK,
   1708	 RTW_PWR_ADDR_MAC,
   1709	 RTW_PWR_CMD_POLLING, BIT(0), 0},
   1710	{0x0020,
   1711	 RTW_PWR_CUT_ALL_MSK,
   1712	 RTW_PWR_INTF_ALL_MSK,
   1713	 RTW_PWR_ADDR_MAC,
   1714	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
   1715	{0x10A8,
   1716	 RTW_PWR_CUT_C_MSK,
   1717	 RTW_PWR_INTF_ALL_MSK,
   1718	 RTW_PWR_ADDR_MAC,
   1719	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1720	{0x10A9,
   1721	 RTW_PWR_CUT_C_MSK,
   1722	 RTW_PWR_INTF_ALL_MSK,
   1723	 RTW_PWR_ADDR_MAC,
   1724	 RTW_PWR_CMD_WRITE, 0xFF, 0xef},
   1725	{0x10AA,
   1726	 RTW_PWR_CUT_C_MSK,
   1727	 RTW_PWR_INTF_ALL_MSK,
   1728	 RTW_PWR_ADDR_MAC,
   1729	 RTW_PWR_CMD_WRITE, 0xFF, 0x0c},
   1730	{0x0068,
   1731	 RTW_PWR_CUT_C_MSK,
   1732	 RTW_PWR_INTF_SDIO_MSK,
   1733	 RTW_PWR_ADDR_MAC,
   1734	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
   1735	{0x0029,
   1736	 RTW_PWR_CUT_ALL_MSK,
   1737	 RTW_PWR_INTF_ALL_MSK,
   1738	 RTW_PWR_ADDR_MAC,
   1739	 RTW_PWR_CMD_WRITE, 0xFF, 0xF9},
   1740	{0x0024,
   1741	 RTW_PWR_CUT_ALL_MSK,
   1742	 RTW_PWR_INTF_ALL_MSK,
   1743	 RTW_PWR_ADDR_MAC,
   1744	 RTW_PWR_CMD_WRITE, BIT(2), 0},
   1745	{0x0074,
   1746	 RTW_PWR_CUT_ALL_MSK,
   1747	 RTW_PWR_INTF_PCI_MSK,
   1748	 RTW_PWR_ADDR_MAC,
   1749	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
   1750	{0x00AF,
   1751	 RTW_PWR_CUT_ALL_MSK,
   1752	 RTW_PWR_INTF_ALL_MSK,
   1753	 RTW_PWR_ADDR_MAC,
   1754	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
   1755	{0xFFFF,
   1756	 RTW_PWR_CUT_ALL_MSK,
   1757	 RTW_PWR_INTF_ALL_MSK,
   1758	 0,
   1759	 RTW_PWR_CMD_END, 0, 0},
   1760};
   1761
   1762static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822b[] = {
   1763	{0x0003,
   1764	 RTW_PWR_CUT_ALL_MSK,
   1765	 RTW_PWR_INTF_SDIO_MSK,
   1766	 RTW_PWR_ADDR_MAC,
   1767	 RTW_PWR_CMD_WRITE, BIT(2), 0},
   1768	{0x0093,
   1769	 RTW_PWR_CUT_ALL_MSK,
   1770	 RTW_PWR_INTF_ALL_MSK,
   1771	 RTW_PWR_ADDR_MAC,
   1772	 RTW_PWR_CMD_WRITE, BIT(3), 0},
   1773	{0x001F,
   1774	 RTW_PWR_CUT_ALL_MSK,
   1775	 RTW_PWR_INTF_ALL_MSK,
   1776	 RTW_PWR_ADDR_MAC,
   1777	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1778	{0x00EF,
   1779	 RTW_PWR_CUT_ALL_MSK,
   1780	 RTW_PWR_INTF_ALL_MSK,
   1781	 RTW_PWR_ADDR_MAC,
   1782	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1783	{0xFF1A,
   1784	 RTW_PWR_CUT_ALL_MSK,
   1785	 RTW_PWR_INTF_USB_MSK,
   1786	 RTW_PWR_ADDR_MAC,
   1787	 RTW_PWR_CMD_WRITE, 0xFF, 0x30},
   1788	{0x0049,
   1789	 RTW_PWR_CUT_ALL_MSK,
   1790	 RTW_PWR_INTF_ALL_MSK,
   1791	 RTW_PWR_ADDR_MAC,
   1792	 RTW_PWR_CMD_WRITE, BIT(1), 0},
   1793	{0x0006,
   1794	 RTW_PWR_CUT_ALL_MSK,
   1795	 RTW_PWR_INTF_ALL_MSK,
   1796	 RTW_PWR_ADDR_MAC,
   1797	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1798	{0x0002,
   1799	 RTW_PWR_CUT_ALL_MSK,
   1800	 RTW_PWR_INTF_ALL_MSK,
   1801	 RTW_PWR_ADDR_MAC,
   1802	 RTW_PWR_CMD_WRITE, BIT(1), 0},
   1803	{0x10C3,
   1804	 RTW_PWR_CUT_ALL_MSK,
   1805	 RTW_PWR_INTF_USB_MSK,
   1806	 RTW_PWR_ADDR_MAC,
   1807	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1808	{0x0005,
   1809	 RTW_PWR_CUT_ALL_MSK,
   1810	 RTW_PWR_INTF_ALL_MSK,
   1811	 RTW_PWR_ADDR_MAC,
   1812	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
   1813	{0x0005,
   1814	 RTW_PWR_CUT_ALL_MSK,
   1815	 RTW_PWR_INTF_ALL_MSK,
   1816	 RTW_PWR_ADDR_MAC,
   1817	 RTW_PWR_CMD_POLLING, BIT(1), 0},
   1818	{0x0020,
   1819	 RTW_PWR_CUT_ALL_MSK,
   1820	 RTW_PWR_INTF_ALL_MSK,
   1821	 RTW_PWR_ADDR_MAC,
   1822	 RTW_PWR_CMD_WRITE, BIT(3), 0},
   1823	{0x0000,
   1824	 RTW_PWR_CUT_ALL_MSK,
   1825	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1826	 RTW_PWR_ADDR_MAC,
   1827	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
   1828	{0xFFFF,
   1829	 RTW_PWR_CUT_ALL_MSK,
   1830	 RTW_PWR_INTF_ALL_MSK,
   1831	 0,
   1832	 RTW_PWR_CMD_END, 0, 0},
   1833};
   1834
   1835static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
   1836	{0x0005,
   1837	 RTW_PWR_CUT_ALL_MSK,
   1838	 RTW_PWR_INTF_SDIO_MSK,
   1839	 RTW_PWR_ADDR_MAC,
   1840	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
   1841	{0x0007,
   1842	 RTW_PWR_CUT_ALL_MSK,
   1843	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1844	 RTW_PWR_ADDR_MAC,
   1845	 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
   1846	{0x0067,
   1847	 RTW_PWR_CUT_ALL_MSK,
   1848	 RTW_PWR_INTF_ALL_MSK,
   1849	 RTW_PWR_ADDR_MAC,
   1850	 RTW_PWR_CMD_WRITE, BIT(5), 0},
   1851	{0x0005,
   1852	 RTW_PWR_CUT_ALL_MSK,
   1853	 RTW_PWR_INTF_PCI_MSK,
   1854	 RTW_PWR_ADDR_MAC,
   1855	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
   1856	{0x004A,
   1857	 RTW_PWR_CUT_ALL_MSK,
   1858	 RTW_PWR_INTF_USB_MSK,
   1859	 RTW_PWR_ADDR_MAC,
   1860	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1861	{0x0067,
   1862	 RTW_PWR_CUT_ALL_MSK,
   1863	 RTW_PWR_INTF_SDIO_MSK,
   1864	 RTW_PWR_ADDR_MAC,
   1865	 RTW_PWR_CMD_WRITE, BIT(5), 0},
   1866	{0x0067,
   1867	 RTW_PWR_CUT_ALL_MSK,
   1868	 RTW_PWR_INTF_SDIO_MSK,
   1869	 RTW_PWR_ADDR_MAC,
   1870	 RTW_PWR_CMD_WRITE, BIT(4), 0},
   1871	{0x004F,
   1872	 RTW_PWR_CUT_ALL_MSK,
   1873	 RTW_PWR_INTF_SDIO_MSK,
   1874	 RTW_PWR_ADDR_MAC,
   1875	 RTW_PWR_CMD_WRITE, BIT(0), 0},
   1876	{0x0067,
   1877	 RTW_PWR_CUT_ALL_MSK,
   1878	 RTW_PWR_INTF_SDIO_MSK,
   1879	 RTW_PWR_ADDR_MAC,
   1880	 RTW_PWR_CMD_WRITE, BIT(1), 0},
   1881	{0x0046,
   1882	 RTW_PWR_CUT_ALL_MSK,
   1883	 RTW_PWR_INTF_SDIO_MSK,
   1884	 RTW_PWR_ADDR_MAC,
   1885	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
   1886	{0x0067,
   1887	 RTW_PWR_CUT_ALL_MSK,
   1888	 RTW_PWR_INTF_SDIO_MSK,
   1889	 RTW_PWR_ADDR_MAC,
   1890	 RTW_PWR_CMD_WRITE, BIT(2), 0},
   1891	{0x0046,
   1892	 RTW_PWR_CUT_ALL_MSK,
   1893	 RTW_PWR_INTF_SDIO_MSK,
   1894	 RTW_PWR_ADDR_MAC,
   1895	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
   1896	{0x0062,
   1897	 RTW_PWR_CUT_ALL_MSK,
   1898	 RTW_PWR_INTF_SDIO_MSK,
   1899	 RTW_PWR_ADDR_MAC,
   1900	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
   1901	{0x0081,
   1902	 RTW_PWR_CUT_ALL_MSK,
   1903	 RTW_PWR_INTF_ALL_MSK,
   1904	 RTW_PWR_ADDR_MAC,
   1905	 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
   1906	{0x0005,
   1907	 RTW_PWR_CUT_ALL_MSK,
   1908	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
   1909	 RTW_PWR_ADDR_MAC,
   1910	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
   1911	{0x0086,
   1912	 RTW_PWR_CUT_ALL_MSK,
   1913	 RTW_PWR_INTF_SDIO_MSK,
   1914	 RTW_PWR_ADDR_SDIO,
   1915	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
   1916	{0x0086,
   1917	 RTW_PWR_CUT_ALL_MSK,
   1918	 RTW_PWR_INTF_SDIO_MSK,
   1919	 RTW_PWR_ADDR_SDIO,
   1920	 RTW_PWR_CMD_POLLING, BIT(1), 0},
   1921	{0x0090,
   1922	 RTW_PWR_CUT_ALL_MSK,
   1923	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
   1924	 RTW_PWR_ADDR_MAC,
   1925	 RTW_PWR_CMD_WRITE, BIT(1), 0},
   1926	{0x0044,
   1927	 RTW_PWR_CUT_ALL_MSK,
   1928	 RTW_PWR_INTF_SDIO_MSK,
   1929	 RTW_PWR_ADDR_SDIO,
   1930	 RTW_PWR_CMD_WRITE, 0xFF, 0},
   1931	{0x0040,
   1932	 RTW_PWR_CUT_ALL_MSK,
   1933	 RTW_PWR_INTF_SDIO_MSK,
   1934	 RTW_PWR_ADDR_SDIO,
   1935	 RTW_PWR_CMD_WRITE, 0xFF, 0x90},
   1936	{0x0041,
   1937	 RTW_PWR_CUT_ALL_MSK,
   1938	 RTW_PWR_INTF_SDIO_MSK,
   1939	 RTW_PWR_ADDR_SDIO,
   1940	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
   1941	{0x0042,
   1942	 RTW_PWR_CUT_ALL_MSK,
   1943	 RTW_PWR_INTF_SDIO_MSK,
   1944	 RTW_PWR_ADDR_SDIO,
   1945	 RTW_PWR_CMD_WRITE, 0xFF, 0x04},
   1946	{0xFFFF,
   1947	 RTW_PWR_CUT_ALL_MSK,
   1948	 RTW_PWR_INTF_ALL_MSK,
   1949	 0,
   1950	 RTW_PWR_CMD_END, 0, 0},
   1951};
   1952
   1953static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
   1954	trans_carddis_to_cardemu_8822b,
   1955	trans_cardemu_to_act_8822b,
   1956	NULL
   1957};
   1958
   1959static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
   1960	trans_act_to_cardemu_8822b,
   1961	trans_cardemu_to_carddis_8822b,
   1962	NULL
   1963};
   1964
   1965static const struct rtw_intf_phy_para usb2_param_8822b[] = {
   1966	{0xFFFF, 0x00,
   1967	 RTW_IP_SEL_PHY,
   1968	 RTW_INTF_PHY_CUT_ALL,
   1969	 RTW_INTF_PHY_PLATFORM_ALL},
   1970};
   1971
   1972static const struct rtw_intf_phy_para usb3_param_8822b[] = {
   1973	{0x0001, 0xA841,
   1974	 RTW_IP_SEL_PHY,
   1975	 RTW_INTF_PHY_CUT_D,
   1976	 RTW_INTF_PHY_PLATFORM_ALL},
   1977	{0xFFFF, 0x0000,
   1978	 RTW_IP_SEL_PHY,
   1979	 RTW_INTF_PHY_CUT_ALL,
   1980	 RTW_INTF_PHY_PLATFORM_ALL},
   1981};
   1982
   1983static const struct rtw_intf_phy_para pcie_gen1_param_8822b[] = {
   1984	{0x0001, 0xA841,
   1985	 RTW_IP_SEL_PHY,
   1986	 RTW_INTF_PHY_CUT_C,
   1987	 RTW_INTF_PHY_PLATFORM_ALL},
   1988	{0x0002, 0x60C6,
   1989	 RTW_IP_SEL_PHY,
   1990	 RTW_INTF_PHY_CUT_C,
   1991	 RTW_INTF_PHY_PLATFORM_ALL},
   1992	{0x0008, 0x3596,
   1993	 RTW_IP_SEL_PHY,
   1994	 RTW_INTF_PHY_CUT_C,
   1995	 RTW_INTF_PHY_PLATFORM_ALL},
   1996	{0x0009, 0x321C,
   1997	 RTW_IP_SEL_PHY,
   1998	 RTW_INTF_PHY_CUT_C,
   1999	 RTW_INTF_PHY_PLATFORM_ALL},
   2000	{0x000A, 0x9623,
   2001	 RTW_IP_SEL_PHY,
   2002	 RTW_INTF_PHY_CUT_C,
   2003	 RTW_INTF_PHY_PLATFORM_ALL},
   2004	{0x0020, 0x94FF,
   2005	 RTW_IP_SEL_PHY,
   2006	 RTW_INTF_PHY_CUT_C,
   2007	 RTW_INTF_PHY_PLATFORM_ALL},
   2008	{0x0021, 0xFFCF,
   2009	 RTW_IP_SEL_PHY,
   2010	 RTW_INTF_PHY_CUT_C,
   2011	 RTW_INTF_PHY_PLATFORM_ALL},
   2012	{0x0026, 0xC006,
   2013	 RTW_IP_SEL_PHY,
   2014	 RTW_INTF_PHY_CUT_C,
   2015	 RTW_INTF_PHY_PLATFORM_ALL},
   2016	{0x0029, 0xFF0E,
   2017	 RTW_IP_SEL_PHY,
   2018	 RTW_INTF_PHY_CUT_C,
   2019	 RTW_INTF_PHY_PLATFORM_ALL},
   2020	{0x002A, 0x1840,
   2021	 RTW_IP_SEL_PHY,
   2022	 RTW_INTF_PHY_CUT_C,
   2023	 RTW_INTF_PHY_PLATFORM_ALL},
   2024	{0xFFFF, 0x0000,
   2025	 RTW_IP_SEL_PHY,
   2026	 RTW_INTF_PHY_CUT_ALL,
   2027	 RTW_INTF_PHY_PLATFORM_ALL},
   2028};
   2029
   2030static const struct rtw_intf_phy_para pcie_gen2_param_8822b[] = {
   2031	{0x0001, 0xA841,
   2032	 RTW_IP_SEL_PHY,
   2033	 RTW_INTF_PHY_CUT_C,
   2034	 RTW_INTF_PHY_PLATFORM_ALL},
   2035	{0x0002, 0x60C6,
   2036	 RTW_IP_SEL_PHY,
   2037	 RTW_INTF_PHY_CUT_C,
   2038	 RTW_INTF_PHY_PLATFORM_ALL},
   2039	{0x0008, 0x3597,
   2040	 RTW_IP_SEL_PHY,
   2041	 RTW_INTF_PHY_CUT_C,
   2042	 RTW_INTF_PHY_PLATFORM_ALL},
   2043	{0x0009, 0x321C,
   2044	 RTW_IP_SEL_PHY,
   2045	 RTW_INTF_PHY_CUT_C,
   2046	 RTW_INTF_PHY_PLATFORM_ALL},
   2047	{0x000A, 0x9623,
   2048	 RTW_IP_SEL_PHY,
   2049	 RTW_INTF_PHY_CUT_C,
   2050	 RTW_INTF_PHY_PLATFORM_ALL},
   2051	{0x0020, 0x94FF,
   2052	 RTW_IP_SEL_PHY,
   2053	 RTW_INTF_PHY_CUT_C,
   2054	 RTW_INTF_PHY_PLATFORM_ALL},
   2055	{0x0021, 0xFFCF,
   2056	 RTW_IP_SEL_PHY,
   2057	 RTW_INTF_PHY_CUT_C,
   2058	 RTW_INTF_PHY_PLATFORM_ALL},
   2059	{0x0026, 0xC006,
   2060	 RTW_IP_SEL_PHY,
   2061	 RTW_INTF_PHY_CUT_C,
   2062	 RTW_INTF_PHY_PLATFORM_ALL},
   2063	{0x0029, 0xFF0E,
   2064	 RTW_IP_SEL_PHY,
   2065	 RTW_INTF_PHY_CUT_C,
   2066	 RTW_INTF_PHY_PLATFORM_ALL},
   2067	{0x002A, 0x3040,
   2068	 RTW_IP_SEL_PHY,
   2069	 RTW_INTF_PHY_CUT_C,
   2070	 RTW_INTF_PHY_PLATFORM_ALL},
   2071	{0xFFFF, 0x0000,
   2072	 RTW_IP_SEL_PHY,
   2073	 RTW_INTF_PHY_CUT_ALL,
   2074	 RTW_INTF_PHY_PLATFORM_ALL},
   2075};
   2076
   2077static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
   2078	.usb2_para	= usb2_param_8822b,
   2079	.usb3_para	= usb3_param_8822b,
   2080	.gen1_para	= pcie_gen1_param_8822b,
   2081	.gen2_para	= pcie_gen2_param_8822b,
   2082	.n_usb2_para	= ARRAY_SIZE(usb2_param_8822b),
   2083	.n_usb3_para	= ARRAY_SIZE(usb2_param_8822b),
   2084	.n_gen1_para	= ARRAY_SIZE(pcie_gen1_param_8822b),
   2085	.n_gen2_para	= ARRAY_SIZE(pcie_gen2_param_8822b),
   2086};
   2087
   2088static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
   2089	[2] = RTW_DEF_RFE(8822b, 2, 2),
   2090	[3] = RTW_DEF_RFE(8822b, 3, 0),
   2091	[5] = RTW_DEF_RFE(8822b, 5, 5),
   2092};
   2093
   2094static const struct rtw_hw_reg rtw8822b_dig[] = {
   2095	[0] = { .addr = 0xc50, .mask = 0x7f },
   2096	[1] = { .addr = 0xe50, .mask = 0x7f },
   2097};
   2098
   2099static const struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = {
   2100	.ctrl = LTECOEX_ACCESS_CTRL,
   2101	.wdata = LTECOEX_WRITE_DATA,
   2102	.rdata = LTECOEX_READ_DATA,
   2103};
   2104
   2105static const struct rtw_page_table page_table_8822b[] = {
   2106	{64, 64, 64, 64, 1},
   2107	{64, 64, 64, 64, 1},
   2108	{64, 64, 0, 0, 1},
   2109	{64, 64, 64, 0, 1},
   2110	{64, 64, 64, 64, 1},
   2111};
   2112
   2113static const struct rtw_rqpn rqpn_table_8822b[] = {
   2114	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
   2115	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
   2116	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
   2117	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
   2118	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
   2119	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
   2120	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
   2121	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
   2122	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
   2123	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
   2124	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
   2125	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
   2126	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
   2127	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
   2128	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
   2129};
   2130
   2131static struct rtw_prioq_addrs prioq_addrs_8822b = {
   2132	.prio[RTW_DMA_MAPPING_EXTRA] = {
   2133		.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
   2134	},
   2135	.prio[RTW_DMA_MAPPING_LOW] = {
   2136		.rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
   2137	},
   2138	.prio[RTW_DMA_MAPPING_NORMAL] = {
   2139		.rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
   2140	},
   2141	.prio[RTW_DMA_MAPPING_HIGH] = {
   2142		.rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
   2143	},
   2144	.wsize = true,
   2145};
   2146
   2147static struct rtw_chip_ops rtw8822b_ops = {
   2148	.phy_set_param		= rtw8822b_phy_set_param,
   2149	.read_efuse		= rtw8822b_read_efuse,
   2150	.query_rx_desc		= rtw8822b_query_rx_desc,
   2151	.set_channel		= rtw8822b_set_channel,
   2152	.mac_init		= rtw8822b_mac_init,
   2153	.read_rf		= rtw_phy_read_rf,
   2154	.write_rf		= rtw_phy_write_rf_reg_sipi,
   2155	.set_tx_power_index	= rtw8822b_set_tx_power_index,
   2156	.set_antenna		= rtw8822b_set_antenna,
   2157	.cfg_ldo25		= rtw8822b_cfg_ldo25,
   2158	.false_alarm_statistics	= rtw8822b_false_alarm_statistics,
   2159	.phy_calibration	= rtw8822b_phy_calibration,
   2160	.pwr_track		= rtw8822b_pwr_track,
   2161	.config_bfee		= rtw8822b_bf_config_bfee,
   2162	.set_gid_table		= rtw_bf_set_gid_table,
   2163	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
   2164	.adaptivity_init	= rtw8822b_adaptivity_init,
   2165	.adaptivity		= rtw8822b_adaptivity,
   2166
   2167	.coex_set_init		= rtw8822b_coex_cfg_init,
   2168	.coex_set_ant_switch	= rtw8822b_coex_cfg_ant_switch,
   2169	.coex_set_gnt_fix	= rtw8822b_coex_cfg_gnt_fix,
   2170	.coex_set_gnt_debug	= rtw8822b_coex_cfg_gnt_debug,
   2171	.coex_set_rfe_type	= rtw8822b_coex_cfg_rfe_type,
   2172	.coex_set_wl_tx_power	= rtw8822b_coex_cfg_wl_tx_power,
   2173	.coex_set_wl_rx_gain	= rtw8822b_coex_cfg_wl_rx_gain,
   2174};
   2175
   2176/* Shared-Antenna Coex Table */
   2177static const struct coex_table_para table_sant_8822b[] = {
   2178	{0xffffffff, 0xffffffff}, /* case-0 */
   2179	{0x55555555, 0x55555555},
   2180	{0x66555555, 0x66555555},
   2181	{0xaaaaaaaa, 0xaaaaaaaa},
   2182	{0x5a5a5a5a, 0x5a5a5a5a},
   2183	{0xfafafafa, 0xfafafafa}, /* case-5 */
   2184	{0x6a5a5555, 0xaaaaaaaa},
   2185	{0x6a5a56aa, 0x6a5a56aa},
   2186	{0x6a5a5a5a, 0x6a5a5a5a},
   2187	{0x66555555, 0x5a5a5a5a},
   2188	{0x66555555, 0x6a5a5a5a}, /* case-10 */
   2189	{0x66555555, 0xfafafafa},
   2190	{0x66555555, 0x5a5a5aaa},
   2191	{0x66555555, 0x6aaa5aaa},
   2192	{0x66555555, 0xaaaa5aaa},
   2193	{0x66555555, 0xaaaaaaaa}, /* case-15 */
   2194	{0xffff55ff, 0xfafafafa},
   2195	{0xffff55ff, 0x6afa5afa},
   2196	{0xaaffffaa, 0xfafafafa},
   2197	{0xaa5555aa, 0x5a5a5a5a},
   2198	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
   2199	{0xaa5555aa, 0xaaaaaaaa},
   2200	{0xffffffff, 0x5a5a5a5a},
   2201	{0xffffffff, 0x5a5a5a5a},
   2202	{0xffffffff, 0x55555555},
   2203	{0xffffffff, 0x6a5a5aaa}, /* case-25 */
   2204	{0x55555555, 0x5a5a5a5a},
   2205	{0x55555555, 0xaaaaaaaa},
   2206	{0x55555555, 0x6a5a6a5a},
   2207	{0x66556655, 0x66556655},
   2208	{0x66556aaa, 0x6a5a6aaa}, /* case-30 */
   2209	{0xffffffff, 0x5aaa5aaa},
   2210	{0x56555555, 0x5a5a5aaa},
   2211};
   2212
   2213/* Non-Shared-Antenna Coex Table */
   2214static const struct coex_table_para table_nsant_8822b[] = {
   2215	{0xffffffff, 0xffffffff}, /* case-100 */
   2216	{0x55555555, 0x55555555},
   2217	{0x66555555, 0x66555555},
   2218	{0xaaaaaaaa, 0xaaaaaaaa},
   2219	{0x5a5a5a5a, 0x5a5a5a5a},
   2220	{0xfafafafa, 0xfafafafa}, /* case-105 */
   2221	{0x5afa5afa, 0x5afa5afa},
   2222	{0x55555555, 0xfafafafa},
   2223	{0x66555555, 0xfafafafa},
   2224	{0x66555555, 0x5a5a5a5a},
   2225	{0x66555555, 0x6a5a5a5a}, /* case-110 */
   2226	{0x66555555, 0xaaaaaaaa},
   2227	{0xffff55ff, 0xfafafafa},
   2228	{0xffff55ff, 0x5afa5afa},
   2229	{0xffff55ff, 0xaaaaaaaa},
   2230	{0xffff55ff, 0xffff55ff}, /* case-115 */
   2231	{0xaaffffaa, 0x5afa5afa},
   2232	{0xaaffffaa, 0xaaaaaaaa},
   2233	{0xffffffff, 0xfafafafa},
   2234	{0xffffffff, 0x5afa5afa},
   2235	{0xffffffff, 0xaaaaaaaa}, /* case-120 */
   2236	{0x55ff55ff, 0x5afa5afa},
   2237	{0x55ff55ff, 0xaaaaaaaa},
   2238	{0x55ff55ff, 0x55ff55ff}
   2239};
   2240
   2241/* Shared-Antenna TDMA */
   2242static const struct coex_tdma_para tdma_sant_8822b[] = {
   2243	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
   2244	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
   2245	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
   2246	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
   2247	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
   2248	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
   2249	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
   2250	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
   2251	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
   2252	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
   2253	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
   2254	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
   2255	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
   2256	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
   2257	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
   2258	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
   2259	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
   2260	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
   2261	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
   2262	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
   2263	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
   2264	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
   2265	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
   2266	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
   2267	{ {0x65, 0x10, 0x03, 0x11, 0x10} },
   2268	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
   2269	{ {0x51, 0x08, 0x03, 0x10, 0x50} },
   2270	{ {0x61, 0x08, 0x03, 0x11, 0x11} }
   2271};
   2272
   2273/* Non-Shared-Antenna TDMA */
   2274static const struct coex_tdma_para tdma_nsant_8822b[] = {
   2275	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */
   2276	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */
   2277	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
   2278	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
   2279	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
   2280	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
   2281	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
   2282	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
   2283	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
   2284	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
   2285	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
   2286	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
   2287	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
   2288	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
   2289	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
   2290	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
   2291	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
   2292	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
   2293	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
   2294	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
   2295	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */
   2296	{ {0x51, 0x08, 0x03, 0x10, 0x50} }
   2297};
   2298
   2299/* rssi in percentage % (dbm = % - 100) */
   2300static const u8 wl_rssi_step_8822b[] = {60, 50, 44, 30};
   2301static const u8 bt_rssi_step_8822b[] = {30, 30, 30, 30};
   2302
   2303/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
   2304static const struct coex_rf_para rf_para_tx_8822b[] = {
   2305	{0, 0, false, 7},  /* for normal */
   2306	{0, 16, false, 7}, /* for WL-CPT */
   2307	{4, 0, true, 1},
   2308	{3, 6, true, 1},
   2309	{2, 9, true, 1},
   2310	{1, 13, true, 1}
   2311};
   2312
   2313static const struct coex_rf_para rf_para_rx_8822b[] = {
   2314	{0, 0, false, 7},  /* for normal */
   2315	{0, 16, false, 7}, /* for WL-CPT */
   2316	{4, 0, true, 1},
   2317	{3, 6, true, 1},
   2318	{2, 9, true, 1},
   2319	{1, 13, true, 1}
   2320};
   2321
   2322static const struct coex_5g_afh_map afh_5g_8822b[] = {
   2323	{120, 2, 4},
   2324	{124, 8, 8},
   2325	{128, 17, 8},
   2326	{132, 26, 10},
   2327	{136, 34, 8},
   2328	{140, 42, 10},
   2329	{144, 51, 8},
   2330	{149, 62, 8},
   2331	{153, 71, 10},
   2332	{157, 77, 4},
   2333	{118, 2, 4},
   2334	{126, 12, 16},
   2335	{134, 29, 16},
   2336	{142, 46, 16},
   2337	{151, 66, 16},
   2338	{159, 76, 4},
   2339	{122, 10, 20},
   2340	{138, 37, 34},
   2341	{155, 68, 20}
   2342};
   2343static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b));
   2344
   2345static const u8
   2346rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
   2347	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2348	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2349	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2350	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2351	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2352	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2353	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2354	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2355	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2356};
   2357
   2358static const u8
   2359rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
   2360	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2361	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2362	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
   2363	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2364	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2365	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
   2366	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2367	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2368	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
   2369};
   2370
   2371static const u8
   2372rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
   2373	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2374	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2375	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2376	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2377	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2378	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2379	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2380	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
   2381	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
   2382};
   2383
   2384static const u8
   2385rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
   2386	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2387	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2388	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
   2389	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2390	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2391	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
   2392	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
   2393	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
   2394	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
   2395};
   2396
   2397static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = {
   2398	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
   2399	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
   2400	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
   2401};
   2402
   2403static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = {
   2404	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
   2405	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
   2406	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
   2407};
   2408
   2409static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = {
   2410	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
   2411	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
   2412	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
   2413};
   2414
   2415static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = {
   2416	0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
   2417	5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
   2418	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
   2419};
   2420
   2421static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = {
   2422	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
   2423	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
   2424	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
   2425};
   2426
   2427static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = {
   2428	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
   2429	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
   2430	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
   2431};
   2432
   2433static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = {
   2434	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
   2435	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
   2436	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
   2437};
   2438
   2439static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
   2440	 0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
   2441	 5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
   2442	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
   2443};
   2444
   2445static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
   2446	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
   2447	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
   2448	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
   2449	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],
   2450	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],
   2451	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],
   2452	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],
   2453	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],
   2454	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],
   2455	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],
   2456	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],
   2457	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],
   2458	.pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n,
   2459	.pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p,
   2460	.pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n,
   2461	.pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p,
   2462	.pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n,
   2463	.pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p,
   2464	.pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n,
   2465	.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
   2466};
   2467
   2468static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
   2469	{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
   2470	{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
   2471	{0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2472	{0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2473	{0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2474	{0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8},
   2475	{0, 0, RTW_REG_DOMAIN_NL},
   2476	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
   2477	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
   2478	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
   2479	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2480	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
   2481	{0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
   2482	{0, 0, RTW_REG_DOMAIN_NL},
   2483	{0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
   2484	{0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
   2485	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
   2486	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
   2487	{0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B},
   2488	{0, 0, RTW_REG_DOMAIN_NL},
   2489	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
   2490	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2491	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
   2492	{0xc50,  MASKBYTE0, RTW_REG_DOMAIN_MAC8},
   2493};
   2494
   2495static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
   2496	[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
   2497	[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
   2498};
   2499
   2500struct rtw_chip_info rtw8822b_hw_spec = {
   2501	.ops = &rtw8822b_ops,
   2502	.id = RTW_CHIP_TYPE_8822B,
   2503	.fw_name = "rtw88/rtw8822b_fw.bin",
   2504	.wlan_cpu = RTW_WCPU_11AC,
   2505	.tx_pkt_desc_sz = 48,
   2506	.tx_buf_desc_sz = 16,
   2507	.rx_pkt_desc_sz = 24,
   2508	.rx_buf_desc_sz = 8,
   2509	.phy_efuse_size = 1024,
   2510	.log_efuse_size = 768,
   2511	.ptct_efuse_size = 96,
   2512	.txff_size = 262144,
   2513	.rxff_size = 24576,
   2514	.fw_rxff_size = 12288,
   2515	.txgi_factor = 1,
   2516	.is_pwr_by_rate_dec = true,
   2517	.max_power_index = 0x3f,
   2518	.csi_buf_pg_num = 0,
   2519	.band = RTW_BAND_2G | RTW_BAND_5G,
   2520	.page_size = 128,
   2521	.dig_min = 0x1c,
   2522	.ht_supported = true,
   2523	.vht_supported = true,
   2524	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
   2525	.sys_func_en = 0xDC,
   2526	.pwr_on_seq = card_enable_flow_8822b,
   2527	.pwr_off_seq = card_disable_flow_8822b,
   2528	.page_table = page_table_8822b,
   2529	.rqpn_table = rqpn_table_8822b,
   2530	.prioq_addrs = &prioq_addrs_8822b,
   2531	.intf_table = &phy_para_table_8822b,
   2532	.dig = rtw8822b_dig,
   2533	.dig_cck = NULL,
   2534	.rf_base_addr = {0x2800, 0x2c00},
   2535	.rf_sipi_addr = {0xc90, 0xe90},
   2536	.ltecoex_addr = &rtw8822b_ltecoex_addr,
   2537	.mac_tbl = &rtw8822b_mac_tbl,
   2538	.agc_tbl = &rtw8822b_agc_tbl,
   2539	.bb_tbl = &rtw8822b_bb_tbl,
   2540	.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
   2541	.rfe_defs = rtw8822b_rfe_defs,
   2542	.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
   2543	.pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
   2544	.iqk_threshold = 8,
   2545	.bfer_su_max_num = 2,
   2546	.bfer_mu_max_num = 1,
   2547	.rx_ldpc = true,
   2548	.edcca_th = rtw8822b_edcca_th,
   2549	.l2h_th_ini_cs = 10 + EDCCA_IGI_BASE,
   2550	.l2h_th_ini_ad = -14 + EDCCA_IGI_BASE,
   2551	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
   2552
   2553	.coex_para_ver = 0x20070206,
   2554	.bt_desired_ver = 0x6,
   2555	.scbd_support = true,
   2556	.new_scbd10_def = false,
   2557	.ble_hid_profile_support = false,
   2558	.wl_mimo_ps_support = false,
   2559	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
   2560	.bt_rssi_type = COEX_BTRSSI_RATIO,
   2561	.ant_isolation = 15,
   2562	.rssi_tolerance = 2,
   2563	.wl_rssi_step = wl_rssi_step_8822b,
   2564	.bt_rssi_step = bt_rssi_step_8822b,
   2565	.table_sant_num = ARRAY_SIZE(table_sant_8822b),
   2566	.table_sant = table_sant_8822b,
   2567	.table_nsant_num = ARRAY_SIZE(table_nsant_8822b),
   2568	.table_nsant = table_nsant_8822b,
   2569	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8822b),
   2570	.tdma_sant = tdma_sant_8822b,
   2571	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822b),
   2572	.tdma_nsant = tdma_nsant_8822b,
   2573	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822b),
   2574	.wl_rf_para_tx = rf_para_tx_8822b,
   2575	.wl_rf_para_rx = rf_para_rx_8822b,
   2576	.bt_afh_span_bw20 = 0x24,
   2577	.bt_afh_span_bw40 = 0x36,
   2578	.afh_5g_num = ARRAY_SIZE(afh_5g_8822b),
   2579	.afh_5g = afh_5g_8822b,
   2580
   2581	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b),
   2582	.coex_info_hw_regs = coex_info_hw_regs_8822b,
   2583
   2584	.fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680},
   2585};
   2586EXPORT_SYMBOL(rtw8822b_hw_spec);
   2587
   2588MODULE_FIRMWARE("rtw88/rtw8822b_fw.bin");
   2589
   2590MODULE_AUTHOR("Realtek Corporation");
   2591MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822b driver");
   2592MODULE_LICENSE("Dual BSD/GPL");