162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 262306a36Sopenharmony_ci/* Copyright(c) 2018-2019 Realtek Corporation 362306a36Sopenharmony_ci */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/module.h> 662306a36Sopenharmony_ci#include "main.h" 762306a36Sopenharmony_ci#include "coex.h" 862306a36Sopenharmony_ci#include "fw.h" 962306a36Sopenharmony_ci#include "tx.h" 1062306a36Sopenharmony_ci#include "rx.h" 1162306a36Sopenharmony_ci#include "phy.h" 1262306a36Sopenharmony_ci#include "rtw8822c.h" 1362306a36Sopenharmony_ci#include "rtw8822c_table.h" 1462306a36Sopenharmony_ci#include "mac.h" 1562306a36Sopenharmony_ci#include "reg.h" 1662306a36Sopenharmony_ci#include "debug.h" 1762306a36Sopenharmony_ci#include "util.h" 1862306a36Sopenharmony_ci#include "bf.h" 1962306a36Sopenharmony_ci#include "efuse.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define IQK_DONE_8822C 0xaa 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, 2462306a36Sopenharmony_ci u8 rx_path, bool is_tx2_path); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse, 2762306a36Sopenharmony_ci struct rtw8822c_efuse *map) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci ether_addr_copy(efuse->addr, map->e.mac_addr); 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse, 3362306a36Sopenharmony_ci struct rtw8822c_efuse *map) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci ether_addr_copy(efuse->addr, map->u.mac_addr); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse, 3962306a36Sopenharmony_ci struct rtw8822c_efuse *map) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci ether_addr_copy(efuse->addr, map->s.mac_addr); 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct rtw_efuse *efuse = &rtwdev->efuse; 4762306a36Sopenharmony_ci struct rtw8822c_efuse *map; 4862306a36Sopenharmony_ci int i; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci map = (struct rtw8822c_efuse *)log_map; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci efuse->rfe_option = map->rfe_option; 5362306a36Sopenharmony_ci efuse->rf_board_option = map->rf_board_option; 5462306a36Sopenharmony_ci efuse->crystal_cap = map->xtal_k & XCAP_MASK; 5562306a36Sopenharmony_ci efuse->channel_plan = map->channel_plan; 5662306a36Sopenharmony_ci efuse->country_code[0] = map->country_code[0]; 5762306a36Sopenharmony_ci efuse->country_code[1] = map->country_code[1]; 5862306a36Sopenharmony_ci efuse->bt_setting = map->rf_bt_setting; 5962306a36Sopenharmony_ci efuse->regd = map->rf_board_option & 0x7; 6062306a36Sopenharmony_ci efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal; 6162306a36Sopenharmony_ci efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal; 6262306a36Sopenharmony_ci efuse->thermal_meter_k = 6362306a36Sopenharmony_ci (map->path_a_thermal + map->path_b_thermal) >> 1; 6462306a36Sopenharmony_ci efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci for (i = 0; i < 4; i++) 6762306a36Sopenharmony_ci efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci switch (rtw_hci_type(rtwdev)) { 7062306a36Sopenharmony_ci case RTW_HCI_TYPE_PCIE: 7162306a36Sopenharmony_ci rtw8822ce_efuse_parsing(efuse, map); 7262306a36Sopenharmony_ci break; 7362306a36Sopenharmony_ci case RTW_HCI_TYPE_USB: 7462306a36Sopenharmony_ci rtw8822cu_efuse_parsing(efuse, map); 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci case RTW_HCI_TYPE_SDIO: 7762306a36Sopenharmony_ci rtw8822cs_efuse_parsing(efuse, map); 7862306a36Sopenharmony_ci break; 7962306a36Sopenharmony_ci default: 8062306a36Sopenharmony_ci /* unsupported now */ 8162306a36Sopenharmony_ci return -ENOTSUPP; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci return 0; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic void rtw8822c_header_file_init(struct rtw_dev *rtwdev, bool pre) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); 9062306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_3WIRE, BIT_3WIRE_PI_ON); 9162306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_TX_EN | BIT_3WIRE_RX_EN); 9262306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_3WIRE2, BIT_3WIRE_PI_ON); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci if (pre) 9562306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); 9662306a36Sopenharmony_ci else 9762306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_ENCCK, BIT_CCK_OFDM_BLK_EN); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic void rtw8822c_bb_reset(struct rtw_dev *rtwdev) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 10362306a36Sopenharmony_ci rtw_write16_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 10462306a36Sopenharmony_ci rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic void rtw8822c_dac_backup_reg(struct rtw_dev *rtwdev, 10862306a36Sopenharmony_ci struct rtw_backup_info *backup, 10962306a36Sopenharmony_ci struct rtw_backup_info *backup_rf) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci u32 path, i; 11262306a36Sopenharmony_ci u32 val; 11362306a36Sopenharmony_ci u32 reg; 11462306a36Sopenharmony_ci u32 rf_addr[DACK_RF_8822C] = {0x8f}; 11562306a36Sopenharmony_ci u32 addrs[DACK_REG_8822C] = {0x180c, 0x1810, 0x410c, 0x4110, 11662306a36Sopenharmony_ci 0x1c3c, 0x1c24, 0x1d70, 0x9b4, 11762306a36Sopenharmony_ci 0x1a00, 0x1a14, 0x1d58, 0x1c38, 11862306a36Sopenharmony_ci 0x1e24, 0x1e28, 0x1860, 0x4160}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci for (i = 0; i < DACK_REG_8822C; i++) { 12162306a36Sopenharmony_ci backup[i].len = 4; 12262306a36Sopenharmony_ci backup[i].reg = addrs[i]; 12362306a36Sopenharmony_ci backup[i].val = rtw_read32(rtwdev, addrs[i]); 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci for (path = 0; path < DACK_PATH_8822C; path++) { 12762306a36Sopenharmony_ci for (i = 0; i < DACK_RF_8822C; i++) { 12862306a36Sopenharmony_ci reg = rf_addr[i]; 12962306a36Sopenharmony_ci val = rtw_read_rf(rtwdev, path, reg, RFREG_MASK); 13062306a36Sopenharmony_ci backup_rf[path * i + i].reg = reg; 13162306a36Sopenharmony_ci backup_rf[path * i + i].val = val; 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev, 13762306a36Sopenharmony_ci struct rtw_backup_info *backup, 13862306a36Sopenharmony_ci struct rtw_backup_info *backup_rf) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci u32 path, i; 14162306a36Sopenharmony_ci u32 val; 14262306a36Sopenharmony_ci u32 reg; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci rtw_restore_reg(rtwdev, backup, DACK_REG_8822C); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci for (path = 0; path < DACK_PATH_8822C; path++) { 14762306a36Sopenharmony_ci for (i = 0; i < DACK_RF_8822C; i++) { 14862306a36Sopenharmony_ci val = backup_rf[path * i + i].val; 14962306a36Sopenharmony_ci reg = backup_rf[path * i + i].reg; 15062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, reg, RFREG_MASK, val); 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value, 15662306a36Sopenharmony_ci u32 *min, u32 *max) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci if (value >= 0x200) { 15962306a36Sopenharmony_ci if (*min >= 0x200) { 16062306a36Sopenharmony_ci if (*min > value) 16162306a36Sopenharmony_ci *min = value; 16262306a36Sopenharmony_ci } else { 16362306a36Sopenharmony_ci *min = value; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci if (*max >= 0x200) { 16662306a36Sopenharmony_ci if (*max < value) 16762306a36Sopenharmony_ci *max = value; 16862306a36Sopenharmony_ci } 16962306a36Sopenharmony_ci } else { 17062306a36Sopenharmony_ci if (*min < 0x200) { 17162306a36Sopenharmony_ci if (*min > value) 17262306a36Sopenharmony_ci *min = value; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci if (*max >= 0x200) { 17662306a36Sopenharmony_ci *max = value; 17762306a36Sopenharmony_ci } else { 17862306a36Sopenharmony_ci if (*max < value) 17962306a36Sopenharmony_ci *max = value; 18062306a36Sopenharmony_ci } 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci if (*v1 >= 0x200 && *v2 >= 0x200) { 18762306a36Sopenharmony_ci if (*v1 > *v2) 18862306a36Sopenharmony_ci swap(*v1, *v2); 18962306a36Sopenharmony_ci } else if (*v1 < 0x200 && *v2 < 0x200) { 19062306a36Sopenharmony_ci if (*v1 > *v2) 19162306a36Sopenharmony_ci swap(*v1, *v2); 19262306a36Sopenharmony_ci } else if (*v1 < 0x200 && *v2 >= 0x200) { 19362306a36Sopenharmony_ci swap(*v1, *v2); 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci u32 i, j; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci for (i = 0; i < DACK_SN_8822C - 1; i++) { 20262306a36Sopenharmony_ci for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) { 20362306a36Sopenharmony_ci __rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]); 20462306a36Sopenharmony_ci __rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]); 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci u32 p, m, t, i; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci m = 0; 21462306a36Sopenharmony_ci p = 0; 21562306a36Sopenharmony_ci for (i = 10; i < DACK_SN_8822C - 10; i++) { 21662306a36Sopenharmony_ci if (vec[i] > 0x200) 21762306a36Sopenharmony_ci m = (0x400 - vec[i]) + m; 21862306a36Sopenharmony_ci else 21962306a36Sopenharmony_ci p = vec[i] + p; 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci if (p > m) { 22362306a36Sopenharmony_ci t = p - m; 22462306a36Sopenharmony_ci t = t / (DACK_SN_8822C - 20); 22562306a36Sopenharmony_ci } else { 22662306a36Sopenharmony_ci t = m - p; 22762306a36Sopenharmony_ci t = t / (DACK_SN_8822C - 20); 22862306a36Sopenharmony_ci if (t != 0x0) 22962306a36Sopenharmony_ci t = 0x400 - t; 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci *val = t; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic u32 rtw8822c_get_path_write_addr(u8 path) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci u32 base_addr; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci switch (path) { 24062306a36Sopenharmony_ci case RF_PATH_A: 24162306a36Sopenharmony_ci base_addr = 0x1800; 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci case RF_PATH_B: 24462306a36Sopenharmony_ci base_addr = 0x4100; 24562306a36Sopenharmony_ci break; 24662306a36Sopenharmony_ci default: 24762306a36Sopenharmony_ci WARN_ON(1); 24862306a36Sopenharmony_ci return -1; 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci return base_addr; 25262306a36Sopenharmony_ci} 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic u32 rtw8822c_get_path_read_addr(u8 path) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci u32 base_addr; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci switch (path) { 25962306a36Sopenharmony_ci case RF_PATH_A: 26062306a36Sopenharmony_ci base_addr = 0x2800; 26162306a36Sopenharmony_ci break; 26262306a36Sopenharmony_ci case RF_PATH_B: 26362306a36Sopenharmony_ci base_addr = 0x4500; 26462306a36Sopenharmony_ci break; 26562306a36Sopenharmony_ci default: 26662306a36Sopenharmony_ci WARN_ON(1); 26762306a36Sopenharmony_ci return -1; 26862306a36Sopenharmony_ci } 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci return base_addr; 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci bool ret = true; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci if ((value >= 0x200 && (0x400 - value) > 0x64) || 27862306a36Sopenharmony_ci (value < 0x200 && value > 0x64)) { 27962306a36Sopenharmony_ci ret = false; 28062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n"); 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci return ret; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci u32 temp; 28962306a36Sopenharmony_ci int i = 0, cnt = 0; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci while (i < DACK_SN_8822C && cnt < 10000) { 29262306a36Sopenharmony_ci cnt++; 29362306a36Sopenharmony_ci temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 29462306a36Sopenharmony_ci iv[i] = (temp & 0x3ff000) >> 12; 29562306a36Sopenharmony_ci qv[i] = temp & 0x3ff; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci if (rtw8822c_dac_iq_check(rtwdev, iv[i]) && 29862306a36Sopenharmony_ci rtw8822c_dac_iq_check(rtwdev, qv[i])) 29962306a36Sopenharmony_ci i++; 30062306a36Sopenharmony_ci } 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev, 30462306a36Sopenharmony_ci u32 *iv, u32 *qv, 30562306a36Sopenharmony_ci u32 *i_value, u32 *q_value) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0; 30862306a36Sopenharmony_ci u32 i_delta, q_delta; 30962306a36Sopenharmony_ci u32 temp; 31062306a36Sopenharmony_ci int i, cnt = 0; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci do { 31362306a36Sopenharmony_ci i_min = iv[0]; 31462306a36Sopenharmony_ci i_max = iv[0]; 31562306a36Sopenharmony_ci q_min = qv[0]; 31662306a36Sopenharmony_ci q_max = qv[0]; 31762306a36Sopenharmony_ci for (i = 0; i < DACK_SN_8822C; i++) { 31862306a36Sopenharmony_ci rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max); 31962306a36Sopenharmony_ci rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max); 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci if (i_max < 0x200 && i_min < 0x200) 32362306a36Sopenharmony_ci i_delta = i_max - i_min; 32462306a36Sopenharmony_ci else if (i_max >= 0x200 && i_min >= 0x200) 32562306a36Sopenharmony_ci i_delta = i_max - i_min; 32662306a36Sopenharmony_ci else 32762306a36Sopenharmony_ci i_delta = i_max + (0x400 - i_min); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci if (q_max < 0x200 && q_min < 0x200) 33062306a36Sopenharmony_ci q_delta = q_max - q_min; 33162306a36Sopenharmony_ci else if (q_max >= 0x200 && q_min >= 0x200) 33262306a36Sopenharmony_ci q_delta = q_max - q_min; 33362306a36Sopenharmony_ci else 33462306a36Sopenharmony_ci q_delta = q_max + (0x400 - q_min); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 33762306a36Sopenharmony_ci "[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n", 33862306a36Sopenharmony_ci i_min, i_max, i_delta); 33962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 34062306a36Sopenharmony_ci "[DACK] q: min=0x%08x, max=0x%08x, delta=0x%08x\n", 34162306a36Sopenharmony_ci q_min, q_max, q_delta); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci rtw8822c_dac_iq_sort(rtwdev, iv, qv); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci if (i_delta > 5 || q_delta > 5) { 34662306a36Sopenharmony_ci temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 34762306a36Sopenharmony_ci iv[0] = (temp & 0x3ff000) >> 12; 34862306a36Sopenharmony_ci qv[0] = temp & 0x3ff; 34962306a36Sopenharmony_ci temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff); 35062306a36Sopenharmony_ci iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12; 35162306a36Sopenharmony_ci qv[DACK_SN_8822C - 1] = temp & 0x3ff; 35262306a36Sopenharmony_ci } else { 35362306a36Sopenharmony_ci break; 35462306a36Sopenharmony_ci } 35562306a36Sopenharmony_ci } while (cnt++ < 100); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci rtw8822c_dac_iq_offset(rtwdev, iv, i_value); 35862306a36Sopenharmony_ci rtw8822c_dac_iq_offset(rtwdev, qv, q_value); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev, 36262306a36Sopenharmony_ci u32 *i_value, u32 *q_value) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C]; 36562306a36Sopenharmony_ci u32 rf_a, rf_b; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK); 36862306a36Sopenharmony_ci rf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK); 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-A=0x%05x\n", rf_a); 37162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] RF path-B=0x%05x\n", rf_b); 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci rtw8822c_dac_cal_iq_sample(rtwdev, iv, qv); 37462306a36Sopenharmony_ci rtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value); 37562306a36Sopenharmony_ci} 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistatic void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev) 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1d58, 0xff8, 0x1ff); 38062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1a00, 0x3, 0x2); 38162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1a14, 0x300, 0x3); 38262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1d70, 0x7e7e7e7e); 38362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x180c, 0x3, 0x0); 38462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x410c, 0x3, 0x0); 38562306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b00, 0x00000008); 38662306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1bcc, 0x3f); 38762306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b00, 0x0000000a); 38862306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1bcc, 0x3f); 38962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1e24, BIT(31), 0x0); 39062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1e28, 0xf, 0x3); 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, 39462306a36Sopenharmony_ci u8 path, u32 *adc_ic, u32 *adc_qc) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 39762306a36Sopenharmony_ci u32 ic = 0, qc = 0, temp = 0; 39862306a36Sopenharmony_ci u32 base_addr; 39962306a36Sopenharmony_ci u32 path_sel; 40062306a36Sopenharmony_ci int i; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK path(%d)\n", path); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci base_addr = rtw8822c_get_path_write_addr(path); 40562306a36Sopenharmony_ci switch (path) { 40662306a36Sopenharmony_ci case RF_PATH_A: 40762306a36Sopenharmony_ci path_sel = 0xa0000; 40862306a36Sopenharmony_ci break; 40962306a36Sopenharmony_ci case RF_PATH_B: 41062306a36Sopenharmony_ci path_sel = 0x80000; 41162306a36Sopenharmony_ci break; 41262306a36Sopenharmony_ci default: 41362306a36Sopenharmony_ci WARN_ON(1); 41462306a36Sopenharmony_ci return; 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci /* ADCK step1 */ 41862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x0); 41962306a36Sopenharmony_ci if (path == RF_PATH_B) 42062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x30, 0x30db8041); 42162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); 42262306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 42362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02dd08c4); 42462306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); 42562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK, 0x10000); 42662306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK, 0x10000); 42762306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 42862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK count=%d\n", i); 42962306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8003); 43062306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c24, 0x00010002); 43162306a36Sopenharmony_ci rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 43262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 43362306a36Sopenharmony_ci "[DACK] before: i=0x%x, q=0x%x\n", ic, qc); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci /* compensation value */ 43662306a36Sopenharmony_ci if (ic != 0x0) { 43762306a36Sopenharmony_ci ic = 0x400 - ic; 43862306a36Sopenharmony_ci *adc_ic = ic; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci if (qc != 0x0) { 44162306a36Sopenharmony_ci qc = 0x400 - qc; 44262306a36Sopenharmony_ci *adc_qc = qc; 44362306a36Sopenharmony_ci } 44462306a36Sopenharmony_ci temp = (ic & 0x3ff) | ((qc & 0x3ff) << 10); 44562306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x68, temp); 44662306a36Sopenharmony_ci dm_info->dack_adck[path] = temp; 44762306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK 0x%08x=0x08%x\n", 44862306a36Sopenharmony_ci base_addr + 0x68, temp); 44962306a36Sopenharmony_ci /* check ADC DC offset */ 45062306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103); 45162306a36Sopenharmony_ci rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 45262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 45362306a36Sopenharmony_ci "[DACK] after: i=0x%08x, q=0x%08x\n", ic, qc); 45462306a36Sopenharmony_ci if (ic >= 0x200) 45562306a36Sopenharmony_ci ic = 0x400 - ic; 45662306a36Sopenharmony_ci if (qc >= 0x200) 45762306a36Sopenharmony_ci qc = 0x400 - qc; 45862306a36Sopenharmony_ci if (ic < 5 && qc < 5) 45962306a36Sopenharmony_ci break; 46062306a36Sopenharmony_ci } 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci /* ADCK step2 */ 46362306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c3c, 0x00000003); 46462306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0x10000260); 46562306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci /* release pull low switch on IQ path */ 46862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0x8f, BIT(13), 0x1); 46962306a36Sopenharmony_ci} 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_cistatic void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path) 47262306a36Sopenharmony_ci{ 47362306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 47462306a36Sopenharmony_ci u32 base_addr; 47562306a36Sopenharmony_ci u32 read_addr; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci base_addr = rtw8822c_get_path_write_addr(path); 47862306a36Sopenharmony_ci read_addr = rtw8822c_get_path_read_addr(path); 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x68, dm_info->dack_adck[path]); 48162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 48262306a36Sopenharmony_ci if (path == RF_PATH_A) { 48362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); 48462306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c38, 0xffffffff); 48562306a36Sopenharmony_ci } 48662306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 48762306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 48862306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); 48962306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff81); 49062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); 49162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); 49262306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xd8, 0x0008ff81); 49362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); 49462306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); 49562306a36Sopenharmony_ci mdelay(2); 49662306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xbc, 0x000aff8d); 49762306a36Sopenharmony_ci mdelay(2); 49862306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); 49962306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); 50062306a36Sopenharmony_ci mdelay(1); 50162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); 50262306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); 50362306a36Sopenharmony_ci mdelay(20); 50462306a36Sopenharmony_ci if (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) || 50562306a36Sopenharmony_ci !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff)) 50662306a36Sopenharmony_ci rtw_err(rtwdev, "failed to wait for dack ready\n"); 50762306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); 50862306a36Sopenharmony_ci mdelay(1); 50962306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); 51062306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb6db600); 51162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 51262306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); 51362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev, 51762306a36Sopenharmony_ci u8 path, u32 *ic_out, u32 *qc_out) 51862306a36Sopenharmony_ci{ 51962306a36Sopenharmony_ci u32 base_addr; 52062306a36Sopenharmony_ci u32 ic, qc, ic_in, qc_in; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci base_addr = rtw8822c_get_path_write_addr(path); 52362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0); 52462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, 0x8); 52562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, 0x0); 52662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, 0x8); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b00, 0x00000008); 52962306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1bcc, 0x03f); 53062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 53162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 53262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1c3c, 0x00088103); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci rtw8822c_dac_cal_rf_mode(rtwdev, &ic_in, &qc_in); 53562306a36Sopenharmony_ci ic = ic_in; 53662306a36Sopenharmony_ci qc = qc_in; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci /* compensation value */ 53962306a36Sopenharmony_ci if (ic != 0x0) 54062306a36Sopenharmony_ci ic = 0x400 - ic; 54162306a36Sopenharmony_ci if (qc != 0x0) 54262306a36Sopenharmony_ci qc = 0x400 - qc; 54362306a36Sopenharmony_ci if (ic < 0x300) { 54462306a36Sopenharmony_ci ic = ic * 2 * 6 / 5; 54562306a36Sopenharmony_ci ic = ic + 0x80; 54662306a36Sopenharmony_ci } else { 54762306a36Sopenharmony_ci ic = (0x400 - ic) * 2 * 6 / 5; 54862306a36Sopenharmony_ci ic = 0x7f - ic; 54962306a36Sopenharmony_ci } 55062306a36Sopenharmony_ci if (qc < 0x300) { 55162306a36Sopenharmony_ci qc = qc * 2 * 6 / 5; 55262306a36Sopenharmony_ci qc = qc + 0x80; 55362306a36Sopenharmony_ci } else { 55462306a36Sopenharmony_ci qc = (0x400 - qc) * 2 * 6 / 5; 55562306a36Sopenharmony_ci qc = 0x7f - qc; 55662306a36Sopenharmony_ci } 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci *ic_out = ic; 55962306a36Sopenharmony_ci *qc_out = qc; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] before i=0x%x, q=0x%x\n", ic_in, qc_in); 56262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] after i=0x%x, q=0x%x\n", ic, qc); 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_cistatic void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, 56662306a36Sopenharmony_ci u32 adc_ic, u32 adc_qc, 56762306a36Sopenharmony_ci u32 *ic_in, u32 *qc_in, 56862306a36Sopenharmony_ci u32 *i_out, u32 *q_out) 56962306a36Sopenharmony_ci{ 57062306a36Sopenharmony_ci u32 base_addr; 57162306a36Sopenharmony_ci u32 read_addr; 57262306a36Sopenharmony_ci u32 ic, qc; 57362306a36Sopenharmony_ci u32 temp; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci base_addr = rtw8822c_get_path_write_addr(path); 57662306a36Sopenharmony_ci read_addr = rtw8822c_get_path_read_addr(path); 57762306a36Sopenharmony_ci ic = *ic_in; 57862306a36Sopenharmony_ci qc = *qc_in; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); 58162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 58262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 58362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88); 58462306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xbc, 0xc008ff81); 58562306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208); 58662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, ic & 0xf); 58762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, (ic & 0xf0) >> 4); 58862306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88); 58962306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xd8, 0xe008ff81); 59062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208); 59162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, qc & 0xf); 59262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xdc, 0xf, (qc & 0xf0) >> 4); 59362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x60000000); 59462306a36Sopenharmony_ci mdelay(2); 59562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x6); 59662306a36Sopenharmony_ci mdelay(2); 59762306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89); 59862306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); 59962306a36Sopenharmony_ci mdelay(1); 60062306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); 60162306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); 60262306a36Sopenharmony_ci mdelay(20); 60362306a36Sopenharmony_ci if (!check_hw_ready(rtwdev, read_addr + 0x24, 0x07f80000, ic) || 60462306a36Sopenharmony_ci !check_hw_ready(rtwdev, read_addr + 0x50, 0x07f80000, qc)) 60562306a36Sopenharmony_ci rtw_err(rtwdev, "failed to write IQ vector to hardware\n"); 60662306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); 60762306a36Sopenharmony_ci mdelay(1); 60862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x3); 60962306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb6db600); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci /* check DAC DC offset */ 61262306a36Sopenharmony_ci temp = ((adc_ic + 0x10) & 0x3ff) | (((adc_qc + 0x10) & 0x3ff) << 10); 61362306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x68, temp); 61462306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); 61562306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x60, 0xf0000000); 61662306a36Sopenharmony_ci rtw8822c_dac_cal_rf_mode(rtwdev, &ic, &qc); 61762306a36Sopenharmony_ci if (ic >= 0x10) 61862306a36Sopenharmony_ci ic = ic - 0x10; 61962306a36Sopenharmony_ci else 62062306a36Sopenharmony_ci ic = 0x400 - (0x10 - ic); 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci if (qc >= 0x10) 62362306a36Sopenharmony_ci qc = qc - 0x10; 62462306a36Sopenharmony_ci else 62562306a36Sopenharmony_ci qc = 0x400 - (0x10 - qc); 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci *i_out = ic; 62862306a36Sopenharmony_ci *q_out = qc; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci if (ic >= 0x200) 63162306a36Sopenharmony_ci ic = 0x400 - ic; 63262306a36Sopenharmony_ci if (qc >= 0x200) 63362306a36Sopenharmony_ci qc = 0x400 - qc; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci *ic_in = ic; 63662306a36Sopenharmony_ci *qc_in = qc; 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 63962306a36Sopenharmony_ci "[DACK] after DACK i=0x%x, q=0x%x\n", *i_out, *q_out); 64062306a36Sopenharmony_ci} 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_cistatic void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path) 64362306a36Sopenharmony_ci{ 64462306a36Sopenharmony_ci u32 base_addr = rtw8822c_get_path_write_addr(path); 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x68, 0x0); 64762306a36Sopenharmony_ci rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); 64862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0xbc, 0x1, 0x0); 64962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x1); 65062306a36Sopenharmony_ci} 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_cistatic void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev, 65362306a36Sopenharmony_ci u8 path, u8 vec, u32 w_addr, u32 r_addr) 65462306a36Sopenharmony_ci{ 65562306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 65662306a36Sopenharmony_ci u16 val; 65762306a36Sopenharmony_ci u32 i; 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci if (WARN_ON(vec >= 2)) 66062306a36Sopenharmony_ci return; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 66362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_addr, 0xf0000000, i); 66462306a36Sopenharmony_ci val = (u16)rtw_read32_mask(rtwdev, r_addr, 0x7fc0000); 66562306a36Sopenharmony_ci dm_info->dack_msbk[path][vec][i] = val; 66662306a36Sopenharmony_ci } 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_cistatic void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path) 67062306a36Sopenharmony_ci{ 67162306a36Sopenharmony_ci u32 w_off = 0x1c; 67262306a36Sopenharmony_ci u32 r_off = 0x2c; 67362306a36Sopenharmony_ci u32 w_addr, r_addr; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci if (WARN_ON(path >= 2)) 67662306a36Sopenharmony_ci return; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci /* backup I vector */ 67962306a36Sopenharmony_ci w_addr = rtw8822c_get_path_write_addr(path) + 0xb0; 68062306a36Sopenharmony_ci r_addr = rtw8822c_get_path_read_addr(path) + 0x10; 68162306a36Sopenharmony_ci rtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci /* backup Q vector */ 68462306a36Sopenharmony_ci w_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; 68562306a36Sopenharmony_ci r_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off; 68662306a36Sopenharmony_ci rtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr); 68762306a36Sopenharmony_ci} 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_cistatic void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev) 69062306a36Sopenharmony_ci{ 69162306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 69262306a36Sopenharmony_ci u8 val; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000); 69562306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_A][0][0] = val; 69662306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_1, 0xf); 69762306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_A][0][1] = val; 69862306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000); 69962306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_A][1][0] = val; 70062306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_1, 0xf); 70162306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_A][1][1] = val; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000); 70462306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_B][0][0] = val; 70562306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_1, 0xf); 70662306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_B][1][0] = val; 70762306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000); 70862306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_B][0][1] = val; 70962306a36Sopenharmony_ci val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_1, 0xf); 71062306a36Sopenharmony_ci dm_info->dack_dck[RF_PATH_B][1][1] = val; 71162306a36Sopenharmony_ci} 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_cistatic void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev) 71462306a36Sopenharmony_ci{ 71562306a36Sopenharmony_ci u32 temp[3]; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci temp[0] = rtw_read32(rtwdev, 0x1860); 71862306a36Sopenharmony_ci temp[1] = rtw_read32(rtwdev, 0x4160); 71962306a36Sopenharmony_ci temp[2] = rtw_read32(rtwdev, 0x9b4); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci /* set clock */ 72262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci /* backup path-A I/Q */ 72562306a36Sopenharmony_ci rtw_write32_clr(rtwdev, 0x1830, BIT(30)); 72662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); 72762306a36Sopenharmony_ci rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci /* backup path-B I/Q */ 73062306a36Sopenharmony_ci rtw_write32_clr(rtwdev, 0x4130, BIT(30)); 73162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); 73262306a36Sopenharmony_ci rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci rtw8822c_dac_cal_backup_dck(rtwdev); 73562306a36Sopenharmony_ci rtw_write32_set(rtwdev, 0x1830, BIT(30)); 73662306a36Sopenharmony_ci rtw_write32_set(rtwdev, 0x4130, BIT(30)); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1860, temp[0]); 73962306a36Sopenharmony_ci rtw_write32(rtwdev, 0x4160, temp[1]); 74062306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, temp[2]); 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cistatic void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev) 74462306a36Sopenharmony_ci{ 74562306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 74662306a36Sopenharmony_ci u8 val; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_DCKA_I_0, BIT(19)); 74962306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_A][0][0]; 75062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000, val); 75162306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_A][0][1]; 75262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKA_I_1, 0xf, val); 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_DCKA_Q_0, BIT(19)); 75562306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_A][1][0]; 75662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000, val); 75762306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_A][1][1]; 75862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKA_Q_1, 0xf, val); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_DCKB_I_0, BIT(19)); 76162306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_B][0][0]; 76262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000, val); 76362306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_B][0][1]; 76462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKB_I_1, 0xf, val); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_DCKB_Q_0, BIT(19)); 76762306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_B][1][0]; 76862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000, val); 76962306a36Sopenharmony_ci val = dm_info->dack_dck[RF_PATH_B][1][1]; 77062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DCKB_Q_1, 0xf, val); 77162306a36Sopenharmony_ci} 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_cistatic void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev) 77462306a36Sopenharmony_ci{ 77562306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, 0xdb66db00); 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x0); 77862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x0); 77962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x0); 78062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x0); 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x0); 78362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); 78462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b4, BIT(0), 0x1); 78562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18d0, BIT(0), 0x1); 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x0); 78862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); 78962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b4, BIT(0), 0x1); 79062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41d0, BIT(0), 0x1); 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b0, 0xf00, 0x0); 79362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18c0, BIT(14), 0x0); 79462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18cc, 0xf00, 0x0); 79562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18dc, BIT(14), 0x0); 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x0); 79862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x0); 79962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x1); 80062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x1); 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci rtw8822c_dac_cal_restore_dck(rtwdev); 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18c0, 0x38000, 0x7); 80562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18dc, 0x38000, 0x7); 80662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41c0, 0x38000, 0x7); 80762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41dc, 0x38000, 0x7); 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b8, BIT(26) | BIT(25), 0x1); 81062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18d4, BIT(26) | BIT(25), 0x1); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b0, 0xf00, 0x0); 81362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41c0, BIT(14), 0x0); 81462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41cc, 0xf00, 0x0); 81562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41dc, BIT(14), 0x0); 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x0); 81862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x0); 81962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x1); 82062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x1); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b8, BIT(26) | BIT(25), 0x1); 82362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41d4, BIT(26) | BIT(25), 0x1); 82462306a36Sopenharmony_ci} 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_cistatic bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev, 82762306a36Sopenharmony_ci u32 target_addr, u32 toggle_addr) 82862306a36Sopenharmony_ci{ 82962306a36Sopenharmony_ci u32 cnt = 0; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci do { 83262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x0); 83362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x2); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci if (rtw_read32_mask(rtwdev, target_addr, 0xf) == 0x6) 83662306a36Sopenharmony_ci return true; 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci } while (cnt++ < 100); 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci return false; 84162306a36Sopenharmony_ci} 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_cistatic bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path) 84462306a36Sopenharmony_ci{ 84562306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 84662306a36Sopenharmony_ci u32 w_off = 0x1c; 84762306a36Sopenharmony_ci u32 r_off = 0x2c; 84862306a36Sopenharmony_ci u32 w_i, r_i, w_q, r_q; 84962306a36Sopenharmony_ci u32 value; 85062306a36Sopenharmony_ci u32 i; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci w_i = rtw8822c_get_path_write_addr(path) + 0xb0; 85362306a36Sopenharmony_ci r_i = rtw8822c_get_path_read_addr(path) + 0x08; 85462306a36Sopenharmony_ci w_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; 85562306a36Sopenharmony_ci r_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8)) 85862306a36Sopenharmony_ci return false; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 86162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); 86262306a36Sopenharmony_ci value = dm_info->dack_msbk[path][0][i]; 86362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x4, 0xff8, value); 86462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i, 0xf0000000, i); 86562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x1); 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8)) 87162306a36Sopenharmony_ci return false; 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { 87462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); 87562306a36Sopenharmony_ci value = dm_info->dack_msbk[path][1][i]; 87662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x4, 0xff8, value); 87762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q, 0xf0000000, i); 87862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x1); 87962306a36Sopenharmony_ci } 88062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x8, BIT(26) | BIT(25), 0x0); 88362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x8, BIT(26) | BIT(25), 0x0); 88462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_i + 0x4, BIT(0), 0x0); 88562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, w_q + 0x4, BIT(0), 0x0); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci return true; 88862306a36Sopenharmony_ci} 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_cistatic bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) 89162306a36Sopenharmony_ci{ 89262306a36Sopenharmony_ci if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A)) 89362306a36Sopenharmony_ci return false; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B)) 89662306a36Sopenharmony_ci return false; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci return true; 89962306a36Sopenharmony_ci} 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_cistatic bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) 90262306a36Sopenharmony_ci{ 90362306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 90462306a36Sopenharmony_ci u32 temp[3]; 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci /* sample the first element for both path's IQ vector */ 90762306a36Sopenharmony_ci if (dm_info->dack_msbk[RF_PATH_A][0][0] == 0 && 90862306a36Sopenharmony_ci dm_info->dack_msbk[RF_PATH_A][1][0] == 0 && 90962306a36Sopenharmony_ci dm_info->dack_msbk[RF_PATH_B][0][0] == 0 && 91062306a36Sopenharmony_ci dm_info->dack_msbk[RF_PATH_B][1][0] == 0) 91162306a36Sopenharmony_ci return false; 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci temp[0] = rtw_read32(rtwdev, 0x1860); 91462306a36Sopenharmony_ci temp[1] = rtw_read32(rtwdev, 0x4160); 91562306a36Sopenharmony_ci temp[2] = rtw_read32(rtwdev, 0x9b4); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci rtw8822c_dac_cal_restore_prepare(rtwdev); 91862306a36Sopenharmony_ci if (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) || 91962306a36Sopenharmony_ci !check_hw_ready(rtwdev, 0x2834, 0x7fff80, 0xffff) || 92062306a36Sopenharmony_ci !check_hw_ready(rtwdev, 0x4508, 0x7fff80, 0xffff) || 92162306a36Sopenharmony_ci !check_hw_ready(rtwdev, 0x4534, 0x7fff80, 0xffff)) 92262306a36Sopenharmony_ci return false; 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci if (!__rtw8822c_dac_cal_restore(rtwdev)) { 92562306a36Sopenharmony_ci rtw_err(rtwdev, "failed to restore dack vectors\n"); 92662306a36Sopenharmony_ci return false; 92762306a36Sopenharmony_ci } 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x1); 93062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); 93162306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1860, temp[0]); 93262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x4160, temp[1]); 93362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x1); 93462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x1); 93562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x1); 93662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x1); 93762306a36Sopenharmony_ci rtw_write32(rtwdev, 0x9b4, temp[2]); 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci return true; 94062306a36Sopenharmony_ci} 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_cistatic void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) 94362306a36Sopenharmony_ci{ 94462306a36Sopenharmony_ci struct rtw_backup_info backup_rf[DACK_RF_8822C * DACK_PATH_8822C]; 94562306a36Sopenharmony_ci struct rtw_backup_info backup[DACK_REG_8822C]; 94662306a36Sopenharmony_ci u32 ic = 0, qc = 0, i; 94762306a36Sopenharmony_ci u32 i_a = 0x0, q_a = 0x0, i_b = 0x0, q_b = 0x0; 94862306a36Sopenharmony_ci u32 ic_a = 0x0, qc_a = 0x0, ic_b = 0x0, qc_b = 0x0; 94962306a36Sopenharmony_ci u32 adc_ic_a = 0x0, adc_qc_a = 0x0, adc_ic_b = 0x0, adc_qc_b = 0x0; 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci if (rtw8822c_dac_cal_restore(rtwdev)) 95262306a36Sopenharmony_ci return; 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci /* not able to restore, do it */ 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci rtw8822c_dac_backup_reg(rtwdev, backup, backup_rf); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci rtw8822c_dac_bb_setting(rtwdev); 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci /* path-A */ 96162306a36Sopenharmony_ci rtw8822c_dac_cal_adc(rtwdev, RF_PATH_A, &adc_ic_a, &adc_qc_a); 96262306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 96362306a36Sopenharmony_ci rtw8822c_dac_cal_step1(rtwdev, RF_PATH_A); 96462306a36Sopenharmony_ci rtw8822c_dac_cal_step2(rtwdev, RF_PATH_A, &ic, &qc); 96562306a36Sopenharmony_ci ic_a = ic; 96662306a36Sopenharmony_ci qc_a = qc; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci rtw8822c_dac_cal_step3(rtwdev, RF_PATH_A, adc_ic_a, adc_qc_a, 96962306a36Sopenharmony_ci &ic, &qc, &i_a, &q_a); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci if (ic < 5 && qc < 5) 97262306a36Sopenharmony_ci break; 97362306a36Sopenharmony_ci } 97462306a36Sopenharmony_ci rtw8822c_dac_cal_step4(rtwdev, RF_PATH_A); 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci /* path-B */ 97762306a36Sopenharmony_ci rtw8822c_dac_cal_adc(rtwdev, RF_PATH_B, &adc_ic_b, &adc_qc_b); 97862306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 97962306a36Sopenharmony_ci rtw8822c_dac_cal_step1(rtwdev, RF_PATH_B); 98062306a36Sopenharmony_ci rtw8822c_dac_cal_step2(rtwdev, RF_PATH_B, &ic, &qc); 98162306a36Sopenharmony_ci ic_b = ic; 98262306a36Sopenharmony_ci qc_b = qc; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci rtw8822c_dac_cal_step3(rtwdev, RF_PATH_B, adc_ic_b, adc_qc_b, 98562306a36Sopenharmony_ci &ic, &qc, &i_b, &q_b); 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci if (ic < 5 && qc < 5) 98862306a36Sopenharmony_ci break; 98962306a36Sopenharmony_ci } 99062306a36Sopenharmony_ci rtw8822c_dac_cal_step4(rtwdev, RF_PATH_B); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b00, 0x00000008); 99362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); 99462306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1bcc, 0x0); 99562306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b00, 0x0000000a); 99662306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1bcc, 0x0); 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci rtw8822c_dac_restore_reg(rtwdev, backup, backup_rf); 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci /* backup results to restore, saving a lot of time */ 100162306a36Sopenharmony_ci rtw8822c_dac_cal_backup(rtwdev); 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: ic=0x%x, qc=0x%x\n", ic_a, qc_a); 100462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: ic=0x%x, qc=0x%x\n", ic_b, qc_b); 100562306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: i=0x%x, q=0x%x\n", i_a, q_a); 100662306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: i=0x%x, q=0x%x\n", i_b, q_b); 100762306a36Sopenharmony_ci} 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_cistatic void rtw8822c_rf_x2_check(struct rtw_dev *rtwdev) 101062306a36Sopenharmony_ci{ 101162306a36Sopenharmony_ci u8 x2k_busy; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci mdelay(1); 101462306a36Sopenharmony_ci x2k_busy = rtw_read_rf(rtwdev, RF_PATH_A, 0xb8, BIT(15)); 101562306a36Sopenharmony_ci if (x2k_busy == 1) { 101662306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0xC4440); 101762306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, 0xba, RFREG_MASK, 0x6840D); 101862306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, 0xb8, RFREG_MASK, 0x80440); 101962306a36Sopenharmony_ci mdelay(1); 102062306a36Sopenharmony_ci } 102162306a36Sopenharmony_ci} 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_cistatic void rtw8822c_set_power_trim(struct rtw_dev *rtwdev, s8 bb_gain[2][8]) 102462306a36Sopenharmony_ci{ 102562306a36Sopenharmony_ci#define RF_SET_POWER_TRIM(_path, _seq, _idx) \ 102662306a36Sopenharmony_ci do { \ 102762306a36Sopenharmony_ci rtw_write_rf(rtwdev, _path, 0x33, RFREG_MASK, _seq); \ 102862306a36Sopenharmony_ci rtw_write_rf(rtwdev, _path, 0x3f, RFREG_MASK, \ 102962306a36Sopenharmony_ci bb_gain[_path][_idx]); \ 103062306a36Sopenharmony_ci } while (0) 103162306a36Sopenharmony_ci u8 path; 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 103462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0xee, BIT(19), 1); 103562306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x0, 0); 103662306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x1, 1); 103762306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x2, 2); 103862306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x3, 2); 103962306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x4, 3); 104062306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x5, 4); 104162306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x6, 5); 104262306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x7, 6); 104362306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x8, 7); 104462306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0x9, 3); 104562306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0xa, 4); 104662306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0xb, 5); 104762306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0xc, 6); 104862306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0xd, 7); 104962306a36Sopenharmony_ci RF_SET_POWER_TRIM(path, 0xe, 7); 105062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0xee, BIT(19), 0); 105162306a36Sopenharmony_ci } 105262306a36Sopenharmony_ci#undef RF_SET_POWER_TRIM 105362306a36Sopenharmony_ci} 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_cistatic void rtw8822c_power_trim(struct rtw_dev *rtwdev) 105662306a36Sopenharmony_ci{ 105762306a36Sopenharmony_ci u8 pg_pwr = 0xff, i, path, idx; 105862306a36Sopenharmony_ci s8 bb_gain[2][8] = {}; 105962306a36Sopenharmony_ci u16 rf_efuse_2g[3] = {PPG_2GL_TXAB, PPG_2GM_TXAB, PPG_2GH_TXAB}; 106062306a36Sopenharmony_ci u16 rf_efuse_5g[2][5] = {{PPG_5GL1_TXA, PPG_5GL2_TXA, PPG_5GM1_TXA, 106162306a36Sopenharmony_ci PPG_5GM2_TXA, PPG_5GH1_TXA}, 106262306a36Sopenharmony_ci {PPG_5GL1_TXB, PPG_5GL2_TXB, PPG_5GM1_TXB, 106362306a36Sopenharmony_ci PPG_5GM2_TXB, PPG_5GH1_TXB} }; 106462306a36Sopenharmony_ci bool set = false; 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rf_efuse_2g); i++) { 106762306a36Sopenharmony_ci rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[i], &pg_pwr); 106862306a36Sopenharmony_ci if (pg_pwr == EFUSE_READ_FAIL) 106962306a36Sopenharmony_ci continue; 107062306a36Sopenharmony_ci set = true; 107162306a36Sopenharmony_ci bb_gain[RF_PATH_A][i] = FIELD_GET(PPG_2G_A_MASK, pg_pwr); 107262306a36Sopenharmony_ci bb_gain[RF_PATH_B][i] = FIELD_GET(PPG_2G_B_MASK, pg_pwr); 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rf_efuse_5g[0]); i++) { 107662306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 107762306a36Sopenharmony_ci rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path][i], 107862306a36Sopenharmony_ci &pg_pwr); 107962306a36Sopenharmony_ci if (pg_pwr == EFUSE_READ_FAIL) 108062306a36Sopenharmony_ci continue; 108162306a36Sopenharmony_ci set = true; 108262306a36Sopenharmony_ci idx = i + ARRAY_SIZE(rf_efuse_2g); 108362306a36Sopenharmony_ci bb_gain[path][idx] = FIELD_GET(PPG_5G_MASK, pg_pwr); 108462306a36Sopenharmony_ci } 108562306a36Sopenharmony_ci } 108662306a36Sopenharmony_ci if (set) 108762306a36Sopenharmony_ci rtw8822c_set_power_trim(rtwdev, bb_gain); 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic void rtw8822c_thermal_trim(struct rtw_dev *rtwdev) 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci u16 rf_efuse[2] = {PPG_THERMAL_A, PPG_THERMAL_B}; 109562306a36Sopenharmony_ci u8 pg_therm = 0xff, thermal[2] = {0}, path; 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 109862306a36Sopenharmony_ci rtw_read8_physical_efuse(rtwdev, rf_efuse[path], &pg_therm); 109962306a36Sopenharmony_ci if (pg_therm == EFUSE_READ_FAIL) 110062306a36Sopenharmony_ci return; 110162306a36Sopenharmony_ci /* Efuse value of BIT(0) shall be move to BIT(3), and the value 110262306a36Sopenharmony_ci * of BIT(1) to BIT(3) should be right shifted 1 bit. 110362306a36Sopenharmony_ci */ 110462306a36Sopenharmony_ci thermal[path] = FIELD_GET(GENMASK(3, 1), pg_therm); 110562306a36Sopenharmony_ci thermal[path] |= FIELD_PREP(BIT(3), pg_therm & BIT(0)); 110662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0x43, RF_THEMAL_MASK, thermal[path]); 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci} 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_cistatic void rtw8822c_pa_bias(struct rtw_dev *rtwdev) 111162306a36Sopenharmony_ci{ 111262306a36Sopenharmony_ci u16 rf_efuse_2g[2] = {PPG_PABIAS_2GA, PPG_PABIAS_2GB}; 111362306a36Sopenharmony_ci u16 rf_efuse_5g[2] = {PPG_PABIAS_5GA, PPG_PABIAS_5GB}; 111462306a36Sopenharmony_ci u8 pg_pa_bias = 0xff, path; 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 111762306a36Sopenharmony_ci rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[path], 111862306a36Sopenharmony_ci &pg_pa_bias); 111962306a36Sopenharmony_ci if (pg_pa_bias == EFUSE_READ_FAIL) 112062306a36Sopenharmony_ci return; 112162306a36Sopenharmony_ci pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); 112262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_2G_MASK, pg_pa_bias); 112362306a36Sopenharmony_ci } 112462306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 112562306a36Sopenharmony_ci rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path], 112662306a36Sopenharmony_ci &pg_pa_bias); 112762306a36Sopenharmony_ci pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias); 112862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_PA, RF_PABIAS_5G_MASK, pg_pa_bias); 112962306a36Sopenharmony_ci } 113062306a36Sopenharmony_ci} 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_cistatic void rtw8822c_rfk_handshake(struct rtw_dev *rtwdev, bool is_before_k) 113362306a36Sopenharmony_ci{ 113462306a36Sopenharmony_ci struct rtw_dm_info *dm = &rtwdev->dm_info; 113562306a36Sopenharmony_ci u8 u1b_tmp; 113662306a36Sopenharmony_ci u8 u4b_tmp; 113762306a36Sopenharmony_ci int ret; 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci if (is_before_k) { 114062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 114162306a36Sopenharmony_ci "[RFK] WiFi / BT RFK handshake start!!\n"); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci if (!dm->is_bt_iqk_timeout) { 114462306a36Sopenharmony_ci ret = read_poll_timeout(rtw_read32_mask, u4b_tmp, 114562306a36Sopenharmony_ci u4b_tmp == 0, 20, 600000, false, 114662306a36Sopenharmony_ci rtwdev, REG_PMC_DBG_CTRL1, 114762306a36Sopenharmony_ci BITS_PMC_BT_IQK_STS); 114862306a36Sopenharmony_ci if (ret) { 114962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 115062306a36Sopenharmony_ci "[RFK] Wait BT IQK finish timeout!!\n"); 115162306a36Sopenharmony_ci dm->is_bt_iqk_timeout = true; 115262306a36Sopenharmony_ci } 115362306a36Sopenharmony_ci } 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci rtw_fw_inform_rfk_status(rtwdev, true); 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, 115862306a36Sopenharmony_ci u1b_tmp == 1, 20, 100000, false, 115962306a36Sopenharmony_ci rtwdev, REG_ARFR4, BIT_WL_RFK); 116062306a36Sopenharmony_ci if (ret) 116162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 116262306a36Sopenharmony_ci "[RFK] Send WiFi RFK start H2C cmd FAIL!!\n"); 116362306a36Sopenharmony_ci } else { 116462306a36Sopenharmony_ci rtw_fw_inform_rfk_status(rtwdev, false); 116562306a36Sopenharmony_ci ret = read_poll_timeout(rtw_read8_mask, u1b_tmp, 116662306a36Sopenharmony_ci u1b_tmp == 1, 20, 100000, false, 116762306a36Sopenharmony_ci rtwdev, REG_ARFR4, 116862306a36Sopenharmony_ci BIT_WL_RFK); 116962306a36Sopenharmony_ci if (ret) 117062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 117162306a36Sopenharmony_ci "[RFK] Send WiFi RFK finish H2C cmd FAIL!!\n"); 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 117462306a36Sopenharmony_ci "[RFK] WiFi / BT RFK handshake finish!!\n"); 117562306a36Sopenharmony_ci } 117662306a36Sopenharmony_ci} 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_cistatic void rtw8822c_rfk_power_save(struct rtw_dev *rtwdev, 117962306a36Sopenharmony_ci bool is_power_save) 118062306a36Sopenharmony_ci{ 118162306a36Sopenharmony_ci u8 path; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 118462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 118562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_PS_EN, 118662306a36Sopenharmony_ci is_power_save ? 0 : 1); 118762306a36Sopenharmony_ci } 118862306a36Sopenharmony_ci} 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_cistatic void rtw8822c_txgapk_backup_bb_reg(struct rtw_dev *rtwdev, const u32 reg[], 119162306a36Sopenharmony_ci u32 reg_backup[], u32 reg_num) 119262306a36Sopenharmony_ci{ 119362306a36Sopenharmony_ci u32 i; 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci for (i = 0; i < reg_num; i++) { 119662306a36Sopenharmony_ci reg_backup[i] = rtw_read32(rtwdev, reg[i]); 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Backup BB 0x%x = 0x%x\n", 119962306a36Sopenharmony_ci reg[i], reg_backup[i]); 120062306a36Sopenharmony_ci } 120162306a36Sopenharmony_ci} 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_cistatic void rtw8822c_txgapk_reload_bb_reg(struct rtw_dev *rtwdev, 120462306a36Sopenharmony_ci const u32 reg[], u32 reg_backup[], 120562306a36Sopenharmony_ci u32 reg_num) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci u32 i; 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci for (i = 0; i < reg_num; i++) { 121062306a36Sopenharmony_ci rtw_write32(rtwdev, reg[i], reg_backup[i]); 121162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Reload BB 0x%x = 0x%x\n", 121262306a36Sopenharmony_ci reg[i], reg_backup[i]); 121362306a36Sopenharmony_ci } 121462306a36Sopenharmony_ci} 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_cistatic bool check_rf_status(struct rtw_dev *rtwdev, u8 status) 121762306a36Sopenharmony_ci{ 121862306a36Sopenharmony_ci u8 reg_rf0_a, reg_rf0_b; 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci reg_rf0_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 122162306a36Sopenharmony_ci RF_MODE_TRXAGC, BIT_RF_MODE); 122262306a36Sopenharmony_ci reg_rf0_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 122362306a36Sopenharmony_ci RF_MODE_TRXAGC, BIT_RF_MODE); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci if (reg_rf0_a == status || reg_rf0_b == status) 122662306a36Sopenharmony_ci return false; 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci return true; 122962306a36Sopenharmony_ci} 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_cistatic void rtw8822c_txgapk_tx_pause(struct rtw_dev *rtwdev) 123262306a36Sopenharmony_ci{ 123362306a36Sopenharmony_ci bool status; 123462306a36Sopenharmony_ci int ret; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci rtw_write8(rtwdev, REG_TXPAUSE, BIT_AC_QUEUE); 123762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TX_FIFO, BIT_STOP_TX, 0x2); 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci ret = read_poll_timeout_atomic(check_rf_status, status, status, 124062306a36Sopenharmony_ci 2, 5000, false, rtwdev, 2); 124162306a36Sopenharmony_ci if (ret) 124262306a36Sopenharmony_ci rtw_warn(rtwdev, "failed to pause TX\n"); 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] Tx pause!!\n"); 124562306a36Sopenharmony_ci} 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_cistatic void rtw8822c_txgapk_bb_dpk(struct rtw_dev *rtwdev, u8 path) 124862306a36Sopenharmony_ci{ 124962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ENFN, BIT_IQK_DPK_EN, 0x1); 125262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, 125362306a36Sopenharmony_ci BIT_IQK_DPK_CLOCK_SRC, 0x1); 125462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, 125562306a36Sopenharmony_ci BIT_IQK_DPK_RESET_SRC, 0x1); 125662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_EN_IOQ_IQK_DPK, 0x1); 125762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CH_DELAY_EXTR2, BIT_TST_IQK2SET_SRC, 0x0); 125862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x1ff); 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci if (path == RF_PATH_A) { 126162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, 126262306a36Sopenharmony_ci BIT_RFTXEN_GCK_FORCE_ON, 0x1); 126362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x1); 126462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, 126562306a36Sopenharmony_ci BIT_TX_SCALE_0DB, 0x1); 126662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x0); 126762306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 126862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, 126962306a36Sopenharmony_ci BIT_RFTXEN_GCK_FORCE_ON, 0x1); 127062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE2, 127162306a36Sopenharmony_ci BIT_DIS_SHARERX_TXGAT, 0x1); 127262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, 127362306a36Sopenharmony_ci BIT_TX_SCALE_0DB, 0x1); 127462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x0); 127562306a36Sopenharmony_ci } 127662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x2); 127762306a36Sopenharmony_ci} 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_cistatic void rtw8822c_txgapk_afe_dpk(struct rtw_dev *rtwdev, u8 path) 128062306a36Sopenharmony_ci{ 128162306a36Sopenharmony_ci u32 reg; 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci if (path == RF_PATH_A) { 128662306a36Sopenharmony_ci reg = REG_ANAPAR_A; 128762306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 128862306a36Sopenharmony_ci reg = REG_ANAPAR_B; 128962306a36Sopenharmony_ci } else { 129062306a36Sopenharmony_ci rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); 129162306a36Sopenharmony_ci return; 129262306a36Sopenharmony_ci } 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, MASKDWORD); 129562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); 129662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700f0001); 129762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x701f0001); 129862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x702f0001); 129962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x703f0001); 130062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x704f0001); 130162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705f0001); 130262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x706f0001); 130362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707f0001); 130462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708f0001); 130562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709f0001); 130662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70af0001); 130762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bf0001); 130862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cf0001); 130962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70df0001); 131062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ef0001); 131162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); 131262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ff0001); 131362306a36Sopenharmony_ci} 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_cistatic void rtw8822c_txgapk_afe_dpk_restore(struct rtw_dev *rtwdev, u8 path) 131662306a36Sopenharmony_ci{ 131762306a36Sopenharmony_ci u32 reg; 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci if (path == RF_PATH_A) { 132262306a36Sopenharmony_ci reg = REG_ANAPAR_A; 132362306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 132462306a36Sopenharmony_ci reg = REG_ANAPAR_B; 132562306a36Sopenharmony_ci } else { 132662306a36Sopenharmony_ci rtw_err(rtwdev, "[TXGAPK] unknown path %d!!\n", path); 132762306a36Sopenharmony_ci return; 132862306a36Sopenharmony_ci } 132962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTRL, MASKDWORD, 0xffa1005e); 133062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x700b8041); 133162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70144041); 133262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70244041); 133362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70344041); 133462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70444041); 133562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x705b8041); 133662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70644041); 133762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x707b8041); 133862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x708b8041); 133962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x709b8041); 134062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70ab8041); 134162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70bb8041); 134262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70cb8041); 134362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70db8041); 134462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70eb8041); 134562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, reg, MASKDWORD, 0x70fb8041); 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_cistatic void rtw8822c_txgapk_bb_dpk_restore(struct rtw_dev *rtwdev, u8 path) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x0); 135362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TIA_BYPASS, 0x0); 135462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DIS_BYPASS_TXBB, BIT_TXBB, 0x0); 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); 135762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 135862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 135962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); 136062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x1); 136162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 136262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 136362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, 0x00); 136462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, 0x0); 136562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCA_OFF, BIT_CCA_ON_BY_PW, 0x0); 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci if (path == RF_PATH_A) { 136862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_A, 136962306a36Sopenharmony_ci BIT_RFTXEN_GCK_FORCE_ON, 0x0); 137062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE, BIT_DIS_SHARERX_TXGAT, 0x0); 137162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_A, 137262306a36Sopenharmony_ci BIT_TX_SCALE_0DB, 0x0); 137362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE, BIT_3WIRE_EN, 0x3); 137462306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 137562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RFTXEN_GCK_B, 137662306a36Sopenharmony_ci BIT_RFTXEN_GCK_FORCE_ON, 0x0); 137762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE2, 137862306a36Sopenharmony_ci BIT_DIS_SHARERX_TXGAT, 0x0); 137962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_SHARE_RX_B, 138062306a36Sopenharmony_ci BIT_TX_SCALE_0DB, 0x0); 138162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_3WIRE2, BIT_3WIRE_EN, 0x3); 138262306a36Sopenharmony_ci } 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCKSB, BIT_BBMODE, 0x0); 138562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_CFIR_EN, 0x5); 138662306a36Sopenharmony_ci} 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_cistatic bool _rtw8822c_txgapk_gain_valid(struct rtw_dev *rtwdev, u32 gain) 138962306a36Sopenharmony_ci{ 139062306a36Sopenharmony_ci if ((FIELD_GET(BIT_GAIN_TX_PAD_H, gain) >= 0xc) && 139162306a36Sopenharmony_ci (FIELD_GET(BIT_GAIN_TX_PAD_L, gain) >= 0xe)) 139262306a36Sopenharmony_ci return true; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci return false; 139562306a36Sopenharmony_ci} 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_cistatic void _rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev, 139862306a36Sopenharmony_ci u8 band, u8 path) 139962306a36Sopenharmony_ci{ 140062306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 140162306a36Sopenharmony_ci u32 v, tmp_3f = 0; 140262306a36Sopenharmony_ci u8 gain, check_txgain; 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ci switch (band) { 140762306a36Sopenharmony_ci case RF_BAND_2G_OFDM: 140862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); 140962306a36Sopenharmony_ci break; 141062306a36Sopenharmony_ci case RF_BAND_5G_L: 141162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); 141262306a36Sopenharmony_ci break; 141362306a36Sopenharmony_ci case RF_BAND_5G_M: 141462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); 141562306a36Sopenharmony_ci break; 141662306a36Sopenharmony_ci case RF_BAND_5G_H: 141762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); 141862306a36Sopenharmony_ci break; 141962306a36Sopenharmony_ci default: 142062306a36Sopenharmony_ci break; 142162306a36Sopenharmony_ci } 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, MASKBYTE0, 0x88); 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci check_txgain = 0; 142662306a36Sopenharmony_ci for (gain = 0; gain < RF_GAIN_NUM; gain++) { 142762306a36Sopenharmony_ci v = txgapk->rf3f_bp[band][gain][path]; 142862306a36Sopenharmony_ci if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { 142962306a36Sopenharmony_ci if (!check_txgain) { 143062306a36Sopenharmony_ci tmp_3f = txgapk->rf3f_bp[band][gain][path]; 143162306a36Sopenharmony_ci check_txgain = 1; 143262306a36Sopenharmony_ci } 143362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 143462306a36Sopenharmony_ci "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", 143562306a36Sopenharmony_ci txgapk->rf3f_bp[band][gain][path]); 143662306a36Sopenharmony_ci } else { 143762306a36Sopenharmony_ci tmp_3f = txgapk->rf3f_bp[band][gain][path]; 143862306a36Sopenharmony_ci } 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN, tmp_3f); 144162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_I_GAIN, gain); 144262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x1); 144362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_GAIN_RST, 0x0); 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 144662306a36Sopenharmony_ci "[TXGAPK] Band=%d 0x1b98[11:0]=0x%03X path=%d\n", 144762306a36Sopenharmony_ci band, tmp_3f, path); 144862306a36Sopenharmony_ci } 144962306a36Sopenharmony_ci} 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_cistatic void rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev) 145262306a36Sopenharmony_ci{ 145362306a36Sopenharmony_ci u8 path, band; 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", 145662306a36Sopenharmony_ci __func__, rtwdev->dm_info.gapk.channel); 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci for (band = 0; band < RF_BAND_MAX; band++) { 145962306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 146062306a36Sopenharmony_ci _rtw8822c_txgapk_write_gain_bb_table(rtwdev, 146162306a36Sopenharmony_ci band, path); 146262306a36Sopenharmony_ci } 146362306a36Sopenharmony_ci } 146462306a36Sopenharmony_ci} 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_cistatic void rtw8822c_txgapk_read_offset(struct rtw_dev *rtwdev, u8 path) 146762306a36Sopenharmony_ci{ 146862306a36Sopenharmony_ci static const u32 cfg1_1b00[2] = {0x00000d18, 0x00000d2a}; 146962306a36Sopenharmony_ci static const u32 cfg2_1b00[2] = {0x00000d19, 0x00000d2b}; 147062306a36Sopenharmony_ci static const u32 set_pi[2] = {REG_RSV_CTRL, REG_WLRF1}; 147162306a36Sopenharmony_ci static const u32 path_setting[2] = {REG_ORITXCODE, REG_ORITXCODE2}; 147262306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 147362306a36Sopenharmony_ci u8 channel = txgapk->channel; 147462306a36Sopenharmony_ci u32 val; 147562306a36Sopenharmony_ci int i; 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci if (path >= ARRAY_SIZE(cfg1_1b00) || 147862306a36Sopenharmony_ci path >= ARRAY_SIZE(cfg2_1b00) || 147962306a36Sopenharmony_ci path >= ARRAY_SIZE(set_pi) || 148062306a36Sopenharmony_ci path >= ARRAY_SIZE(path_setting)) { 148162306a36Sopenharmony_ci rtw_warn(rtwdev, "[TXGAPK] wrong path %d\n", path); 148262306a36Sopenharmony_ci return; 148362306a36Sopenharmony_ci } 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, BIT_ANT_PATH, path + 1); 148662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, MASKDWORD, 0xe4e40000); 148762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXANTSEG, BIT_ANTSEG, 0x3); 148862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, path_setting[path], MASK20BITS, 0x33312); 148962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, path_setting[path], BIT_PATH_EN, 0x1); 149062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x0); 149162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT_TXA_TANK, 0x1); 149262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_IDAC, BIT_TX_MODE, 0x820); 149362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 149462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TX_TONE_IDX, MASKBYTE0, 0x018); 149762306a36Sopenharmony_ci fsleep(1000); 149862306a36Sopenharmony_ci if (channel >= 1 && channel <= 14) 149962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_2G_SWING); 150062306a36Sopenharmony_ci else 150162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, MASKBYTE0, BIT_5G_SWING); 150262306a36Sopenharmony_ci fsleep(1000); 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg1_1b00[path]); 150562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, MASKDWORD, cfg2_1b00[path]); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci read_poll_timeout(rtw_read32_mask, val, 150862306a36Sopenharmony_ci val == 0x55, 1000, 100000, false, 150962306a36Sopenharmony_ci rtwdev, REG_RPT_CIP, BIT_RPT_CIP_STATUS); 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, set_pi[path], BITS_RFC_DIRECT, 0x2); 151262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 151362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_EN, 0x1); 151462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x12); 151562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x3); 151662306a36Sopenharmony_ci val = rtw_read32(rtwdev, REG_STAT_RPT); 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci txgapk->offset[0][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); 151962306a36Sopenharmony_ci txgapk->offset[1][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); 152062306a36Sopenharmony_ci txgapk->offset[2][path] = (s8)FIELD_GET(BIT_GAPK_RPT2, val); 152162306a36Sopenharmony_ci txgapk->offset[3][path] = (s8)FIELD_GET(BIT_GAPK_RPT3, val); 152262306a36Sopenharmony_ci txgapk->offset[4][path] = (s8)FIELD_GET(BIT_GAPK_RPT4, val); 152362306a36Sopenharmony_ci txgapk->offset[5][path] = (s8)FIELD_GET(BIT_GAPK_RPT5, val); 152462306a36Sopenharmony_ci txgapk->offset[6][path] = (s8)FIELD_GET(BIT_GAPK_RPT6, val); 152562306a36Sopenharmony_ci txgapk->offset[7][path] = (s8)FIELD_GET(BIT_GAPK_RPT7, val); 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TX_GAIN_SET, BIT_GAPK_RPT_IDX, 0x4); 152862306a36Sopenharmony_ci val = rtw_read32(rtwdev, REG_STAT_RPT); 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci txgapk->offset[8][path] = (s8)FIELD_GET(BIT_GAPK_RPT0, val); 153162306a36Sopenharmony_ci txgapk->offset[9][path] = (s8)FIELD_GET(BIT_GAPK_RPT1, val); 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci for (i = 0; i < RF_HW_OFFSET_NUM; i++) 153462306a36Sopenharmony_ci if (txgapk->offset[i][path] & BIT(3)) 153562306a36Sopenharmony_ci txgapk->offset[i][path] = txgapk->offset[i][path] | 153662306a36Sopenharmony_ci 0xf0; 153762306a36Sopenharmony_ci for (i = 0; i < RF_HW_OFFSET_NUM; i++) 153862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 153962306a36Sopenharmony_ci "[TXGAPK] offset %d %d path=%d\n", 154062306a36Sopenharmony_ci txgapk->offset[i][path], i, path); 154162306a36Sopenharmony_ci} 154262306a36Sopenharmony_ci 154362306a36Sopenharmony_cistatic void rtw8822c_txgapk_calculate_offset(struct rtw_dev *rtwdev, u8 path) 154462306a36Sopenharmony_ci{ 154562306a36Sopenharmony_ci static const u32 bb_reg[] = {REG_ANTMAP0, REG_TXLGMAP, REG_TXANTSEG, 154662306a36Sopenharmony_ci REG_ORITXCODE, REG_ORITXCODE2}; 154762306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 154862306a36Sopenharmony_ci u8 channel = txgapk->channel; 154962306a36Sopenharmony_ci u32 reg_backup[ARRAY_SIZE(bb_reg)] = {0}; 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s channel=%d\n", 155262306a36Sopenharmony_ci __func__, channel); 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_ci rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, 155562306a36Sopenharmony_ci reg_backup, ARRAY_SIZE(bb_reg)); 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci if (channel >= 1 && channel <= 14) { 155862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 155962306a36Sopenharmony_ci REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 156062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 156162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); 156262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 156362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 156462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x5000f); 156562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x0); 156662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x1); 156762306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0f); 156862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 156962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); 157062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 157162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x00); 157462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x0); 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci rtw8822c_txgapk_read_offset(rtwdev, path); 157762306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci } else { 158062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 158162306a36Sopenharmony_ci REG_SINGLE_TONE_SW, BIT_IRQ_TEST_MODE, 0x0); 158262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SEL_PATH, path); 158362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x3f); 158462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 158562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 158662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50011); 158762306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x3); 158862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x3); 158962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); 159062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 159162306a36Sopenharmony_ci RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0x2); 159262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0x12); 159362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 159462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 159562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x1); 159662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x5); 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQKSTAT, MASKBYTE0, 0x0); 159962306a36Sopenharmony_ci 160062306a36Sopenharmony_ci if (channel >= 36 && channel <= 64) 160162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 160262306a36Sopenharmony_ci REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x2); 160362306a36Sopenharmony_ci else if (channel >= 100 && channel <= 144) 160462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 160562306a36Sopenharmony_ci REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x3); 160662306a36Sopenharmony_ci else if (channel >= 149 && channel <= 177) 160762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 160862306a36Sopenharmony_ci REG_TABLE_SEL, BIT_Q_GAIN_SEL, 0x4); 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci rtw8822c_txgapk_read_offset(rtwdev, path); 161162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "=============================\n"); 161262306a36Sopenharmony_ci } 161362306a36Sopenharmony_ci rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, 161462306a36Sopenharmony_ci reg_backup, ARRAY_SIZE(bb_reg)); 161562306a36Sopenharmony_ci} 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_cistatic void rtw8822c_txgapk_rf_restore(struct rtw_dev *rtwdev, u8 path) 161862306a36Sopenharmony_ci{ 161962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci if (path >= rtwdev->hal.rf_path_num) 162262306a36Sopenharmony_ci return; 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RF_MODE, 0x3); 162562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x0); 162662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT_PW_EXT_TIA, 0x0); 162762306a36Sopenharmony_ci} 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_cistatic u32 rtw8822c_txgapk_cal_gain(struct rtw_dev *rtwdev, u32 gain, s8 offset) 163062306a36Sopenharmony_ci{ 163162306a36Sopenharmony_ci u32 gain_x2, new_gain; 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci if (_rtw8822c_txgapk_gain_valid(rtwdev, gain)) { 163662306a36Sopenharmony_ci new_gain = gain; 163762306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 163862306a36Sopenharmony_ci "[TXGAPK] gain=0x%03X(>=0xCEX) offset=%d new_gain=0x%03X\n", 163962306a36Sopenharmony_ci gain, offset, new_gain); 164062306a36Sopenharmony_ci return new_gain; 164162306a36Sopenharmony_ci } 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci gain_x2 = (gain << 1) + offset; 164462306a36Sopenharmony_ci new_gain = (gain_x2 >> 1) | (gain_x2 & BIT(0) ? BIT_GAIN_EXT : 0); 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 164762306a36Sopenharmony_ci "[TXGAPK] gain=0x%X offset=%d new_gain=0x%X\n", 164862306a36Sopenharmony_ci gain, offset, new_gain); 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci return new_gain; 165162306a36Sopenharmony_ci} 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_cistatic void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev) 165462306a36Sopenharmony_ci{ 165562306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 165662306a36Sopenharmony_ci u32 i, j, tmp = 0x20, tmp_3f, v; 165762306a36Sopenharmony_ci s8 offset_tmp[RF_GAIN_NUM] = {0}; 165862306a36Sopenharmony_ci u8 path, band = RF_BAND_2G_OFDM, channel = txgapk->channel; 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci if (channel >= 1 && channel <= 14) { 166362306a36Sopenharmony_ci tmp = 0x20; 166462306a36Sopenharmony_ci band = RF_BAND_2G_OFDM; 166562306a36Sopenharmony_ci } else if (channel >= 36 && channel <= 64) { 166662306a36Sopenharmony_ci tmp = 0x200; 166762306a36Sopenharmony_ci band = RF_BAND_5G_L; 166862306a36Sopenharmony_ci } else if (channel >= 100 && channel <= 144) { 166962306a36Sopenharmony_ci tmp = 0x280; 167062306a36Sopenharmony_ci band = RF_BAND_5G_M; 167162306a36Sopenharmony_ci } else if (channel >= 149 && channel <= 177) { 167262306a36Sopenharmony_ci tmp = 0x300; 167362306a36Sopenharmony_ci band = RF_BAND_5G_H; 167462306a36Sopenharmony_ci } else { 167562306a36Sopenharmony_ci rtw_err(rtwdev, "[TXGAPK] unknown channel %d!!\n", channel); 167662306a36Sopenharmony_ci return; 167762306a36Sopenharmony_ci } 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 168062306a36Sopenharmony_ci for (i = 0; i < RF_GAIN_NUM; i++) { 168162306a36Sopenharmony_ci offset_tmp[i] = 0; 168262306a36Sopenharmony_ci for (j = i; j < RF_GAIN_NUM; j++) { 168362306a36Sopenharmony_ci v = txgapk->rf3f_bp[band][j][path]; 168462306a36Sopenharmony_ci if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) 168562306a36Sopenharmony_ci continue; 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_ci offset_tmp[i] += txgapk->offset[j][path]; 168862306a36Sopenharmony_ci txgapk->fianl_offset[i][path] = offset_tmp[i]; 168962306a36Sopenharmony_ci } 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci v = txgapk->rf3f_bp[band][i][path]; 169262306a36Sopenharmony_ci if (_rtw8822c_txgapk_gain_valid(rtwdev, v)) { 169362306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 169462306a36Sopenharmony_ci "[TXGAPK] tx_gain=0x%03X >= 0xCEX\n", 169562306a36Sopenharmony_ci txgapk->rf3f_bp[band][i][path]); 169662306a36Sopenharmony_ci } else { 169762306a36Sopenharmony_ci txgapk->rf3f_fs[path][i] = offset_tmp[i]; 169862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 169962306a36Sopenharmony_ci "[TXGAPK] offset %d %d\n", 170062306a36Sopenharmony_ci offset_tmp[i], i); 170162306a36Sopenharmony_ci } 170262306a36Sopenharmony_ci } 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x10000); 170562306a36Sopenharmony_ci for (i = 0; i < RF_GAIN_NUM; i++) { 170662306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 170762306a36Sopenharmony_ci RF_LUTWA, RFREG_MASK, tmp + i); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci tmp_3f = rtw8822c_txgapk_cal_gain(rtwdev, 171062306a36Sopenharmony_ci txgapk->rf3f_bp[band][i][path], 171162306a36Sopenharmony_ci offset_tmp[i]); 171262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_LUTWD0, 171362306a36Sopenharmony_ci BIT_GAIN_EXT | BIT_DATA_L, tmp_3f); 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 171662306a36Sopenharmony_ci "[TXGAPK] 0x33=0x%05X 0x3f=0x%04X\n", 171762306a36Sopenharmony_ci tmp + i, tmp_3f); 171862306a36Sopenharmony_ci } 171962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_LUTWE2, RFREG_MASK, 0x0); 172062306a36Sopenharmony_ci } 172162306a36Sopenharmony_ci} 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_cistatic void rtw8822c_txgapk_save_all_tx_gain_table(struct rtw_dev *rtwdev) 172462306a36Sopenharmony_ci{ 172562306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 172662306a36Sopenharmony_ci static const u32 three_wire[2] = {REG_3WIRE, REG_3WIRE2}; 172762306a36Sopenharmony_ci static const u8 ch_num[RF_BAND_MAX] = {1, 1, 36, 100, 149}; 172862306a36Sopenharmony_ci static const u8 band_num[RF_BAND_MAX] = {0x0, 0x0, 0x1, 0x3, 0x5}; 172962306a36Sopenharmony_ci static const u8 cck[RF_BAND_MAX] = {0x1, 0x0, 0x0, 0x0, 0x0}; 173062306a36Sopenharmony_ci u8 path, band, gain, rf0_idx; 173162306a36Sopenharmony_ci u32 rf18, v; 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci if (rtwdev->dm_info.dm_flags & BIT(RTW_DM_CAP_TXGAPK)) 173462306a36Sopenharmony_ci return; 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci if (txgapk->read_txgain == 1) { 173962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 174062306a36Sopenharmony_ci "[TXGAPK] Already Read txgapk->read_txgain return!!!\n"); 174162306a36Sopenharmony_ci rtw8822c_txgapk_write_gain_bb_table(rtwdev); 174262306a36Sopenharmony_ci return; 174362306a36Sopenharmony_ci } 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci for (band = 0; band < RF_BAND_MAX; band++) { 174662306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 174762306a36Sopenharmony_ci rf18 = rtw_read_rf(rtwdev, path, RF_CFGCH, RFREG_MASK); 174862306a36Sopenharmony_ci 174962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 175062306a36Sopenharmony_ci three_wire[path], BIT_3WIRE_EN, 0x0); 175162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 175262306a36Sopenharmony_ci RF_CFGCH, MASKBYTE0, ch_num[band]); 175362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 175462306a36Sopenharmony_ci RF_CFGCH, BIT_BAND, band_num[band]); 175562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 175662306a36Sopenharmony_ci RF_BW_TRXBB, BIT_DBG_CCK_CCA, cck[band]); 175762306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 175862306a36Sopenharmony_ci RF_BW_TRXBB, BIT_TX_CCK_IND, cck[band]); 175962306a36Sopenharmony_ci gain = 0; 176062306a36Sopenharmony_ci for (rf0_idx = 1; rf0_idx < 32; rf0_idx += 3) { 176162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, 176262306a36Sopenharmony_ci MASKBYTE0, rf0_idx); 176362306a36Sopenharmony_ci v = rtw_read_rf(rtwdev, path, 176462306a36Sopenharmony_ci RF_TX_RESULT, RFREG_MASK); 176562306a36Sopenharmony_ci txgapk->rf3f_bp[band][gain][path] = v & BIT_DATA_L; 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 176862306a36Sopenharmony_ci "[TXGAPK] 0x5f=0x%03X band=%d path=%d\n", 176962306a36Sopenharmony_ci txgapk->rf3f_bp[band][gain][path], 177062306a36Sopenharmony_ci band, path); 177162306a36Sopenharmony_ci gain++; 177262306a36Sopenharmony_ci } 177362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_CFGCH, RFREG_MASK, rf18); 177462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 177562306a36Sopenharmony_ci three_wire[path], BIT_3WIRE_EN, 0x3); 177662306a36Sopenharmony_ci } 177762306a36Sopenharmony_ci } 177862306a36Sopenharmony_ci rtw8822c_txgapk_write_gain_bb_table(rtwdev); 177962306a36Sopenharmony_ci txgapk->read_txgain = 1; 178062306a36Sopenharmony_ci} 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_cistatic void rtw8822c_txgapk(struct rtw_dev *rtwdev) 178362306a36Sopenharmony_ci{ 178462306a36Sopenharmony_ci static const u32 bb_reg[2] = {REG_TX_PTCL_CTRL, REG_TX_FIFO}; 178562306a36Sopenharmony_ci struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk; 178662306a36Sopenharmony_ci u32 bb_reg_backup[2]; 178762306a36Sopenharmony_ci u8 path; 178862306a36Sopenharmony_ci 178962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] ======>%s\n", __func__); 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci rtw8822c_txgapk_save_all_tx_gain_table(rtwdev); 179262306a36Sopenharmony_ci 179362306a36Sopenharmony_ci if (txgapk->read_txgain == 0) { 179462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 179562306a36Sopenharmony_ci "[TXGAPK] txgapk->read_txgain == 0 return!!!\n"); 179662306a36Sopenharmony_ci return; 179762306a36Sopenharmony_ci } 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci if (rtwdev->efuse.power_track_type >= 4 && 180062306a36Sopenharmony_ci rtwdev->efuse.power_track_type <= 7) { 180162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 180262306a36Sopenharmony_ci "[TXGAPK] Normal Mode in TSSI mode. return!!!\n"); 180362306a36Sopenharmony_ci return; 180462306a36Sopenharmony_ci } 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci rtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg, 180762306a36Sopenharmony_ci bb_reg_backup, ARRAY_SIZE(bb_reg)); 180862306a36Sopenharmony_ci rtw8822c_txgapk_tx_pause(rtwdev); 180962306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 181062306a36Sopenharmony_ci txgapk->channel = rtw_read_rf(rtwdev, path, 181162306a36Sopenharmony_ci RF_CFGCH, RFREG_MASK) & MASKBYTE0; 181262306a36Sopenharmony_ci rtw8822c_txgapk_bb_dpk(rtwdev, path); 181362306a36Sopenharmony_ci rtw8822c_txgapk_afe_dpk(rtwdev, path); 181462306a36Sopenharmony_ci rtw8822c_txgapk_calculate_offset(rtwdev, path); 181562306a36Sopenharmony_ci rtw8822c_txgapk_rf_restore(rtwdev, path); 181662306a36Sopenharmony_ci rtw8822c_txgapk_afe_dpk_restore(rtwdev, path); 181762306a36Sopenharmony_ci rtw8822c_txgapk_bb_dpk_restore(rtwdev, path); 181862306a36Sopenharmony_ci } 181962306a36Sopenharmony_ci rtw8822c_txgapk_write_tx_gain(rtwdev); 182062306a36Sopenharmony_ci rtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg, 182162306a36Sopenharmony_ci bb_reg_backup, ARRAY_SIZE(bb_reg)); 182262306a36Sopenharmony_ci} 182362306a36Sopenharmony_ci 182462306a36Sopenharmony_cistatic void rtw8822c_do_gapk(struct rtw_dev *rtwdev) 182562306a36Sopenharmony_ci{ 182662306a36Sopenharmony_ci struct rtw_dm_info *dm = &rtwdev->dm_info; 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci if (dm->dm_flags & BIT(RTW_DM_CAP_TXGAPK)) { 182962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[TXGAPK] feature disable!!!\n"); 183062306a36Sopenharmony_ci return; 183162306a36Sopenharmony_ci } 183262306a36Sopenharmony_ci rtw8822c_rfk_handshake(rtwdev, true); 183362306a36Sopenharmony_ci rtw8822c_txgapk(rtwdev); 183462306a36Sopenharmony_ci rtw8822c_rfk_handshake(rtwdev, false); 183562306a36Sopenharmony_ci} 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_cistatic void rtw8822c_rf_init(struct rtw_dev *rtwdev) 183862306a36Sopenharmony_ci{ 183962306a36Sopenharmony_ci rtw8822c_rf_dac_cal(rtwdev); 184062306a36Sopenharmony_ci rtw8822c_rf_x2_check(rtwdev); 184162306a36Sopenharmony_ci rtw8822c_thermal_trim(rtwdev); 184262306a36Sopenharmony_ci rtw8822c_power_trim(rtwdev); 184362306a36Sopenharmony_ci rtw8822c_pa_bias(rtwdev); 184462306a36Sopenharmony_ci} 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_cistatic void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev) 184762306a36Sopenharmony_ci{ 184862306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 184962306a36Sopenharmony_ci u8 path; 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) { 185262306a36Sopenharmony_ci dm_info->delta_power_index[path] = 0; 185362306a36Sopenharmony_ci ewma_thermal_init(&dm_info->avg_thermal[path]); 185462306a36Sopenharmony_ci dm_info->thermal_avg[path] = 0xff; 185562306a36Sopenharmony_ci } 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci dm_info->pwr_trk_triggered = false; 185862306a36Sopenharmony_ci dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 185962306a36Sopenharmony_ci dm_info->thermal_meter_lck = rtwdev->efuse.thermal_meter_k; 186062306a36Sopenharmony_ci} 186162306a36Sopenharmony_ci 186262306a36Sopenharmony_cistatic void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) 186362306a36Sopenharmony_ci{ 186462306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 186562306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 186662306a36Sopenharmony_ci u8 crystal_cap; 186762306a36Sopenharmony_ci u8 cck_gi_u_bnd_msb = 0; 186862306a36Sopenharmony_ci u8 cck_gi_u_bnd_lsb = 0; 186962306a36Sopenharmony_ci u8 cck_gi_l_bnd_msb = 0; 187062306a36Sopenharmony_ci u8 cck_gi_l_bnd_lsb = 0; 187162306a36Sopenharmony_ci bool is_tx2_path; 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci /* power on BB/RF domain */ 187462306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, 187562306a36Sopenharmony_ci BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); 187662306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_RF_CTRL, 187762306a36Sopenharmony_ci BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 187862306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN); 187962306a36Sopenharmony_ci 188062306a36Sopenharmony_ci /* disable low rate DPD */ 188162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DIS_DPD, DIS_DPD_MASK, DIS_DPD_RATEALL); 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci /* pre init before header files config */ 188462306a36Sopenharmony_ci rtw8822c_header_file_init(rtwdev, true); 188562306a36Sopenharmony_ci 188662306a36Sopenharmony_ci rtw_phy_load_tables(rtwdev); 188762306a36Sopenharmony_ci 188862306a36Sopenharmony_ci crystal_cap = rtwdev->efuse.crystal_cap & 0x7f; 188962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, 0xfffc00, 189062306a36Sopenharmony_ci crystal_cap | (crystal_cap << 7)); 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci /* post init after header files config */ 189362306a36Sopenharmony_ci rtw8822c_header_file_init(rtwdev, false); 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci is_tx2_path = false; 189662306a36Sopenharmony_ci rtw8822c_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx, 189762306a36Sopenharmony_ci is_tx2_path); 189862306a36Sopenharmony_ci rtw_phy_init(rtwdev); 189962306a36Sopenharmony_ci 190062306a36Sopenharmony_ci cck_gi_u_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc000); 190162306a36Sopenharmony_ci cck_gi_u_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1aa8, 0xf0000); 190262306a36Sopenharmony_ci cck_gi_l_bnd_msb = (u8)rtw_read32_mask(rtwdev, 0x1a98, 0xc0); 190362306a36Sopenharmony_ci cck_gi_l_bnd_lsb = (u8)rtw_read32_mask(rtwdev, 0x1a70, 0x0f000000); 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci dm_info->cck_gi_u_bnd = ((cck_gi_u_bnd_msb << 4) | (cck_gi_u_bnd_lsb)); 190662306a36Sopenharmony_ci dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb)); 190762306a36Sopenharmony_ci 190862306a36Sopenharmony_ci rtw8822c_rf_init(rtwdev); 190962306a36Sopenharmony_ci rtw8822c_pwrtrack_init(rtwdev); 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_ci rtw_bf_phy_init(rtwdev); 191262306a36Sopenharmony_ci} 191362306a36Sopenharmony_ci 191462306a36Sopenharmony_ci#define WLAN_TXQ_RPT_EN 0x1F 191562306a36Sopenharmony_ci#define WLAN_SLOT_TIME 0x09 191662306a36Sopenharmony_ci#define WLAN_PIFS_TIME 0x1C 191762306a36Sopenharmony_ci#define WLAN_SIFS_CCK_CONT_TX 0x0A 191862306a36Sopenharmony_ci#define WLAN_SIFS_OFDM_CONT_TX 0x0E 191962306a36Sopenharmony_ci#define WLAN_SIFS_CCK_TRX 0x0A 192062306a36Sopenharmony_ci#define WLAN_SIFS_OFDM_TRX 0x10 192162306a36Sopenharmony_ci#define WLAN_NAV_MAX 0xC8 192262306a36Sopenharmony_ci#define WLAN_RDG_NAV 0x05 192362306a36Sopenharmony_ci#define WLAN_TXOP_NAV 0x1B 192462306a36Sopenharmony_ci#define WLAN_CCK_RX_TSF 0x30 192562306a36Sopenharmony_ci#define WLAN_OFDM_RX_TSF 0x30 192662306a36Sopenharmony_ci#define WLAN_TBTT_PROHIBIT 0x04 /* unit : 32us */ 192762306a36Sopenharmony_ci#define WLAN_TBTT_HOLD_TIME 0x064 /* unit : 32us */ 192862306a36Sopenharmony_ci#define WLAN_DRV_EARLY_INT 0x04 192962306a36Sopenharmony_ci#define WLAN_BCN_CTRL_CLT0 0x10 193062306a36Sopenharmony_ci#define WLAN_BCN_DMA_TIME 0x02 193162306a36Sopenharmony_ci#define WLAN_BCN_MAX_ERR 0xFF 193262306a36Sopenharmony_ci#define WLAN_SIFS_CCK_DUR_TUNE 0x0A 193362306a36Sopenharmony_ci#define WLAN_SIFS_OFDM_DUR_TUNE 0x10 193462306a36Sopenharmony_ci#define WLAN_SIFS_CCK_CTX 0x0A 193562306a36Sopenharmony_ci#define WLAN_SIFS_CCK_IRX 0x0A 193662306a36Sopenharmony_ci#define WLAN_SIFS_OFDM_CTX 0x0E 193762306a36Sopenharmony_ci#define WLAN_SIFS_OFDM_IRX 0x0E 193862306a36Sopenharmony_ci#define WLAN_EIFS_DUR_TUNE 0x40 193962306a36Sopenharmony_ci#define WLAN_EDCA_VO_PARAM 0x002FA226 194062306a36Sopenharmony_ci#define WLAN_EDCA_VI_PARAM 0x005EA328 194162306a36Sopenharmony_ci#define WLAN_EDCA_BE_PARAM 0x005EA42B 194262306a36Sopenharmony_ci#define WLAN_EDCA_BK_PARAM 0x0000A44F 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_ci#define WLAN_RX_FILTER0 0xFFFFFFFF 194562306a36Sopenharmony_ci#define WLAN_RX_FILTER2 0xFFFF 194662306a36Sopenharmony_ci#define WLAN_RCR_CFG 0xE400220E 194762306a36Sopenharmony_ci#define WLAN_RXPKT_MAX_SZ 12288 194862306a36Sopenharmony_ci#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) 194962306a36Sopenharmony_ci 195062306a36Sopenharmony_ci#define WLAN_AMPDU_MAX_TIME 0x70 195162306a36Sopenharmony_ci#define WLAN_RTS_LEN_TH 0xFF 195262306a36Sopenharmony_ci#define WLAN_RTS_TX_TIME_TH 0x08 195362306a36Sopenharmony_ci#define WLAN_MAX_AGG_PKT_LIMIT 0x3f 195462306a36Sopenharmony_ci#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x3f 195562306a36Sopenharmony_ci#define WLAN_PRE_TXCNT_TIME_TH 0x1E0 195662306a36Sopenharmony_ci#define FAST_EDCA_VO_TH 0x06 195762306a36Sopenharmony_ci#define FAST_EDCA_VI_TH 0x06 195862306a36Sopenharmony_ci#define FAST_EDCA_BE_TH 0x06 195962306a36Sopenharmony_ci#define FAST_EDCA_BK_TH 0x06 196062306a36Sopenharmony_ci#define WLAN_BAR_RETRY_LIMIT 0x01 196162306a36Sopenharmony_ci#define WLAN_BAR_ACK_TYPE 0x05 196262306a36Sopenharmony_ci#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 196362306a36Sopenharmony_ci#define WLAN_RESP_TXRATE 0x84 196462306a36Sopenharmony_ci#define WLAN_ACK_TO 0x21 196562306a36Sopenharmony_ci#define WLAN_ACK_TO_CCK 0x6A 196662306a36Sopenharmony_ci#define WLAN_DATA_RATE_FB_CNT_1_4 0x01000000 196762306a36Sopenharmony_ci#define WLAN_DATA_RATE_FB_CNT_5_8 0x08070504 196862306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_CNT_5_8 0x08070504 196962306a36Sopenharmony_ci#define WLAN_DATA_RATE_FB_RATE0 0xFE01F010 197062306a36Sopenharmony_ci#define WLAN_DATA_RATE_FB_RATE0_H 0x40000000 197162306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE1 0x003FF010 197262306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE1_H 0x40000000 197362306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE4 0x0600F010 197462306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE4_H 0x400003E0 197562306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE5 0x0600F015 197662306a36Sopenharmony_ci#define WLAN_RTS_RATE_FB_RATE5_H 0x000000E0 197762306a36Sopenharmony_ci#define WLAN_MULTI_ADDR 0xFFFFFFFF 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_ci#define WLAN_TX_FUNC_CFG1 0x30 198062306a36Sopenharmony_ci#define WLAN_TX_FUNC_CFG2 0x30 198162306a36Sopenharmony_ci#define WLAN_MAC_OPT_NORM_FUNC1 0x98 198262306a36Sopenharmony_ci#define WLAN_MAC_OPT_LB_FUNC1 0x80 198362306a36Sopenharmony_ci#define WLAN_MAC_OPT_FUNC2 0xb0810041 198462306a36Sopenharmony_ci#define WLAN_MAC_INT_MIG_CFG 0x33330000 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ 198762306a36Sopenharmony_ci (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ 198862306a36Sopenharmony_ci (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ 198962306a36Sopenharmony_ci (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci#define WLAN_SIFS_DUR_TUNE (WLAN_SIFS_CCK_DUR_TUNE | \ 199262306a36Sopenharmony_ci (WLAN_SIFS_OFDM_DUR_TUNE << 8)) 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ 199562306a36Sopenharmony_ci (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) 199862306a36Sopenharmony_ci#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) 199962306a36Sopenharmony_ci 200062306a36Sopenharmony_ci#define MAC_CLK_SPEED 80 /* 80M */ 200162306a36Sopenharmony_ci#define EFUSE_PCB_INFO_OFFSET 0xCA 200262306a36Sopenharmony_ci 200362306a36Sopenharmony_cistatic int rtw8822c_mac_init(struct rtw_dev *rtwdev) 200462306a36Sopenharmony_ci{ 200562306a36Sopenharmony_ci u8 value8; 200662306a36Sopenharmony_ci u16 value16; 200762306a36Sopenharmony_ci u32 value32; 200862306a36Sopenharmony_ci u16 pre_txcnt; 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci /* txq control */ 201162306a36Sopenharmony_ci value8 = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL); 201262306a36Sopenharmony_ci value8 |= (BIT(7) & ~BIT(1) & ~BIT(2)); 201362306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, value8); 201462306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 201562306a36Sopenharmony_ci /* sifs control */ 201662306a36Sopenharmony_ci rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SIFS_DUR_TUNE); 201762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); 201862306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RESP_SIFS_CCK, 201962306a36Sopenharmony_ci WLAN_SIFS_CCK_CTX | WLAN_SIFS_CCK_IRX << 8); 202062306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RESP_SIFS_OFDM, 202162306a36Sopenharmony_ci WLAN_SIFS_OFDM_CTX | WLAN_SIFS_OFDM_IRX << 8); 202262306a36Sopenharmony_ci /* rate fallback control */ 202362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DARFRC, WLAN_DATA_RATE_FB_CNT_1_4); 202462306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DARFRCH, WLAN_DATA_RATE_FB_CNT_5_8); 202562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RARFRCH, WLAN_RTS_RATE_FB_CNT_5_8); 202662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFR0, WLAN_DATA_RATE_FB_RATE0); 202762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFRH0, WLAN_DATA_RATE_FB_RATE0_H); 202862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFR1_V1, WLAN_RTS_RATE_FB_RATE1); 202962306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFRH1_V1, WLAN_RTS_RATE_FB_RATE1_H); 203062306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFR4, WLAN_RTS_RATE_FB_RATE4); 203162306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFRH4, WLAN_RTS_RATE_FB_RATE4_H); 203262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFR5, WLAN_RTS_RATE_FB_RATE5); 203362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_ARFRH5, WLAN_RTS_RATE_FB_RATE5_H); 203462306a36Sopenharmony_ci /* protocol configuration */ 203562306a36Sopenharmony_ci rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); 203662306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); 203762306a36Sopenharmony_ci pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; 203862306a36Sopenharmony_ci rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); 203962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); 204062306a36Sopenharmony_ci value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | 204162306a36Sopenharmony_ci (WLAN_MAX_AGG_PKT_LIMIT << 16) | 204262306a36Sopenharmony_ci (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); 204362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); 204462306a36Sopenharmony_ci rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, 204562306a36Sopenharmony_ci WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); 204662306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); 204762306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); 204862306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); 204962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); 205062306a36Sopenharmony_ci /* close BA parser */ 205162306a36Sopenharmony_ci rtw_write8_clr(rtwdev, REG_LIFETIME_EN, BIT_BA_PARSER_EN); 205262306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_RRSR, BITS_RRSR_RSC); 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci /* EDCA configuration */ 205562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_EDCA_VO_PARAM, WLAN_EDCA_VO_PARAM); 205662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_EDCA_VI_PARAM, WLAN_EDCA_VI_PARAM); 205762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_EDCA_BE_PARAM, WLAN_EDCA_BE_PARAM); 205862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_EDCA_BK_PARAM, WLAN_EDCA_BK_PARAM); 205962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); 206062306a36Sopenharmony_ci rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); 206162306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_RD_CTRL + 1, 206262306a36Sopenharmony_ci (BIT_DIS_TXOP_CFE | BIT_DIS_LSIG_CFE | 206362306a36Sopenharmony_ci BIT_DIS_STBC_CFE) >> 8); 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci /* MAC clock configuration */ 206662306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BIT_MAC_CLK_SEL); 206762306a36Sopenharmony_ci rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED); 206862306a36Sopenharmony_ci rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED); 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_MISC_CTRL, 207162306a36Sopenharmony_ci BIT_EN_FREE_CNT | BIT_DIS_SECOND_CCA); 207262306a36Sopenharmony_ci rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); 207362306a36Sopenharmony_ci rtw_write16(rtwdev, REG_TXPAUSE, 0x0000); 207462306a36Sopenharmony_ci rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); 207562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); 207662306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); 207762306a36Sopenharmony_ci /* Set beacon cotnrol - enable TSF and other related functions */ 207862306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 207962306a36Sopenharmony_ci /* Set send beacon related registers */ 208062306a36Sopenharmony_ci rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); 208162306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); 208262306a36Sopenharmony_ci rtw_write8(rtwdev, REG_BCN_CTRL_CLINT0, WLAN_BCN_CTRL_CLT0); 208362306a36Sopenharmony_ci rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); 208462306a36Sopenharmony_ci rtw_write8(rtwdev, REG_BCN_MAX_ERR, WLAN_BCN_MAX_ERR); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci /* WMAC configuration */ 208762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_MAR, WLAN_MULTI_ADDR); 208862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_MAR + 4, WLAN_MULTI_ADDR); 208962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_BBPSF_CTRL + 2, WLAN_RESP_TXRATE); 209062306a36Sopenharmony_ci rtw_write8(rtwdev, REG_ACKTO, WLAN_ACK_TO); 209162306a36Sopenharmony_ci rtw_write8(rtwdev, REG_ACKTO_CCK, WLAN_ACK_TO_CCK); 209262306a36Sopenharmony_ci rtw_write16(rtwdev, REG_EIFS, WLAN_EIFS_DUR_TUNE); 209362306a36Sopenharmony_ci rtw_write8(rtwdev, REG_NAV_CTRL + 2, WLAN_NAV_MAX); 209462306a36Sopenharmony_ci rtw_write8(rtwdev, REG_WMAC_TRXPTCL_CTL_H + 2, WLAN_BAR_ACK_TYPE); 209562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 209662306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 209762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 209862306a36Sopenharmony_ci rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); 209962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); 210062306a36Sopenharmony_ci rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); 210162306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_GENERAL_OPTION, BIT_DUMMY_FCS_READY_MASK_EN); 210262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); 210362306a36Sopenharmony_ci rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION_1, WLAN_MAC_OPT_NORM_FUNC1); 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci /* init low power */ 210662306a36Sopenharmony_ci value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL + 2) & 0xF00F; 210762306a36Sopenharmony_ci value16 |= (BIT_RXGCK_VHT_FIFOTHR(1) | BIT_RXGCK_HT_FIFOTHR(1) | 210862306a36Sopenharmony_ci BIT_RXGCK_OFDM_FIFOTHR(1) | BIT_RXGCK_CCK_FIFOTHR(1)) >> 16; 210962306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RXPSF_CTRL + 2, value16); 211062306a36Sopenharmony_ci value16 = 0; 211162306a36Sopenharmony_ci value16 = BIT_SET_RXPSF_PKTLENTHR(value16, 1); 211262306a36Sopenharmony_ci value16 |= BIT_RXPSF_CTRLEN | BIT_RXPSF_VHTCHKEN | BIT_RXPSF_HTCHKEN 211362306a36Sopenharmony_ci | BIT_RXPSF_OFDMCHKEN | BIT_RXPSF_CCKCHKEN 211462306a36Sopenharmony_ci | BIT_RXPSF_OFDMRST; 211562306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); 211662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXPSF_TYPE_CTRL, 0xFFFFFFFF); 211762306a36Sopenharmony_ci /* rx ignore configuration */ 211862306a36Sopenharmony_ci value16 = rtw_read16(rtwdev, REG_RXPSF_CTRL); 211962306a36Sopenharmony_ci value16 &= ~(BIT_RXPSF_MHCHKEN | BIT_RXPSF_CCKRST | 212062306a36Sopenharmony_ci BIT_RXPSF_CONT_ERRCHKEN); 212162306a36Sopenharmony_ci value16 = BIT_SET_RXPSF_ERRTHR(value16, 0x07); 212262306a36Sopenharmony_ci rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); 212362306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, 212462306a36Sopenharmony_ci BIT_DIS_CHK_VHTSIGB_CRC); 212562306a36Sopenharmony_ci 212662306a36Sopenharmony_ci /* Interrupt migration configuration */ 212762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG); 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_ci return 0; 213062306a36Sopenharmony_ci} 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci#define FWCD_SIZE_REG_8822C 0x2000 213362306a36Sopenharmony_ci#define FWCD_SIZE_DMEM_8822C 0x10000 213462306a36Sopenharmony_ci#define FWCD_SIZE_IMEM_8822C 0x10000 213562306a36Sopenharmony_ci#define FWCD_SIZE_EMEM_8822C 0x20000 213662306a36Sopenharmony_ci#define FWCD_SIZE_ROM_8822C 0x10000 213762306a36Sopenharmony_ci 213862306a36Sopenharmony_cistatic const u32 __fwcd_segs_8822c[] = { 213962306a36Sopenharmony_ci FWCD_SIZE_REG_8822C, 214062306a36Sopenharmony_ci FWCD_SIZE_DMEM_8822C, 214162306a36Sopenharmony_ci FWCD_SIZE_IMEM_8822C, 214262306a36Sopenharmony_ci FWCD_SIZE_EMEM_8822C, 214362306a36Sopenharmony_ci FWCD_SIZE_ROM_8822C, 214462306a36Sopenharmony_ci}; 214562306a36Sopenharmony_ci 214662306a36Sopenharmony_cistatic const struct rtw_fwcd_segs rtw8822c_fwcd_segs = { 214762306a36Sopenharmony_ci .segs = __fwcd_segs_8822c, 214862306a36Sopenharmony_ci .num = ARRAY_SIZE(__fwcd_segs_8822c), 214962306a36Sopenharmony_ci}; 215062306a36Sopenharmony_ci 215162306a36Sopenharmony_cistatic int rtw8822c_dump_fw_crash(struct rtw_dev *rtwdev) 215262306a36Sopenharmony_ci{ 215362306a36Sopenharmony_ci#define __dump_fw_8822c(_dev, _mem) \ 215462306a36Sopenharmony_ci rtw_dump_fw(_dev, OCPBASE_ ## _mem ## _88XX, \ 215562306a36Sopenharmony_ci FWCD_SIZE_ ## _mem ## _8822C, RTW_FWCD_ ## _mem) 215662306a36Sopenharmony_ci int ret; 215762306a36Sopenharmony_ci 215862306a36Sopenharmony_ci ret = rtw_dump_reg(rtwdev, 0x0, FWCD_SIZE_REG_8822C); 215962306a36Sopenharmony_ci if (ret) 216062306a36Sopenharmony_ci return ret; 216162306a36Sopenharmony_ci ret = __dump_fw_8822c(rtwdev, DMEM); 216262306a36Sopenharmony_ci if (ret) 216362306a36Sopenharmony_ci return ret; 216462306a36Sopenharmony_ci ret = __dump_fw_8822c(rtwdev, IMEM); 216562306a36Sopenharmony_ci if (ret) 216662306a36Sopenharmony_ci return ret; 216762306a36Sopenharmony_ci ret = __dump_fw_8822c(rtwdev, EMEM); 216862306a36Sopenharmony_ci if (ret) 216962306a36Sopenharmony_ci return ret; 217062306a36Sopenharmony_ci ret = __dump_fw_8822c(rtwdev, ROM); 217162306a36Sopenharmony_ci if (ret) 217262306a36Sopenharmony_ci return ret; 217362306a36Sopenharmony_ci 217462306a36Sopenharmony_ci return 0; 217562306a36Sopenharmony_ci 217662306a36Sopenharmony_ci#undef __dump_fw_8822c 217762306a36Sopenharmony_ci} 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_cistatic void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable) 218062306a36Sopenharmony_ci{ 218162306a36Sopenharmony_ci if (enable) { 218262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x1); 218362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANAPAR_A, BIT_ANAPAR_UPDATE, 0x1); 218462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANAPAR_B, BIT_ANAPAR_UPDATE, 0x1); 218562306a36Sopenharmony_ci } else { 218662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x0); 218762306a36Sopenharmony_ci } 218862306a36Sopenharmony_ci} 218962306a36Sopenharmony_ci 219062306a36Sopenharmony_cistatic void rtw8822c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 219162306a36Sopenharmony_ci{ 219262306a36Sopenharmony_ci#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) 219362306a36Sopenharmony_ci#define RF18_BAND_2G (0) 219462306a36Sopenharmony_ci#define RF18_BAND_5G (BIT(16) | BIT(8)) 219562306a36Sopenharmony_ci#define RF18_CHANNEL_MASK (MASKBYTE0) 219662306a36Sopenharmony_ci#define RF18_RFSI_MASK (BIT(18) | BIT(17)) 219762306a36Sopenharmony_ci#define RF18_RFSI_GE_CH80 (BIT(17)) 219862306a36Sopenharmony_ci#define RF18_RFSI_GT_CH140 (BIT(18)) 219962306a36Sopenharmony_ci#define RF18_BW_MASK (BIT(13) | BIT(12)) 220062306a36Sopenharmony_ci#define RF18_BW_20M (BIT(13) | BIT(12)) 220162306a36Sopenharmony_ci#define RF18_BW_40M (BIT(13)) 220262306a36Sopenharmony_ci#define RF18_BW_80M (BIT(12)) 220362306a36Sopenharmony_ci 220462306a36Sopenharmony_ci u32 rf_reg18 = 0; 220562306a36Sopenharmony_ci u32 rf_rxbb = 0; 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ci rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); 220862306a36Sopenharmony_ci 220962306a36Sopenharmony_ci rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | 221062306a36Sopenharmony_ci RF18_BW_MASK); 221162306a36Sopenharmony_ci 221262306a36Sopenharmony_ci rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); 221362306a36Sopenharmony_ci rf_reg18 |= (channel & RF18_CHANNEL_MASK); 221462306a36Sopenharmony_ci if (IS_CH_5G_BAND_4(channel)) 221562306a36Sopenharmony_ci rf_reg18 |= RF18_RFSI_GT_CH140; 221662306a36Sopenharmony_ci else if (IS_CH_5G_BAND_3(channel)) 221762306a36Sopenharmony_ci rf_reg18 |= RF18_RFSI_GE_CH80; 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci switch (bw) { 222062306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_5: 222162306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_10: 222262306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_20: 222362306a36Sopenharmony_ci default: 222462306a36Sopenharmony_ci rf_reg18 |= RF18_BW_20M; 222562306a36Sopenharmony_ci rf_rxbb = 0x18; 222662306a36Sopenharmony_ci break; 222762306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_40: 222862306a36Sopenharmony_ci /* RF bandwidth */ 222962306a36Sopenharmony_ci rf_reg18 |= RF18_BW_40M; 223062306a36Sopenharmony_ci rf_rxbb = 0x10; 223162306a36Sopenharmony_ci break; 223262306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_80: 223362306a36Sopenharmony_ci rf_reg18 |= RF18_BW_80M; 223462306a36Sopenharmony_ci rf_rxbb = 0x8; 223562306a36Sopenharmony_ci break; 223662306a36Sopenharmony_ci } 223762306a36Sopenharmony_ci 223862306a36Sopenharmony_ci rtw8822c_rstb_3wire(rtwdev, false); 223962306a36Sopenharmony_ci 224062306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x01); 224162306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, 0x1f, 0x12); 224262306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, 0xfffff, rf_rxbb); 224362306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x00); 224462306a36Sopenharmony_ci 224562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x01); 224662306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWA, 0x1f, 0x12); 224762306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWD0, 0xfffff, rf_rxbb); 224862306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE2, 0x04, 0x00); 224962306a36Sopenharmony_ci 225062306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_reg18); 225162306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_reg18); 225262306a36Sopenharmony_ci 225362306a36Sopenharmony_ci rtw8822c_rstb_3wire(rtwdev, true); 225462306a36Sopenharmony_ci} 225562306a36Sopenharmony_ci 225662306a36Sopenharmony_cistatic void rtw8822c_toggle_igi(struct rtw_dev *rtwdev) 225762306a36Sopenharmony_ci{ 225862306a36Sopenharmony_ci u32 igi; 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_ci igi = rtw_read32_mask(rtwdev, REG_RXIGI, 0x7f); 226162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi - 2); 226262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi - 2); 226362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f, igi); 226462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXIGI, 0x7f00, igi); 226562306a36Sopenharmony_ci} 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_cistatic void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, 226862306a36Sopenharmony_ci u8 primary_ch_idx) 226962306a36Sopenharmony_ci{ 227062306a36Sopenharmony_ci if (IS_CH_2G_BAND(channel)) { 227162306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); 227262306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_TXF4, BIT(20)); 227362306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 227462306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); 227562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0xF); 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_ci switch (bw) { 227862306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_20: 227962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, 228062306a36Sopenharmony_ci 0x5); 228162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, 228262306a36Sopenharmony_ci 0x5); 228362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 228462306a36Sopenharmony_ci 0x6); 228562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 228662306a36Sopenharmony_ci 0x6); 228762306a36Sopenharmony_ci break; 228862306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_40: 228962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, 229062306a36Sopenharmony_ci 0x4); 229162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, 229262306a36Sopenharmony_ci 0x4); 229362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 229462306a36Sopenharmony_ci 0x0); 229562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 229662306a36Sopenharmony_ci 0x0); 229762306a36Sopenharmony_ci break; 229862306a36Sopenharmony_ci } 229962306a36Sopenharmony_ci if (channel == 13 || channel == 14) 230062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x969); 230162306a36Sopenharmony_ci else if (channel == 11 || channel == 12) 230262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x96a); 230362306a36Sopenharmony_ci else 230462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x9aa); 230562306a36Sopenharmony_ci if (channel == 14) { 230662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x3da0); 230762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, 230862306a36Sopenharmony_ci 0x4962c931); 230962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x6aa3); 231062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xaa7b); 231162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xf3d7); 231262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 0x0); 231362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, 231462306a36Sopenharmony_ci 0xff012455); 231562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 0xffff); 231662306a36Sopenharmony_ci } else { 231762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF0, MASKHWORD, 0x5284); 231862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF1, MASKDWORD, 231962306a36Sopenharmony_ci 0x3e18fec8); 232062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF2, MASKLWORD, 0x0a88); 232162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF3, MASKHWORD, 0xacc4); 232262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF4, MASKLWORD, 0xc8b2); 232362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF5, MASKDWORD, 232462306a36Sopenharmony_ci 0x00faf0de); 232562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF6, MASKDWORD, 232662306a36Sopenharmony_ci 0x00122344); 232762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXF7, MASKDWORD, 232862306a36Sopenharmony_ci 0x0fffffff); 232962306a36Sopenharmony_ci } 233062306a36Sopenharmony_ci if (channel == 13) 233162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); 233262306a36Sopenharmony_ci else 233362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x1); 233462306a36Sopenharmony_ci } else if (IS_CH_5G_BAND(channel)) { 233562306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); 233662306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 233762306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); 233862306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_TXF4, BIT(20)); 233962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22); 234062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); 234162306a36Sopenharmony_ci if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { 234262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 234362306a36Sopenharmony_ci 0x1); 234462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 234562306a36Sopenharmony_ci 0x1); 234662306a36Sopenharmony_ci } else if (IS_CH_5G_BAND_3(channel)) { 234762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 234862306a36Sopenharmony_ci 0x2); 234962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 235062306a36Sopenharmony_ci 0x2); 235162306a36Sopenharmony_ci } else if (IS_CH_5G_BAND_4(channel)) { 235262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 235362306a36Sopenharmony_ci 0x3); 235462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 235562306a36Sopenharmony_ci 0x3); 235662306a36Sopenharmony_ci } 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci if (channel >= 36 && channel <= 51) 235962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x494); 236062306a36Sopenharmony_ci else if (channel >= 52 && channel <= 55) 236162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x493); 236262306a36Sopenharmony_ci else if (channel >= 56 && channel <= 111) 236362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x453); 236462306a36Sopenharmony_ci else if (channel >= 112 && channel <= 119) 236562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x452); 236662306a36Sopenharmony_ci else if (channel >= 120 && channel <= 172) 236762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x412); 236862306a36Sopenharmony_ci else if (channel >= 173 && channel <= 177) 236962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x411); 237062306a36Sopenharmony_ci } 237162306a36Sopenharmony_ci 237262306a36Sopenharmony_ci switch (bw) { 237362306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_20: 237462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x19B); 237562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 237662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x0); 237762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x7); 237862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x6); 237962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 238062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 238162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 238262306a36Sopenharmony_ci break; 238362306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_40: 238462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4), 238562306a36Sopenharmony_ci (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); 238662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x5); 238762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); 238862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, 238962306a36Sopenharmony_ci (primary_ch_idx | (primary_ch_idx << 4))); 239062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x1); 239162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 239262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); 239362306a36Sopenharmony_ci break; 239462306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_80: 239562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0xa); 239662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); 239762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, 239862306a36Sopenharmony_ci (primary_ch_idx | (primary_ch_idx << 4))); 239962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x6); 240062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); 240162306a36Sopenharmony_ci break; 240262306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_5: 240362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); 240462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 240562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x1); 240662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x4); 240762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x4); 240862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 240962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 241062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 241162306a36Sopenharmony_ci break; 241262306a36Sopenharmony_ci case RTW_CHANNEL_WIDTH_10: 241362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); 241462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x0); 241562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x2); 241662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x6); 241762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x5); 241862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); 241962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); 242062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); 242162306a36Sopenharmony_ci break; 242262306a36Sopenharmony_ci } 242362306a36Sopenharmony_ci} 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_cistatic void rtw8822c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, 242662306a36Sopenharmony_ci u8 primary_chan_idx) 242762306a36Sopenharmony_ci{ 242862306a36Sopenharmony_ci rtw8822c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 242962306a36Sopenharmony_ci rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); 243062306a36Sopenharmony_ci rtw8822c_set_channel_rf(rtwdev, channel, bw); 243162306a36Sopenharmony_ci rtw8822c_toggle_igi(rtwdev); 243262306a36Sopenharmony_ci} 243362306a36Sopenharmony_ci 243462306a36Sopenharmony_cistatic void rtw8822c_config_cck_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 243562306a36Sopenharmony_ci{ 243662306a36Sopenharmony_ci if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { 243762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x0); 243862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x0); 243962306a36Sopenharmony_ci } else if (rx_path == BB_PATH_AB) { 244062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, 0x00600000, 0x1); 244162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, 0x00060000, 0x1); 244262306a36Sopenharmony_ci } 244362306a36Sopenharmony_ci 244462306a36Sopenharmony_ci if (rx_path == BB_PATH_A) 244562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x0); 244662306a36Sopenharmony_ci else if (rx_path == BB_PATH_B) 244762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x5); 244862306a36Sopenharmony_ci else if (rx_path == BB_PATH_AB) 244962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0x0f000000, 0x1); 245062306a36Sopenharmony_ci} 245162306a36Sopenharmony_ci 245262306a36Sopenharmony_cistatic void rtw8822c_config_ofdm_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 245362306a36Sopenharmony_ci{ 245462306a36Sopenharmony_ci if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) { 245562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x0); 245662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x0); 245762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x0); 245862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x0); 245962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x0); 246062306a36Sopenharmony_ci } else if (rx_path == BB_PATH_AB) { 246162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x300, 0x1); 246262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXFNCTL, 0x600000, 0x1); 246362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_AGCSWSH, BIT(17), 0x1); 246462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTWTPD, BIT(20), 0x1); 246562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_MRCM, BIT(24), 0x1); 246662306a36Sopenharmony_ci } 246762306a36Sopenharmony_ci 246862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x824, 0x0f000000, rx_path); 246962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x824, 0x000f0000, rx_path); 247062306a36Sopenharmony_ci} 247162306a36Sopenharmony_ci 247262306a36Sopenharmony_cistatic void rtw8822c_config_rx_path(struct rtw_dev *rtwdev, u8 rx_path) 247362306a36Sopenharmony_ci{ 247462306a36Sopenharmony_ci rtw8822c_config_cck_rx_path(rtwdev, rx_path); 247562306a36Sopenharmony_ci rtw8822c_config_ofdm_rx_path(rtwdev, rx_path); 247662306a36Sopenharmony_ci} 247762306a36Sopenharmony_ci 247862306a36Sopenharmony_cistatic void rtw8822c_config_cck_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 247962306a36Sopenharmony_ci bool is_tx2_path) 248062306a36Sopenharmony_ci{ 248162306a36Sopenharmony_ci if (tx_path == BB_PATH_A) { 248262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); 248362306a36Sopenharmony_ci } else if (tx_path == BB_PATH_B) { 248462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x4); 248562306a36Sopenharmony_ci } else { 248662306a36Sopenharmony_ci if (is_tx2_path) 248762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0xc); 248862306a36Sopenharmony_ci else 248962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); 249062306a36Sopenharmony_ci } 249162306a36Sopenharmony_ci rtw8822c_bb_reset(rtwdev); 249262306a36Sopenharmony_ci} 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_cistatic void rtw8822c_config_ofdm_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 249562306a36Sopenharmony_ci enum rtw_bb_path tx_path_sel_1ss) 249662306a36Sopenharmony_ci{ 249762306a36Sopenharmony_ci if (tx_path == BB_PATH_A) { 249862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x11); 249962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); 250062306a36Sopenharmony_ci } else if (tx_path == BB_PATH_B) { 250162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x12); 250262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xff, 0x0); 250362306a36Sopenharmony_ci } else { 250462306a36Sopenharmony_ci if (tx_path_sel_1ss == BB_PATH_AB) { 250562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x33); 250662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0404); 250762306a36Sopenharmony_ci } else if (tx_path_sel_1ss == BB_PATH_B) { 250862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x32); 250962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); 251062306a36Sopenharmony_ci } else if (tx_path_sel_1ss == BB_PATH_A) { 251162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANTMAP0, 0xff, 0x31); 251262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_TXLGMAP, 0xffff, 0x0400); 251362306a36Sopenharmony_ci } 251462306a36Sopenharmony_ci } 251562306a36Sopenharmony_ci rtw8822c_bb_reset(rtwdev); 251662306a36Sopenharmony_ci} 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_cistatic void rtw8822c_config_tx_path(struct rtw_dev *rtwdev, u8 tx_path, 251962306a36Sopenharmony_ci enum rtw_bb_path tx_path_sel_1ss, 252062306a36Sopenharmony_ci enum rtw_bb_path tx_path_cck, 252162306a36Sopenharmony_ci bool is_tx2_path) 252262306a36Sopenharmony_ci{ 252362306a36Sopenharmony_ci rtw8822c_config_cck_tx_path(rtwdev, tx_path_cck, is_tx2_path); 252462306a36Sopenharmony_ci rtw8822c_config_ofdm_tx_path(rtwdev, tx_path, tx_path_sel_1ss); 252562306a36Sopenharmony_ci rtw8822c_bb_reset(rtwdev); 252662306a36Sopenharmony_ci} 252762306a36Sopenharmony_ci 252862306a36Sopenharmony_cistatic void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, 252962306a36Sopenharmony_ci u8 rx_path, bool is_tx2_path) 253062306a36Sopenharmony_ci{ 253162306a36Sopenharmony_ci if ((tx_path | rx_path) & BB_PATH_A) 253262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x33312); 253362306a36Sopenharmony_ci else 253462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ORITXCODE, MASK20BITS, 0x11111); 253562306a36Sopenharmony_ci if ((tx_path | rx_path) & BB_PATH_B) 253662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x33312); 253762306a36Sopenharmony_ci else 253862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ORITXCODE2, MASK20BITS, 0x11111); 253962306a36Sopenharmony_ci 254062306a36Sopenharmony_ci rtw8822c_config_rx_path(rtwdev, rx_path); 254162306a36Sopenharmony_ci rtw8822c_config_tx_path(rtwdev, tx_path, BB_PATH_A, BB_PATH_A, 254262306a36Sopenharmony_ci is_tx2_path); 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_ci rtw8822c_toggle_igi(rtwdev); 254562306a36Sopenharmony_ci} 254662306a36Sopenharmony_ci 254762306a36Sopenharmony_cistatic void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, 254862306a36Sopenharmony_ci struct rtw_rx_pkt_stat *pkt_stat) 254962306a36Sopenharmony_ci{ 255062306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 255162306a36Sopenharmony_ci u8 l_bnd, u_bnd; 255262306a36Sopenharmony_ci u8 gain_a, gain_b; 255362306a36Sopenharmony_ci s8 rx_power[RTW_RF_PATH_MAX]; 255462306a36Sopenharmony_ci s8 min_rx_power = -120; 255562306a36Sopenharmony_ci u8 rssi; 255662306a36Sopenharmony_ci u8 channel; 255762306a36Sopenharmony_ci int path; 255862306a36Sopenharmony_ci 255962306a36Sopenharmony_ci rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status); 256062306a36Sopenharmony_ci rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status); 256162306a36Sopenharmony_ci l_bnd = dm_info->cck_gi_l_bnd; 256262306a36Sopenharmony_ci u_bnd = dm_info->cck_gi_u_bnd; 256362306a36Sopenharmony_ci gain_a = GET_PHY_STAT_P0_GAIN_A(phy_status); 256462306a36Sopenharmony_ci gain_b = GET_PHY_STAT_P0_GAIN_B(phy_status); 256562306a36Sopenharmony_ci if (gain_a < l_bnd) 256662306a36Sopenharmony_ci rx_power[RF_PATH_A] += (l_bnd - gain_a) << 1; 256762306a36Sopenharmony_ci else if (gain_a > u_bnd) 256862306a36Sopenharmony_ci rx_power[RF_PATH_A] -= (gain_a - u_bnd) << 1; 256962306a36Sopenharmony_ci if (gain_b < l_bnd) 257062306a36Sopenharmony_ci rx_power[RF_PATH_B] += (l_bnd - gain_b) << 1; 257162306a36Sopenharmony_ci else if (gain_b > u_bnd) 257262306a36Sopenharmony_ci rx_power[RF_PATH_B] -= (gain_b - u_bnd) << 1; 257362306a36Sopenharmony_ci 257462306a36Sopenharmony_ci rx_power[RF_PATH_A] -= 110; 257562306a36Sopenharmony_ci rx_power[RF_PATH_B] -= 110; 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_ci channel = GET_PHY_STAT_P0_CHANNEL(phy_status); 257862306a36Sopenharmony_ci if (channel == 0) 257962306a36Sopenharmony_ci channel = rtwdev->hal.current_channel; 258062306a36Sopenharmony_ci rtw_set_rx_freq_band(pkt_stat, channel); 258162306a36Sopenharmony_ci 258262306a36Sopenharmony_ci pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; 258362306a36Sopenharmony_ci pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; 258462306a36Sopenharmony_ci 258562306a36Sopenharmony_ci for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 258662306a36Sopenharmony_ci rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 258762306a36Sopenharmony_ci dm_info->rssi[path] = rssi; 258862306a36Sopenharmony_ci } 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 259162306a36Sopenharmony_ci pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 259262306a36Sopenharmony_ci pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 259362306a36Sopenharmony_ci min_rx_power); 259462306a36Sopenharmony_ci} 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_cistatic void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 259762306a36Sopenharmony_ci struct rtw_rx_pkt_stat *pkt_stat) 259862306a36Sopenharmony_ci{ 259962306a36Sopenharmony_ci struct rtw_path_div *p_div = &rtwdev->dm_path_div; 260062306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 260162306a36Sopenharmony_ci u8 rxsc, bw; 260262306a36Sopenharmony_ci s8 min_rx_power = -120; 260362306a36Sopenharmony_ci s8 rx_evm; 260462306a36Sopenharmony_ci u8 evm_dbm = 0; 260562306a36Sopenharmony_ci u8 rssi; 260662306a36Sopenharmony_ci int path; 260762306a36Sopenharmony_ci u8 channel; 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 261062306a36Sopenharmony_ci rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); 261162306a36Sopenharmony_ci else 261262306a36Sopenharmony_ci rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); 261362306a36Sopenharmony_ci 261462306a36Sopenharmony_ci if (rxsc >= 9 && rxsc <= 12) 261562306a36Sopenharmony_ci bw = RTW_CHANNEL_WIDTH_40; 261662306a36Sopenharmony_ci else if (rxsc >= 13) 261762306a36Sopenharmony_ci bw = RTW_CHANNEL_WIDTH_80; 261862306a36Sopenharmony_ci else 261962306a36Sopenharmony_ci bw = RTW_CHANNEL_WIDTH_20; 262062306a36Sopenharmony_ci 262162306a36Sopenharmony_ci channel = GET_PHY_STAT_P1_CHANNEL(phy_status); 262262306a36Sopenharmony_ci rtw_set_rx_freq_band(pkt_stat, channel); 262362306a36Sopenharmony_ci 262462306a36Sopenharmony_ci pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; 262562306a36Sopenharmony_ci pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110; 262662306a36Sopenharmony_ci pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2); 262762306a36Sopenharmony_ci pkt_stat->bw = bw; 262862306a36Sopenharmony_ci pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], 262962306a36Sopenharmony_ci pkt_stat->rx_power[RF_PATH_B], 263062306a36Sopenharmony_ci min_rx_power); 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci dm_info->curr_rx_rate = pkt_stat->rate; 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); 263562306a36Sopenharmony_ci pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); 263662306a36Sopenharmony_ci 263762306a36Sopenharmony_ci pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); 263862306a36Sopenharmony_ci pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); 263962306a36Sopenharmony_ci 264062306a36Sopenharmony_ci pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); 264162306a36Sopenharmony_ci pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); 264262306a36Sopenharmony_ci 264362306a36Sopenharmony_ci for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 264462306a36Sopenharmony_ci rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 264562306a36Sopenharmony_ci dm_info->rssi[path] = rssi; 264662306a36Sopenharmony_ci if (path == RF_PATH_A) { 264762306a36Sopenharmony_ci p_div->path_a_sum += rssi; 264862306a36Sopenharmony_ci p_div->path_a_cnt++; 264962306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 265062306a36Sopenharmony_ci p_div->path_b_sum += rssi; 265162306a36Sopenharmony_ci p_div->path_b_cnt++; 265262306a36Sopenharmony_ci } 265362306a36Sopenharmony_ci dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; 265462306a36Sopenharmony_ci dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; 265562306a36Sopenharmony_ci 265662306a36Sopenharmony_ci rx_evm = pkt_stat->rx_evm[path]; 265762306a36Sopenharmony_ci 265862306a36Sopenharmony_ci if (rx_evm < 0) { 265962306a36Sopenharmony_ci if (rx_evm == S8_MIN) 266062306a36Sopenharmony_ci evm_dbm = 0; 266162306a36Sopenharmony_ci else 266262306a36Sopenharmony_ci evm_dbm = ((u8)-rx_evm >> 1); 266362306a36Sopenharmony_ci } 266462306a36Sopenharmony_ci dm_info->rx_evm_dbm[path] = evm_dbm; 266562306a36Sopenharmony_ci } 266662306a36Sopenharmony_ci rtw_phy_parsing_cfo(rtwdev, pkt_stat); 266762306a36Sopenharmony_ci} 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_cistatic void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 267062306a36Sopenharmony_ci struct rtw_rx_pkt_stat *pkt_stat) 267162306a36Sopenharmony_ci{ 267262306a36Sopenharmony_ci u8 page; 267362306a36Sopenharmony_ci 267462306a36Sopenharmony_ci page = *phy_status & 0xf; 267562306a36Sopenharmony_ci 267662306a36Sopenharmony_ci switch (page) { 267762306a36Sopenharmony_ci case 0: 267862306a36Sopenharmony_ci query_phy_status_page0(rtwdev, phy_status, pkt_stat); 267962306a36Sopenharmony_ci break; 268062306a36Sopenharmony_ci case 1: 268162306a36Sopenharmony_ci query_phy_status_page1(rtwdev, phy_status, pkt_stat); 268262306a36Sopenharmony_ci break; 268362306a36Sopenharmony_ci default: 268462306a36Sopenharmony_ci rtw_warn(rtwdev, "unused phy status page (%d)\n", page); 268562306a36Sopenharmony_ci return; 268662306a36Sopenharmony_ci } 268762306a36Sopenharmony_ci} 268862306a36Sopenharmony_ci 268962306a36Sopenharmony_cistatic void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, 269062306a36Sopenharmony_ci struct rtw_rx_pkt_stat *pkt_stat, 269162306a36Sopenharmony_ci struct ieee80211_rx_status *rx_status) 269262306a36Sopenharmony_ci{ 269362306a36Sopenharmony_ci struct ieee80211_hdr *hdr; 269462306a36Sopenharmony_ci u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; 269562306a36Sopenharmony_ci u8 *phy_status = NULL; 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci memset(pkt_stat, 0, sizeof(*pkt_stat)); 269862306a36Sopenharmony_ci 269962306a36Sopenharmony_ci pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); 270062306a36Sopenharmony_ci pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); 270162306a36Sopenharmony_ci pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); 270262306a36Sopenharmony_ci pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && 270362306a36Sopenharmony_ci GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; 270462306a36Sopenharmony_ci pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); 270562306a36Sopenharmony_ci pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); 270662306a36Sopenharmony_ci pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); 270762306a36Sopenharmony_ci pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); 270862306a36Sopenharmony_ci pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); 270962306a36Sopenharmony_ci pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); 271062306a36Sopenharmony_ci pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); 271162306a36Sopenharmony_ci pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); 271262306a36Sopenharmony_ci 271362306a36Sopenharmony_ci /* drv_info_sz is in unit of 8-bytes */ 271462306a36Sopenharmony_ci pkt_stat->drv_info_sz *= 8; 271562306a36Sopenharmony_ci 271662306a36Sopenharmony_ci /* c2h cmd pkt's rx/phy status is not interested */ 271762306a36Sopenharmony_ci if (pkt_stat->is_c2h) 271862306a36Sopenharmony_ci return; 271962306a36Sopenharmony_ci 272062306a36Sopenharmony_ci hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + 272162306a36Sopenharmony_ci pkt_stat->drv_info_sz); 272262306a36Sopenharmony_ci pkt_stat->hdr = hdr; 272362306a36Sopenharmony_ci if (pkt_stat->phy_status) { 272462306a36Sopenharmony_ci phy_status = rx_desc + desc_sz + pkt_stat->shift; 272562306a36Sopenharmony_ci query_phy_status(rtwdev, phy_status, pkt_stat); 272662306a36Sopenharmony_ci } 272762306a36Sopenharmony_ci 272862306a36Sopenharmony_ci rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); 272962306a36Sopenharmony_ci} 273062306a36Sopenharmony_ci 273162306a36Sopenharmony_cistatic void 273262306a36Sopenharmony_cirtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, 273362306a36Sopenharmony_ci u8 *tx_pwr_ref_ofdm) 273462306a36Sopenharmony_ci{ 273562306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 273662306a36Sopenharmony_ci u32 txref_cck[2] = {0x18a0, 0x41a0}; 273762306a36Sopenharmony_ci u32 txref_ofdm[2] = {0x18e8, 0x41e8}; 273862306a36Sopenharmony_ci u8 path; 273962306a36Sopenharmony_ci 274062306a36Sopenharmony_ci for (path = 0; path < hal->rf_path_num; path++) { 274162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); 274262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, txref_cck[path], 0x7f0000, 274362306a36Sopenharmony_ci tx_pwr_ref_cck[path]); 274462306a36Sopenharmony_ci } 274562306a36Sopenharmony_ci for (path = 0; path < hal->rf_path_num; path++) { 274662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0); 274762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, txref_ofdm[path], 0x1fc00, 274862306a36Sopenharmony_ci tx_pwr_ref_ofdm[path]); 274962306a36Sopenharmony_ci } 275062306a36Sopenharmony_ci} 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_cistatic void rtw8822c_set_tx_power_diff(struct rtw_dev *rtwdev, u8 rate, 275362306a36Sopenharmony_ci s8 *diff_idx) 275462306a36Sopenharmony_ci{ 275562306a36Sopenharmony_ci u32 offset_txagc = 0x3a00; 275662306a36Sopenharmony_ci u8 rate_idx = rate & 0xfc; 275762306a36Sopenharmony_ci u8 pwr_idx[4]; 275862306a36Sopenharmony_ci u32 phy_pwr_idx; 275962306a36Sopenharmony_ci int i; 276062306a36Sopenharmony_ci 276162306a36Sopenharmony_ci for (i = 0; i < 4; i++) 276262306a36Sopenharmony_ci pwr_idx[i] = diff_idx[i] & 0x7f; 276362306a36Sopenharmony_ci 276462306a36Sopenharmony_ci phy_pwr_idx = pwr_idx[0] | 276562306a36Sopenharmony_ci (pwr_idx[1] << 8) | 276662306a36Sopenharmony_ci (pwr_idx[2] << 16) | 276762306a36Sopenharmony_ci (pwr_idx[3] << 24); 276862306a36Sopenharmony_ci 276962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1c90, BIT(15), 0x0); 277062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, offset_txagc + rate_idx, MASKDWORD, 277162306a36Sopenharmony_ci phy_pwr_idx); 277262306a36Sopenharmony_ci} 277362306a36Sopenharmony_ci 277462306a36Sopenharmony_cistatic void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) 277562306a36Sopenharmony_ci{ 277662306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 277762306a36Sopenharmony_ci u8 rs, rate, j; 277862306a36Sopenharmony_ci u8 pwr_ref_cck[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATE11M], 277962306a36Sopenharmony_ci hal->tx_pwr_tbl[RF_PATH_B][DESC_RATE11M]}; 278062306a36Sopenharmony_ci u8 pwr_ref_ofdm[2] = {hal->tx_pwr_tbl[RF_PATH_A][DESC_RATEMCS7], 278162306a36Sopenharmony_ci hal->tx_pwr_tbl[RF_PATH_B][DESC_RATEMCS7]}; 278262306a36Sopenharmony_ci s8 diff_a, diff_b; 278362306a36Sopenharmony_ci u8 pwr_a, pwr_b; 278462306a36Sopenharmony_ci s8 diff_idx[4]; 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_ci rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); 278762306a36Sopenharmony_ci for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { 278862306a36Sopenharmony_ci for (j = 0; j < rtw_rate_size[rs]; j++) { 278962306a36Sopenharmony_ci rate = rtw_rate_section[rs][j]; 279062306a36Sopenharmony_ci pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; 279162306a36Sopenharmony_ci pwr_b = hal->tx_pwr_tbl[RF_PATH_B][rate]; 279262306a36Sopenharmony_ci if (rs == 0) { 279362306a36Sopenharmony_ci diff_a = (s8)pwr_a - (s8)pwr_ref_cck[0]; 279462306a36Sopenharmony_ci diff_b = (s8)pwr_b - (s8)pwr_ref_cck[1]; 279562306a36Sopenharmony_ci } else { 279662306a36Sopenharmony_ci diff_a = (s8)pwr_a - (s8)pwr_ref_ofdm[0]; 279762306a36Sopenharmony_ci diff_b = (s8)pwr_b - (s8)pwr_ref_ofdm[1]; 279862306a36Sopenharmony_ci } 279962306a36Sopenharmony_ci diff_idx[rate % 4] = min(diff_a, diff_b); 280062306a36Sopenharmony_ci if (rate % 4 == 3) 280162306a36Sopenharmony_ci rtw8822c_set_tx_power_diff(rtwdev, rate - 3, 280262306a36Sopenharmony_ci diff_idx); 280362306a36Sopenharmony_ci } 280462306a36Sopenharmony_ci } 280562306a36Sopenharmony_ci} 280662306a36Sopenharmony_ci 280762306a36Sopenharmony_cistatic int rtw8822c_set_antenna(struct rtw_dev *rtwdev, 280862306a36Sopenharmony_ci u32 antenna_tx, 280962306a36Sopenharmony_ci u32 antenna_rx) 281062306a36Sopenharmony_ci{ 281162306a36Sopenharmony_ci struct rtw_hal *hal = &rtwdev->hal; 281262306a36Sopenharmony_ci 281362306a36Sopenharmony_ci switch (antenna_tx) { 281462306a36Sopenharmony_ci case BB_PATH_A: 281562306a36Sopenharmony_ci case BB_PATH_B: 281662306a36Sopenharmony_ci case BB_PATH_AB: 281762306a36Sopenharmony_ci break; 281862306a36Sopenharmony_ci default: 281962306a36Sopenharmony_ci rtw_warn(rtwdev, "unsupported tx path 0x%x\n", antenna_tx); 282062306a36Sopenharmony_ci return -EINVAL; 282162306a36Sopenharmony_ci } 282262306a36Sopenharmony_ci 282362306a36Sopenharmony_ci /* path B only is not available for RX */ 282462306a36Sopenharmony_ci switch (antenna_rx) { 282562306a36Sopenharmony_ci case BB_PATH_A: 282662306a36Sopenharmony_ci case BB_PATH_AB: 282762306a36Sopenharmony_ci break; 282862306a36Sopenharmony_ci default: 282962306a36Sopenharmony_ci rtw_warn(rtwdev, "unsupported rx path 0x%x\n", antenna_rx); 283062306a36Sopenharmony_ci return -EINVAL; 283162306a36Sopenharmony_ci } 283262306a36Sopenharmony_ci 283362306a36Sopenharmony_ci hal->antenna_tx = antenna_tx; 283462306a36Sopenharmony_ci hal->antenna_rx = antenna_rx; 283562306a36Sopenharmony_ci 283662306a36Sopenharmony_ci rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); 283762306a36Sopenharmony_ci 283862306a36Sopenharmony_ci return 0; 283962306a36Sopenharmony_ci} 284062306a36Sopenharmony_ci 284162306a36Sopenharmony_cistatic void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 284262306a36Sopenharmony_ci{ 284362306a36Sopenharmony_ci u8 ldo_pwr; 284462306a36Sopenharmony_ci 284562306a36Sopenharmony_ci ldo_pwr = rtw_read8(rtwdev, REG_ANAPARLDO_POW_MAC); 284662306a36Sopenharmony_ci ldo_pwr = enable ? ldo_pwr | BIT_LDOE25_PON : ldo_pwr & ~BIT_LDOE25_PON; 284762306a36Sopenharmony_ci rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr); 284862306a36Sopenharmony_ci} 284962306a36Sopenharmony_ci 285062306a36Sopenharmony_cistatic void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) 285162306a36Sopenharmony_ci{ 285262306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 285362306a36Sopenharmony_ci u32 cck_enable; 285462306a36Sopenharmony_ci u32 cck_fa_cnt; 285562306a36Sopenharmony_ci u32 crc32_cnt; 285662306a36Sopenharmony_ci u32 cca32_cnt; 285762306a36Sopenharmony_ci u32 ofdm_fa_cnt; 285862306a36Sopenharmony_ci u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; 285962306a36Sopenharmony_ci u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, 286062306a36Sopenharmony_ci fast_fsync, crc8_fail_vhta, mcs_fail_vht; 286162306a36Sopenharmony_ci 286262306a36Sopenharmony_ci cck_enable = rtw_read32(rtwdev, REG_ENCCK) & BIT_CCK_BLK_EN; 286362306a36Sopenharmony_ci cck_fa_cnt = rtw_read16(rtwdev, REG_CCK_FACNT); 286462306a36Sopenharmony_ci 286562306a36Sopenharmony_ci ofdm_fa_cnt1 = rtw_read32(rtwdev, REG_OFDM_FACNT1); 286662306a36Sopenharmony_ci ofdm_fa_cnt2 = rtw_read32(rtwdev, REG_OFDM_FACNT2); 286762306a36Sopenharmony_ci ofdm_fa_cnt3 = rtw_read32(rtwdev, REG_OFDM_FACNT3); 286862306a36Sopenharmony_ci ofdm_fa_cnt4 = rtw_read32(rtwdev, REG_OFDM_FACNT4); 286962306a36Sopenharmony_ci ofdm_fa_cnt5 = rtw_read32(rtwdev, REG_OFDM_FACNT5); 287062306a36Sopenharmony_ci 287162306a36Sopenharmony_ci parity_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt1); 287262306a36Sopenharmony_ci rate_illegal = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt2); 287362306a36Sopenharmony_ci crc8_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt2); 287462306a36Sopenharmony_ci crc8_fail_vhta = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt3); 287562306a36Sopenharmony_ci mcs_fail = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt4); 287662306a36Sopenharmony_ci mcs_fail_vht = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt4); 287762306a36Sopenharmony_ci fast_fsync = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt5); 287862306a36Sopenharmony_ci sb_search_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt5); 287962306a36Sopenharmony_ci 288062306a36Sopenharmony_ci ofdm_fa_cnt = parity_fail + rate_illegal + crc8_fail + crc8_fail_vhta + 288162306a36Sopenharmony_ci mcs_fail + mcs_fail_vht + fast_fsync + sb_search_fail; 288262306a36Sopenharmony_ci 288362306a36Sopenharmony_ci dm_info->cck_fa_cnt = cck_fa_cnt; 288462306a36Sopenharmony_ci dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 288562306a36Sopenharmony_ci dm_info->total_fa_cnt = ofdm_fa_cnt; 288662306a36Sopenharmony_ci dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0; 288762306a36Sopenharmony_ci 288862306a36Sopenharmony_ci crc32_cnt = rtw_read32(rtwdev, 0x2c04); 288962306a36Sopenharmony_ci dm_info->cck_ok_cnt = crc32_cnt & 0xffff; 289062306a36Sopenharmony_ci dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 289162306a36Sopenharmony_ci crc32_cnt = rtw_read32(rtwdev, 0x2c14); 289262306a36Sopenharmony_ci dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff; 289362306a36Sopenharmony_ci dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 289462306a36Sopenharmony_ci crc32_cnt = rtw_read32(rtwdev, 0x2c10); 289562306a36Sopenharmony_ci dm_info->ht_ok_cnt = crc32_cnt & 0xffff; 289662306a36Sopenharmony_ci dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 289762306a36Sopenharmony_ci crc32_cnt = rtw_read32(rtwdev, 0x2c0c); 289862306a36Sopenharmony_ci dm_info->vht_ok_cnt = crc32_cnt & 0xffff; 289962306a36Sopenharmony_ci dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 290062306a36Sopenharmony_ci 290162306a36Sopenharmony_ci cca32_cnt = rtw_read32(rtwdev, 0x2c08); 290262306a36Sopenharmony_ci dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); 290362306a36Sopenharmony_ci dm_info->cck_cca_cnt = cca32_cnt & 0xffff; 290462306a36Sopenharmony_ci dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 290562306a36Sopenharmony_ci if (cck_enable) 290662306a36Sopenharmony_ci dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 290762306a36Sopenharmony_ci 290862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0); 290962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2); 291062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0); 291162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 2); 291262306a36Sopenharmony_ci 291362306a36Sopenharmony_ci /* disable rx clk gating to reset counters */ 291462306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); 291562306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); 291662306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); 291762306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); 291862306a36Sopenharmony_ci} 291962306a36Sopenharmony_ci 292062306a36Sopenharmony_cistatic void rtw8822c_do_lck(struct rtw_dev *rtwdev) 292162306a36Sopenharmony_ci{ 292262306a36Sopenharmony_ci u32 val; 292362306a36Sopenharmony_ci 292462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_CTRL, RFREG_MASK, 0x80010); 292562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0FA); 292662306a36Sopenharmony_ci fsleep(1); 292762306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_AAC_CTRL, RFREG_MASK, 0x80000); 292862306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_AAC, RFREG_MASK, 0x80001); 292962306a36Sopenharmony_ci read_poll_timeout(rtw_read_rf, val, val != 0x1, 1000, 100000, 293062306a36Sopenharmony_ci true, rtwdev, RF_PATH_A, RF_AAC_CTRL, 0x1000); 293162306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_SYN_PFD, RFREG_MASK, 0x1F0F8); 293262306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_SYN_CTRL, RFREG_MASK, 0x80010); 293362306a36Sopenharmony_ci 293462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); 293562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x4f000); 293662306a36Sopenharmony_ci fsleep(1); 293762306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_FAST_LCK, RFREG_MASK, 0x0f000); 293862306a36Sopenharmony_ci} 293962306a36Sopenharmony_ci 294062306a36Sopenharmony_cistatic void rtw8822c_do_iqk(struct rtw_dev *rtwdev) 294162306a36Sopenharmony_ci{ 294262306a36Sopenharmony_ci struct rtw_iqk_para para = {0}; 294362306a36Sopenharmony_ci u8 iqk_chk; 294462306a36Sopenharmony_ci int ret; 294562306a36Sopenharmony_ci 294662306a36Sopenharmony_ci para.clear = 1; 294762306a36Sopenharmony_ci rtw_fw_do_iqk(rtwdev, ¶); 294862306a36Sopenharmony_ci 294962306a36Sopenharmony_ci ret = read_poll_timeout(rtw_read8, iqk_chk, iqk_chk == IQK_DONE_8822C, 295062306a36Sopenharmony_ci 20000, 300000, false, rtwdev, REG_RPT_CIP); 295162306a36Sopenharmony_ci if (ret) 295262306a36Sopenharmony_ci rtw_warn(rtwdev, "failed to poll iqk status bit\n"); 295362306a36Sopenharmony_ci 295462306a36Sopenharmony_ci rtw_write8(rtwdev, REG_IQKSTAT, 0x0); 295562306a36Sopenharmony_ci} 295662306a36Sopenharmony_ci 295762306a36Sopenharmony_ci/* for coex */ 295862306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_init(struct rtw_dev *rtwdev) 295962306a36Sopenharmony_ci{ 296062306a36Sopenharmony_ci /* enable TBTT nterrupt */ 296162306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 296262306a36Sopenharmony_ci 296362306a36Sopenharmony_ci /* BT report packet sample rate */ 296462306a36Sopenharmony_ci /* 0x790[5:0]=0x5 */ 296562306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 296662306a36Sopenharmony_ci 296762306a36Sopenharmony_ci /* enable BT counter statistics */ 296862306a36Sopenharmony_ci rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); 296962306a36Sopenharmony_ci 297062306a36Sopenharmony_ci /* enable PTA (3-wire function form BT side) */ 297162306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 297262306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); 297362306a36Sopenharmony_ci 297462306a36Sopenharmony_ci /* enable PTA (tx/rx signal form WiFi side) */ 297562306a36Sopenharmony_ci rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 297662306a36Sopenharmony_ci /* wl tx signal to PTA not case EDCCA */ 297762306a36Sopenharmony_ci rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); 297862306a36Sopenharmony_ci /* GNT_BT=1 while select both */ 297962306a36Sopenharmony_ci rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); 298062306a36Sopenharmony_ci /* BT_CCA = ~GNT_WL_BB, not or GNT_BT_BB, LTE_Rx */ 298162306a36Sopenharmony_ci rtw_write8_clr(rtwdev, REG_DUMMY_PAGE4_V1, BIT_BTCCA_CTRL); 298262306a36Sopenharmony_ci 298362306a36Sopenharmony_ci /* to avoid RF parameter error */ 298462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_MODOPT, 0xfffff, 0x40000); 298562306a36Sopenharmony_ci} 298662306a36Sopenharmony_ci 298762306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 298862306a36Sopenharmony_ci{ 298962306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 299062306a36Sopenharmony_ci struct rtw_coex_stat *coex_stat = &coex->stat; 299162306a36Sopenharmony_ci struct rtw_efuse *efuse = &rtwdev->efuse; 299262306a36Sopenharmony_ci u32 rf_0x1; 299362306a36Sopenharmony_ci 299462306a36Sopenharmony_ci if (coex_stat->gnt_workaround_state == coex_stat->wl_coex_mode) 299562306a36Sopenharmony_ci return; 299662306a36Sopenharmony_ci 299762306a36Sopenharmony_ci coex_stat->gnt_workaround_state = coex_stat->wl_coex_mode; 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_ci if ((coex_stat->kt_ver == 0 && coex->under_5g) || coex->freerun) 300062306a36Sopenharmony_ci rf_0x1 = 0x40021; 300162306a36Sopenharmony_ci else 300262306a36Sopenharmony_ci rf_0x1 = 0x40000; 300362306a36Sopenharmony_ci 300462306a36Sopenharmony_ci /* BT at S1 for Shared-Ant */ 300562306a36Sopenharmony_ci if (efuse->share_ant) 300662306a36Sopenharmony_ci rf_0x1 |= BIT(13); 300762306a36Sopenharmony_ci 300862306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, 0x1, 0xfffff, rf_0x1); 300962306a36Sopenharmony_ci 301062306a36Sopenharmony_ci /* WL-S0 2G RF TRX cannot be masked by GNT_BT 301162306a36Sopenharmony_ci * enable "WLS0 BB chage RF mode if GNT_BT = 1" for shared-antenna type 301262306a36Sopenharmony_ci * disable:0x1860[3] = 1, enable:0x1860[3] = 0 301362306a36Sopenharmony_ci * 301462306a36Sopenharmony_ci * enable "DAC off if GNT_WL = 0" for non-shared-antenna 301562306a36Sopenharmony_ci * disable 0x1c30[22] = 0, 301662306a36Sopenharmony_ci * enable: 0x1c30[22] = 1, 0x1c38[12] = 0, 0x1c38[28] = 1 301762306a36Sopenharmony_ci */ 301862306a36Sopenharmony_ci if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { 301962306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_ANAPAR + 2, 302062306a36Sopenharmony_ci BIT_ANAPAR_BTPS >> 16, 0); 302162306a36Sopenharmony_ci } else { 302262306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_ANAPAR + 2, 302362306a36Sopenharmony_ci BIT_ANAPAR_BTPS >> 16, 1); 302462306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_RSTB_SEL + 1, 302562306a36Sopenharmony_ci BIT_DAC_OFF_ENABLE, 0); 302662306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_RSTB_SEL + 3, 302762306a36Sopenharmony_ci BIT_DAC_OFF_ENABLE, 1); 302862306a36Sopenharmony_ci } 302962306a36Sopenharmony_ci 303062306a36Sopenharmony_ci /* disable WL-S1 BB chage RF mode if GNT_BT 303162306a36Sopenharmony_ci * since RF TRx mask can do it 303262306a36Sopenharmony_ci */ 303362306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_IGN_GNTBT4, 303462306a36Sopenharmony_ci BIT_PI_IGNORE_GNT_BT, 1); 303562306a36Sopenharmony_ci 303662306a36Sopenharmony_ci /* disable WL-S0 BB chage RF mode if wifi is at 5G, 303762306a36Sopenharmony_ci * or antenna path is separated 303862306a36Sopenharmony_ci */ 303962306a36Sopenharmony_ci if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) { 304062306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 304162306a36Sopenharmony_ci BIT_PI_IGNORE_GNT_BT, 1); 304262306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 304362306a36Sopenharmony_ci BIT_NOMASK_TXBT_ENABLE, 1); 304462306a36Sopenharmony_ci } else if (coex_stat->wl_coex_mode == COEX_WLINK_5G || 304562306a36Sopenharmony_ci coex->under_5g || !efuse->share_ant) { 304662306a36Sopenharmony_ci if (coex_stat->kt_ver >= 3) { 304762306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 304862306a36Sopenharmony_ci BIT_PI_IGNORE_GNT_BT, 0); 304962306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 305062306a36Sopenharmony_ci BIT_NOMASK_TXBT_ENABLE, 1); 305162306a36Sopenharmony_ci } else { 305262306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 305362306a36Sopenharmony_ci BIT_PI_IGNORE_GNT_BT, 1); 305462306a36Sopenharmony_ci } 305562306a36Sopenharmony_ci } else { 305662306a36Sopenharmony_ci /* shared-antenna */ 305762306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_IGN_GNT_BT1, 305862306a36Sopenharmony_ci BIT_PI_IGNORE_GNT_BT, 0); 305962306a36Sopenharmony_ci if (coex_stat->kt_ver >= 3) { 306062306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_NOMASK_TXBT, 306162306a36Sopenharmony_ci BIT_NOMASK_TXBT_ENABLE, 0); 306262306a36Sopenharmony_ci } 306362306a36Sopenharmony_ci } 306462306a36Sopenharmony_ci} 306562306a36Sopenharmony_ci 306662306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) 306762306a36Sopenharmony_ci{ 306862306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0); 306962306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0); 307062306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0); 307162306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0); 307262306a36Sopenharmony_ci rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0); 307362306a36Sopenharmony_ci} 307462306a36Sopenharmony_ci 307562306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 307662306a36Sopenharmony_ci{ 307762306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 307862306a36Sopenharmony_ci struct rtw_coex_rfe *coex_rfe = &coex->rfe; 307962306a36Sopenharmony_ci struct rtw_efuse *efuse = &rtwdev->efuse; 308062306a36Sopenharmony_ci 308162306a36Sopenharmony_ci coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; 308262306a36Sopenharmony_ci coex_rfe->ant_switch_polarity = 0; 308362306a36Sopenharmony_ci coex_rfe->ant_switch_exist = false; 308462306a36Sopenharmony_ci coex_rfe->ant_switch_with_bt = false; 308562306a36Sopenharmony_ci coex_rfe->ant_switch_diversity = false; 308662306a36Sopenharmony_ci 308762306a36Sopenharmony_ci if (efuse->share_ant) 308862306a36Sopenharmony_ci coex_rfe->wlg_at_btg = true; 308962306a36Sopenharmony_ci else 309062306a36Sopenharmony_ci coex_rfe->wlg_at_btg = false; 309162306a36Sopenharmony_ci 309262306a36Sopenharmony_ci /* disable LTE coex in wifi side */ 309362306a36Sopenharmony_ci rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); 309462306a36Sopenharmony_ci rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); 309562306a36Sopenharmony_ci rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); 309662306a36Sopenharmony_ci} 309762306a36Sopenharmony_ci 309862306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 309962306a36Sopenharmony_ci{ 310062306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 310162306a36Sopenharmony_ci struct rtw_coex_dm *coex_dm = &coex->dm; 310262306a36Sopenharmony_ci 310362306a36Sopenharmony_ci if (wl_pwr == coex_dm->cur_wl_pwr_lvl) 310462306a36Sopenharmony_ci return; 310562306a36Sopenharmony_ci 310662306a36Sopenharmony_ci coex_dm->cur_wl_pwr_lvl = wl_pwr; 310762306a36Sopenharmony_ci} 310862306a36Sopenharmony_ci 310962306a36Sopenharmony_cistatic void rtw8822c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 311062306a36Sopenharmony_ci{ 311162306a36Sopenharmony_ci struct rtw_coex *coex = &rtwdev->coex; 311262306a36Sopenharmony_ci struct rtw_coex_dm *coex_dm = &coex->dm; 311362306a36Sopenharmony_ci 311462306a36Sopenharmony_ci if (low_gain == coex_dm->cur_wl_rx_low_gain_en) 311562306a36Sopenharmony_ci return; 311662306a36Sopenharmony_ci 311762306a36Sopenharmony_ci coex_dm->cur_wl_rx_low_gain_en = low_gain; 311862306a36Sopenharmony_ci 311962306a36Sopenharmony_ci if (coex_dm->cur_wl_rx_low_gain_en) { 312062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n"); 312162306a36Sopenharmony_ci 312262306a36Sopenharmony_ci /* set Rx filter corner RCK offset */ 312362306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x22); 312462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x36); 312562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x22); 312662306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x36); 312762306a36Sopenharmony_ci 312862306a36Sopenharmony_ci } else { 312962306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n"); 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci /* set Rx filter corner RCK offset */ 313262306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, RFREG_MASK, 0x20); 313362306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, RFREG_MASK, 0x0); 313462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, RFREG_MASK, 0x20); 313562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, RFREG_MASK, 0x0); 313662306a36Sopenharmony_ci } 313762306a36Sopenharmony_ci} 313862306a36Sopenharmony_ci 313962306a36Sopenharmony_cistatic void rtw8822c_bf_enable_bfee_su(struct rtw_dev *rtwdev, 314062306a36Sopenharmony_ci struct rtw_vif *vif, 314162306a36Sopenharmony_ci struct rtw_bfee *bfee) 314262306a36Sopenharmony_ci{ 314362306a36Sopenharmony_ci u8 csi_rsc = 0; 314462306a36Sopenharmony_ci u32 tmp6dc; 314562306a36Sopenharmony_ci 314662306a36Sopenharmony_ci rtw_bf_enable_bfee_su(rtwdev, vif, bfee); 314762306a36Sopenharmony_ci 314862306a36Sopenharmony_ci tmp6dc = rtw_read32(rtwdev, REG_BBPSF_CTRL) | 314962306a36Sopenharmony_ci BIT_WMAC_USE_NDPARATE | 315062306a36Sopenharmony_ci (csi_rsc << 13); 315162306a36Sopenharmony_ci if (vif->net_type == RTW_NET_AP_MODE) 315262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc | BIT(12)); 315362306a36Sopenharmony_ci else 315462306a36Sopenharmony_ci rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc & ~BIT(12)); 315562306a36Sopenharmony_ci 315662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_CSI_RRSR, 0x550); 315762306a36Sopenharmony_ci} 315862306a36Sopenharmony_ci 315962306a36Sopenharmony_cistatic void rtw8822c_bf_config_bfee_su(struct rtw_dev *rtwdev, 316062306a36Sopenharmony_ci struct rtw_vif *vif, 316162306a36Sopenharmony_ci struct rtw_bfee *bfee, bool enable) 316262306a36Sopenharmony_ci{ 316362306a36Sopenharmony_ci if (enable) 316462306a36Sopenharmony_ci rtw8822c_bf_enable_bfee_su(rtwdev, vif, bfee); 316562306a36Sopenharmony_ci else 316662306a36Sopenharmony_ci rtw_bf_remove_bfee_su(rtwdev, bfee); 316762306a36Sopenharmony_ci} 316862306a36Sopenharmony_ci 316962306a36Sopenharmony_cistatic void rtw8822c_bf_config_bfee_mu(struct rtw_dev *rtwdev, 317062306a36Sopenharmony_ci struct rtw_vif *vif, 317162306a36Sopenharmony_ci struct rtw_bfee *bfee, bool enable) 317262306a36Sopenharmony_ci{ 317362306a36Sopenharmony_ci if (enable) 317462306a36Sopenharmony_ci rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); 317562306a36Sopenharmony_ci else 317662306a36Sopenharmony_ci rtw_bf_remove_bfee_mu(rtwdev, bfee); 317762306a36Sopenharmony_ci} 317862306a36Sopenharmony_ci 317962306a36Sopenharmony_cistatic void rtw8822c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, 318062306a36Sopenharmony_ci struct rtw_bfee *bfee, bool enable) 318162306a36Sopenharmony_ci{ 318262306a36Sopenharmony_ci if (bfee->role == RTW_BFEE_SU) 318362306a36Sopenharmony_ci rtw8822c_bf_config_bfee_su(rtwdev, vif, bfee, enable); 318462306a36Sopenharmony_ci else if (bfee->role == RTW_BFEE_MU) 318562306a36Sopenharmony_ci rtw8822c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); 318662306a36Sopenharmony_ci else 318762306a36Sopenharmony_ci rtw_warn(rtwdev, "wrong bfee role\n"); 318862306a36Sopenharmony_ci} 318962306a36Sopenharmony_ci 319062306a36Sopenharmony_cistruct dpk_cfg_pair { 319162306a36Sopenharmony_ci u32 addr; 319262306a36Sopenharmony_ci u32 bitmask; 319362306a36Sopenharmony_ci u32 data; 319462306a36Sopenharmony_ci}; 319562306a36Sopenharmony_ci 319662306a36Sopenharmony_civoid rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev, 319762306a36Sopenharmony_ci const struct rtw_table *tbl) 319862306a36Sopenharmony_ci{ 319962306a36Sopenharmony_ci const struct dpk_cfg_pair *p = tbl->data; 320062306a36Sopenharmony_ci const struct dpk_cfg_pair *end = p + tbl->size / 3; 320162306a36Sopenharmony_ci 320262306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(struct dpk_cfg_pair) != sizeof(u32) * 3); 320362306a36Sopenharmony_ci 320462306a36Sopenharmony_ci for (; p < end; p++) 320562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, p->addr, p->bitmask, p->data); 320662306a36Sopenharmony_ci} 320762306a36Sopenharmony_ci 320862306a36Sopenharmony_cistatic void rtw8822c_dpk_set_gnt_wl(struct rtw_dev *rtwdev, bool is_before_k) 320962306a36Sopenharmony_ci{ 321062306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 321162306a36Sopenharmony_ci 321262306a36Sopenharmony_ci if (is_before_k) { 321362306a36Sopenharmony_ci dpk_info->gnt_control = rtw_read32(rtwdev, 0x70); 321462306a36Sopenharmony_ci dpk_info->gnt_value = rtw_coex_read_indirect_reg(rtwdev, 0x38); 321562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x70, BIT(26), 0x1); 321662306a36Sopenharmony_ci rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKBYTE1, 0x77); 321762306a36Sopenharmony_ci } else { 321862306a36Sopenharmony_ci rtw_coex_write_indirect_reg(rtwdev, 0x38, MASKDWORD, 321962306a36Sopenharmony_ci dpk_info->gnt_value); 322062306a36Sopenharmony_ci rtw_write32(rtwdev, 0x70, dpk_info->gnt_control); 322162306a36Sopenharmony_ci } 322262306a36Sopenharmony_ci} 322362306a36Sopenharmony_ci 322462306a36Sopenharmony_cistatic void 322562306a36Sopenharmony_cirtw8822c_dpk_restore_registers(struct rtw_dev *rtwdev, u32 reg_num, 322662306a36Sopenharmony_ci struct rtw_backup_info *bckp) 322762306a36Sopenharmony_ci{ 322862306a36Sopenharmony_ci rtw_restore_reg(rtwdev, bckp, reg_num); 322962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 323062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0x4); 323162306a36Sopenharmony_ci} 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_cistatic void 323462306a36Sopenharmony_cirtw8822c_dpk_backup_registers(struct rtw_dev *rtwdev, u32 *reg, 323562306a36Sopenharmony_ci u32 reg_num, struct rtw_backup_info *bckp) 323662306a36Sopenharmony_ci{ 323762306a36Sopenharmony_ci u32 i; 323862306a36Sopenharmony_ci 323962306a36Sopenharmony_ci for (i = 0; i < reg_num; i++) { 324062306a36Sopenharmony_ci bckp[i].len = 4; 324162306a36Sopenharmony_ci bckp[i].reg = reg[i]; 324262306a36Sopenharmony_ci bckp[i].val = rtw_read32(rtwdev, reg[i]); 324362306a36Sopenharmony_ci } 324462306a36Sopenharmony_ci} 324562306a36Sopenharmony_ci 324662306a36Sopenharmony_cistatic void rtw8822c_dpk_backup_rf_registers(struct rtw_dev *rtwdev, 324762306a36Sopenharmony_ci u32 *rf_reg, 324862306a36Sopenharmony_ci u32 rf_reg_bak[][2]) 324962306a36Sopenharmony_ci{ 325062306a36Sopenharmony_ci u32 i; 325162306a36Sopenharmony_ci 325262306a36Sopenharmony_ci for (i = 0; i < DPK_RF_REG_NUM; i++) { 325362306a36Sopenharmony_ci rf_reg_bak[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A, 325462306a36Sopenharmony_ci rf_reg[i], RFREG_MASK); 325562306a36Sopenharmony_ci rf_reg_bak[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B, 325662306a36Sopenharmony_ci rf_reg[i], RFREG_MASK); 325762306a36Sopenharmony_ci } 325862306a36Sopenharmony_ci} 325962306a36Sopenharmony_ci 326062306a36Sopenharmony_cistatic void rtw8822c_dpk_reload_rf_registers(struct rtw_dev *rtwdev, 326162306a36Sopenharmony_ci u32 *rf_reg, 326262306a36Sopenharmony_ci u32 rf_reg_bak[][2]) 326362306a36Sopenharmony_ci{ 326462306a36Sopenharmony_ci u32 i; 326562306a36Sopenharmony_ci 326662306a36Sopenharmony_ci for (i = 0; i < DPK_RF_REG_NUM; i++) { 326762306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, rf_reg[i], RFREG_MASK, 326862306a36Sopenharmony_ci rf_reg_bak[i][RF_PATH_A]); 326962306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, rf_reg[i], RFREG_MASK, 327062306a36Sopenharmony_ci rf_reg_bak[i][RF_PATH_B]); 327162306a36Sopenharmony_ci } 327262306a36Sopenharmony_ci} 327362306a36Sopenharmony_ci 327462306a36Sopenharmony_cistatic void rtw8822c_dpk_information(struct rtw_dev *rtwdev) 327562306a36Sopenharmony_ci{ 327662306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 327762306a36Sopenharmony_ci u32 reg; 327862306a36Sopenharmony_ci u8 band_shift; 327962306a36Sopenharmony_ci 328062306a36Sopenharmony_ci reg = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); 328162306a36Sopenharmony_ci 328262306a36Sopenharmony_ci band_shift = FIELD_GET(BIT(16), reg); 328362306a36Sopenharmony_ci dpk_info->dpk_band = 1 << band_shift; 328462306a36Sopenharmony_ci dpk_info->dpk_ch = FIELD_GET(0xff, reg); 328562306a36Sopenharmony_ci dpk_info->dpk_bw = FIELD_GET(0x3000, reg); 328662306a36Sopenharmony_ci} 328762306a36Sopenharmony_ci 328862306a36Sopenharmony_cistatic void rtw8822c_dpk_rxbb_dc_cal(struct rtw_dev *rtwdev, u8 path) 328962306a36Sopenharmony_ci{ 329062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); 329162306a36Sopenharmony_ci udelay(5); 329262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84801); 329362306a36Sopenharmony_ci usleep_range(600, 610); 329462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, 0x92, RFREG_MASK, 0x84800); 329562306a36Sopenharmony_ci} 329662306a36Sopenharmony_ci 329762306a36Sopenharmony_cistatic u8 rtw8822c_dpk_dc_corr_check(struct rtw_dev *rtwdev, u8 path) 329862306a36Sopenharmony_ci{ 329962306a36Sopenharmony_ci u16 dc_i, dc_q; 330062306a36Sopenharmony_ci u8 corr_idx; 330162306a36Sopenharmony_ci 330262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000900f0); 330362306a36Sopenharmony_ci dc_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); 330462306a36Sopenharmony_ci dc_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(11, 0)); 330562306a36Sopenharmony_ci 330662306a36Sopenharmony_ci if (dc_i & BIT(11)) 330762306a36Sopenharmony_ci dc_i = 0x1000 - dc_i; 330862306a36Sopenharmony_ci if (dc_q & BIT(11)) 330962306a36Sopenharmony_ci dc_q = 0x1000 - dc_q; 331062306a36Sopenharmony_ci 331162306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 331262306a36Sopenharmony_ci corr_idx = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(7, 0)); 331362306a36Sopenharmony_ci rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(15, 8)); 331462306a36Sopenharmony_ci 331562306a36Sopenharmony_ci if (dc_i > 200 || dc_q > 200 || corr_idx < 40 || corr_idx > 65) 331662306a36Sopenharmony_ci return 1; 331762306a36Sopenharmony_ci else 331862306a36Sopenharmony_ci return 0; 331962306a36Sopenharmony_ci 332062306a36Sopenharmony_ci} 332162306a36Sopenharmony_ci 332262306a36Sopenharmony_cistatic void rtw8822c_dpk_tx_pause(struct rtw_dev *rtwdev) 332362306a36Sopenharmony_ci{ 332462306a36Sopenharmony_ci u8 reg_a, reg_b; 332562306a36Sopenharmony_ci u16 count = 0; 332662306a36Sopenharmony_ci 332762306a36Sopenharmony_ci rtw_write8(rtwdev, 0x522, 0xff); 332862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1e70, 0xf, 0x2); 332962306a36Sopenharmony_ci 333062306a36Sopenharmony_ci do { 333162306a36Sopenharmony_ci reg_a = (u8)rtw_read_rf(rtwdev, RF_PATH_A, 0x00, 0xf0000); 333262306a36Sopenharmony_ci reg_b = (u8)rtw_read_rf(rtwdev, RF_PATH_B, 0x00, 0xf0000); 333362306a36Sopenharmony_ci udelay(2); 333462306a36Sopenharmony_ci count++; 333562306a36Sopenharmony_ci } while ((reg_a == 2 || reg_b == 2) && count < 2500); 333662306a36Sopenharmony_ci} 333762306a36Sopenharmony_ci 333862306a36Sopenharmony_cistatic void rtw8822c_dpk_mac_bb_setting(struct rtw_dev *rtwdev) 333962306a36Sopenharmony_ci{ 334062306a36Sopenharmony_ci rtw8822c_dpk_tx_pause(rtwdev); 334162306a36Sopenharmony_ci rtw_load_table(rtwdev, &rtw8822c_dpk_mac_bb_tbl); 334262306a36Sopenharmony_ci} 334362306a36Sopenharmony_ci 334462306a36Sopenharmony_cistatic void rtw8822c_dpk_afe_setting(struct rtw_dev *rtwdev, bool is_do_dpk) 334562306a36Sopenharmony_ci{ 334662306a36Sopenharmony_ci if (is_do_dpk) 334762306a36Sopenharmony_ci rtw_load_table(rtwdev, &rtw8822c_dpk_afe_is_dpk_tbl); 334862306a36Sopenharmony_ci else 334962306a36Sopenharmony_ci rtw_load_table(rtwdev, &rtw8822c_dpk_afe_no_dpk_tbl); 335062306a36Sopenharmony_ci} 335162306a36Sopenharmony_ci 335262306a36Sopenharmony_cistatic void rtw8822c_dpk_pre_setting(struct rtw_dev *rtwdev) 335362306a36Sopenharmony_ci{ 335462306a36Sopenharmony_ci u8 path; 335562306a36Sopenharmony_ci 335662306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 335762306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_RXAGC_OFFSET, RFREG_MASK, 0x0); 335862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); 335962306a36Sopenharmony_ci if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) 336062306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); 336162306a36Sopenharmony_ci else 336262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); 336362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_LUT0, BIT_GLOSS_DB, 0x4); 336462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x3); 336562306a36Sopenharmony_ci } 336662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 336762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL11, 0x3b23170b); 336862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL12, 0x775f5347); 336962306a36Sopenharmony_ci} 337062306a36Sopenharmony_ci 337162306a36Sopenharmony_cistatic u32 rtw8822c_dpk_rf_setting(struct rtw_dev *rtwdev, u8 path) 337262306a36Sopenharmony_ci{ 337362306a36Sopenharmony_ci u32 ori_txbb; 337462306a36Sopenharmony_ci 337562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x50017); 337662306a36Sopenharmony_ci ori_txbb = rtw_read_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK); 337762306a36Sopenharmony_ci 337862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TX_GAIN, 0x1); 337962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_PWR_TRIM, 0x1); 338062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_BB_GAIN, 0x0); 338162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TX_GAIN, RFREG_MASK, ori_txbb); 338262306a36Sopenharmony_ci 338362306a36Sopenharmony_ci if (rtwdev->dm_info.dpk_info.dpk_band == RTW_BAND_2G) { 338462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TX_GAIN_OFFSET, BIT_RF_GAIN, 0x1); 338562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_RXG_GAIN, BIT_RXG_GAIN, 0x0); 338662306a36Sopenharmony_ci } else { 338762306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_TXA_LB_ATT, 0x0); 338862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_ATT, 0x6); 338962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TXA_LB_SW, BIT_LB_SW, 0x1); 339062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_RXA_MIX_GAIN, BIT_RXA_MIX_GAIN, 0); 339162306a36Sopenharmony_ci } 339262306a36Sopenharmony_ci 339362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); 339462306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_DEBUG, BIT_DE_TRXBW, 0x1); 339562306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_RXBB, 0x0); 339662306a36Sopenharmony_ci 339762306a36Sopenharmony_ci if (rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80) 339862306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x2); 339962306a36Sopenharmony_ci else 340062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_BW_TRXBB, BIT_BW_TXBB, 0x1); 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_EXT_TIA_BW, BIT(1), 0x1); 340362306a36Sopenharmony_ci 340462306a36Sopenharmony_ci usleep_range(100, 110); 340562306a36Sopenharmony_ci 340662306a36Sopenharmony_ci return ori_txbb & 0x1f; 340762306a36Sopenharmony_ci} 340862306a36Sopenharmony_ci 340962306a36Sopenharmony_cistatic u16 rtw8822c_dpk_get_cmd(struct rtw_dev *rtwdev, u8 action, u8 path) 341062306a36Sopenharmony_ci{ 341162306a36Sopenharmony_ci u16 cmd; 341262306a36Sopenharmony_ci u8 bw = rtwdev->dm_info.dpk_info.dpk_bw == DPK_CHANNEL_WIDTH_80 ? 2 : 0; 341362306a36Sopenharmony_ci 341462306a36Sopenharmony_ci switch (action) { 341562306a36Sopenharmony_ci case RTW_DPK_GAIN_LOSS: 341662306a36Sopenharmony_ci cmd = 0x14 + path; 341762306a36Sopenharmony_ci break; 341862306a36Sopenharmony_ci case RTW_DPK_DO_DPK: 341962306a36Sopenharmony_ci cmd = 0x16 + path + bw; 342062306a36Sopenharmony_ci break; 342162306a36Sopenharmony_ci case RTW_DPK_DPK_ON: 342262306a36Sopenharmony_ci cmd = 0x1a + path; 342362306a36Sopenharmony_ci break; 342462306a36Sopenharmony_ci case RTW_DPK_DAGC: 342562306a36Sopenharmony_ci cmd = 0x1c + path + bw; 342662306a36Sopenharmony_ci break; 342762306a36Sopenharmony_ci default: 342862306a36Sopenharmony_ci return 0; 342962306a36Sopenharmony_ci } 343062306a36Sopenharmony_ci 343162306a36Sopenharmony_ci return (cmd << 8) | 0x48; 343262306a36Sopenharmony_ci} 343362306a36Sopenharmony_ci 343462306a36Sopenharmony_cistatic u8 rtw8822c_dpk_one_shot(struct rtw_dev *rtwdev, u8 path, u8 action) 343562306a36Sopenharmony_ci{ 343662306a36Sopenharmony_ci u16 dpk_cmd; 343762306a36Sopenharmony_ci u8 result = 0; 343862306a36Sopenharmony_ci 343962306a36Sopenharmony_ci rtw8822c_dpk_set_gnt_wl(rtwdev, true); 344062306a36Sopenharmony_ci 344162306a36Sopenharmony_ci if (action == RTW_DPK_CAL_PWR) { 344262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x1); 344362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(12), 0x0); 344462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); 344562306a36Sopenharmony_ci msleep(10); 344662306a36Sopenharmony_ci if (!check_hw_ready(rtwdev, REG_STAT_RPT, BIT(31), 0x1)) { 344762306a36Sopenharmony_ci result = 1; 344862306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); 344962306a36Sopenharmony_ci } 345062306a36Sopenharmony_ci } else { 345162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 345262306a36Sopenharmony_ci 0x8 | (path << 1)); 345362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); 345462306a36Sopenharmony_ci 345562306a36Sopenharmony_ci dpk_cmd = rtw8822c_dpk_get_cmd(rtwdev, action, path); 345662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, dpk_cmd); 345762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, dpk_cmd + 1); 345862306a36Sopenharmony_ci msleep(10); 345962306a36Sopenharmony_ci if (!check_hw_ready(rtwdev, 0x2d9c, 0xff, 0x55)) { 346062306a36Sopenharmony_ci result = 1; 346162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] one-shot over 20ms\n"); 346262306a36Sopenharmony_ci } 346362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 346462306a36Sopenharmony_ci 0x8 | (path << 1)); 346562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); 346662306a36Sopenharmony_ci } 346762306a36Sopenharmony_ci 346862306a36Sopenharmony_ci rtw8822c_dpk_set_gnt_wl(rtwdev, false); 346962306a36Sopenharmony_ci 347062306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1b10, 0x0); 347162306a36Sopenharmony_ci 347262306a36Sopenharmony_ci return result; 347362306a36Sopenharmony_ci} 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_cistatic u16 rtw8822c_dpk_dgain_read(struct rtw_dev *rtwdev, u8 path) 347662306a36Sopenharmony_ci{ 347762306a36Sopenharmony_ci u16 dgain; 347862306a36Sopenharmony_ci 347962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 348062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, 0x00ff0000, 0x0); 348162306a36Sopenharmony_ci 348262306a36Sopenharmony_ci dgain = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, GENMASK(27, 16)); 348362306a36Sopenharmony_ci 348462306a36Sopenharmony_ci return dgain; 348562306a36Sopenharmony_ci} 348662306a36Sopenharmony_ci 348762306a36Sopenharmony_cistatic u8 rtw8822c_dpk_thermal_read(struct rtw_dev *rtwdev, u8 path) 348862306a36Sopenharmony_ci{ 348962306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); 349062306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x0); 349162306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_T_METER, BIT(19), 0x1); 349262306a36Sopenharmony_ci udelay(15); 349362306a36Sopenharmony_ci 349462306a36Sopenharmony_ci return (u8)rtw_read_rf(rtwdev, path, RF_T_METER, 0x0007e); 349562306a36Sopenharmony_ci} 349662306a36Sopenharmony_ci 349762306a36Sopenharmony_cistatic u32 rtw8822c_dpk_pas_read(struct rtw_dev *rtwdev, u8 path) 349862306a36Sopenharmony_ci{ 349962306a36Sopenharmony_ci u32 i_val, q_val; 350062306a36Sopenharmony_ci 350162306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x8 | (path << 1)); 350262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); 350362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060001); 350462306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b4c, 0x00000000); 350562306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b4c, 0x00080000); 350662306a36Sopenharmony_ci 350762306a36Sopenharmony_ci q_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD); 350862306a36Sopenharmony_ci i_val = rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD); 350962306a36Sopenharmony_ci 351062306a36Sopenharmony_ci if (i_val & BIT(15)) 351162306a36Sopenharmony_ci i_val = 0x10000 - i_val; 351262306a36Sopenharmony_ci if (q_val & BIT(15)) 351362306a36Sopenharmony_ci q_val = 0x10000 - q_val; 351462306a36Sopenharmony_ci 351562306a36Sopenharmony_ci rtw_write32(rtwdev, 0x1b4c, 0x00000000); 351662306a36Sopenharmony_ci 351762306a36Sopenharmony_ci return i_val * i_val + q_val * q_val; 351862306a36Sopenharmony_ci} 351962306a36Sopenharmony_ci 352062306a36Sopenharmony_cistatic u32 rtw8822c_psd_log2base(u32 val) 352162306a36Sopenharmony_ci{ 352262306a36Sopenharmony_ci u32 tmp, val_integerd_b, tindex; 352362306a36Sopenharmony_ci u32 result, val_fractiond_b; 352462306a36Sopenharmony_ci u32 table_fraction[21] = {0, 432, 332, 274, 232, 200, 174, 352562306a36Sopenharmony_ci 151, 132, 115, 100, 86, 74, 62, 51, 352662306a36Sopenharmony_ci 42, 32, 23, 15, 7, 0}; 352762306a36Sopenharmony_ci 352862306a36Sopenharmony_ci if (val == 0) 352962306a36Sopenharmony_ci return 0; 353062306a36Sopenharmony_ci 353162306a36Sopenharmony_ci val_integerd_b = __fls(val) + 1; 353262306a36Sopenharmony_ci 353362306a36Sopenharmony_ci tmp = (val * 100) / (1 << val_integerd_b); 353462306a36Sopenharmony_ci tindex = tmp / 5; 353562306a36Sopenharmony_ci 353662306a36Sopenharmony_ci if (tindex >= ARRAY_SIZE(table_fraction)) 353762306a36Sopenharmony_ci tindex = ARRAY_SIZE(table_fraction) - 1; 353862306a36Sopenharmony_ci 353962306a36Sopenharmony_ci val_fractiond_b = table_fraction[tindex]; 354062306a36Sopenharmony_ci 354162306a36Sopenharmony_ci result = val_integerd_b * 100 - val_fractiond_b; 354262306a36Sopenharmony_ci 354362306a36Sopenharmony_ci return result; 354462306a36Sopenharmony_ci} 354562306a36Sopenharmony_ci 354662306a36Sopenharmony_cistatic u8 rtw8822c_dpk_gainloss_result(struct rtw_dev *rtwdev, u8 path) 354762306a36Sopenharmony_ci{ 354862306a36Sopenharmony_ci u8 result; 354962306a36Sopenharmony_ci 355062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 355162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x1); 355262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x00060000); 355362306a36Sopenharmony_ci 355462306a36Sopenharmony_ci result = (u8)rtw_read32_mask(rtwdev, REG_STAT_RPT, 0x000000f0); 355562306a36Sopenharmony_ci 355662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b48, BIT(14), 0x0); 355762306a36Sopenharmony_ci 355862306a36Sopenharmony_ci return result; 355962306a36Sopenharmony_ci} 356062306a36Sopenharmony_ci 356162306a36Sopenharmony_cistatic u8 rtw8822c_dpk_agc_gain_chk(struct rtw_dev *rtwdev, u8 path, 356262306a36Sopenharmony_ci u8 limited_pga) 356362306a36Sopenharmony_ci{ 356462306a36Sopenharmony_ci u8 result = 0; 356562306a36Sopenharmony_ci u16 dgain; 356662306a36Sopenharmony_ci 356762306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 356862306a36Sopenharmony_ci dgain = rtw8822c_dpk_dgain_read(rtwdev, path); 356962306a36Sopenharmony_ci 357062306a36Sopenharmony_ci if (dgain > 1535 && !limited_pga) 357162306a36Sopenharmony_ci return RTW_DPK_GAIN_LESS; 357262306a36Sopenharmony_ci else if (dgain < 768 && !limited_pga) 357362306a36Sopenharmony_ci return RTW_DPK_GAIN_LARGE; 357462306a36Sopenharmony_ci else 357562306a36Sopenharmony_ci return result; 357662306a36Sopenharmony_ci} 357762306a36Sopenharmony_ci 357862306a36Sopenharmony_cistatic u8 rtw8822c_dpk_agc_loss_chk(struct rtw_dev *rtwdev, u8 path) 357962306a36Sopenharmony_ci{ 358062306a36Sopenharmony_ci u32 loss, loss_db; 358162306a36Sopenharmony_ci 358262306a36Sopenharmony_ci loss = rtw8822c_dpk_pas_read(rtwdev, path); 358362306a36Sopenharmony_ci if (loss < 0x4000000) 358462306a36Sopenharmony_ci return RTW_DPK_GL_LESS; 358562306a36Sopenharmony_ci loss_db = 3 * rtw8822c_psd_log2base(loss >> 13) - 3870; 358662306a36Sopenharmony_ci 358762306a36Sopenharmony_ci if (loss_db > 1000) 358862306a36Sopenharmony_ci return RTW_DPK_GL_LARGE; 358962306a36Sopenharmony_ci else if (loss_db < 250) 359062306a36Sopenharmony_ci return RTW_DPK_GL_LESS; 359162306a36Sopenharmony_ci else 359262306a36Sopenharmony_ci return RTW_DPK_AGC_OUT; 359362306a36Sopenharmony_ci} 359462306a36Sopenharmony_ci 359562306a36Sopenharmony_cistruct rtw8822c_dpk_data { 359662306a36Sopenharmony_ci u8 txbb; 359762306a36Sopenharmony_ci u8 pga; 359862306a36Sopenharmony_ci u8 limited_pga; 359962306a36Sopenharmony_ci u8 agc_cnt; 360062306a36Sopenharmony_ci bool loss_only; 360162306a36Sopenharmony_ci bool gain_only; 360262306a36Sopenharmony_ci u8 path; 360362306a36Sopenharmony_ci}; 360462306a36Sopenharmony_ci 360562306a36Sopenharmony_cistatic u8 rtw8822c_gain_check_state(struct rtw_dev *rtwdev, 360662306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 360762306a36Sopenharmony_ci{ 360862306a36Sopenharmony_ci u8 state; 360962306a36Sopenharmony_ci 361062306a36Sopenharmony_ci data->txbb = (u8)rtw_read_rf(rtwdev, data->path, RF_TX_GAIN, 361162306a36Sopenharmony_ci BIT_GAIN_TXBB); 361262306a36Sopenharmony_ci data->pga = (u8)rtw_read_rf(rtwdev, data->path, RF_MODE_TRXAGC, 361362306a36Sopenharmony_ci BIT_RXAGC); 361462306a36Sopenharmony_ci 361562306a36Sopenharmony_ci if (data->loss_only) { 361662306a36Sopenharmony_ci state = RTW_DPK_LOSS_CHECK; 361762306a36Sopenharmony_ci goto check_end; 361862306a36Sopenharmony_ci } 361962306a36Sopenharmony_ci 362062306a36Sopenharmony_ci state = rtw8822c_dpk_agc_gain_chk(rtwdev, data->path, 362162306a36Sopenharmony_ci data->limited_pga); 362262306a36Sopenharmony_ci if (state == RTW_DPK_GAIN_CHECK && data->gain_only) 362362306a36Sopenharmony_ci state = RTW_DPK_AGC_OUT; 362462306a36Sopenharmony_ci else if (state == RTW_DPK_GAIN_CHECK) 362562306a36Sopenharmony_ci state = RTW_DPK_LOSS_CHECK; 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_cicheck_end: 362862306a36Sopenharmony_ci data->agc_cnt++; 362962306a36Sopenharmony_ci if (data->agc_cnt >= 6) 363062306a36Sopenharmony_ci state = RTW_DPK_AGC_OUT; 363162306a36Sopenharmony_ci 363262306a36Sopenharmony_ci return state; 363362306a36Sopenharmony_ci} 363462306a36Sopenharmony_ci 363562306a36Sopenharmony_cistatic u8 rtw8822c_gain_large_state(struct rtw_dev *rtwdev, 363662306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 363762306a36Sopenharmony_ci{ 363862306a36Sopenharmony_ci u8 pga = data->pga; 363962306a36Sopenharmony_ci 364062306a36Sopenharmony_ci if (pga > 0xe) 364162306a36Sopenharmony_ci rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); 364262306a36Sopenharmony_ci else if (pga > 0xb && pga < 0xf) 364362306a36Sopenharmony_ci rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0x0); 364462306a36Sopenharmony_ci else if (pga < 0xc) 364562306a36Sopenharmony_ci data->limited_pga = 1; 364662306a36Sopenharmony_ci 364762306a36Sopenharmony_ci return RTW_DPK_GAIN_CHECK; 364862306a36Sopenharmony_ci} 364962306a36Sopenharmony_ci 365062306a36Sopenharmony_cistatic u8 rtw8822c_gain_less_state(struct rtw_dev *rtwdev, 365162306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 365262306a36Sopenharmony_ci{ 365362306a36Sopenharmony_ci u8 pga = data->pga; 365462306a36Sopenharmony_ci 365562306a36Sopenharmony_ci if (pga < 0xc) 365662306a36Sopenharmony_ci rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xc); 365762306a36Sopenharmony_ci else if (pga > 0xb && pga < 0xf) 365862306a36Sopenharmony_ci rtw_write_rf(rtwdev, data->path, RF_MODE_TRXAGC, BIT_RXAGC, 0xf); 365962306a36Sopenharmony_ci else if (pga > 0xe) 366062306a36Sopenharmony_ci data->limited_pga = 1; 366162306a36Sopenharmony_ci 366262306a36Sopenharmony_ci return RTW_DPK_GAIN_CHECK; 366362306a36Sopenharmony_ci} 366462306a36Sopenharmony_ci 366562306a36Sopenharmony_cistatic u8 rtw8822c_gl_state(struct rtw_dev *rtwdev, 366662306a36Sopenharmony_ci struct rtw8822c_dpk_data *data, u8 is_large) 366762306a36Sopenharmony_ci{ 366862306a36Sopenharmony_ci u8 txbb_bound[] = {0x1f, 0}; 366962306a36Sopenharmony_ci 367062306a36Sopenharmony_ci if (data->txbb == txbb_bound[is_large]) 367162306a36Sopenharmony_ci return RTW_DPK_AGC_OUT; 367262306a36Sopenharmony_ci 367362306a36Sopenharmony_ci if (is_large == 1) 367462306a36Sopenharmony_ci data->txbb -= 2; 367562306a36Sopenharmony_ci else 367662306a36Sopenharmony_ci data->txbb += 3; 367762306a36Sopenharmony_ci 367862306a36Sopenharmony_ci rtw_write_rf(rtwdev, data->path, RF_TX_GAIN, BIT_GAIN_TXBB, data->txbb); 367962306a36Sopenharmony_ci data->limited_pga = 0; 368062306a36Sopenharmony_ci 368162306a36Sopenharmony_ci return RTW_DPK_GAIN_CHECK; 368262306a36Sopenharmony_ci} 368362306a36Sopenharmony_ci 368462306a36Sopenharmony_cistatic u8 rtw8822c_gl_large_state(struct rtw_dev *rtwdev, 368562306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 368662306a36Sopenharmony_ci{ 368762306a36Sopenharmony_ci return rtw8822c_gl_state(rtwdev, data, 1); 368862306a36Sopenharmony_ci} 368962306a36Sopenharmony_ci 369062306a36Sopenharmony_cistatic u8 rtw8822c_gl_less_state(struct rtw_dev *rtwdev, 369162306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 369262306a36Sopenharmony_ci{ 369362306a36Sopenharmony_ci return rtw8822c_gl_state(rtwdev, data, 0); 369462306a36Sopenharmony_ci} 369562306a36Sopenharmony_ci 369662306a36Sopenharmony_cistatic u8 rtw8822c_loss_check_state(struct rtw_dev *rtwdev, 369762306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) 369862306a36Sopenharmony_ci{ 369962306a36Sopenharmony_ci u8 path = data->path; 370062306a36Sopenharmony_ci u8 state; 370162306a36Sopenharmony_ci 370262306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_GAIN_LOSS); 370362306a36Sopenharmony_ci state = rtw8822c_dpk_agc_loss_chk(rtwdev, path); 370462306a36Sopenharmony_ci 370562306a36Sopenharmony_ci return state; 370662306a36Sopenharmony_ci} 370762306a36Sopenharmony_ci 370862306a36Sopenharmony_cistatic u8 (*dpk_state[])(struct rtw_dev *rtwdev, 370962306a36Sopenharmony_ci struct rtw8822c_dpk_data *data) = { 371062306a36Sopenharmony_ci rtw8822c_gain_check_state, rtw8822c_gain_large_state, 371162306a36Sopenharmony_ci rtw8822c_gain_less_state, rtw8822c_gl_large_state, 371262306a36Sopenharmony_ci rtw8822c_gl_less_state, rtw8822c_loss_check_state }; 371362306a36Sopenharmony_ci 371462306a36Sopenharmony_cistatic u8 rtw8822c_dpk_pas_agc(struct rtw_dev *rtwdev, u8 path, 371562306a36Sopenharmony_ci bool gain_only, bool loss_only) 371662306a36Sopenharmony_ci{ 371762306a36Sopenharmony_ci struct rtw8822c_dpk_data data = {0}; 371862306a36Sopenharmony_ci u8 (*func)(struct rtw_dev *rtwdev, struct rtw8822c_dpk_data *data); 371962306a36Sopenharmony_ci u8 state = RTW_DPK_GAIN_CHECK; 372062306a36Sopenharmony_ci 372162306a36Sopenharmony_ci data.loss_only = loss_only; 372262306a36Sopenharmony_ci data.gain_only = gain_only; 372362306a36Sopenharmony_ci data.path = path; 372462306a36Sopenharmony_ci 372562306a36Sopenharmony_ci for (;;) { 372662306a36Sopenharmony_ci func = dpk_state[state]; 372762306a36Sopenharmony_ci state = func(rtwdev, &data); 372862306a36Sopenharmony_ci if (state == RTW_DPK_AGC_OUT) 372962306a36Sopenharmony_ci break; 373062306a36Sopenharmony_ci } 373162306a36Sopenharmony_ci 373262306a36Sopenharmony_ci return data.txbb; 373362306a36Sopenharmony_ci} 373462306a36Sopenharmony_ci 373562306a36Sopenharmony_cistatic bool rtw8822c_dpk_coef_iq_check(struct rtw_dev *rtwdev, 373662306a36Sopenharmony_ci u16 coef_i, u16 coef_q) 373762306a36Sopenharmony_ci{ 373862306a36Sopenharmony_ci if (coef_i == 0x1000 || coef_i == 0x0fff || 373962306a36Sopenharmony_ci coef_q == 0x1000 || coef_q == 0x0fff) 374062306a36Sopenharmony_ci return true; 374162306a36Sopenharmony_ci 374262306a36Sopenharmony_ci return false; 374362306a36Sopenharmony_ci} 374462306a36Sopenharmony_ci 374562306a36Sopenharmony_cistatic u32 rtw8822c_dpk_coef_transfer(struct rtw_dev *rtwdev) 374662306a36Sopenharmony_ci{ 374762306a36Sopenharmony_ci u32 reg = 0; 374862306a36Sopenharmony_ci u16 coef_i = 0, coef_q = 0; 374962306a36Sopenharmony_ci 375062306a36Sopenharmony_ci reg = rtw_read32(rtwdev, REG_STAT_RPT); 375162306a36Sopenharmony_ci 375262306a36Sopenharmony_ci coef_i = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKHWORD) & 0x1fff; 375362306a36Sopenharmony_ci coef_q = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, MASKLWORD) & 0x1fff; 375462306a36Sopenharmony_ci 375562306a36Sopenharmony_ci coef_q = ((0x2000 - coef_q) & 0x1fff) - 1; 375662306a36Sopenharmony_ci 375762306a36Sopenharmony_ci reg = (coef_i << 16) | coef_q; 375862306a36Sopenharmony_ci 375962306a36Sopenharmony_ci return reg; 376062306a36Sopenharmony_ci} 376162306a36Sopenharmony_ci 376262306a36Sopenharmony_cistatic const u32 rtw8822c_dpk_get_coef_tbl[] = { 376362306a36Sopenharmony_ci 0x000400f0, 0x040400f0, 0x080400f0, 0x010400f0, 0x050400f0, 376462306a36Sopenharmony_ci 0x090400f0, 0x020400f0, 0x060400f0, 0x0a0400f0, 0x030400f0, 376562306a36Sopenharmony_ci 0x070400f0, 0x0b0400f0, 0x0c0400f0, 0x100400f0, 0x0d0400f0, 376662306a36Sopenharmony_ci 0x110400f0, 0x0e0400f0, 0x120400f0, 0x0f0400f0, 0x130400f0, 376762306a36Sopenharmony_ci}; 376862306a36Sopenharmony_ci 376962306a36Sopenharmony_cistatic void rtw8822c_dpk_coef_tbl_apply(struct rtw_dev *rtwdev, u8 path) 377062306a36Sopenharmony_ci{ 377162306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 377262306a36Sopenharmony_ci int i; 377362306a36Sopenharmony_ci 377462306a36Sopenharmony_ci for (i = 0; i < 20; i++) { 377562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 377662306a36Sopenharmony_ci rtw8822c_dpk_get_coef_tbl[i]); 377762306a36Sopenharmony_ci dpk_info->coef[path][i] = rtw8822c_dpk_coef_transfer(rtwdev); 377862306a36Sopenharmony_ci } 377962306a36Sopenharmony_ci} 378062306a36Sopenharmony_ci 378162306a36Sopenharmony_cistatic void rtw8822c_dpk_get_coef(struct rtw_dev *rtwdev, u8 path) 378262306a36Sopenharmony_ci{ 378362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); 378462306a36Sopenharmony_ci 378562306a36Sopenharmony_ci if (path == RF_PATH_A) { 378662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x0); 378762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL0_S0, 0x30000080); 378862306a36Sopenharmony_ci } else if (path == RF_PATH_B) { 378962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0, BIT(24), 0x1); 379062306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL0_S1, 0x30000080); 379162306a36Sopenharmony_ci } 379262306a36Sopenharmony_ci 379362306a36Sopenharmony_ci rtw8822c_dpk_coef_tbl_apply(rtwdev, path); 379462306a36Sopenharmony_ci} 379562306a36Sopenharmony_ci 379662306a36Sopenharmony_cistatic u8 rtw8822c_dpk_coef_read(struct rtw_dev *rtwdev, u8 path) 379762306a36Sopenharmony_ci{ 379862306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 379962306a36Sopenharmony_ci u8 addr, result = 1; 380062306a36Sopenharmony_ci u16 coef_i, coef_q; 380162306a36Sopenharmony_ci 380262306a36Sopenharmony_ci for (addr = 0; addr < 20; addr++) { 380362306a36Sopenharmony_ci coef_i = FIELD_GET(0x1fff0000, dpk_info->coef[path][addr]); 380462306a36Sopenharmony_ci coef_q = FIELD_GET(0x1fff, dpk_info->coef[path][addr]); 380562306a36Sopenharmony_ci 380662306a36Sopenharmony_ci if (rtw8822c_dpk_coef_iq_check(rtwdev, coef_i, coef_q)) { 380762306a36Sopenharmony_ci result = 0; 380862306a36Sopenharmony_ci break; 380962306a36Sopenharmony_ci } 381062306a36Sopenharmony_ci } 381162306a36Sopenharmony_ci return result; 381262306a36Sopenharmony_ci} 381362306a36Sopenharmony_ci 381462306a36Sopenharmony_cistatic void rtw8822c_dpk_coef_write(struct rtw_dev *rtwdev, u8 path, u8 result) 381562306a36Sopenharmony_ci{ 381662306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 381762306a36Sopenharmony_ci u16 reg[DPK_RF_PATH_NUM] = {0x1b0c, 0x1b64}; 381862306a36Sopenharmony_ci u32 coef; 381962306a36Sopenharmony_ci u8 addr; 382062306a36Sopenharmony_ci 382162306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x0000000c); 382262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 382362306a36Sopenharmony_ci 382462306a36Sopenharmony_ci for (addr = 0; addr < 20; addr++) { 382562306a36Sopenharmony_ci if (result == 0) { 382662306a36Sopenharmony_ci if (addr == 3) 382762306a36Sopenharmony_ci coef = 0x04001fff; 382862306a36Sopenharmony_ci else 382962306a36Sopenharmony_ci coef = 0x00001fff; 383062306a36Sopenharmony_ci } else { 383162306a36Sopenharmony_ci coef = dpk_info->coef[path][addr]; 383262306a36Sopenharmony_ci } 383362306a36Sopenharmony_ci rtw_write32(rtwdev, reg[path] + addr * 4, coef); 383462306a36Sopenharmony_ci } 383562306a36Sopenharmony_ci} 383662306a36Sopenharmony_ci 383762306a36Sopenharmony_cistatic void rtw8822c_dpk_fill_result(struct rtw_dev *rtwdev, u32 dpk_txagc, 383862306a36Sopenharmony_ci u8 path, u8 result) 383962306a36Sopenharmony_ci{ 384062306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 384162306a36Sopenharmony_ci 384262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 384362306a36Sopenharmony_ci 384462306a36Sopenharmony_ci if (result) 384562306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DPD_AGC, (u8)(dpk_txagc - 6)); 384662306a36Sopenharmony_ci else 384762306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DPD_AGC, 0x00); 384862306a36Sopenharmony_ci 384962306a36Sopenharmony_ci dpk_info->result[path] = result; 385062306a36Sopenharmony_ci dpk_info->dpk_txagc[path] = rtw_read8(rtwdev, REG_DPD_AGC); 385162306a36Sopenharmony_ci 385262306a36Sopenharmony_ci rtw8822c_dpk_coef_write(rtwdev, path, result); 385362306a36Sopenharmony_ci} 385462306a36Sopenharmony_ci 385562306a36Sopenharmony_cistatic u32 rtw8822c_dpk_gainloss(struct rtw_dev *rtwdev, u8 path) 385662306a36Sopenharmony_ci{ 385762306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 385862306a36Sopenharmony_ci u8 tx_agc, tx_bb, ori_txbb, ori_txagc, tx_agc_search, t1, t2; 385962306a36Sopenharmony_ci 386062306a36Sopenharmony_ci ori_txbb = rtw8822c_dpk_rf_setting(rtwdev, path); 386162306a36Sopenharmony_ci ori_txagc = (u8)rtw_read_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_TXAGC); 386262306a36Sopenharmony_ci 386362306a36Sopenharmony_ci rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 386462306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 386562306a36Sopenharmony_ci rtw8822c_dpk_dgain_read(rtwdev, path); 386662306a36Sopenharmony_ci 386762306a36Sopenharmony_ci if (rtw8822c_dpk_dc_corr_check(rtwdev, path)) { 386862306a36Sopenharmony_ci rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 386962306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC); 387062306a36Sopenharmony_ci rtw8822c_dpk_dc_corr_check(rtwdev, path); 387162306a36Sopenharmony_ci } 387262306a36Sopenharmony_ci 387362306a36Sopenharmony_ci t1 = rtw8822c_dpk_thermal_read(rtwdev, path); 387462306a36Sopenharmony_ci tx_bb = rtw8822c_dpk_pas_agc(rtwdev, path, false, true); 387562306a36Sopenharmony_ci tx_agc_search = rtw8822c_dpk_gainloss_result(rtwdev, path); 387662306a36Sopenharmony_ci 387762306a36Sopenharmony_ci if (tx_bb < tx_agc_search) 387862306a36Sopenharmony_ci tx_bb = 0; 387962306a36Sopenharmony_ci else 388062306a36Sopenharmony_ci tx_bb = tx_bb - tx_agc_search; 388162306a36Sopenharmony_ci 388262306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_TX_GAIN, BIT_GAIN_TXBB, tx_bb); 388362306a36Sopenharmony_ci 388462306a36Sopenharmony_ci tx_agc = ori_txagc - (ori_txbb - tx_bb); 388562306a36Sopenharmony_ci 388662306a36Sopenharmony_ci t2 = rtw8822c_dpk_thermal_read(rtwdev, path); 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci dpk_info->thermal_dpk_delta[path] = abs(t2 - t1); 388962306a36Sopenharmony_ci 389062306a36Sopenharmony_ci return tx_agc; 389162306a36Sopenharmony_ci} 389262306a36Sopenharmony_ci 389362306a36Sopenharmony_cistatic u8 rtw8822c_dpk_by_path(struct rtw_dev *rtwdev, u32 tx_agc, u8 path) 389462306a36Sopenharmony_ci{ 389562306a36Sopenharmony_ci u8 result; 389662306a36Sopenharmony_ci 389762306a36Sopenharmony_ci result = rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DO_DPK); 389862306a36Sopenharmony_ci 389962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 390062306a36Sopenharmony_ci 390162306a36Sopenharmony_ci result = result | (u8)rtw_read32_mask(rtwdev, REG_DPD_CTL1_S0, BIT(26)); 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci rtw_write_rf(rtwdev, path, RF_MODE_TRXAGC, RFREG_MASK, 0x33e14); 390462306a36Sopenharmony_ci 390562306a36Sopenharmony_ci rtw8822c_dpk_get_coef(rtwdev, path); 390662306a36Sopenharmony_ci 390762306a36Sopenharmony_ci return result; 390862306a36Sopenharmony_ci} 390962306a36Sopenharmony_ci 391062306a36Sopenharmony_cistatic void rtw8822c_dpk_cal_gs(struct rtw_dev *rtwdev, u8 path) 391162306a36Sopenharmony_ci{ 391262306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 391362306a36Sopenharmony_ci u32 tmp_gs = 0; 391462306a36Sopenharmony_ci 391562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 391662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_BYPASS_DPD, 0x0); 391762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 391862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x9); 391962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x1); 392062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 392162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_DPD_CLK, 0xf); 392262306a36Sopenharmony_ci 392362306a36Sopenharmony_ci if (path == RF_PATH_A) { 392462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 392562306a36Sopenharmony_ci 0x1066680); 392662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 0x1); 392762306a36Sopenharmony_ci } else { 392862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 392962306a36Sopenharmony_ci 0x1066680); 393062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 0x1); 393162306a36Sopenharmony_ci } 393262306a36Sopenharmony_ci 393362306a36Sopenharmony_ci if (dpk_info->dpk_bw == DPK_CHANNEL_WIDTH_80) { 393462306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x80001310); 393562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x00001310); 393662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x810000db); 393762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x010000db); 393862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); 393962306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL15, 394062306a36Sopenharmony_ci 0x05020000 | (BIT(path) << 28)); 394162306a36Sopenharmony_ci } else { 394262306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x8200190c); 394362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x0200190c); 394462306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x8301ee14); 394562306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x0301ee14); 394662306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL16, 0x0000b428); 394762306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL15, 394862306a36Sopenharmony_ci 0x05020008 | (BIT(path) << 28)); 394962306a36Sopenharmony_ci } 395062306a36Sopenharmony_ci 395162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0, MASKBYTE3, 0x8 | path); 395262306a36Sopenharmony_ci 395362306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_CAL_PWR); 395462306a36Sopenharmony_ci 395562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL15, MASKBYTE3, 0x0); 395662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 395762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_IQ_SWITCH, 0x0); 395862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_R_CONFIG, BIT_INNER_LB, 0x0); 395962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 396062306a36Sopenharmony_ci 396162306a36Sopenharmony_ci if (path == RF_PATH_A) 396262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 0x5b); 396362306a36Sopenharmony_ci else 396462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 0x5b); 396562306a36Sopenharmony_ci 396662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_RXSRAM_CTL, BIT_RPT_SEL, 0x0); 396762306a36Sopenharmony_ci 396862306a36Sopenharmony_ci tmp_gs = (u16)rtw_read32_mask(rtwdev, REG_STAT_RPT, BIT_RPT_DGAIN); 396962306a36Sopenharmony_ci tmp_gs = (tmp_gs * 910) >> 10; 397062306a36Sopenharmony_ci tmp_gs = DIV_ROUND_CLOSEST(tmp_gs, 10); 397162306a36Sopenharmony_ci 397262306a36Sopenharmony_ci if (path == RF_PATH_A) 397362306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, tmp_gs); 397462306a36Sopenharmony_ci else 397562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, tmp_gs); 397662306a36Sopenharmony_ci 397762306a36Sopenharmony_ci dpk_info->dpk_gs[path] = tmp_gs; 397862306a36Sopenharmony_ci} 397962306a36Sopenharmony_ci 398062306a36Sopenharmony_cistatic void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) 398162306a36Sopenharmony_ci{ 398262306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 398362306a36Sopenharmony_ci u32 offset[DPK_RF_PATH_NUM] = {0, 0x58}; 398462306a36Sopenharmony_ci u32 i_scaling; 398562306a36Sopenharmony_ci u8 path; 398662306a36Sopenharmony_ci 398762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); 398862306a36Sopenharmony_ci rtw_write32(rtwdev, REG_RXSRAM_CTL, 0x000000f0); 398962306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x00001148); 399062306a36Sopenharmony_ci rtw_write32(rtwdev, REG_NCTL0, 0x00001149); 399162306a36Sopenharmony_ci 399262306a36Sopenharmony_ci check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55); 399362306a36Sopenharmony_ci 399462306a36Sopenharmony_ci rtw_write8(rtwdev, 0x1b10, 0x0); 399562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); 399662306a36Sopenharmony_ci 399762306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 399862306a36Sopenharmony_ci i_scaling = 0x16c00 / dpk_info->dpk_gs[path]; 399962306a36Sopenharmony_ci 400062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b18 + offset[path], MASKHWORD, 400162306a36Sopenharmony_ci i_scaling); 400262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 400362306a36Sopenharmony_ci GENMASK(31, 28), 0x9); 400462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 400562306a36Sopenharmony_ci GENMASK(31, 28), 0x1); 400662306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0 + offset[path], 400762306a36Sopenharmony_ci GENMASK(31, 28), 0x0); 400862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0 + offset[path], 400962306a36Sopenharmony_ci BIT(14), 0x0); 401062306a36Sopenharmony_ci } 401162306a36Sopenharmony_ci} 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_cistatic void rtw8822c_dpk_on(struct rtw_dev *rtwdev, u8 path) 401462306a36Sopenharmony_ci{ 401562306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 401662306a36Sopenharmony_ci 401762306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); 401862306a36Sopenharmony_ci 401962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x8 | (path << 1)); 402062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_IQK_CTL1, BIT_TX_CFIR, 0x0); 402162306a36Sopenharmony_ci 402262306a36Sopenharmony_ci if (test_bit(path, dpk_info->dpk_path_ok)) 402362306a36Sopenharmony_ci rtw8822c_dpk_cal_gs(rtwdev, path); 402462306a36Sopenharmony_ci} 402562306a36Sopenharmony_ci 402662306a36Sopenharmony_cistatic bool rtw8822c_dpk_check_pass(struct rtw_dev *rtwdev, bool is_fail, 402762306a36Sopenharmony_ci u32 dpk_txagc, u8 path) 402862306a36Sopenharmony_ci{ 402962306a36Sopenharmony_ci bool result; 403062306a36Sopenharmony_ci 403162306a36Sopenharmony_ci if (!is_fail) { 403262306a36Sopenharmony_ci if (rtw8822c_dpk_coef_read(rtwdev, path)) 403362306a36Sopenharmony_ci result = true; 403462306a36Sopenharmony_ci else 403562306a36Sopenharmony_ci result = false; 403662306a36Sopenharmony_ci } else { 403762306a36Sopenharmony_ci result = false; 403862306a36Sopenharmony_ci } 403962306a36Sopenharmony_ci 404062306a36Sopenharmony_ci rtw8822c_dpk_fill_result(rtwdev, dpk_txagc, path, result); 404162306a36Sopenharmony_ci 404262306a36Sopenharmony_ci return result; 404362306a36Sopenharmony_ci} 404462306a36Sopenharmony_ci 404562306a36Sopenharmony_cistatic void rtw8822c_dpk_result_reset(struct rtw_dev *rtwdev) 404662306a36Sopenharmony_ci{ 404762306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 404862306a36Sopenharmony_ci u8 path; 404962306a36Sopenharmony_ci 405062306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 405162306a36Sopenharmony_ci clear_bit(path, dpk_info->dpk_path_ok); 405262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 405362306a36Sopenharmony_ci 0x8 | (path << 1)); 405462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b58, 0x0000007f, 0x0); 405562306a36Sopenharmony_ci 405662306a36Sopenharmony_ci dpk_info->dpk_txagc[path] = 0; 405762306a36Sopenharmony_ci dpk_info->result[path] = 0; 405862306a36Sopenharmony_ci dpk_info->dpk_gs[path] = 0x5b; 405962306a36Sopenharmony_ci dpk_info->pre_pwsf[path] = 0; 406062306a36Sopenharmony_ci dpk_info->thermal_dpk[path] = rtw8822c_dpk_thermal_read(rtwdev, 406162306a36Sopenharmony_ci path); 406262306a36Sopenharmony_ci } 406362306a36Sopenharmony_ci} 406462306a36Sopenharmony_ci 406562306a36Sopenharmony_cistatic void rtw8822c_dpk_calibrate(struct rtw_dev *rtwdev, u8 path) 406662306a36Sopenharmony_ci{ 406762306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 406862306a36Sopenharmony_ci u32 dpk_txagc; 406962306a36Sopenharmony_ci u8 dpk_fail; 407062306a36Sopenharmony_ci 407162306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk start\n", path); 407262306a36Sopenharmony_ci 407362306a36Sopenharmony_ci dpk_txagc = rtw8822c_dpk_gainloss(rtwdev, path); 407462306a36Sopenharmony_ci 407562306a36Sopenharmony_ci dpk_fail = rtw8822c_dpk_by_path(rtwdev, dpk_txagc, path); 407662306a36Sopenharmony_ci 407762306a36Sopenharmony_ci if (!rtw8822c_dpk_check_pass(rtwdev, dpk_fail, dpk_txagc, path)) 407862306a36Sopenharmony_ci rtw_err(rtwdev, "failed to do dpk calibration\n"); 407962306a36Sopenharmony_ci 408062306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] s%d dpk finish\n", path); 408162306a36Sopenharmony_ci 408262306a36Sopenharmony_ci if (dpk_info->result[path]) 408362306a36Sopenharmony_ci set_bit(path, dpk_info->dpk_path_ok); 408462306a36Sopenharmony_ci} 408562306a36Sopenharmony_ci 408662306a36Sopenharmony_cistatic void rtw8822c_dpk_path_select(struct rtw_dev *rtwdev) 408762306a36Sopenharmony_ci{ 408862306a36Sopenharmony_ci rtw8822c_dpk_calibrate(rtwdev, RF_PATH_A); 408962306a36Sopenharmony_ci rtw8822c_dpk_calibrate(rtwdev, RF_PATH_B); 409062306a36Sopenharmony_ci rtw8822c_dpk_on(rtwdev, RF_PATH_A); 409162306a36Sopenharmony_ci rtw8822c_dpk_on(rtwdev, RF_PATH_B); 409262306a36Sopenharmony_ci rtw8822c_dpk_cal_coef1(rtwdev); 409362306a36Sopenharmony_ci} 409462306a36Sopenharmony_ci 409562306a36Sopenharmony_cistatic void rtw8822c_dpk_enable_disable(struct rtw_dev *rtwdev) 409662306a36Sopenharmony_ci{ 409762306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 409862306a36Sopenharmony_ci u32 mask = BIT(15) | BIT(14); 409962306a36Sopenharmony_ci 410062306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 410162306a36Sopenharmony_ci 410262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, BIT_DPD_EN, 410362306a36Sopenharmony_ci dpk_info->is_dpk_pwr_on); 410462306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, BIT_DPD_EN, 410562306a36Sopenharmony_ci dpk_info->is_dpk_pwr_on); 410662306a36Sopenharmony_ci 410762306a36Sopenharmony_ci if (test_bit(RF_PATH_A, dpk_info->dpk_path_ok)) { 410862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S0, mask, 0x0); 410962306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DPD_CTL0_S0, dpk_info->dpk_gs[RF_PATH_A]); 411062306a36Sopenharmony_ci } 411162306a36Sopenharmony_ci if (test_bit(RF_PATH_B, dpk_info->dpk_path_ok)) { 411262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL1_S1, mask, 0x0); 411362306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DPD_CTL0_S1, dpk_info->dpk_gs[RF_PATH_B]); 411462306a36Sopenharmony_ci } 411562306a36Sopenharmony_ci} 411662306a36Sopenharmony_ci 411762306a36Sopenharmony_cistatic void rtw8822c_dpk_reload_data(struct rtw_dev *rtwdev) 411862306a36Sopenharmony_ci{ 411962306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 412062306a36Sopenharmony_ci u8 path; 412162306a36Sopenharmony_ci 412262306a36Sopenharmony_ci if (!test_bit(RF_PATH_A, dpk_info->dpk_path_ok) && 412362306a36Sopenharmony_ci !test_bit(RF_PATH_B, dpk_info->dpk_path_ok) && 412462306a36Sopenharmony_ci dpk_info->dpk_ch == 0) 412562306a36Sopenharmony_ci return; 412662306a36Sopenharmony_ci 412762306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 412862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 412962306a36Sopenharmony_ci 0x8 | (path << 1)); 413062306a36Sopenharmony_ci if (dpk_info->dpk_band == RTW_BAND_2G) 413162306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f100000); 413262306a36Sopenharmony_ci else 413362306a36Sopenharmony_ci rtw_write32(rtwdev, REG_DPD_CTL1_S1, 0x1f0d0000); 413462306a36Sopenharmony_ci 413562306a36Sopenharmony_ci rtw_write8(rtwdev, REG_DPD_AGC, dpk_info->dpk_txagc[path]); 413662306a36Sopenharmony_ci 413762306a36Sopenharmony_ci rtw8822c_dpk_coef_write(rtwdev, path, 413862306a36Sopenharmony_ci test_bit(path, dpk_info->dpk_path_ok)); 413962306a36Sopenharmony_ci 414062306a36Sopenharmony_ci rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DPK_ON); 414162306a36Sopenharmony_ci 414262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0xc); 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_ci if (path == RF_PATH_A) 414562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S0, BIT_GS_PWSF, 414662306a36Sopenharmony_ci dpk_info->dpk_gs[path]); 414762306a36Sopenharmony_ci else 414862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_DPD_CTL0_S1, BIT_GS_PWSF, 414962306a36Sopenharmony_ci dpk_info->dpk_gs[path]); 415062306a36Sopenharmony_ci } 415162306a36Sopenharmony_ci rtw8822c_dpk_cal_coef1(rtwdev); 415262306a36Sopenharmony_ci} 415362306a36Sopenharmony_ci 415462306a36Sopenharmony_cistatic bool rtw8822c_dpk_reload(struct rtw_dev *rtwdev) 415562306a36Sopenharmony_ci{ 415662306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 415762306a36Sopenharmony_ci u8 channel; 415862306a36Sopenharmony_ci 415962306a36Sopenharmony_ci dpk_info->is_reload = false; 416062306a36Sopenharmony_ci 416162306a36Sopenharmony_ci channel = (u8)(rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK) & 0xff); 416262306a36Sopenharmony_ci 416362306a36Sopenharmony_ci if (channel == dpk_info->dpk_ch) { 416462306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, 416562306a36Sopenharmony_ci "[DPK] DPK reload for CH%d!!\n", dpk_info->dpk_ch); 416662306a36Sopenharmony_ci rtw8822c_dpk_reload_data(rtwdev); 416762306a36Sopenharmony_ci dpk_info->is_reload = true; 416862306a36Sopenharmony_ci } 416962306a36Sopenharmony_ci 417062306a36Sopenharmony_ci return dpk_info->is_reload; 417162306a36Sopenharmony_ci} 417262306a36Sopenharmony_ci 417362306a36Sopenharmony_cistatic void rtw8822c_do_dpk(struct rtw_dev *rtwdev) 417462306a36Sopenharmony_ci{ 417562306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 417662306a36Sopenharmony_ci struct rtw_backup_info bckp[DPK_BB_REG_NUM]; 417762306a36Sopenharmony_ci u32 rf_reg_backup[DPK_RF_REG_NUM][DPK_RF_PATH_NUM]; 417862306a36Sopenharmony_ci u32 bb_reg[DPK_BB_REG_NUM] = { 417962306a36Sopenharmony_ci 0x520, 0x820, 0x824, 0x1c3c, 0x1d58, 0x1864, 418062306a36Sopenharmony_ci 0x4164, 0x180c, 0x410c, 0x186c, 0x416c, 418162306a36Sopenharmony_ci 0x1a14, 0x1e70, 0x80c, 0x1d70, 0x1e7c, 0x18a4, 0x41a4}; 418262306a36Sopenharmony_ci u32 rf_reg[DPK_RF_REG_NUM] = { 418362306a36Sopenharmony_ci 0x0, 0x1a, 0x55, 0x63, 0x87, 0x8f, 0xde}; 418462306a36Sopenharmony_ci u8 path; 418562306a36Sopenharmony_ci 418662306a36Sopenharmony_ci if (!dpk_info->is_dpk_pwr_on) { 418762306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_RFK, "[DPK] Skip DPK due to DPD PWR off\n"); 418862306a36Sopenharmony_ci return; 418962306a36Sopenharmony_ci } else if (rtw8822c_dpk_reload(rtwdev)) { 419062306a36Sopenharmony_ci return; 419162306a36Sopenharmony_ci } 419262306a36Sopenharmony_ci 419362306a36Sopenharmony_ci for (path = RF_PATH_A; path < DPK_RF_PATH_NUM; path++) 419462306a36Sopenharmony_ci ewma_thermal_init(&dpk_info->avg_thermal[path]); 419562306a36Sopenharmony_ci 419662306a36Sopenharmony_ci rtw8822c_dpk_information(rtwdev); 419762306a36Sopenharmony_ci 419862306a36Sopenharmony_ci rtw8822c_dpk_backup_registers(rtwdev, bb_reg, DPK_BB_REG_NUM, bckp); 419962306a36Sopenharmony_ci rtw8822c_dpk_backup_rf_registers(rtwdev, rf_reg, rf_reg_backup); 420062306a36Sopenharmony_ci 420162306a36Sopenharmony_ci rtw8822c_dpk_mac_bb_setting(rtwdev); 420262306a36Sopenharmony_ci rtw8822c_dpk_afe_setting(rtwdev, true); 420362306a36Sopenharmony_ci rtw8822c_dpk_pre_setting(rtwdev); 420462306a36Sopenharmony_ci rtw8822c_dpk_result_reset(rtwdev); 420562306a36Sopenharmony_ci rtw8822c_dpk_path_select(rtwdev); 420662306a36Sopenharmony_ci rtw8822c_dpk_afe_setting(rtwdev, false); 420762306a36Sopenharmony_ci rtw8822c_dpk_enable_disable(rtwdev); 420862306a36Sopenharmony_ci 420962306a36Sopenharmony_ci rtw8822c_dpk_reload_rf_registers(rtwdev, rf_reg, rf_reg_backup); 421062306a36Sopenharmony_ci for (path = 0; path < rtwdev->hal.rf_path_num; path++) 421162306a36Sopenharmony_ci rtw8822c_dpk_rxbb_dc_cal(rtwdev, path); 421262306a36Sopenharmony_ci rtw8822c_dpk_restore_registers(rtwdev, DPK_BB_REG_NUM, bckp); 421362306a36Sopenharmony_ci} 421462306a36Sopenharmony_ci 421562306a36Sopenharmony_cistatic void rtw8822c_phy_calibration(struct rtw_dev *rtwdev) 421662306a36Sopenharmony_ci{ 421762306a36Sopenharmony_ci rtw8822c_rfk_power_save(rtwdev, false); 421862306a36Sopenharmony_ci rtw8822c_do_gapk(rtwdev); 421962306a36Sopenharmony_ci rtw8822c_do_iqk(rtwdev); 422062306a36Sopenharmony_ci rtw8822c_do_dpk(rtwdev); 422162306a36Sopenharmony_ci rtw8822c_rfk_power_save(rtwdev, true); 422262306a36Sopenharmony_ci} 422362306a36Sopenharmony_ci 422462306a36Sopenharmony_cistatic void rtw8822c_dpk_track(struct rtw_dev *rtwdev) 422562306a36Sopenharmony_ci{ 422662306a36Sopenharmony_ci struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; 422762306a36Sopenharmony_ci u8 path; 422862306a36Sopenharmony_ci u8 thermal_value[DPK_RF_PATH_NUM] = {0}; 422962306a36Sopenharmony_ci s8 offset[DPK_RF_PATH_NUM], delta_dpk[DPK_RF_PATH_NUM]; 423062306a36Sopenharmony_ci 423162306a36Sopenharmony_ci if (dpk_info->thermal_dpk[0] == 0 && dpk_info->thermal_dpk[1] == 0) 423262306a36Sopenharmony_ci return; 423362306a36Sopenharmony_ci 423462306a36Sopenharmony_ci for (path = 0; path < DPK_RF_PATH_NUM; path++) { 423562306a36Sopenharmony_ci thermal_value[path] = rtw8822c_dpk_thermal_read(rtwdev, path); 423662306a36Sopenharmony_ci ewma_thermal_add(&dpk_info->avg_thermal[path], 423762306a36Sopenharmony_ci thermal_value[path]); 423862306a36Sopenharmony_ci thermal_value[path] = 423962306a36Sopenharmony_ci ewma_thermal_read(&dpk_info->avg_thermal[path]); 424062306a36Sopenharmony_ci delta_dpk[path] = dpk_info->thermal_dpk[path] - 424162306a36Sopenharmony_ci thermal_value[path]; 424262306a36Sopenharmony_ci offset[path] = delta_dpk[path] - 424362306a36Sopenharmony_ci dpk_info->thermal_dpk_delta[path]; 424462306a36Sopenharmony_ci offset[path] &= 0x7f; 424562306a36Sopenharmony_ci 424662306a36Sopenharmony_ci if (offset[path] != dpk_info->pre_pwsf[path]) { 424762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 424862306a36Sopenharmony_ci 0x8 | (path << 1)); 424962306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x1b58, GENMASK(6, 0), 425062306a36Sopenharmony_ci offset[path]); 425162306a36Sopenharmony_ci dpk_info->pre_pwsf[path] = offset[path]; 425262306a36Sopenharmony_ci } 425362306a36Sopenharmony_ci } 425462306a36Sopenharmony_ci} 425562306a36Sopenharmony_ci 425662306a36Sopenharmony_ci#define XCAP_EXTEND(val) ({typeof(val) _v = (val); _v | _v << 7; }) 425762306a36Sopenharmony_cistatic void rtw8822c_set_crystal_cap_reg(struct rtw_dev *rtwdev, u8 crystal_cap) 425862306a36Sopenharmony_ci{ 425962306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 426062306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 426162306a36Sopenharmony_ci u32 val = 0; 426262306a36Sopenharmony_ci 426362306a36Sopenharmony_ci val = XCAP_EXTEND(crystal_cap); 426462306a36Sopenharmony_ci cfo->crystal_cap = crystal_cap; 426562306a36Sopenharmony_ci rtw_write32_mask(rtwdev, REG_ANAPAR_XTAL_0, BIT_XCAP_0, val); 426662306a36Sopenharmony_ci} 426762306a36Sopenharmony_ci 426862306a36Sopenharmony_cistatic void rtw8822c_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap) 426962306a36Sopenharmony_ci{ 427062306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 427162306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 427262306a36Sopenharmony_ci 427362306a36Sopenharmony_ci if (cfo->crystal_cap == crystal_cap) 427462306a36Sopenharmony_ci return; 427562306a36Sopenharmony_ci 427662306a36Sopenharmony_ci rtw8822c_set_crystal_cap_reg(rtwdev, crystal_cap); 427762306a36Sopenharmony_ci} 427862306a36Sopenharmony_ci 427962306a36Sopenharmony_cistatic void rtw8822c_cfo_tracking_reset(struct rtw_dev *rtwdev) 428062306a36Sopenharmony_ci{ 428162306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 428262306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 428362306a36Sopenharmony_ci 428462306a36Sopenharmony_ci cfo->is_adjust = true; 428562306a36Sopenharmony_ci 428662306a36Sopenharmony_ci if (cfo->crystal_cap > rtwdev->efuse.crystal_cap) 428762306a36Sopenharmony_ci rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap - 1); 428862306a36Sopenharmony_ci else if (cfo->crystal_cap < rtwdev->efuse.crystal_cap) 428962306a36Sopenharmony_ci rtw8822c_set_crystal_cap(rtwdev, cfo->crystal_cap + 1); 429062306a36Sopenharmony_ci} 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_cistatic void rtw8822c_cfo_init(struct rtw_dev *rtwdev) 429362306a36Sopenharmony_ci{ 429462306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 429562306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 429662306a36Sopenharmony_ci 429762306a36Sopenharmony_ci cfo->crystal_cap = rtwdev->efuse.crystal_cap; 429862306a36Sopenharmony_ci cfo->is_adjust = true; 429962306a36Sopenharmony_ci} 430062306a36Sopenharmony_ci 430162306a36Sopenharmony_ci#define REPORT_TO_KHZ(val) ({typeof(val) _v = (val); (_v << 1) + (_v >> 1); }) 430262306a36Sopenharmony_cistatic s32 rtw8822c_cfo_calc_avg(struct rtw_dev *rtwdev, u8 path_num) 430362306a36Sopenharmony_ci{ 430462306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 430562306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 430662306a36Sopenharmony_ci s32 cfo_avg, cfo_path_sum = 0, cfo_rpt_sum; 430762306a36Sopenharmony_ci u8 i; 430862306a36Sopenharmony_ci 430962306a36Sopenharmony_ci for (i = 0; i < path_num; i++) { 431062306a36Sopenharmony_ci cfo_rpt_sum = REPORT_TO_KHZ(cfo->cfo_tail[i]); 431162306a36Sopenharmony_ci 431262306a36Sopenharmony_ci if (cfo->cfo_cnt[i]) 431362306a36Sopenharmony_ci cfo_avg = cfo_rpt_sum / cfo->cfo_cnt[i]; 431462306a36Sopenharmony_ci else 431562306a36Sopenharmony_ci cfo_avg = 0; 431662306a36Sopenharmony_ci 431762306a36Sopenharmony_ci cfo_path_sum += cfo_avg; 431862306a36Sopenharmony_ci } 431962306a36Sopenharmony_ci 432062306a36Sopenharmony_ci for (i = 0; i < path_num; i++) { 432162306a36Sopenharmony_ci cfo->cfo_tail[i] = 0; 432262306a36Sopenharmony_ci cfo->cfo_cnt[i] = 0; 432362306a36Sopenharmony_ci } 432462306a36Sopenharmony_ci 432562306a36Sopenharmony_ci return cfo_path_sum / path_num; 432662306a36Sopenharmony_ci} 432762306a36Sopenharmony_ci 432862306a36Sopenharmony_cistatic void rtw8822c_cfo_need_adjust(struct rtw_dev *rtwdev, s32 cfo_avg) 432962306a36Sopenharmony_ci{ 433062306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 433162306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 433262306a36Sopenharmony_ci 433362306a36Sopenharmony_ci if (!cfo->is_adjust) { 433462306a36Sopenharmony_ci if (abs(cfo_avg) > CFO_TRK_ENABLE_TH) 433562306a36Sopenharmony_ci cfo->is_adjust = true; 433662306a36Sopenharmony_ci } else { 433762306a36Sopenharmony_ci if (abs(cfo_avg) <= CFO_TRK_STOP_TH) 433862306a36Sopenharmony_ci cfo->is_adjust = false; 433962306a36Sopenharmony_ci } 434062306a36Sopenharmony_ci 434162306a36Sopenharmony_ci if (!rtw_coex_disabled(rtwdev)) { 434262306a36Sopenharmony_ci cfo->is_adjust = false; 434362306a36Sopenharmony_ci rtw8822c_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); 434462306a36Sopenharmony_ci } 434562306a36Sopenharmony_ci} 434662306a36Sopenharmony_ci 434762306a36Sopenharmony_cistatic void rtw8822c_cfo_track(struct rtw_dev *rtwdev) 434862306a36Sopenharmony_ci{ 434962306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 435062306a36Sopenharmony_ci struct rtw_cfo_track *cfo = &dm_info->cfo_track; 435162306a36Sopenharmony_ci u8 path_num = rtwdev->hal.rf_path_num; 435262306a36Sopenharmony_ci s8 crystal_cap = cfo->crystal_cap; 435362306a36Sopenharmony_ci s32 cfo_avg = 0; 435462306a36Sopenharmony_ci 435562306a36Sopenharmony_ci if (rtwdev->sta_cnt != 1) { 435662306a36Sopenharmony_ci rtw8822c_cfo_tracking_reset(rtwdev); 435762306a36Sopenharmony_ci return; 435862306a36Sopenharmony_ci } 435962306a36Sopenharmony_ci 436062306a36Sopenharmony_ci if (cfo->packet_count == cfo->packet_count_pre) 436162306a36Sopenharmony_ci return; 436262306a36Sopenharmony_ci 436362306a36Sopenharmony_ci cfo->packet_count_pre = cfo->packet_count; 436462306a36Sopenharmony_ci cfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num); 436562306a36Sopenharmony_ci rtw8822c_cfo_need_adjust(rtwdev, cfo_avg); 436662306a36Sopenharmony_ci 436762306a36Sopenharmony_ci if (cfo->is_adjust) { 436862306a36Sopenharmony_ci if (cfo_avg > CFO_TRK_ADJ_TH) 436962306a36Sopenharmony_ci crystal_cap++; 437062306a36Sopenharmony_ci else if (cfo_avg < -CFO_TRK_ADJ_TH) 437162306a36Sopenharmony_ci crystal_cap--; 437262306a36Sopenharmony_ci 437362306a36Sopenharmony_ci crystal_cap = clamp_t(s8, crystal_cap, 0, XCAP_MASK); 437462306a36Sopenharmony_ci rtw8822c_set_crystal_cap(rtwdev, (u8)crystal_cap); 437562306a36Sopenharmony_ci } 437662306a36Sopenharmony_ci} 437762306a36Sopenharmony_ci 437862306a36Sopenharmony_cistatic const struct rtw_phy_cck_pd_reg 437962306a36Sopenharmony_cirtw8822c_cck_pd_reg[RTW_CHANNEL_WIDTH_40 + 1][RTW_RF_PATH_MAX] = { 438062306a36Sopenharmony_ci { 438162306a36Sopenharmony_ci {0x1ac8, 0x00ff, 0x1ad0, 0x01f}, 438262306a36Sopenharmony_ci {0x1ac8, 0xff00, 0x1ad0, 0x3e0} 438362306a36Sopenharmony_ci }, 438462306a36Sopenharmony_ci { 438562306a36Sopenharmony_ci {0x1acc, 0x00ff, 0x1ad0, 0x01F00000}, 438662306a36Sopenharmony_ci {0x1acc, 0xff00, 0x1ad0, 0x3E000000} 438762306a36Sopenharmony_ci }, 438862306a36Sopenharmony_ci}; 438962306a36Sopenharmony_ci 439062306a36Sopenharmony_ci#define RTW_CCK_PD_MAX 255 439162306a36Sopenharmony_ci#define RTW_CCK_CS_MAX 31 439262306a36Sopenharmony_ci#define RTW_CCK_CS_ERR1 27 439362306a36Sopenharmony_ci#define RTW_CCK_CS_ERR2 29 439462306a36Sopenharmony_cistatic void 439562306a36Sopenharmony_cirtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev, 439662306a36Sopenharmony_ci s8 pd_diff, s8 cs_diff, u8 bw, u8 nrx) 439762306a36Sopenharmony_ci{ 439862306a36Sopenharmony_ci u32 pd, cs; 439962306a36Sopenharmony_ci 440062306a36Sopenharmony_ci if (WARN_ON(bw > RTW_CHANNEL_WIDTH_40 || nrx >= RTW_RF_PATH_MAX)) 440162306a36Sopenharmony_ci return; 440262306a36Sopenharmony_ci 440362306a36Sopenharmony_ci pd = rtw_read32_mask(rtwdev, 440462306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].reg_pd, 440562306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].mask_pd); 440662306a36Sopenharmony_ci cs = rtw_read32_mask(rtwdev, 440762306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].reg_cs, 440862306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].mask_cs); 440962306a36Sopenharmony_ci pd += pd_diff; 441062306a36Sopenharmony_ci cs += cs_diff; 441162306a36Sopenharmony_ci if (pd > RTW_CCK_PD_MAX) 441262306a36Sopenharmony_ci pd = RTW_CCK_PD_MAX; 441362306a36Sopenharmony_ci if (cs == RTW_CCK_CS_ERR1 || cs == RTW_CCK_CS_ERR2) 441462306a36Sopenharmony_ci cs++; 441562306a36Sopenharmony_ci else if (cs > RTW_CCK_CS_MAX) 441662306a36Sopenharmony_ci cs = RTW_CCK_CS_MAX; 441762306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 441862306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].reg_pd, 441962306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].mask_pd, 442062306a36Sopenharmony_ci pd); 442162306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 442262306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].reg_cs, 442362306a36Sopenharmony_ci rtw8822c_cck_pd_reg[bw][nrx].mask_cs, 442462306a36Sopenharmony_ci cs); 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_PHY, 442762306a36Sopenharmony_ci "is_linked=%d, bw=%d, nrx=%d, cs_ratio=0x%x, pd_th=0x%x\n", 442862306a36Sopenharmony_ci rtw_is_assoc(rtwdev), bw, nrx, cs, pd); 442962306a36Sopenharmony_ci} 443062306a36Sopenharmony_ci 443162306a36Sopenharmony_cistatic void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) 443262306a36Sopenharmony_ci{ 443362306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 443462306a36Sopenharmony_ci s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8}; 443562306a36Sopenharmony_ci s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4}; 443662306a36Sopenharmony_ci u8 cur_lvl; 443762306a36Sopenharmony_ci u8 nrx, bw; 443862306a36Sopenharmony_ci 443962306a36Sopenharmony_ci nrx = (u8)rtw_read32_mask(rtwdev, 0x1a2c, 0x60000); 444062306a36Sopenharmony_ci bw = (u8)rtw_read32_mask(rtwdev, 0x9b0, 0xc); 444162306a36Sopenharmony_ci 444262306a36Sopenharmony_ci rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d) bw=%d nr=%d cck_fa_avg=%d\n", 444362306a36Sopenharmony_ci dm_info->cck_pd_lv[bw][nrx], new_lvl, bw, nrx, 444462306a36Sopenharmony_ci dm_info->cck_fa_avg); 444562306a36Sopenharmony_ci 444662306a36Sopenharmony_ci if (dm_info->cck_pd_lv[bw][nrx] == new_lvl) 444762306a36Sopenharmony_ci return; 444862306a36Sopenharmony_ci 444962306a36Sopenharmony_ci cur_lvl = dm_info->cck_pd_lv[bw][nrx]; 445062306a36Sopenharmony_ci 445162306a36Sopenharmony_ci /* update cck pd info */ 445262306a36Sopenharmony_ci dm_info->cck_fa_avg = CCK_FA_AVG_RESET; 445362306a36Sopenharmony_ci 445462306a36Sopenharmony_ci rtw8822c_phy_cck_pd_set_reg(rtwdev, 445562306a36Sopenharmony_ci pd_lvl[new_lvl] - pd_lvl[cur_lvl], 445662306a36Sopenharmony_ci cs_lvl[new_lvl] - cs_lvl[cur_lvl], 445762306a36Sopenharmony_ci bw, nrx); 445862306a36Sopenharmony_ci dm_info->cck_pd_lv[bw][nrx] = new_lvl; 445962306a36Sopenharmony_ci} 446062306a36Sopenharmony_ci 446162306a36Sopenharmony_ci#define PWR_TRACK_MASK 0x7f 446262306a36Sopenharmony_cistatic void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) 446362306a36Sopenharmony_ci{ 446462306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 446562306a36Sopenharmony_ci 446662306a36Sopenharmony_ci switch (rf_path) { 446762306a36Sopenharmony_ci case RF_PATH_A: 446862306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK, 446962306a36Sopenharmony_ci dm_info->delta_power_index[rf_path]); 447062306a36Sopenharmony_ci break; 447162306a36Sopenharmony_ci case RF_PATH_B: 447262306a36Sopenharmony_ci rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK, 447362306a36Sopenharmony_ci dm_info->delta_power_index[rf_path]); 447462306a36Sopenharmony_ci break; 447562306a36Sopenharmony_ci default: 447662306a36Sopenharmony_ci break; 447762306a36Sopenharmony_ci } 447862306a36Sopenharmony_ci} 447962306a36Sopenharmony_ci 448062306a36Sopenharmony_cistatic void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path) 448162306a36Sopenharmony_ci{ 448262306a36Sopenharmony_ci u8 thermal_value; 448362306a36Sopenharmony_ci 448462306a36Sopenharmony_ci if (rtwdev->efuse.thermal_meter[path] == 0xff) 448562306a36Sopenharmony_ci return; 448662306a36Sopenharmony_ci 448762306a36Sopenharmony_ci thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); 448862306a36Sopenharmony_ci rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); 448962306a36Sopenharmony_ci} 449062306a36Sopenharmony_ci 449162306a36Sopenharmony_cistatic void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, 449262306a36Sopenharmony_ci struct rtw_swing_table *swing_table, 449362306a36Sopenharmony_ci u8 path) 449462306a36Sopenharmony_ci{ 449562306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 449662306a36Sopenharmony_ci u8 delta; 449762306a36Sopenharmony_ci 449862306a36Sopenharmony_ci delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); 449962306a36Sopenharmony_ci dm_info->delta_power_index[path] = 450062306a36Sopenharmony_ci rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, 450162306a36Sopenharmony_ci delta); 450262306a36Sopenharmony_ci rtw8822c_pwrtrack_set(rtwdev, path); 450362306a36Sopenharmony_ci} 450462306a36Sopenharmony_ci 450562306a36Sopenharmony_cistatic void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) 450662306a36Sopenharmony_ci{ 450762306a36Sopenharmony_ci struct rtw_swing_table swing_table; 450862306a36Sopenharmony_ci u8 i; 450962306a36Sopenharmony_ci 451062306a36Sopenharmony_ci rtw_phy_config_swing_table(rtwdev, &swing_table); 451162306a36Sopenharmony_ci 451262306a36Sopenharmony_ci for (i = 0; i < rtwdev->hal.rf_path_num; i++) 451362306a36Sopenharmony_ci rtw8822c_pwr_track_stats(rtwdev, i); 451462306a36Sopenharmony_ci if (rtw_phy_pwrtrack_need_lck(rtwdev)) 451562306a36Sopenharmony_ci rtw8822c_do_lck(rtwdev); 451662306a36Sopenharmony_ci for (i = 0; i < rtwdev->hal.rf_path_num; i++) 451762306a36Sopenharmony_ci rtw8822c_pwr_track_path(rtwdev, &swing_table, i); 451862306a36Sopenharmony_ci} 451962306a36Sopenharmony_ci 452062306a36Sopenharmony_cistatic void rtw8822c_pwr_track(struct rtw_dev *rtwdev) 452162306a36Sopenharmony_ci{ 452262306a36Sopenharmony_ci struct rtw_efuse *efuse = &rtwdev->efuse; 452362306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 452462306a36Sopenharmony_ci 452562306a36Sopenharmony_ci if (efuse->power_track_type != 0) 452662306a36Sopenharmony_ci return; 452762306a36Sopenharmony_ci 452862306a36Sopenharmony_ci if (!dm_info->pwr_trk_triggered) { 452962306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 453062306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00); 453162306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 453262306a36Sopenharmony_ci 453362306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 453462306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00); 453562306a36Sopenharmony_ci rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 453662306a36Sopenharmony_ci 453762306a36Sopenharmony_ci dm_info->pwr_trk_triggered = true; 453862306a36Sopenharmony_ci return; 453962306a36Sopenharmony_ci } 454062306a36Sopenharmony_ci 454162306a36Sopenharmony_ci __rtw8822c_pwr_track(rtwdev); 454262306a36Sopenharmony_ci dm_info->pwr_trk_triggered = false; 454362306a36Sopenharmony_ci} 454462306a36Sopenharmony_ci 454562306a36Sopenharmony_cistatic void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev) 454662306a36Sopenharmony_ci{ 454762306a36Sopenharmony_ci rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX); 454862306a36Sopenharmony_ci 454962306a36Sopenharmony_ci /* mac edcca state setting */ 455062306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA); 455162306a36Sopenharmony_ci rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN); 455262306a36Sopenharmony_ci 455362306a36Sopenharmony_ci /* edcca decistion opt */ 455462306a36Sopenharmony_ci rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION); 455562306a36Sopenharmony_ci} 455662306a36Sopenharmony_ci 455762306a36Sopenharmony_cistatic void rtw8822c_adaptivity(struct rtw_dev *rtwdev) 455862306a36Sopenharmony_ci{ 455962306a36Sopenharmony_ci struct rtw_dm_info *dm_info = &rtwdev->dm_info; 456062306a36Sopenharmony_ci s8 l2h, h2l; 456162306a36Sopenharmony_ci u8 igi; 456262306a36Sopenharmony_ci 456362306a36Sopenharmony_ci igi = dm_info->igi_history[0]; 456462306a36Sopenharmony_ci if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { 456562306a36Sopenharmony_ci l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); 456662306a36Sopenharmony_ci h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; 456762306a36Sopenharmony_ci } else { 456862306a36Sopenharmony_ci if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF) 456962306a36Sopenharmony_ci l2h = igi + EDCCA_ADC_BACKOFF; 457062306a36Sopenharmony_ci else 457162306a36Sopenharmony_ci l2h = dm_info->l2h_th_ini; 457262306a36Sopenharmony_ci h2l = l2h - EDCCA_L2H_H2L_DIFF; 457362306a36Sopenharmony_ci } 457462306a36Sopenharmony_ci 457562306a36Sopenharmony_ci rtw_phy_set_edcca_th(rtwdev, l2h, h2l); 457662306a36Sopenharmony_ci} 457762306a36Sopenharmony_ci 457862306a36Sopenharmony_cistatic void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, 457962306a36Sopenharmony_ci struct rtw_tx_pkt_info *pkt_info, 458062306a36Sopenharmony_ci u8 *txdesc) 458162306a36Sopenharmony_ci{ 458262306a36Sopenharmony_ci const struct rtw_chip_info *chip = rtwdev->chip; 458362306a36Sopenharmony_ci size_t words; 458462306a36Sopenharmony_ci 458562306a36Sopenharmony_ci words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2; 458662306a36Sopenharmony_ci 458762306a36Sopenharmony_ci fill_txdesc_checksum_common(txdesc, words); 458862306a36Sopenharmony_ci} 458962306a36Sopenharmony_ci 459062306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { 459162306a36Sopenharmony_ci {0x0086, 459262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 459362306a36Sopenharmony_ci RTW_PWR_INTF_SDIO_MSK, 459462306a36Sopenharmony_ci RTW_PWR_ADDR_SDIO, 459562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), 0}, 459662306a36Sopenharmony_ci {0x0086, 459762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 459862306a36Sopenharmony_ci RTW_PWR_INTF_SDIO_MSK, 459962306a36Sopenharmony_ci RTW_PWR_ADDR_SDIO, 460062306a36Sopenharmony_ci RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 460162306a36Sopenharmony_ci {0x002E, 460262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 460362306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 460462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 460562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 460662306a36Sopenharmony_ci {0x002D, 460762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 460862306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 460962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 461062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), 0}, 461162306a36Sopenharmony_ci {0x007F, 461262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 461362306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 461462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 461562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(7), 0}, 461662306a36Sopenharmony_ci {0x004A, 461762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 461862306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK, 461962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 462062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), 0}, 462162306a36Sopenharmony_ci {0x0005, 462262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 462362306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 462462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 462562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, 462662306a36Sopenharmony_ci {0xFFFF, 462762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 462862306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 462962306a36Sopenharmony_ci 0, 463062306a36Sopenharmony_ci RTW_PWR_CMD_END, 0, 0}, 463162306a36Sopenharmony_ci}; 463262306a36Sopenharmony_ci 463362306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822c[] = { 463462306a36Sopenharmony_ci {0x0000, 463562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 463662306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 463762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 463862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(5), 0}, 463962306a36Sopenharmony_ci {0x0005, 464062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 464162306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 464262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 464362306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, 464462306a36Sopenharmony_ci {0x0075, 464562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 464662306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 464762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 464862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 464962306a36Sopenharmony_ci {0x0006, 465062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 465162306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 465262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 465362306a36Sopenharmony_ci RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 465462306a36Sopenharmony_ci {0x0075, 465562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 465662306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 465762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 465862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), 0}, 465962306a36Sopenharmony_ci {0xFF1A, 466062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 466162306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK, 466262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 466362306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0}, 466462306a36Sopenharmony_ci {0x002E, 466562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 466662306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 466762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 466862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(3), 0}, 466962306a36Sopenharmony_ci {0x0006, 467062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 467162306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 467262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 467362306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 467462306a36Sopenharmony_ci {0x0005, 467562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 467662306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 467762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 467862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, 467962306a36Sopenharmony_ci {0x1018, 468062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 468162306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 468262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 468362306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 468462306a36Sopenharmony_ci {0x0005, 468562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 468662306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 468762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 468862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 468962306a36Sopenharmony_ci {0x0005, 469062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 469162306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 469262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 469362306a36Sopenharmony_ci RTW_PWR_CMD_POLLING, BIT(0), 0}, 469462306a36Sopenharmony_ci {0x0074, 469562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 469662306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 469762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 469862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 469962306a36Sopenharmony_ci {0x0071, 470062306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 470162306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 470262306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 470362306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(4), 0}, 470462306a36Sopenharmony_ci {0x0062, 470562306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 470662306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 470762306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 470862306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 470962306a36Sopenharmony_ci (BIT(7) | BIT(6) | BIT(5))}, 471062306a36Sopenharmony_ci {0x0061, 471162306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 471262306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 471362306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 471462306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, 471562306a36Sopenharmony_ci {0x001F, 471662306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 471762306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 471862306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 471962306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, 472062306a36Sopenharmony_ci {0x00EF, 472162306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 472262306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 472362306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 472462306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6)), BIT(7)}, 472562306a36Sopenharmony_ci {0x1045, 472662306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 472762306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 472862306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 472962306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, 473062306a36Sopenharmony_ci {0x0010, 473162306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 473262306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 473362306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 473462306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 473562306a36Sopenharmony_ci {0x1064, 473662306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 473762306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 473862306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 473962306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 474062306a36Sopenharmony_ci {0xFFFF, 474162306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 474262306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 474362306a36Sopenharmony_ci 0, 474462306a36Sopenharmony_ci RTW_PWR_CMD_END, 0, 0}, 474562306a36Sopenharmony_ci}; 474662306a36Sopenharmony_ci 474762306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822c[] = { 474862306a36Sopenharmony_ci {0x0093, 474962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 475062306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 475162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 475262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(3), 0}, 475362306a36Sopenharmony_ci {0x001F, 475462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 475562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 475662306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 475762306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0}, 475862306a36Sopenharmony_ci {0x00EF, 475962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 476062306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 476162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 476262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0}, 476362306a36Sopenharmony_ci {0x1045, 476462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 476562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 476662306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 476762306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(4), 0}, 476862306a36Sopenharmony_ci {0xFF1A, 476962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 477062306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK, 477162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 477262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0x30}, 477362306a36Sopenharmony_ci {0x0049, 477462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 477562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 477662306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 477762306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(1), 0}, 477862306a36Sopenharmony_ci {0x0006, 477962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 478062306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 478162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 478262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 478362306a36Sopenharmony_ci {0x0002, 478462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 478562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 478662306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 478762306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(1), 0}, 478862306a36Sopenharmony_ci {0x0005, 478962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 479062306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 479162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 479262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 479362306a36Sopenharmony_ci {0x0005, 479462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 479562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 479662306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 479762306a36Sopenharmony_ci RTW_PWR_CMD_POLLING, BIT(1), 0}, 479862306a36Sopenharmony_ci {0x0000, 479962306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 480062306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 480162306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 480262306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 480362306a36Sopenharmony_ci {0xFFFF, 480462306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 480562306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 480662306a36Sopenharmony_ci 0, 480762306a36Sopenharmony_ci RTW_PWR_CMD_END, 0, 0}, 480862306a36Sopenharmony_ci}; 480962306a36Sopenharmony_ci 481062306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = { 481162306a36Sopenharmony_ci {0x0005, 481262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 481362306a36Sopenharmony_ci RTW_PWR_INTF_SDIO_MSK, 481462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 481562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, 481662306a36Sopenharmony_ci {0x0007, 481762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 481862306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 481962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 482062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 482162306a36Sopenharmony_ci {0x0067, 482262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 482362306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 482462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 482562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(5), 0}, 482662306a36Sopenharmony_ci {0x004A, 482762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 482862306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK, 482962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 483062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), 0}, 483162306a36Sopenharmony_ci {0x0081, 483262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 483362306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 483462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 483562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, 483662306a36Sopenharmony_ci {0x0090, 483762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 483862306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 483962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 484062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(1), 0}, 484162306a36Sopenharmony_ci {0x0092, 484262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 484362306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 484462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 484562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0x20}, 484662306a36Sopenharmony_ci {0x0093, 484762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 484862306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 484962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 485062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, 0xFF, 0x04}, 485162306a36Sopenharmony_ci {0x0005, 485262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 485362306a36Sopenharmony_ci RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 485462306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 485562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, 485662306a36Sopenharmony_ci {0x0005, 485762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 485862306a36Sopenharmony_ci RTW_PWR_INTF_PCI_MSK, 485962306a36Sopenharmony_ci RTW_PWR_ADDR_MAC, 486062306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 486162306a36Sopenharmony_ci {0x0086, 486262306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 486362306a36Sopenharmony_ci RTW_PWR_INTF_SDIO_MSK, 486462306a36Sopenharmony_ci RTW_PWR_ADDR_SDIO, 486562306a36Sopenharmony_ci RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 486662306a36Sopenharmony_ci {0xFFFF, 486762306a36Sopenharmony_ci RTW_PWR_CUT_ALL_MSK, 486862306a36Sopenharmony_ci RTW_PWR_INTF_ALL_MSK, 486962306a36Sopenharmony_ci 0, 487062306a36Sopenharmony_ci RTW_PWR_CMD_END, 0, 0}, 487162306a36Sopenharmony_ci}; 487262306a36Sopenharmony_ci 487362306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = { 487462306a36Sopenharmony_ci trans_carddis_to_cardemu_8822c, 487562306a36Sopenharmony_ci trans_cardemu_to_act_8822c, 487662306a36Sopenharmony_ci NULL 487762306a36Sopenharmony_ci}; 487862306a36Sopenharmony_ci 487962306a36Sopenharmony_cistatic const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = { 488062306a36Sopenharmony_ci trans_act_to_cardemu_8822c, 488162306a36Sopenharmony_ci trans_cardemu_to_carddis_8822c, 488262306a36Sopenharmony_ci NULL 488362306a36Sopenharmony_ci}; 488462306a36Sopenharmony_ci 488562306a36Sopenharmony_cistatic const struct rtw_intf_phy_para usb2_param_8822c[] = { 488662306a36Sopenharmony_ci {0xFFFF, 0x00, 488762306a36Sopenharmony_ci RTW_IP_SEL_PHY, 488862306a36Sopenharmony_ci RTW_INTF_PHY_CUT_ALL, 488962306a36Sopenharmony_ci RTW_INTF_PHY_PLATFORM_ALL}, 489062306a36Sopenharmony_ci}; 489162306a36Sopenharmony_ci 489262306a36Sopenharmony_cistatic const struct rtw_intf_phy_para usb3_param_8822c[] = { 489362306a36Sopenharmony_ci {0xFFFF, 0x0000, 489462306a36Sopenharmony_ci RTW_IP_SEL_PHY, 489562306a36Sopenharmony_ci RTW_INTF_PHY_CUT_ALL, 489662306a36Sopenharmony_ci RTW_INTF_PHY_PLATFORM_ALL}, 489762306a36Sopenharmony_ci}; 489862306a36Sopenharmony_ci 489962306a36Sopenharmony_cistatic const struct rtw_intf_phy_para pcie_gen1_param_8822c[] = { 490062306a36Sopenharmony_ci {0xFFFF, 0x0000, 490162306a36Sopenharmony_ci RTW_IP_SEL_PHY, 490262306a36Sopenharmony_ci RTW_INTF_PHY_CUT_ALL, 490362306a36Sopenharmony_ci RTW_INTF_PHY_PLATFORM_ALL}, 490462306a36Sopenharmony_ci}; 490562306a36Sopenharmony_ci 490662306a36Sopenharmony_cistatic const struct rtw_intf_phy_para pcie_gen2_param_8822c[] = { 490762306a36Sopenharmony_ci {0xFFFF, 0x0000, 490862306a36Sopenharmony_ci RTW_IP_SEL_PHY, 490962306a36Sopenharmony_ci RTW_INTF_PHY_CUT_ALL, 491062306a36Sopenharmony_ci RTW_INTF_PHY_PLATFORM_ALL}, 491162306a36Sopenharmony_ci}; 491262306a36Sopenharmony_ci 491362306a36Sopenharmony_cistatic const struct rtw_intf_phy_para_table phy_para_table_8822c = { 491462306a36Sopenharmony_ci .usb2_para = usb2_param_8822c, 491562306a36Sopenharmony_ci .usb3_para = usb3_param_8822c, 491662306a36Sopenharmony_ci .gen1_para = pcie_gen1_param_8822c, 491762306a36Sopenharmony_ci .gen2_para = pcie_gen2_param_8822c, 491862306a36Sopenharmony_ci .n_usb2_para = ARRAY_SIZE(usb2_param_8822c), 491962306a36Sopenharmony_ci .n_usb3_para = ARRAY_SIZE(usb2_param_8822c), 492062306a36Sopenharmony_ci .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8822c), 492162306a36Sopenharmony_ci .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), 492262306a36Sopenharmony_ci}; 492362306a36Sopenharmony_ci 492462306a36Sopenharmony_cistatic const struct rtw_rfe_def rtw8822c_rfe_defs[] = { 492562306a36Sopenharmony_ci [0] = RTW_DEF_RFE(8822c, 0, 0), 492662306a36Sopenharmony_ci [1] = RTW_DEF_RFE(8822c, 0, 0), 492762306a36Sopenharmony_ci [2] = RTW_DEF_RFE(8822c, 0, 0), 492862306a36Sopenharmony_ci [3] = RTW_DEF_RFE(8822c, 0, 0), 492962306a36Sopenharmony_ci [4] = RTW_DEF_RFE(8822c, 0, 0), 493062306a36Sopenharmony_ci [5] = RTW_DEF_RFE(8822c, 0, 5), 493162306a36Sopenharmony_ci [6] = RTW_DEF_RFE(8822c, 0, 0), 493262306a36Sopenharmony_ci}; 493362306a36Sopenharmony_ci 493462306a36Sopenharmony_cistatic const struct rtw_hw_reg rtw8822c_dig[] = { 493562306a36Sopenharmony_ci [0] = { .addr = 0x1d70, .mask = 0x7f }, 493662306a36Sopenharmony_ci [1] = { .addr = 0x1d70, .mask = 0x7f00 }, 493762306a36Sopenharmony_ci}; 493862306a36Sopenharmony_ci 493962306a36Sopenharmony_cistatic const struct rtw_ltecoex_addr rtw8822c_ltecoex_addr = { 494062306a36Sopenharmony_ci .ctrl = LTECOEX_ACCESS_CTRL, 494162306a36Sopenharmony_ci .wdata = LTECOEX_WRITE_DATA, 494262306a36Sopenharmony_ci .rdata = LTECOEX_READ_DATA, 494362306a36Sopenharmony_ci}; 494462306a36Sopenharmony_ci 494562306a36Sopenharmony_cistatic const struct rtw_page_table page_table_8822c[] = { 494662306a36Sopenharmony_ci {64, 64, 64, 64, 1}, 494762306a36Sopenharmony_ci {64, 64, 64, 64, 1}, 494862306a36Sopenharmony_ci {64, 64, 0, 0, 1}, 494962306a36Sopenharmony_ci {64, 64, 64, 0, 1}, 495062306a36Sopenharmony_ci {64, 64, 64, 64, 1}, 495162306a36Sopenharmony_ci}; 495262306a36Sopenharmony_ci 495362306a36Sopenharmony_cistatic const struct rtw_rqpn rqpn_table_8822c[] = { 495462306a36Sopenharmony_ci {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 495562306a36Sopenharmony_ci RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 495662306a36Sopenharmony_ci RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 495762306a36Sopenharmony_ci {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 495862306a36Sopenharmony_ci RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 495962306a36Sopenharmony_ci RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 496062306a36Sopenharmony_ci {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 496162306a36Sopenharmony_ci RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, 496262306a36Sopenharmony_ci RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 496362306a36Sopenharmony_ci {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 496462306a36Sopenharmony_ci RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 496562306a36Sopenharmony_ci RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 496662306a36Sopenharmony_ci {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 496762306a36Sopenharmony_ci RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 496862306a36Sopenharmony_ci RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 496962306a36Sopenharmony_ci}; 497062306a36Sopenharmony_ci 497162306a36Sopenharmony_cistatic struct rtw_prioq_addrs prioq_addrs_8822c = { 497262306a36Sopenharmony_ci .prio[RTW_DMA_MAPPING_EXTRA] = { 497362306a36Sopenharmony_ci .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, 497462306a36Sopenharmony_ci }, 497562306a36Sopenharmony_ci .prio[RTW_DMA_MAPPING_LOW] = { 497662306a36Sopenharmony_ci .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, 497762306a36Sopenharmony_ci }, 497862306a36Sopenharmony_ci .prio[RTW_DMA_MAPPING_NORMAL] = { 497962306a36Sopenharmony_ci .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, 498062306a36Sopenharmony_ci }, 498162306a36Sopenharmony_ci .prio[RTW_DMA_MAPPING_HIGH] = { 498262306a36Sopenharmony_ci .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, 498362306a36Sopenharmony_ci }, 498462306a36Sopenharmony_ci .wsize = true, 498562306a36Sopenharmony_ci}; 498662306a36Sopenharmony_ci 498762306a36Sopenharmony_cistatic struct rtw_chip_ops rtw8822c_ops = { 498862306a36Sopenharmony_ci .phy_set_param = rtw8822c_phy_set_param, 498962306a36Sopenharmony_ci .read_efuse = rtw8822c_read_efuse, 499062306a36Sopenharmony_ci .query_rx_desc = rtw8822c_query_rx_desc, 499162306a36Sopenharmony_ci .set_channel = rtw8822c_set_channel, 499262306a36Sopenharmony_ci .mac_init = rtw8822c_mac_init, 499362306a36Sopenharmony_ci .dump_fw_crash = rtw8822c_dump_fw_crash, 499462306a36Sopenharmony_ci .read_rf = rtw_phy_read_rf, 499562306a36Sopenharmony_ci .write_rf = rtw_phy_write_rf_reg_mix, 499662306a36Sopenharmony_ci .set_tx_power_index = rtw8822c_set_tx_power_index, 499762306a36Sopenharmony_ci .set_antenna = rtw8822c_set_antenna, 499862306a36Sopenharmony_ci .cfg_ldo25 = rtw8822c_cfg_ldo25, 499962306a36Sopenharmony_ci .false_alarm_statistics = rtw8822c_false_alarm_statistics, 500062306a36Sopenharmony_ci .dpk_track = rtw8822c_dpk_track, 500162306a36Sopenharmony_ci .phy_calibration = rtw8822c_phy_calibration, 500262306a36Sopenharmony_ci .cck_pd_set = rtw8822c_phy_cck_pd_set, 500362306a36Sopenharmony_ci .pwr_track = rtw8822c_pwr_track, 500462306a36Sopenharmony_ci .config_bfee = rtw8822c_bf_config_bfee, 500562306a36Sopenharmony_ci .set_gid_table = rtw_bf_set_gid_table, 500662306a36Sopenharmony_ci .cfg_csi_rate = rtw_bf_cfg_csi_rate, 500762306a36Sopenharmony_ci .adaptivity_init = rtw8822c_adaptivity_init, 500862306a36Sopenharmony_ci .adaptivity = rtw8822c_adaptivity, 500962306a36Sopenharmony_ci .cfo_init = rtw8822c_cfo_init, 501062306a36Sopenharmony_ci .cfo_track = rtw8822c_cfo_track, 501162306a36Sopenharmony_ci .config_tx_path = rtw8822c_config_tx_path, 501262306a36Sopenharmony_ci .config_txrx_mode = rtw8822c_config_trx_mode, 501362306a36Sopenharmony_ci .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, 501462306a36Sopenharmony_ci 501562306a36Sopenharmony_ci .coex_set_init = rtw8822c_coex_cfg_init, 501662306a36Sopenharmony_ci .coex_set_ant_switch = NULL, 501762306a36Sopenharmony_ci .coex_set_gnt_fix = rtw8822c_coex_cfg_gnt_fix, 501862306a36Sopenharmony_ci .coex_set_gnt_debug = rtw8822c_coex_cfg_gnt_debug, 501962306a36Sopenharmony_ci .coex_set_rfe_type = rtw8822c_coex_cfg_rfe_type, 502062306a36Sopenharmony_ci .coex_set_wl_tx_power = rtw8822c_coex_cfg_wl_tx_power, 502162306a36Sopenharmony_ci .coex_set_wl_rx_gain = rtw8822c_coex_cfg_wl_rx_gain, 502262306a36Sopenharmony_ci}; 502362306a36Sopenharmony_ci 502462306a36Sopenharmony_ci/* Shared-Antenna Coex Table */ 502562306a36Sopenharmony_cistatic const struct coex_table_para table_sant_8822c[] = { 502662306a36Sopenharmony_ci {0xffffffff, 0xffffffff}, /* case-0 */ 502762306a36Sopenharmony_ci {0x55555555, 0x55555555}, 502862306a36Sopenharmony_ci {0x66555555, 0x66555555}, 502962306a36Sopenharmony_ci {0xaaaaaaaa, 0xaaaaaaaa}, 503062306a36Sopenharmony_ci {0x5a5a5a5a, 0x5a5a5a5a}, 503162306a36Sopenharmony_ci {0xfafafafa, 0xfafafafa}, /* case-5 */ 503262306a36Sopenharmony_ci {0x6a5a5555, 0xaaaaaaaa}, 503362306a36Sopenharmony_ci {0x6a5a56aa, 0x6a5a56aa}, 503462306a36Sopenharmony_ci {0x6a5a5a5a, 0x6a5a5a5a}, 503562306a36Sopenharmony_ci {0x66555555, 0x5a5a5a5a}, 503662306a36Sopenharmony_ci {0x66555555, 0x6a5a5a5a}, /* case-10 */ 503762306a36Sopenharmony_ci {0x66555555, 0x6a5a5aaa}, 503862306a36Sopenharmony_ci {0x66555555, 0x5a5a5aaa}, 503962306a36Sopenharmony_ci {0x66555555, 0x6aaa5aaa}, 504062306a36Sopenharmony_ci {0x66555555, 0xaaaa5aaa}, 504162306a36Sopenharmony_ci {0x66555555, 0xaaaaaaaa}, /* case-15 */ 504262306a36Sopenharmony_ci {0xffff55ff, 0xfafafafa}, 504362306a36Sopenharmony_ci {0xffff55ff, 0x6afa5afa}, 504462306a36Sopenharmony_ci {0xaaffffaa, 0xfafafafa}, 504562306a36Sopenharmony_ci {0xaa5555aa, 0x5a5a5a5a}, 504662306a36Sopenharmony_ci {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 504762306a36Sopenharmony_ci {0xaa5555aa, 0xaaaaaaaa}, 504862306a36Sopenharmony_ci {0xffffffff, 0x5a5a5a5a}, 504962306a36Sopenharmony_ci {0xffffffff, 0x5a5a5a5a}, 505062306a36Sopenharmony_ci {0xffffffff, 0x55555555}, 505162306a36Sopenharmony_ci {0xffffffff, 0x5a5a5aaa}, /* case-25 */ 505262306a36Sopenharmony_ci {0x55555555, 0x5a5a5a5a}, 505362306a36Sopenharmony_ci {0x55555555, 0xaaaaaaaa}, 505462306a36Sopenharmony_ci {0x55555555, 0x6a5a6a5a}, 505562306a36Sopenharmony_ci {0x66556655, 0x66556655}, 505662306a36Sopenharmony_ci {0x66556aaa, 0x6a5a6aaa}, /*case-30*/ 505762306a36Sopenharmony_ci {0xffffffff, 0x5aaa5aaa}, 505862306a36Sopenharmony_ci {0x56555555, 0x5a5a5aaa}, 505962306a36Sopenharmony_ci {0xdaffdaff, 0xdaffdaff}, 506062306a36Sopenharmony_ci {0xddffddff, 0xddffddff}, 506162306a36Sopenharmony_ci}; 506262306a36Sopenharmony_ci 506362306a36Sopenharmony_ci/* Non-Shared-Antenna Coex Table */ 506462306a36Sopenharmony_cistatic const struct coex_table_para table_nsant_8822c[] = { 506562306a36Sopenharmony_ci {0xffffffff, 0xffffffff}, /* case-100 */ 506662306a36Sopenharmony_ci {0x55555555, 0x55555555}, 506762306a36Sopenharmony_ci {0x66555555, 0x66555555}, 506862306a36Sopenharmony_ci {0xaaaaaaaa, 0xaaaaaaaa}, 506962306a36Sopenharmony_ci {0x5a5a5a5a, 0x5a5a5a5a}, 507062306a36Sopenharmony_ci {0xfafafafa, 0xfafafafa}, /* case-105 */ 507162306a36Sopenharmony_ci {0x5afa5afa, 0x5afa5afa}, 507262306a36Sopenharmony_ci {0x55555555, 0xfafafafa}, 507362306a36Sopenharmony_ci {0x66555555, 0xfafafafa}, 507462306a36Sopenharmony_ci {0x66555555, 0x5a5a5a5a}, 507562306a36Sopenharmony_ci {0x66555555, 0x6a5a5a5a}, /* case-110 */ 507662306a36Sopenharmony_ci {0x66555555, 0xaaaaaaaa}, 507762306a36Sopenharmony_ci {0xffff55ff, 0xfafafafa}, 507862306a36Sopenharmony_ci {0xffff55ff, 0x5afa5afa}, 507962306a36Sopenharmony_ci {0xffff55ff, 0xaaaaaaaa}, 508062306a36Sopenharmony_ci {0xffff55ff, 0xffff55ff}, /* case-115 */ 508162306a36Sopenharmony_ci {0xaaffffaa, 0x5afa5afa}, 508262306a36Sopenharmony_ci {0xaaffffaa, 0xaaaaaaaa}, 508362306a36Sopenharmony_ci {0xffffffff, 0xfafafafa}, 508462306a36Sopenharmony_ci {0xffffffff, 0x5afa5afa}, 508562306a36Sopenharmony_ci {0xffffffff, 0xaaaaaaaa}, /* case-120 */ 508662306a36Sopenharmony_ci {0x55ff55ff, 0x5afa5afa}, 508762306a36Sopenharmony_ci {0x55ff55ff, 0xaaaaaaaa}, 508862306a36Sopenharmony_ci {0x55ff55ff, 0x55ff55ff} 508962306a36Sopenharmony_ci}; 509062306a36Sopenharmony_ci 509162306a36Sopenharmony_ci/* Shared-Antenna TDMA */ 509262306a36Sopenharmony_cistatic const struct coex_tdma_para tdma_sant_8822c[] = { 509362306a36Sopenharmony_ci { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 509462306a36Sopenharmony_ci { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 509562306a36Sopenharmony_ci { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 509662306a36Sopenharmony_ci { {0x61, 0x30, 0x03, 0x11, 0x11} }, 509762306a36Sopenharmony_ci { {0x61, 0x20, 0x03, 0x11, 0x11} }, 509862306a36Sopenharmony_ci { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ 509962306a36Sopenharmony_ci { {0x61, 0x45, 0x03, 0x11, 0x10} }, 510062306a36Sopenharmony_ci { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 510162306a36Sopenharmony_ci { {0x61, 0x30, 0x03, 0x11, 0x10} }, 510262306a36Sopenharmony_ci { {0x61, 0x20, 0x03, 0x11, 0x10} }, 510362306a36Sopenharmony_ci { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 510462306a36Sopenharmony_ci { {0x61, 0x08, 0x03, 0x11, 0x14} }, 510562306a36Sopenharmony_ci { {0x61, 0x08, 0x03, 0x10, 0x14} }, 510662306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x54} }, 510762306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x55} }, 510862306a36Sopenharmony_ci { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ 510962306a36Sopenharmony_ci { {0x51, 0x45, 0x03, 0x10, 0x50} }, 511062306a36Sopenharmony_ci { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 511162306a36Sopenharmony_ci { {0x51, 0x30, 0x03, 0x10, 0x50} }, 511262306a36Sopenharmony_ci { {0x51, 0x20, 0x03, 0x10, 0x50} }, 511362306a36Sopenharmony_ci { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ 511462306a36Sopenharmony_ci { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 511562306a36Sopenharmony_ci { {0x51, 0x0c, 0x03, 0x10, 0x54} }, 511662306a36Sopenharmony_ci { {0x55, 0x08, 0x03, 0x10, 0x54} }, 511762306a36Sopenharmony_ci { {0x65, 0x10, 0x03, 0x11, 0x10} }, 511862306a36Sopenharmony_ci { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ 511962306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x50} }, 512062306a36Sopenharmony_ci { {0x61, 0x08, 0x03, 0x11, 0x11} } 512162306a36Sopenharmony_ci}; 512262306a36Sopenharmony_ci 512362306a36Sopenharmony_ci/* Non-Shared-Antenna TDMA */ 512462306a36Sopenharmony_cistatic const struct coex_tdma_para tdma_nsant_8822c[] = { 512562306a36Sopenharmony_ci { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */ 512662306a36Sopenharmony_ci { {0x61, 0x45, 0x03, 0x11, 0x11} }, 512762306a36Sopenharmony_ci { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 512862306a36Sopenharmony_ci { {0x61, 0x30, 0x03, 0x11, 0x11} }, 512962306a36Sopenharmony_ci { {0x61, 0x20, 0x03, 0x11, 0x11} }, 513062306a36Sopenharmony_ci { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ 513162306a36Sopenharmony_ci { {0x61, 0x45, 0x03, 0x11, 0x10} }, 513262306a36Sopenharmony_ci { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 513362306a36Sopenharmony_ci { {0x61, 0x30, 0x03, 0x11, 0x10} }, 513462306a36Sopenharmony_ci { {0x61, 0x20, 0x03, 0x11, 0x10} }, 513562306a36Sopenharmony_ci { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ 513662306a36Sopenharmony_ci { {0x61, 0x08, 0x03, 0x11, 0x14} }, 513762306a36Sopenharmony_ci { {0x61, 0x08, 0x03, 0x10, 0x14} }, 513862306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x54} }, 513962306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x55} }, 514062306a36Sopenharmony_ci { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ 514162306a36Sopenharmony_ci { {0x51, 0x45, 0x03, 0x10, 0x50} }, 514262306a36Sopenharmony_ci { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 514362306a36Sopenharmony_ci { {0x51, 0x30, 0x03, 0x10, 0x50} }, 514462306a36Sopenharmony_ci { {0x51, 0x20, 0x03, 0x10, 0x50} }, 514562306a36Sopenharmony_ci { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ 514662306a36Sopenharmony_ci { {0x51, 0x08, 0x03, 0x10, 0x50} } 514762306a36Sopenharmony_ci}; 514862306a36Sopenharmony_ci 514962306a36Sopenharmony_ci/* rssi in percentage % (dbm = % - 100) */ 515062306a36Sopenharmony_cistatic const u8 wl_rssi_step_8822c[] = {60, 50, 44, 30}; 515162306a36Sopenharmony_cistatic const u8 bt_rssi_step_8822c[] = {8, 15, 20, 25}; 515262306a36Sopenharmony_cistatic const struct coex_5g_afh_map afh_5g_8822c[] = { {0, 0, 0} }; 515362306a36Sopenharmony_ci 515462306a36Sopenharmony_ci/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ 515562306a36Sopenharmony_cistatic const struct coex_rf_para rf_para_tx_8822c[] = { 515662306a36Sopenharmony_ci {0, 0, false, 7}, /* for normal */ 515762306a36Sopenharmony_ci {0, 16, false, 7}, /* for WL-CPT */ 515862306a36Sopenharmony_ci {8, 17, true, 4}, 515962306a36Sopenharmony_ci {7, 18, true, 4}, 516062306a36Sopenharmony_ci {6, 19, true, 4}, 516162306a36Sopenharmony_ci {5, 20, true, 4}, 516262306a36Sopenharmony_ci {0, 21, true, 4} /* for gamg hid */ 516362306a36Sopenharmony_ci}; 516462306a36Sopenharmony_ci 516562306a36Sopenharmony_cistatic const struct coex_rf_para rf_para_rx_8822c[] = { 516662306a36Sopenharmony_ci {0, 0, false, 7}, /* for normal */ 516762306a36Sopenharmony_ci {0, 16, false, 7}, /* for WL-CPT */ 516862306a36Sopenharmony_ci {3, 24, true, 5}, 516962306a36Sopenharmony_ci {2, 26, true, 5}, 517062306a36Sopenharmony_ci {1, 27, true, 5}, 517162306a36Sopenharmony_ci {0, 28, true, 5}, 517262306a36Sopenharmony_ci {0, 28, true, 5} /* for gamg hid */ 517362306a36Sopenharmony_ci}; 517462306a36Sopenharmony_ci 517562306a36Sopenharmony_cistatic_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); 517662306a36Sopenharmony_ci 517762306a36Sopenharmony_cistatic const u8 517862306a36Sopenharmony_cirtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 517962306a36Sopenharmony_ci { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 518062306a36Sopenharmony_ci 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 518162306a36Sopenharmony_ci 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 518262306a36Sopenharmony_ci { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 518362306a36Sopenharmony_ci 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 518462306a36Sopenharmony_ci 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 518562306a36Sopenharmony_ci { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 518662306a36Sopenharmony_ci 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 518762306a36Sopenharmony_ci 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 518862306a36Sopenharmony_ci}; 518962306a36Sopenharmony_ci 519062306a36Sopenharmony_cistatic const u8 519162306a36Sopenharmony_cirtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 519262306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 519362306a36Sopenharmony_ci 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 519462306a36Sopenharmony_ci 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 519562306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 519662306a36Sopenharmony_ci 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 519762306a36Sopenharmony_ci 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 519862306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 519962306a36Sopenharmony_ci 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 520062306a36Sopenharmony_ci 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 520162306a36Sopenharmony_ci}; 520262306a36Sopenharmony_ci 520362306a36Sopenharmony_cistatic const u8 520462306a36Sopenharmony_cirtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 520562306a36Sopenharmony_ci { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 520662306a36Sopenharmony_ci 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 520762306a36Sopenharmony_ci 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 520862306a36Sopenharmony_ci { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 520962306a36Sopenharmony_ci 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 521062306a36Sopenharmony_ci 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 521162306a36Sopenharmony_ci { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 521262306a36Sopenharmony_ci 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 521362306a36Sopenharmony_ci 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 521462306a36Sopenharmony_ci}; 521562306a36Sopenharmony_ci 521662306a36Sopenharmony_cistatic const u8 521762306a36Sopenharmony_cirtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 521862306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 521962306a36Sopenharmony_ci 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 522062306a36Sopenharmony_ci 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 522162306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 522262306a36Sopenharmony_ci 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 522362306a36Sopenharmony_ci 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 522462306a36Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 522562306a36Sopenharmony_ci 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 522662306a36Sopenharmony_ci 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 522762306a36Sopenharmony_ci}; 522862306a36Sopenharmony_ci 522962306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { 523062306a36Sopenharmony_ci 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 523162306a36Sopenharmony_ci 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, 523262306a36Sopenharmony_ci 17, 18, 19, 20, 20, 21, 22, 23, 24, 25 523362306a36Sopenharmony_ci}; 523462306a36Sopenharmony_ci 523562306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { 523662306a36Sopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 523762306a36Sopenharmony_ci 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 523862306a36Sopenharmony_ci 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 523962306a36Sopenharmony_ci}; 524062306a36Sopenharmony_ci 524162306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { 524262306a36Sopenharmony_ci 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 524362306a36Sopenharmony_ci 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 524462306a36Sopenharmony_ci 13, 14, 15, 15, 16, 17, 17, 18, 19, 19 524562306a36Sopenharmony_ci}; 524662306a36Sopenharmony_ci 524762306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { 524862306a36Sopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 524962306a36Sopenharmony_ci 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 525062306a36Sopenharmony_ci 19, 20, 21, 22, 23, 24, 25, 25, 26, 27 525162306a36Sopenharmony_ci}; 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { 525462306a36Sopenharmony_ci 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 525562306a36Sopenharmony_ci 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 525662306a36Sopenharmony_ci 17, 18, 19, 20, 21, 22, 23, 23, 24, 25 525762306a36Sopenharmony_ci}; 525862306a36Sopenharmony_ci 525962306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { 526062306a36Sopenharmony_ci 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 526162306a36Sopenharmony_ci 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 526262306a36Sopenharmony_ci 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 526362306a36Sopenharmony_ci}; 526462306a36Sopenharmony_ci 526562306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { 526662306a36Sopenharmony_ci 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 526762306a36Sopenharmony_ci 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 526862306a36Sopenharmony_ci 15, 16, 17, 18, 18, 19, 20, 21, 21, 22 526962306a36Sopenharmony_ci}; 527062306a36Sopenharmony_ci 527162306a36Sopenharmony_cistatic const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { 527262306a36Sopenharmony_ci 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 527362306a36Sopenharmony_ci 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 527462306a36Sopenharmony_ci 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 527562306a36Sopenharmony_ci}; 527662306a36Sopenharmony_ci 527762306a36Sopenharmony_cistatic const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { 527862306a36Sopenharmony_ci .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], 527962306a36Sopenharmony_ci .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], 528062306a36Sopenharmony_ci .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], 528162306a36Sopenharmony_ci .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], 528262306a36Sopenharmony_ci .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], 528362306a36Sopenharmony_ci .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], 528462306a36Sopenharmony_ci .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], 528562306a36Sopenharmony_ci .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], 528662306a36Sopenharmony_ci .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], 528762306a36Sopenharmony_ci .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], 528862306a36Sopenharmony_ci .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], 528962306a36Sopenharmony_ci .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], 529062306a36Sopenharmony_ci .pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n, 529162306a36Sopenharmony_ci .pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p, 529262306a36Sopenharmony_ci .pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n, 529362306a36Sopenharmony_ci .pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p, 529462306a36Sopenharmony_ci .pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n, 529562306a36Sopenharmony_ci .pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p, 529662306a36Sopenharmony_ci .pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n, 529762306a36Sopenharmony_ci .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, 529862306a36Sopenharmony_ci}; 529962306a36Sopenharmony_ci 530062306a36Sopenharmony_cistatic struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { 530162306a36Sopenharmony_ci [EDCCA_TH_L2H_IDX] = { 530262306a36Sopenharmony_ci {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 530362306a36Sopenharmony_ci }, 530462306a36Sopenharmony_ci [EDCCA_TH_H2L_IDX] = { 530562306a36Sopenharmony_ci {.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80 530662306a36Sopenharmony_ci }, 530762306a36Sopenharmony_ci}; 530862306a36Sopenharmony_ci 530962306a36Sopenharmony_ci#ifdef CONFIG_PM 531062306a36Sopenharmony_cistatic const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = { 531162306a36Sopenharmony_ci .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | 531262306a36Sopenharmony_ci WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 531362306a36Sopenharmony_ci WIPHY_WOWLAN_NET_DETECT, 531462306a36Sopenharmony_ci .n_patterns = RTW_MAX_PATTERN_NUM, 531562306a36Sopenharmony_ci .pattern_max_len = RTW_MAX_PATTERN_SIZE, 531662306a36Sopenharmony_ci .pattern_min_len = 1, 531762306a36Sopenharmony_ci .max_nd_match_sets = 4, 531862306a36Sopenharmony_ci}; 531962306a36Sopenharmony_ci#endif 532062306a36Sopenharmony_ci 532162306a36Sopenharmony_cistatic const struct rtw_reg_domain coex_info_hw_regs_8822c[] = { 532262306a36Sopenharmony_ci {0x1860, BIT(3), RTW_REG_DOMAIN_MAC8}, 532362306a36Sopenharmony_ci {0x4160, BIT(3), RTW_REG_DOMAIN_MAC8}, 532462306a36Sopenharmony_ci {0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8}, 532562306a36Sopenharmony_ci {0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32}, 532662306a36Sopenharmony_ci {0, 0, RTW_REG_DOMAIN_NL}, 532762306a36Sopenharmony_ci {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 532862306a36Sopenharmony_ci {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 532962306a36Sopenharmony_ci {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 533062306a36Sopenharmony_ci {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 533162306a36Sopenharmony_ci {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, 533262306a36Sopenharmony_ci {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 533362306a36Sopenharmony_ci {0, 0, RTW_REG_DOMAIN_NL}, 533462306a36Sopenharmony_ci {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, 533562306a36Sopenharmony_ci {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, 533662306a36Sopenharmony_ci {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, 533762306a36Sopenharmony_ci {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, 533862306a36Sopenharmony_ci {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, 533962306a36Sopenharmony_ci {0, 0, RTW_REG_DOMAIN_NL}, 534062306a36Sopenharmony_ci {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 534162306a36Sopenharmony_ci {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 534262306a36Sopenharmony_ci {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, 534362306a36Sopenharmony_ci {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 534462306a36Sopenharmony_ci}; 534562306a36Sopenharmony_ci 534662306a36Sopenharmony_ciconst struct rtw_chip_info rtw8822c_hw_spec = { 534762306a36Sopenharmony_ci .ops = &rtw8822c_ops, 534862306a36Sopenharmony_ci .id = RTW_CHIP_TYPE_8822C, 534962306a36Sopenharmony_ci .fw_name = "rtw88/rtw8822c_fw.bin", 535062306a36Sopenharmony_ci .wlan_cpu = RTW_WCPU_11AC, 535162306a36Sopenharmony_ci .tx_pkt_desc_sz = 48, 535262306a36Sopenharmony_ci .tx_buf_desc_sz = 16, 535362306a36Sopenharmony_ci .rx_pkt_desc_sz = 24, 535462306a36Sopenharmony_ci .rx_buf_desc_sz = 8, 535562306a36Sopenharmony_ci .phy_efuse_size = 512, 535662306a36Sopenharmony_ci .log_efuse_size = 768, 535762306a36Sopenharmony_ci .ptct_efuse_size = 124, 535862306a36Sopenharmony_ci .txff_size = 262144, 535962306a36Sopenharmony_ci .rxff_size = 24576, 536062306a36Sopenharmony_ci .fw_rxff_size = 12288, 536162306a36Sopenharmony_ci .rsvd_drv_pg_num = 16, 536262306a36Sopenharmony_ci .txgi_factor = 2, 536362306a36Sopenharmony_ci .is_pwr_by_rate_dec = false, 536462306a36Sopenharmony_ci .max_power_index = 0x7f, 536562306a36Sopenharmony_ci .csi_buf_pg_num = 50, 536662306a36Sopenharmony_ci .band = RTW_BAND_2G | RTW_BAND_5G, 536762306a36Sopenharmony_ci .page_size = TX_PAGE_SIZE, 536862306a36Sopenharmony_ci .dig_min = 0x20, 536962306a36Sopenharmony_ci .default_1ss_tx_path = BB_PATH_A, 537062306a36Sopenharmony_ci .path_div_supported = true, 537162306a36Sopenharmony_ci .ht_supported = true, 537262306a36Sopenharmony_ci .vht_supported = true, 537362306a36Sopenharmony_ci .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK) | BIT(LPS_DEEP_MODE_PG), 537462306a36Sopenharmony_ci .sys_func_en = 0xD8, 537562306a36Sopenharmony_ci .pwr_on_seq = card_enable_flow_8822c, 537662306a36Sopenharmony_ci .pwr_off_seq = card_disable_flow_8822c, 537762306a36Sopenharmony_ci .page_table = page_table_8822c, 537862306a36Sopenharmony_ci .rqpn_table = rqpn_table_8822c, 537962306a36Sopenharmony_ci .prioq_addrs = &prioq_addrs_8822c, 538062306a36Sopenharmony_ci .intf_table = &phy_para_table_8822c, 538162306a36Sopenharmony_ci .dig = rtw8822c_dig, 538262306a36Sopenharmony_ci .dig_cck = NULL, 538362306a36Sopenharmony_ci .rf_base_addr = {0x3c00, 0x4c00}, 538462306a36Sopenharmony_ci .rf_sipi_addr = {0x1808, 0x4108}, 538562306a36Sopenharmony_ci .ltecoex_addr = &rtw8822c_ltecoex_addr, 538662306a36Sopenharmony_ci .mac_tbl = &rtw8822c_mac_tbl, 538762306a36Sopenharmony_ci .agc_tbl = &rtw8822c_agc_tbl, 538862306a36Sopenharmony_ci .bb_tbl = &rtw8822c_bb_tbl, 538962306a36Sopenharmony_ci .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, 539062306a36Sopenharmony_ci .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, 539162306a36Sopenharmony_ci .rfe_defs = rtw8822c_rfe_defs, 539262306a36Sopenharmony_ci .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), 539362306a36Sopenharmony_ci .en_dis_dpd = true, 539462306a36Sopenharmony_ci .dpd_ratemask = DIS_DPD_RATEALL, 539562306a36Sopenharmony_ci .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, 539662306a36Sopenharmony_ci .iqk_threshold = 8, 539762306a36Sopenharmony_ci .lck_threshold = 8, 539862306a36Sopenharmony_ci .bfer_su_max_num = 2, 539962306a36Sopenharmony_ci .bfer_mu_max_num = 1, 540062306a36Sopenharmony_ci .rx_ldpc = true, 540162306a36Sopenharmony_ci .tx_stbc = true, 540262306a36Sopenharmony_ci .edcca_th = rtw8822c_edcca_th, 540362306a36Sopenharmony_ci .l2h_th_ini_cs = 60, 540462306a36Sopenharmony_ci .l2h_th_ini_ad = 45, 540562306a36Sopenharmony_ci .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, 540662306a36Sopenharmony_ci 540762306a36Sopenharmony_ci#ifdef CONFIG_PM 540862306a36Sopenharmony_ci .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", 540962306a36Sopenharmony_ci .wowlan_stub = &rtw_wowlan_stub_8822c, 541062306a36Sopenharmony_ci .max_sched_scan_ssids = 4, 541162306a36Sopenharmony_ci#endif 541262306a36Sopenharmony_ci .max_scan_ie_len = (RTW_PROBE_PG_CNT - 1) * TX_PAGE_SIZE, 541362306a36Sopenharmony_ci .coex_para_ver = 0x22020720, 541462306a36Sopenharmony_ci .bt_desired_ver = 0x20, 541562306a36Sopenharmony_ci .scbd_support = true, 541662306a36Sopenharmony_ci .new_scbd10_def = true, 541762306a36Sopenharmony_ci .ble_hid_profile_support = true, 541862306a36Sopenharmony_ci .wl_mimo_ps_support = true, 541962306a36Sopenharmony_ci .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 542062306a36Sopenharmony_ci .bt_rssi_type = COEX_BTRSSI_DBM, 542162306a36Sopenharmony_ci .ant_isolation = 15, 542262306a36Sopenharmony_ci .rssi_tolerance = 2, 542362306a36Sopenharmony_ci .wl_rssi_step = wl_rssi_step_8822c, 542462306a36Sopenharmony_ci .bt_rssi_step = bt_rssi_step_8822c, 542562306a36Sopenharmony_ci .table_sant_num = ARRAY_SIZE(table_sant_8822c), 542662306a36Sopenharmony_ci .table_sant = table_sant_8822c, 542762306a36Sopenharmony_ci .table_nsant_num = ARRAY_SIZE(table_nsant_8822c), 542862306a36Sopenharmony_ci .table_nsant = table_nsant_8822c, 542962306a36Sopenharmony_ci .tdma_sant_num = ARRAY_SIZE(tdma_sant_8822c), 543062306a36Sopenharmony_ci .tdma_sant = tdma_sant_8822c, 543162306a36Sopenharmony_ci .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822c), 543262306a36Sopenharmony_ci .tdma_nsant = tdma_nsant_8822c, 543362306a36Sopenharmony_ci .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822c), 543462306a36Sopenharmony_ci .wl_rf_para_tx = rf_para_tx_8822c, 543562306a36Sopenharmony_ci .wl_rf_para_rx = rf_para_rx_8822c, 543662306a36Sopenharmony_ci .bt_afh_span_bw20 = 0x24, 543762306a36Sopenharmony_ci .bt_afh_span_bw40 = 0x36, 543862306a36Sopenharmony_ci .afh_5g_num = ARRAY_SIZE(afh_5g_8822c), 543962306a36Sopenharmony_ci .afh_5g = afh_5g_8822c, 544062306a36Sopenharmony_ci 544162306a36Sopenharmony_ci .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), 544262306a36Sopenharmony_ci .coex_info_hw_regs = coex_info_hw_regs_8822c, 544362306a36Sopenharmony_ci 544462306a36Sopenharmony_ci .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, 544562306a36Sopenharmony_ci .fwcd_segs = &rtw8822c_fwcd_segs, 544662306a36Sopenharmony_ci}; 544762306a36Sopenharmony_ciEXPORT_SYMBOL(rtw8822c_hw_spec); 544862306a36Sopenharmony_ci 544962306a36Sopenharmony_ciMODULE_FIRMWARE("rtw88/rtw8822c_fw.bin"); 545062306a36Sopenharmony_ciMODULE_FIRMWARE("rtw88/rtw8822c_wow_fw.bin"); 545162306a36Sopenharmony_ci 545262306a36Sopenharmony_ciMODULE_AUTHOR("Realtek Corporation"); 545362306a36Sopenharmony_ciMODULE_DESCRIPTION("Realtek 802.11ac wireless 8822c driver"); 545462306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 5455