Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtw88: add power tracking support

The temperature of the chip can affect the output power
of the RF components. Hence driver requires to compensate
the power by adjusting the power index recorded in the
power swing table.

And if the difference of current thermal value to the
default thermal value exceeds a threshold, the RF IQK
should be triggered to re-calibrate the characteristics
of the RF components, to keep the output IQ vectors of
the RF components orthogonal enough.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Reviewed-by: Chris Chiu <chiu@endlessm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

authored by

Tzu-En Huang and committed by
Kalle Valo
c97ee3e0 8575b534

+745 -1
+1
drivers/net/wireless/realtek/rtw88/fw.c
··· 117 117 if (WARN(length < 7, "invalid ra report c2h length\n")) 118 118 return; 119 119 120 + rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload); 120 121 ra_data.rtwdev = rtwdev; 121 122 ra_data.payload = payload; 122 123 rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data);
+48 -1
drivers/net/wireless/realtek/rtw88/main.h
··· 691 691 void (*phy_calibration)(struct rtw_dev *rtwdev); 692 692 void (*dpk_track)(struct rtw_dev *rtwdev); 693 693 void (*cck_pd_set)(struct rtw_dev *rtwdev, u8 level); 694 + void (*pwr_track)(struct rtw_dev *rtwdev); 694 695 695 696 /* for coex */ 696 697 void (*coex_set_init)(struct rtw_dev *rtwdev); ··· 868 867 .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ 869 868 } 870 869 870 + #define RTW_PWR_TRK_5G_1 0 871 + #define RTW_PWR_TRK_5G_2 1 872 + #define RTW_PWR_TRK_5G_3 2 873 + #define RTW_PWR_TRK_5G_NUM 3 874 + 875 + #define RTW_PWR_TRK_TBL_SZ 30 876 + 877 + /* This table stores the values of TX power that will be adjusted by power 878 + * tracking. 879 + * 880 + * For 5G bands, there are 3 different settings. 881 + * For 2G there are cck rate and ofdm rate with different settings. 882 + */ 883 + struct rtw_pwr_track_tbl { 884 + const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM]; 885 + const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM]; 886 + const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM]; 887 + const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM]; 888 + const u8 *pwrtrk_2gb_n; 889 + const u8 *pwrtrk_2gb_p; 890 + const u8 *pwrtrk_2ga_n; 891 + const u8 *pwrtrk_2ga_p; 892 + const u8 *pwrtrk_2g_cckb_n; 893 + const u8 *pwrtrk_2g_cckb_p; 894 + const u8 *pwrtrk_2g_ccka_n; 895 + const u8 *pwrtrk_2g_ccka_p; 896 + }; 897 + 871 898 /* hardware configuration for each IC */ 872 899 struct rtw_chip_info { 873 900 struct rtw_chip_ops *ops; ··· 947 918 948 919 bool en_dis_dpd; 949 920 u16 dpd_ratemask; 921 + u8 iqk_threshold; 922 + const struct rtw_pwr_track_tbl *pwr_track_tbl; 950 923 951 924 /* coex paras */ 952 925 u32 coex_para_ver; ··· 1202 1171 #define DACK_MSBK_BACKUP_NUM 0xf 1203 1172 #define DACK_DCK_BACKUP_NUM 0x2 1204 1173 1174 + struct rtw_swing_table { 1175 + const u8 *p[RTW_RF_PATH_MAX]; 1176 + const u8 *n[RTW_RF_PATH_MAX]; 1177 + }; 1178 + 1205 1179 struct rtw_dm_info { 1206 1180 u32 cck_fa_cnt; 1207 1181 u32 ofdm_fa_cnt; ··· 1233 1197 u8 cck_gi_u_bnd; 1234 1198 u8 cck_gi_l_bnd; 1235 1199 1200 + u8 tx_rate; 1201 + u8 thermal_avg[RTW_RF_PATH_MAX]; 1202 + u8 thermal_meter_k; 1203 + s8 delta_power_index[RTW_RF_PATH_MAX]; 1204 + u8 default_ofdm_index; 1205 + bool pwr_trk_triggered; 1206 + bool pwr_trk_init_trigger; 1207 + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; 1208 + 1236 1209 /* backup dack results for each path and I/Q */ 1237 1210 u32 dack_adck[RTW_RF_PATH_MAX]; 1238 1211 u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM]; ··· 1265 1220 u8 country_code[2]; 1266 1221 u8 rf_board_option; 1267 1222 u8 rfe_option; 1268 - u8 thermal_meter; 1223 + u8 power_track_type; 1224 + u8 thermal_meter[RTW_RF_PATH_MAX]; 1225 + u8 thermal_meter_k; 1269 1226 u8 crystal_cap; 1270 1227 u8 ant_div_cfg; 1271 1228 u8 ant_div_type;
+126
drivers/net/wireless/realtek/rtw88/phy.c
··· 539 539 chip->ops->cck_pd_set(rtwdev, level); 540 540 } 541 541 542 + static void rtw_phy_pwr_track(struct rtw_dev *rtwdev) 543 + { 544 + rtwdev->chip->ops->pwr_track(rtwdev); 545 + } 546 + 542 547 void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev) 543 548 { 544 549 /* for further calculation */ ··· 552 547 rtw_phy_cck_pd(rtwdev); 553 548 rtw_phy_ra_info_update(rtwdev); 554 549 rtw_phy_dpk_track(rtwdev); 550 + rtw_phy_pwr_track(rtwdev); 555 551 } 556 552 557 553 #define FRAC_BITS 3 ··· 1973 1967 for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) 1974 1968 rtw_phy_init_tx_power_limit(rtwdev, regd, bw, 1975 1969 rs); 1970 + } 1971 + 1972 + void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, 1973 + struct rtw_swing_table *swing_table) 1974 + { 1975 + const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; 1976 + u8 channel = rtwdev->hal.current_channel; 1977 + 1978 + if (IS_CH_2G_BAND(channel)) { 1979 + if (rtwdev->dm_info.tx_rate <= DESC_RATE11M) { 1980 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2g_ccka_p; 1981 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n; 1982 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p; 1983 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n; 1984 + } else { 1985 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; 1986 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; 1987 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; 1988 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; 1989 + } 1990 + } else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { 1991 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1]; 1992 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1]; 1993 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1]; 1994 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1]; 1995 + } else if (IS_CH_5G_BAND_3(channel)) { 1996 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2]; 1997 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2]; 1998 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2]; 1999 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2]; 2000 + } else if (IS_CH_5G_BAND_4(channel)) { 2001 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3]; 2002 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3]; 2003 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3]; 2004 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3]; 2005 + } else { 2006 + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; 2007 + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; 2008 + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; 2009 + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; 2010 + } 2011 + } 2012 + 2013 + void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path) 2014 + { 2015 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 2016 + 2017 + ewma_thermal_add(&dm_info->avg_thermal[path], thermal); 2018 + dm_info->thermal_avg[path] = 2019 + ewma_thermal_read(&dm_info->avg_thermal[path]); 2020 + } 2021 + 2022 + bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, 2023 + u8 path) 2024 + { 2025 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 2026 + u8 avg = ewma_thermal_read(&dm_info->avg_thermal[path]); 2027 + 2028 + if (avg == thermal) 2029 + return false; 2030 + 2031 + return true; 2032 + } 2033 + 2034 + u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path) 2035 + { 2036 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 2037 + u8 therm_avg, therm_efuse, therm_delta; 2038 + 2039 + therm_avg = dm_info->thermal_avg[path]; 2040 + therm_efuse = rtwdev->efuse.thermal_meter[path]; 2041 + therm_delta = abs(therm_avg - therm_efuse); 2042 + 2043 + return min_t(u8, therm_delta, RTW_PWR_TRK_TBL_SZ - 1); 2044 + } 2045 + 2046 + s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, 2047 + struct rtw_swing_table *swing_table, 2048 + u8 tbl_path, u8 therm_path, u8 delta) 2049 + { 2050 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 2051 + const u8 *delta_swing_table_idx_pos; 2052 + const u8 *delta_swing_table_idx_neg; 2053 + 2054 + if (delta >= RTW_PWR_TRK_TBL_SZ) { 2055 + rtw_warn(rtwdev, "power track table overflow\n"); 2056 + return 0; 2057 + } 2058 + 2059 + if (!swing_table || !swing_table->n || !swing_table->p) { 2060 + rtw_warn(rtwdev, "swing table not configured\n"); 2061 + return 0; 2062 + } 2063 + 2064 + delta_swing_table_idx_pos = swing_table->p[tbl_path]; 2065 + delta_swing_table_idx_neg = swing_table->n[tbl_path]; 2066 + 2067 + if (!delta_swing_table_idx_pos || !delta_swing_table_idx_neg) { 2068 + rtw_warn(rtwdev, "invalid swing table index\n"); 2069 + return 0; 2070 + } 2071 + 2072 + if (dm_info->thermal_avg[therm_path] > 2073 + rtwdev->efuse.thermal_meter[therm_path]) 2074 + return delta_swing_table_idx_pos[delta]; 2075 + else 2076 + return -delta_swing_table_idx_neg[delta]; 2077 + } 2078 + 2079 + bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev) 2080 + { 2081 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 2082 + u8 delta_iqk; 2083 + 2084 + delta_iqk = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_k); 2085 + if (delta_iqk >= rtwdev->chip->iqk_threshold) { 2086 + dm_info->thermal_meter_k = dm_info->thermal_avg[0]; 2087 + return true; 2088 + } 2089 + return false; 1976 2090 }
+12
drivers/net/wireless/realtek/rtw88/phy.h
··· 41 41 u32 addr, u32 data); 42 42 void rtw_phy_init_tx_power(struct rtw_dev *rtwdev); 43 43 void rtw_phy_load_tables(struct rtw_dev *rtwdev); 44 + u8 rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, 45 + enum rtw_bandwidth bw, u8 channel, u8 regd); 44 46 void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel); 45 47 void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal); 46 48 void rtw_phy_tx_power_limit_config(struct rtw_hal *hal); 49 + void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path); 50 + bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, 51 + u8 path); 52 + u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path); 53 + s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, 54 + struct rtw_swing_table *swing_table, 55 + u8 tbl_path, u8 therm_path, u8 delta); 56 + bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev); 57 + void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, 58 + struct rtw_swing_table *swing_table); 47 59 48 60 struct rtw_txpwr_lmt_cfg_pair { 49 61 u8 regd;
+330
drivers/net/wireless/realtek/rtw88/rtw8822b.c
··· 43 43 efuse->country_code[1] = map->country_code[1]; 44 44 efuse->bt_setting = map->rf_bt_setting; 45 45 efuse->regd = map->rf_board_option & 0x7; 46 + efuse->thermal_meter[RF_PATH_A] = map->thermal_meter; 47 + efuse->thermal_meter_k = map->thermal_meter; 46 48 47 49 for (i = 0; i < 4; i++) 48 50 efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; ··· 75 73 /* input or output */ 76 74 rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f); 77 75 rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3); 76 + } 77 + 78 + #define RTW_TXSCALE_SIZE 37 79 + static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = { 80 + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, 81 + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, 82 + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, 83 + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe 84 + }; 85 + 86 + static const u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev) 87 + { 88 + u8 i = 0; 89 + u32 swing, table_value; 90 + 91 + swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000); 92 + for (i = 0; i < RTW_TXSCALE_SIZE; i++) { 93 + table_value = rtw8822b_txscale_tbl[i]; 94 + if (swing == table_value) 95 + break; 96 + } 97 + 98 + return i; 99 + } 100 + 101 + static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev) 102 + { 103 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 104 + u8 swing_idx = rtw8822b_get_swing_index(rtwdev); 105 + u8 path; 106 + 107 + if (swing_idx >= RTW_TXSCALE_SIZE) 108 + dm_info->default_ofdm_index = 24; 109 + else 110 + dm_info->default_ofdm_index = swing_idx; 111 + 112 + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { 113 + ewma_thermal_init(&dm_info->avg_thermal[path]); 114 + dm_info->delta_power_index[path] = 0; 115 + } 116 + dm_info->pwr_trk_triggered = false; 117 + dm_info->pwr_trk_init_trigger = true; 118 + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 78 119 } 79 120 80 121 static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) ··· 151 106 rtw_phy_init(rtwdev); 152 107 153 108 rtw8822b_phy_rfe_init(rtwdev); 109 + rtw8822b_pwrtrack_init(rtwdev); 154 110 } 155 111 156 112 #define WLAN_SLOT_TIME 0x09 ··· 1298 1252 } 1299 1253 } 1300 1254 1255 + static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path, 1256 + u8 tx_pwr_idx_offset, 1257 + s8 *txagc_idx, u8 *swing_idx) 1258 + { 1259 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1260 + s8 delta_pwr_idx = dm_info->delta_power_index[path]; 1261 + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; 1262 + u8 swing_lower_bound = 0; 1263 + u8 max_tx_pwr_idx_offset = 0xf; 1264 + s8 agc_index = 0; 1265 + u8 swing_index = dm_info->default_ofdm_index; 1266 + 1267 + tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset); 1268 + 1269 + if (delta_pwr_idx >= 0) { 1270 + if (delta_pwr_idx <= tx_pwr_idx_offset) { 1271 + agc_index = delta_pwr_idx; 1272 + swing_index = dm_info->default_ofdm_index; 1273 + } else if (delta_pwr_idx > tx_pwr_idx_offset) { 1274 + agc_index = tx_pwr_idx_offset; 1275 + swing_index = dm_info->default_ofdm_index + 1276 + delta_pwr_idx - tx_pwr_idx_offset; 1277 + swing_index = min_t(u8, swing_index, swing_upper_bound); 1278 + } 1279 + } else { 1280 + if (dm_info->default_ofdm_index > abs(delta_pwr_idx)) 1281 + swing_index = 1282 + dm_info->default_ofdm_index + delta_pwr_idx; 1283 + else 1284 + swing_index = swing_lower_bound; 1285 + swing_index = max_t(u8, swing_index, swing_lower_bound); 1286 + 1287 + agc_index = 0; 1288 + } 1289 + 1290 + if (swing_index >= RTW_TXSCALE_SIZE) { 1291 + rtw_warn(rtwdev, "swing index overflow\n"); 1292 + swing_index = RTW_TXSCALE_SIZE - 1; 1293 + } 1294 + *txagc_idx = agc_index; 1295 + *swing_idx = swing_index; 1296 + } 1297 + 1298 + static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path, 1299 + u8 pwr_idx_offset) 1300 + { 1301 + s8 txagc_idx; 1302 + u8 swing_idx; 1303 + u32 reg1, reg2; 1304 + 1305 + if (path == RF_PATH_A) { 1306 + reg1 = 0xc94; 1307 + reg2 = 0xc1c; 1308 + } else if (path == RF_PATH_B) { 1309 + reg1 = 0xe94; 1310 + reg2 = 0xe1c; 1311 + } else { 1312 + return; 1313 + } 1314 + 1315 + rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset, 1316 + &txagc_idx, &swing_idx); 1317 + rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx); 1318 + rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21), 1319 + rtw8822b_txscale_tbl[swing_idx]); 1320 + } 1321 + 1322 + static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) 1323 + { 1324 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1325 + u8 pwr_idx_offset, tx_pwr_idx; 1326 + u8 channel = rtwdev->hal.current_channel; 1327 + u8 band_width = rtwdev->hal.current_band_width; 1328 + u8 regd = rtwdev->regd.txpwr_regd; 1329 + u8 tx_rate = dm_info->tx_rate; 1330 + u8 max_pwr_idx = rtwdev->chip->max_power_index; 1331 + 1332 + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate, 1333 + band_width, channel, regd); 1334 + 1335 + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); 1336 + 1337 + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; 1338 + 1339 + rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset); 1340 + } 1341 + 1342 + static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev, 1343 + struct rtw_swing_table *swing_table, 1344 + u8 path) 1345 + { 1346 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1347 + u8 power_idx_cur, power_idx_last; 1348 + u8 delta; 1349 + 1350 + /* 8822B only has one thermal meter at PATH A */ 1351 + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); 1352 + 1353 + power_idx_last = dm_info->delta_power_index[path]; 1354 + power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, 1355 + path, RF_PATH_A, delta); 1356 + 1357 + /* if delta of power indexes are the same, just skip */ 1358 + if (power_idx_cur == power_idx_last) 1359 + return; 1360 + 1361 + dm_info->delta_power_index[path] = power_idx_cur; 1362 + rtw8822b_pwrtrack_set(rtwdev, path); 1363 + } 1364 + 1365 + static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev) 1366 + { 1367 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1368 + struct rtw_swing_table swing_table; 1369 + u8 thermal_value, path; 1370 + 1371 + rtw_phy_config_swing_table(rtwdev, &swing_table); 1372 + 1373 + if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff) 1374 + return; 1375 + 1376 + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); 1377 + 1378 + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); 1379 + 1380 + if (dm_info->pwr_trk_init_trigger) 1381 + dm_info->pwr_trk_init_trigger = false; 1382 + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, 1383 + RF_PATH_A)) 1384 + goto iqk; 1385 + 1386 + for (path = 0; path < rtwdev->hal.rf_path_num; path++) 1387 + rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path); 1388 + 1389 + iqk: 1390 + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) 1391 + rtw8822b_do_iqk(rtwdev); 1392 + } 1393 + 1394 + void rtw8822b_pwr_track(struct rtw_dev *rtwdev) 1395 + { 1396 + struct rtw_efuse *efuse = &rtwdev->efuse; 1397 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1398 + 1399 + if (efuse->power_track_type != 0) 1400 + return; 1401 + 1402 + if (!dm_info->pwr_trk_triggered) { 1403 + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 1404 + GENMASK(17, 16), 0x03); 1405 + dm_info->pwr_trk_triggered = true; 1406 + return; 1407 + } 1408 + 1409 + rtw8822b_phy_pwrtrack(rtwdev); 1410 + dm_info->pwr_trk_triggered = false; 1411 + } 1412 + 1301 1413 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = { 1302 1414 {0x0086, 1303 1415 RTW_PWR_CUT_ALL_MSK, ··· 2002 1798 .cfg_ldo25 = rtw8822b_cfg_ldo25, 2003 1799 .false_alarm_statistics = rtw8822b_false_alarm_statistics, 2004 1800 .phy_calibration = rtw8822b_phy_calibration, 1801 + .pwr_track = rtw8822b_pwr_track, 2005 1802 2006 1803 .coex_set_init = rtw8822b_coex_cfg_init, 2007 1804 .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch, ··· 2157 1952 2158 1953 static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b)); 2159 1954 1955 + static const u8 1956 + rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 1957 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1958 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1959 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1960 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1961 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1962 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1963 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1964 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1965 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1966 + }; 1967 + 1968 + static const u8 1969 + rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 1970 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1971 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 1972 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, 1973 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1974 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 1975 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, 1976 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1977 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 1978 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, 1979 + }; 1980 + 1981 + static const u8 1982 + rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 1983 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1984 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1985 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1986 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1987 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1988 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1989 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1990 + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, 1991 + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, 1992 + }; 1993 + 1994 + static const u8 1995 + rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 1996 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 1997 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 1998 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, 1999 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 2000 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 2001 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, 2002 + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 2003 + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, 2004 + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, 2005 + }; 2006 + 2007 + static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { 2008 + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 2009 + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 2010 + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 2011 + }; 2012 + 2013 + static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { 2014 + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2015 + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 2016 + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 2017 + }; 2018 + 2019 + static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { 2020 + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 2021 + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 2022 + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 2023 + }; 2024 + 2025 + static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { 2026 + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 2027 + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 2028 + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 2029 + }; 2030 + 2031 + static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { 2032 + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 2033 + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 2034 + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 2035 + }; 2036 + 2037 + static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { 2038 + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2039 + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 2040 + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 2041 + }; 2042 + 2043 + static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { 2044 + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 2045 + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 2046 + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 2047 + }; 2048 + 2049 + static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { 2050 + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 2051 + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 2052 + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 2053 + }; 2054 + 2055 + static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { 2056 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], 2057 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], 2058 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], 2059 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], 2060 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], 2061 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], 2062 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], 2063 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], 2064 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], 2065 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], 2066 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], 2067 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], 2068 + .pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n, 2069 + .pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p, 2070 + .pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n, 2071 + .pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p, 2072 + .pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n, 2073 + .pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p, 2074 + .pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n, 2075 + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, 2076 + }; 2077 + 2160 2078 struct rtw_chip_info rtw8822b_hw_spec = { 2161 2079 .ops = &rtw8822b_ops, 2162 2080 .id = RTW_CHIP_TYPE_8822B, ··· 2318 1990 .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, 2319 1991 .rfe_defs = rtw8822b_rfe_defs, 2320 1992 .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), 1993 + .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl, 1994 + .iqk_threshold = 8, 2321 1995 2322 1996 .coex_para_ver = 0x19062706, 2323 1997 .bt_desired_ver = 0x6,
+228
drivers/net/wireless/realtek/rtw88/rtw8822c.c
··· 40 40 efuse->country_code[1] = map->country_code[1]; 41 41 efuse->bt_setting = map->rf_bt_setting; 42 42 efuse->regd = map->rf_board_option & 0x7; 43 + efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal; 44 + efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal; 45 + efuse->thermal_meter_k = 46 + (map->path_a_thermal + map->path_b_thermal) >> 1; 47 + efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf; 43 48 44 49 for (i = 0; i < 4; i++) 45 50 efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; ··· 1005 1000 rtw8822c_rf_x2_check(rtwdev); 1006 1001 } 1007 1002 1003 + void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev) 1004 + { 1005 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1006 + u8 path; 1007 + 1008 + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) { 1009 + dm_info->delta_power_index[path] = 0; 1010 + ewma_thermal_init(&dm_info->avg_thermal[path]); 1011 + dm_info->thermal_avg[path] = 0xff; 1012 + } 1013 + 1014 + dm_info->pwr_trk_triggered = false; 1015 + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 1016 + } 1017 + 1008 1018 static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) 1009 1019 { 1010 1020 struct rtw_dm_info *dm_info = &rtwdev->dm_info; ··· 1067 1047 dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb)); 1068 1048 1069 1049 rtw8822c_rf_init(rtwdev); 1050 + rtw8822c_pwrtrack_init(rtwdev); 1070 1051 } 1071 1052 1072 1053 #define WLAN_TXQ_RPT_EN 0x1F ··· 3216 3195 dm_info->cck_pd_lv[bw][nrx] = new_lvl; 3217 3196 } 3218 3197 3198 + #define PWR_TRACK_MASK 0x7f 3199 + static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) 3200 + { 3201 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 3202 + 3203 + switch (rf_path) { 3204 + case RF_PATH_A: 3205 + rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK, 3206 + dm_info->delta_power_index[rf_path]); 3207 + break; 3208 + case RF_PATH_B: 3209 + rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK, 3210 + dm_info->delta_power_index[rf_path]); 3211 + break; 3212 + default: 3213 + break; 3214 + } 3215 + } 3216 + 3217 + static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, 3218 + struct rtw_swing_table *swing_table, 3219 + u8 path) 3220 + { 3221 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 3222 + u8 thermal_value, delta; 3223 + 3224 + if (rtwdev->efuse.thermal_meter[path] == 0xff) 3225 + return; 3226 + 3227 + thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); 3228 + 3229 + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); 3230 + 3231 + delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); 3232 + 3233 + dm_info->delta_power_index[path] = 3234 + rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, 3235 + delta); 3236 + 3237 + rtw8822c_pwrtrack_set(rtwdev, path); 3238 + } 3239 + 3240 + static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) 3241 + { 3242 + struct rtw_swing_table swing_table; 3243 + u8 i; 3244 + 3245 + rtw_phy_config_swing_table(rtwdev, &swing_table); 3246 + 3247 + for (i = 0; i < rtwdev->hal.rf_path_num; i++) 3248 + rtw8822c_pwr_track_path(rtwdev, &swing_table, i); 3249 + 3250 + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) 3251 + rtw8822c_do_iqk(rtwdev); 3252 + } 3253 + 3254 + static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) 3255 + { 3256 + struct rtw_efuse *efuse = &rtwdev->efuse; 3257 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 3258 + 3259 + if (efuse->power_track_type != 0) 3260 + return; 3261 + 3262 + if (!dm_info->pwr_trk_triggered) { 3263 + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 3264 + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00); 3265 + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); 3266 + 3267 + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 3268 + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00); 3269 + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); 3270 + 3271 + dm_info->pwr_trk_triggered = true; 3272 + return; 3273 + } 3274 + 3275 + __rtw8822c_pwr_track(rtwdev); 3276 + dm_info->pwr_trk_triggered = false; 3277 + } 3278 + 3219 3279 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { 3220 3280 {0x0086, 3221 3281 RTW_PWR_CUT_ALL_MSK, ··· 3677 3575 .dpk_track = rtw8822c_dpk_track, 3678 3576 .phy_calibration = rtw8822c_phy_calibration, 3679 3577 .cck_pd_set = rtw8822c_phy_cck_pd_set, 3578 + .pwr_track = rtw8822c_pwr_track, 3680 3579 3681 3580 .coex_set_init = rtw8822c_coex_cfg_init, 3682 3581 .coex_set_ant_switch = NULL, ··· 3832 3729 3833 3730 static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); 3834 3731 3732 + static const u8 3733 + rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 3734 + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 3735 + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 3736 + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 3737 + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 3738 + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 3739 + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 3740 + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 3741 + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 3742 + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, 3743 + }; 3744 + 3745 + static const u8 3746 + rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 3747 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3748 + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 3749 + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 3750 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3751 + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 3752 + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 3753 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3754 + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 3755 + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, 3756 + }; 3757 + 3758 + static const u8 3759 + rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 3760 + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 3761 + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 3762 + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 3763 + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 3764 + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 3765 + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 3766 + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 3767 + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 3768 + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, 3769 + }; 3770 + 3771 + static const u8 3772 + rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { 3773 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3774 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 3775 + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 3776 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3777 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 3778 + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 3779 + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3780 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 3781 + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, 3782 + }; 3783 + 3784 + static const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { 3785 + 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 3786 + 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, 3787 + 17, 18, 19, 20, 20, 21, 22, 23, 24, 25 3788 + }; 3789 + 3790 + static const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { 3791 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3792 + 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 3793 + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 3794 + }; 3795 + 3796 + static const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { 3797 + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 3798 + 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 3799 + 13, 14, 15, 15, 16, 17, 17, 18, 19, 19 3800 + }; 3801 + 3802 + static const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { 3803 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3804 + 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 3805 + 19, 20, 21, 22, 23, 24, 25, 25, 26, 27 3806 + }; 3807 + 3808 + static const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { 3809 + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 3810 + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 3811 + 17, 18, 19, 20, 21, 22, 23, 23, 24, 25 3812 + }; 3813 + 3814 + static const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { 3815 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3816 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3817 + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 3818 + }; 3819 + 3820 + static const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { 3821 + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 3822 + 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 3823 + 15, 16, 17, 18, 18, 19, 20, 21, 21, 22 3824 + }; 3825 + 3826 + static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { 3827 + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 3828 + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 3829 + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 3830 + }; 3831 + 3832 + static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { 3833 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], 3834 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], 3835 + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], 3836 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], 3837 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], 3838 + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], 3839 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], 3840 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], 3841 + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], 3842 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], 3843 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], 3844 + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], 3845 + .pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n, 3846 + .pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p, 3847 + .pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n, 3848 + .pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p, 3849 + .pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n, 3850 + .pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p, 3851 + .pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n, 3852 + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, 3853 + }; 3854 + 3835 3855 struct rtw_chip_info rtw8822c_hw_spec = { 3836 3856 .ops = &rtw8822c_ops, 3837 3857 .id = RTW_CHIP_TYPE_8822C, ··· 3996 3770 .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), 3997 3771 .en_dis_dpd = true, 3998 3772 .dpd_ratemask = DIS_DPD_RATEALL, 3773 + .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, 3774 + .iqk_threshold = 8, 3999 3775 4000 3776 .coex_para_ver = 0x19062706, 4001 3777 .bt_desired_ver = 0x6,