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