File Index
Files and directories
Sign in
FILE

rtw8822b.c

File preview with syntax highlighting.

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