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

rtw88: add phy_info debugfs to show Tx/Rx physical status

This commit adds several Tx/Rx physical information to phy_info
debugfs for 8822B/8822C. By this debugfs, we can know physical
information, such as Tx/Rx rate, RSSI, EVM,SNR, etc. The
information is gotten from the packets of Tx/Rx path. It has
no impact for the performance of 8822B/8822C.

In the fields, we may meet different kinds of problems, but
we may have no professional instrument to check them. At
this moment, this debugfs is a good tool, and it may provide
useful information for debug.

Signed-off-by: Tsang-Shian Lin <thlin@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

Tsang-Shian Lin and committed by
Kalle Valo
082a36dc f39e9bd4

+431 -33
+153 -21
drivers/net/wireless/realtek/rtw88/debug.c
··· 498 498 seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); 499 499 } 500 500 501 + static void rtw_print_rate(struct seq_file *m, u8 rate) 502 + { 503 + switch (rate) { 504 + case DESC_RATE1M...DESC_RATE11M: 505 + rtw_print_cck_rate_txt(m, rate); 506 + break; 507 + case DESC_RATE6M...DESC_RATE54M: 508 + rtw_print_ofdm_rate_txt(m, rate); 509 + break; 510 + case DESC_RATEMCS0...DESC_RATEMCS15: 511 + rtw_print_ht_rate_txt(m, rate); 512 + break; 513 + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 514 + rtw_print_vht_rate_txt(m, rate); 515 + break; 516 + default: 517 + seq_printf(m, " Unknown rate=0x%x\n", rate); 518 + break; 519 + } 520 + } 521 + 501 522 static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) 502 523 { 503 524 struct rtw_debugfs_priv *debugfs_priv = m->private; 504 525 struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 505 526 struct rtw_hal *hal = &rtwdev->hal; 506 - void (*print_rate)(struct seq_file *, u8) = NULL; 507 527 u8 path, rate; 508 528 struct rtw_power_params pwr_param = {0}; 509 529 u8 bw = hal->current_band_width; ··· 548 528 rate < DESC_RATEVHT1SS_MCS0) 549 529 continue; 550 530 551 - switch (rate) { 552 - case DESC_RATE1M...DESC_RATE11M: 553 - print_rate = rtw_print_cck_rate_txt; 554 - break; 555 - case DESC_RATE6M...DESC_RATE54M: 556 - print_rate = rtw_print_ofdm_rate_txt; 557 - break; 558 - case DESC_RATEMCS0...DESC_RATEMCS15: 559 - print_rate = rtw_print_ht_rate_txt; 560 - break; 561 - case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: 562 - print_rate = rtw_print_vht_rate_txt; 563 - break; 564 - default: 565 - print_rate = NULL; 566 - break; 567 - } 568 - 569 531 rtw_get_tx_power_params(rtwdev, path, rate, bw, 570 532 ch, regd, &pwr_param); 571 533 572 534 seq_printf(m, "%4c ", path + 'A'); 573 - if (print_rate) 574 - print_rate(m, rate); 535 + rtw_print_rate(m, rate); 575 536 seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d)\n", 576 537 hal->tx_pwr_tbl[path][rate], 577 538 hal->tx_pwr_tbl[path][rate], ··· 565 564 566 565 mutex_unlock(&hal->tx_power_mutex); 567 566 567 + return 0; 568 + } 569 + 570 + static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) 571 + { 572 + struct rtw_debugfs_priv *debugfs_priv = m->private; 573 + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; 574 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 575 + struct rtw_traffic_stats *stats = &rtwdev->stats; 576 + struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; 577 + struct rtw_efuse *efuse = &rtwdev->efuse; 578 + struct ewma_evm *ewma_evm = dm_info->ewma_evm; 579 + struct ewma_snr *ewma_snr = dm_info->ewma_snr; 580 + u8 ss, rate_id; 581 + 582 + seq_puts(m, "==========[Common Info]========\n"); 583 + seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); 584 + seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); 585 + seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); 586 + seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); 587 + seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n", 588 + stats->tx_throughput, stats->rx_throughput); 589 + 590 + seq_puts(m, "==========[Tx Phy Info]========\n"); 591 + seq_puts(m, "[Tx Rate] = "); 592 + rtw_print_rate(m, dm_info->tx_rate); 593 + seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); 594 + 595 + seq_puts(m, "==========[Rx Phy Info]========\n"); 596 + seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); 597 + seq_puts(m, "[Rx Rate] = "); 598 + rtw_print_rate(m, dm_info->curr_rx_rate); 599 + seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); 600 + 601 + seq_puts(m, "[Rx Rate Count]:\n"); 602 + seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", 603 + last_cnt->num_qry_pkt[DESC_RATE1M], 604 + last_cnt->num_qry_pkt[DESC_RATE2M], 605 + last_cnt->num_qry_pkt[DESC_RATE5_5M], 606 + last_cnt->num_qry_pkt[DESC_RATE11M]); 607 + 608 + seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 609 + last_cnt->num_qry_pkt[DESC_RATE6M], 610 + last_cnt->num_qry_pkt[DESC_RATE9M], 611 + last_cnt->num_qry_pkt[DESC_RATE12M], 612 + last_cnt->num_qry_pkt[DESC_RATE18M], 613 + last_cnt->num_qry_pkt[DESC_RATE24M], 614 + last_cnt->num_qry_pkt[DESC_RATE36M], 615 + last_cnt->num_qry_pkt[DESC_RATE48M], 616 + last_cnt->num_qry_pkt[DESC_RATE54M]); 617 + 618 + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 619 + rate_id = DESC_RATEMCS0 + ss * 8; 620 + seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", 621 + ss * 8, ss * 8 + 7, 622 + last_cnt->num_qry_pkt[rate_id], 623 + last_cnt->num_qry_pkt[rate_id + 1], 624 + last_cnt->num_qry_pkt[rate_id + 2], 625 + last_cnt->num_qry_pkt[rate_id + 3], 626 + last_cnt->num_qry_pkt[rate_id + 4], 627 + last_cnt->num_qry_pkt[rate_id + 5], 628 + last_cnt->num_qry_pkt[rate_id + 6], 629 + last_cnt->num_qry_pkt[rate_id + 7]); 630 + } 631 + 632 + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { 633 + rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; 634 + seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", 635 + ss + 1, 636 + last_cnt->num_qry_pkt[rate_id], 637 + last_cnt->num_qry_pkt[rate_id + 1], 638 + last_cnt->num_qry_pkt[rate_id + 2], 639 + last_cnt->num_qry_pkt[rate_id + 3], 640 + last_cnt->num_qry_pkt[rate_id + 4], 641 + last_cnt->num_qry_pkt[rate_id + 5], 642 + last_cnt->num_qry_pkt[rate_id + 6], 643 + last_cnt->num_qry_pkt[rate_id + 7], 644 + last_cnt->num_qry_pkt[rate_id + 8], 645 + last_cnt->num_qry_pkt[rate_id + 9]); 646 + } 647 + 648 + seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", 649 + dm_info->rssi[RF_PATH_A] - 100, 650 + dm_info->rssi[RF_PATH_B] - 100); 651 + seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", 652 + dm_info->rx_evm_dbm[RF_PATH_A], 653 + dm_info->rx_evm_dbm[RF_PATH_B]); 654 + seq_printf(m, "[Rx SNR] = {%d, %d}\n", 655 + dm_info->rx_snr[RF_PATH_A], 656 + dm_info->rx_snr[RF_PATH_B]); 657 + seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", 658 + dm_info->cfo_tail[RF_PATH_A], 659 + dm_info->cfo_tail[RF_PATH_B]); 660 + 661 + if (dm_info->curr_rx_rate >= DESC_RATE11M) { 662 + seq_puts(m, "[Rx Average Status]:\n"); 663 + seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", 664 + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), 665 + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); 666 + seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", 667 + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), 668 + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); 669 + seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", 670 + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), 671 + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), 672 + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), 673 + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); 674 + } 675 + 676 + seq_puts(m, "[Rx Counter]:\n"); 677 + seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", 678 + dm_info->cck_cca_cnt, 679 + dm_info->ofdm_cca_cnt, 680 + dm_info->total_cca_cnt); 681 + seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", 682 + dm_info->cck_fa_cnt, 683 + dm_info->ofdm_fa_cnt, 684 + dm_info->total_fa_cnt); 685 + seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", 686 + dm_info->cck_ok_cnt, dm_info->cck_err_cnt); 687 + seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", 688 + dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); 689 + seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", 690 + dm_info->ht_ok_cnt, dm_info->ht_err_cnt); 691 + seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", 692 + dm_info->vht_ok_cnt, dm_info->vht_err_cnt); 568 693 return 0; 569 694 } 570 695 ··· 780 653 .cb_read = rtw_debugfs_get_rsvd_page, 781 654 }; 782 655 656 + static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { 657 + .cb_read = rtw_debugfs_get_phy_info, 658 + }; 659 + 783 660 #define rtw_debugfs_add_core(name, mode, fopname, parent) \ 784 661 do { \ 785 662 rtw_debug_priv_ ##name.rtwdev = rtwdev; \ ··· 813 682 rtw_debugfs_add_rw(rf_read); 814 683 rtw_debugfs_add_rw(dump_cam); 815 684 rtw_debugfs_add_rw(rsvd_page); 685 + rtw_debugfs_add_r(phy_info); 816 686 rtw_debugfs_add_r(mac_0); 817 687 rtw_debugfs_add_r(mac_1); 818 688 rtw_debugfs_add_r(mac_2);
+31 -6
drivers/net/wireless/realtek/rtw88/main.c
··· 178 178 { 179 179 struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, 180 180 watch_dog_work.work); 181 + struct rtw_traffic_stats *stats = &rtwdev->stats; 181 182 struct rtw_watch_dog_iter_data data = {}; 182 183 bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); 183 184 bool ps_active; ··· 199 198 if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags)) 200 199 rtw_coex_wl_status_change_notify(rtwdev); 201 200 202 - if (rtwdev->stats.tx_cnt > RTW_LPS_THRESHOLD || 203 - rtwdev->stats.rx_cnt > RTW_LPS_THRESHOLD) 201 + if (stats->tx_cnt > RTW_LPS_THRESHOLD || 202 + stats->rx_cnt > RTW_LPS_THRESHOLD) 204 203 ps_active = true; 205 204 else 206 205 ps_active = false; 207 206 207 + ewma_tp_add(&stats->tx_ewma_tp, 208 + (u32)(stats->tx_unicast >> RTW_TP_SHIFT)); 209 + ewma_tp_add(&stats->rx_ewma_tp, 210 + (u32)(stats->rx_unicast >> RTW_TP_SHIFT)); 211 + stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); 212 + stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); 213 + 208 214 /* reset tx/rx statictics */ 209 - rtwdev->stats.tx_unicast = 0; 210 - rtwdev->stats.rx_unicast = 0; 211 - rtwdev->stats.tx_cnt = 0; 212 - rtwdev->stats.rx_cnt = 0; 215 + stats->tx_unicast = 0; 216 + stats->rx_unicast = 0; 217 + stats->tx_cnt = 0; 218 + stats->rx_cnt = 0; 213 219 214 220 if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) 215 221 goto unlock; ··· 1289 1281 } 1290 1282 EXPORT_SYMBOL(rtw_chip_info_setup); 1291 1283 1284 + static void rtw_stats_init(struct rtw_dev *rtwdev) 1285 + { 1286 + struct rtw_traffic_stats *stats = &rtwdev->stats; 1287 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1288 + int i; 1289 + 1290 + ewma_tp_init(&stats->tx_ewma_tp); 1291 + ewma_tp_init(&stats->rx_ewma_tp); 1292 + 1293 + for (i = 0; i < RTW_EVM_NUM; i++) 1294 + ewma_evm_init(&dm_info->ewma_evm[i]); 1295 + for (i = 0; i < RTW_SNR_NUM; i++) 1296 + ewma_snr_init(&dm_info->ewma_snr[i]); 1297 + } 1298 + 1292 1299 int rtw_core_init(struct rtw_dev *rtwdev) 1293 1300 { 1294 1301 struct rtw_chip_info *chip = rtwdev->chip; ··· 1351 1328 mutex_lock(&rtwdev->mutex); 1352 1329 rtw_add_rsvd_page(rtwdev, RSVD_BEACON, false); 1353 1330 mutex_unlock(&rtwdev->mutex); 1331 + 1332 + rtw_stats_init(rtwdev); 1354 1333 1355 1334 /* default rx filter setting */ 1356 1335 rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV |
+58
drivers/net/wireless/realtek/rtw88/main.h
··· 29 29 #define RTW_RF_PATH_MAX 4 30 30 #define HW_FEATURE_LEN 13 31 31 32 + #define RTW_TP_SHIFT 18 /* bytes/2s --> Mbps */ 33 + 32 34 extern bool rtw_bf_support; 33 35 extern unsigned int rtw_fw_lps_deep_mode; 34 36 extern unsigned int rtw_debug_mask; ··· 341 339 NUM_OF_RTW_FLAGS, 342 340 }; 343 341 342 + enum rtw_evm { 343 + RTW_EVM_OFDM = 0, 344 + RTW_EVM_1SS, 345 + RTW_EVM_2SS_A, 346 + RTW_EVM_2SS_B, 347 + /* keep it last */ 348 + RTW_EVM_NUM 349 + }; 350 + 351 + enum rtw_snr { 352 + RTW_SNR_OFDM_A = 0, 353 + RTW_SNR_OFDM_B, 354 + RTW_SNR_OFDM_C, 355 + RTW_SNR_OFDM_D, 356 + RTW_SNR_1SS_A, 357 + RTW_SNR_1SS_B, 358 + RTW_SNR_1SS_C, 359 + RTW_SNR_1SS_D, 360 + RTW_SNR_2SS_A, 361 + RTW_SNR_2SS_B, 362 + RTW_SNR_2SS_C, 363 + RTW_SNR_2SS_D, 364 + /* keep it last */ 365 + RTW_SNR_NUM 366 + }; 367 + 344 368 /* the power index is represented by differences, which cck-1s & ht40-1s are 345 369 * the base values, so for 1s's differences, there are only ht20 & ofdm 346 370 */ ··· 555 527 s8 rx_power[RTW_RF_PATH_MAX]; 556 528 u8 rssi; 557 529 u8 rxsc; 530 + s8 rx_snr[RTW_RF_PATH_MAX]; 531 + u8 rx_evm[RTW_RF_PATH_MAX]; 532 + s8 cfo_tail[RTW_RF_PATH_MAX]; 533 + 558 534 struct rtw_sta_info *si; 559 535 struct ieee80211_vif *vif; 560 536 }; 537 + 538 + DECLARE_EWMA(tp, 10, 2); 561 539 562 540 struct rtw_traffic_stats { 563 541 /* units in bytes */ ··· 577 543 /* units in Mbps */ 578 544 u32 tx_throughput; 579 545 u32 rx_throughput; 546 + struct ewma_tp tx_ewma_tp; 547 + struct ewma_tp rx_ewma_tp; 580 548 }; 581 549 582 550 enum rtw_lps_mode { ··· 1287 1251 const u8 *n[RTW_RF_PATH_MAX]; 1288 1252 }; 1289 1253 1254 + struct rtw_pkt_count { 1255 + u16 num_bcn_pkt; 1256 + u16 num_qry_pkt[DESC_RATE_MAX]; 1257 + }; 1258 + 1259 + DECLARE_EWMA(evm, 10, 4); 1260 + DECLARE_EWMA(snr, 10, 4); 1261 + 1290 1262 struct rtw_dm_info { 1291 1263 u32 cck_fa_cnt; 1292 1264 u32 ofdm_fa_cnt; 1293 1265 u32 total_fa_cnt; 1266 + u32 cck_cca_cnt; 1267 + u32 ofdm_cca_cnt; 1268 + u32 total_cca_cnt; 1294 1269 1295 1270 u32 cck_ok_cnt; 1296 1271 u32 cck_err_cnt; ··· 1343 1296 /* [bandwidth 0:20M/1:40M][number of path] */ 1344 1297 u8 cck_pd_lv[2][RTW_RF_PATH_MAX]; 1345 1298 u32 cck_fa_avg; 1299 + 1300 + /* save the last rx phy status for debug */ 1301 + s8 rx_snr[RTW_RF_PATH_MAX]; 1302 + u8 rx_evm_dbm[RTW_RF_PATH_MAX]; 1303 + s16 cfo_tail[RTW_RF_PATH_MAX]; 1304 + u8 rssi[RTW_RF_PATH_MAX]; 1305 + u8 curr_rx_rate; 1306 + struct rtw_pkt_count cur_pkt_count; 1307 + struct rtw_pkt_count last_pkt_count; 1308 + struct ewma_evm ewma_evm[RTW_EVM_NUM]; 1309 + struct ewma_snr ewma_snr[RTW_SNR_NUM]; 1346 1310 }; 1347 1311 1348 1312 struct rtw_efuse {
+9
drivers/net/wireless/realtek/rtw88/phy.c
··· 222 222 dm_info->min_rssi = data.min_rssi; 223 223 } 224 224 225 + static void rtw_phy_stat_rate_cnt(struct rtw_dev *rtwdev) 226 + { 227 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 228 + 229 + dm_info->last_pkt_count = dm_info->cur_pkt_count; 230 + memset(&dm_info->cur_pkt_count, 0, sizeof(dm_info->cur_pkt_count)); 231 + } 232 + 225 233 static void rtw_phy_statistics(struct rtw_dev *rtwdev) 226 234 { 227 235 rtw_phy_stat_rssi(rtwdev); 228 236 rtw_phy_stat_false_alarm(rtwdev); 237 + rtw_phy_stat_rate_cnt(rtwdev); 229 238 } 230 239 231 240 #define DIG_PERF_FA_TH_LOW 250
+45
drivers/net/wireless/realtek/rtw88/rtw8822b.c
··· 815 815 static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, 816 816 struct rtw_rx_pkt_stat *pkt_stat) 817 817 { 818 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 818 819 s8 min_rx_power = -120; 819 820 u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); 820 821 ··· 825 824 pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 826 825 pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 827 826 min_rx_power); 827 + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 828 828 } 829 829 830 830 static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 831 831 struct rtw_rx_pkt_stat *pkt_stat) 832 832 { 833 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 833 834 u8 rxsc, bw; 834 835 s8 min_rx_power = -120; 836 + s8 rx_evm; 837 + u8 evm_dbm = 0; 838 + u8 rssi; 839 + int path; 835 840 836 841 if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 837 842 rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); ··· 860 853 pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], 861 854 pkt_stat->rx_power[RF_PATH_B], 862 855 min_rx_power); 856 + 857 + dm_info->curr_rx_rate = pkt_stat->rate; 858 + 859 + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); 860 + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); 861 + 862 + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); 863 + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); 864 + 865 + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); 866 + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); 867 + 868 + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 869 + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 870 + dm_info->rssi[path] = rssi; 871 + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; 872 + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; 873 + 874 + rx_evm = pkt_stat->rx_evm[path]; 875 + 876 + if (rx_evm < 0) { 877 + if (rx_evm == S8_MIN) 878 + evm_dbm = 0; 879 + else 880 + evm_dbm = ((u8)-rx_evm >> 1); 881 + } 882 + dm_info->rx_evm_dbm[path] = evm_dbm; 883 + } 863 884 } 864 885 865 886 static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ··· 1034 999 u32 cck_fa_cnt; 1035 1000 u32 ofdm_fa_cnt; 1036 1001 u32 crc32_cnt; 1002 + u32 cca32_cnt; 1037 1003 1038 1004 cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28); 1039 1005 cck_fa_cnt = rtw_read16(rtwdev, 0xa5c); ··· 1057 1021 crc32_cnt = rtw_read32(rtwdev, 0xf0c); 1058 1022 dm_info->vht_ok_cnt = crc32_cnt & 0xffff; 1059 1023 dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 1024 + 1025 + cca32_cnt = rtw_read32(rtwdev, 0xf08); 1026 + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); 1027 + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 1028 + if (cck_enable) { 1029 + cca32_cnt = rtw_read32(rtwdev, 0xfcc); 1030 + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; 1031 + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 1032 + } 1060 1033 1061 1034 rtw_write32_set(rtwdev, 0x9a4, BIT(17)); 1062 1035 rtw_write32_clr(rtwdev, 0x9a4, BIT(17));
+12
drivers/net/wireless/realtek/rtw88/rtw8822b.h
··· 127 127 le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) 128 128 #define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ 129 129 le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) 130 + #define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ 131 + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) 132 + #define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ 133 + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) 134 + #define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ 135 + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) 136 + #define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ 137 + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) 138 + #define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ 139 + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) 140 + #define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ 141 + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) 130 142 131 143 #define REG_HTSTFWT 0x800 132 144 #define REG_RXPSEL 0x808
+48
drivers/net/wireless/realtek/rtw88/rtw8822c.c
··· 1643 1643 u8 gain_a, gain_b; 1644 1644 s8 rx_power[RTW_RF_PATH_MAX]; 1645 1645 s8 min_rx_power = -120; 1646 + u8 rssi; 1647 + int path; 1646 1648 1647 1649 rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status); 1648 1650 rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status); ··· 1667 1665 pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; 1668 1666 pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; 1669 1667 1668 + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 1669 + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 1670 + dm_info->rssi[path] = rssi; 1671 + } 1672 + 1670 1673 pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 1671 1674 pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 1672 1675 pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], ··· 1681 1674 static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 1682 1675 struct rtw_rx_pkt_stat *pkt_stat) 1683 1676 { 1677 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1684 1678 u8 rxsc, bw; 1685 1679 s8 min_rx_power = -120; 1680 + s8 rx_evm; 1681 + u8 evm_dbm = 0; 1682 + u8 rssi; 1683 + int path; 1686 1684 1687 1685 if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 1688 1686 rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); ··· 1708 1696 pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], 1709 1697 pkt_stat->rx_power[RF_PATH_B], 1710 1698 min_rx_power); 1699 + 1700 + dm_info->curr_rx_rate = pkt_stat->rate; 1701 + 1702 + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); 1703 + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); 1704 + 1705 + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); 1706 + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); 1707 + 1708 + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); 1709 + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); 1710 + 1711 + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { 1712 + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); 1713 + dm_info->rssi[path] = rssi; 1714 + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; 1715 + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; 1716 + 1717 + rx_evm = pkt_stat->rx_evm[path]; 1718 + 1719 + if (rx_evm < 0) { 1720 + if (rx_evm == S8_MIN) 1721 + evm_dbm = 0; 1722 + else 1723 + evm_dbm = ((u8)-rx_evm >> 1); 1724 + } 1725 + dm_info->rx_evm_dbm[path] = evm_dbm; 1726 + } 1711 1727 } 1712 1728 1713 1729 static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ··· 1890 1850 u32 cck_enable; 1891 1851 u32 cck_fa_cnt; 1892 1852 u32 crc32_cnt; 1853 + u32 cca32_cnt; 1893 1854 u32 ofdm_fa_cnt; 1894 1855 u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; 1895 1856 u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, ··· 1934 1893 crc32_cnt = rtw_read32(rtwdev, 0x2c0c); 1935 1894 dm_info->vht_ok_cnt = crc32_cnt & 0xffff; 1936 1895 dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; 1896 + 1897 + cca32_cnt = rtw_read32(rtwdev, 0x2c08); 1898 + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); 1899 + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; 1900 + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 1901 + if (cck_enable) 1902 + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 1937 1903 1938 1904 rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0); 1939 1905 rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2);
+12
drivers/net/wireless/realtek/rtw88/rtw8822c.h
··· 149 149 le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) 150 150 #define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ 151 151 le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) 152 + #define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ 153 + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) 154 + #define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ 155 + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) 156 + #define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ 157 + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) 158 + #define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ 159 + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) 160 + #define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ 161 + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) 162 + #define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ 163 + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) 152 164 153 165 #define REG_ANAPARLDO_POW_MAC 0x0029 154 166 #define BIT_LDOE25_PON BIT(0)
+63 -6
drivers/net/wireless/realtek/rtw88/rx.c
··· 5 5 #include "main.h" 6 6 #include "rx.h" 7 7 #include "ps.h" 8 + #include "debug.h" 8 9 9 10 void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, 10 11 struct sk_buff *skb) ··· 38 37 u8 *bssid; 39 38 }; 40 39 40 + static void rtw_rx_phy_stat(struct rtw_dev *rtwdev, 41 + struct rtw_rx_pkt_stat *pkt_stat, 42 + struct ieee80211_hdr *hdr) 43 + { 44 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 45 + struct rtw_pkt_count *cur_pkt_cnt = &dm_info->cur_pkt_count; 46 + u8 rate_ss, rate_ss_evm, evm_id; 47 + u8 i, idx; 48 + 49 + dm_info->curr_rx_rate = pkt_stat->rate; 50 + 51 + if (ieee80211_is_beacon(hdr->frame_control)) 52 + cur_pkt_cnt->num_bcn_pkt++; 53 + 54 + switch (pkt_stat->rate) { 55 + case DESC_RATE1M...DESC_RATE11M: 56 + goto pkt_num; 57 + case DESC_RATE6M...DESC_RATE54M: 58 + rate_ss = 0; 59 + rate_ss_evm = 1; 60 + evm_id = RTW_EVM_OFDM; 61 + break; 62 + case DESC_RATEMCS0...DESC_RATEMCS7: 63 + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT1SS_MCS9: 64 + rate_ss = 1; 65 + rate_ss_evm = 1; 66 + evm_id = RTW_EVM_1SS; 67 + break; 68 + case DESC_RATEMCS8...DESC_RATEMCS15: 69 + case DESC_RATEVHT2SS_MCS0...DESC_RATEVHT2SS_MCS9: 70 + rate_ss = 2; 71 + rate_ss_evm = 2; 72 + evm_id = RTW_EVM_2SS_A; 73 + break; 74 + default: 75 + rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate); 76 + return; 77 + } 78 + 79 + for (i = 0; i < rate_ss_evm; i++) { 80 + idx = evm_id + i; 81 + ewma_evm_add(&dm_info->ewma_evm[idx], 82 + dm_info->rx_evm_dbm[i]); 83 + } 84 + 85 + for (i = 0; i < rtwdev->hal.rf_path_num; i++) { 86 + idx = RTW_SNR_OFDM_A + 4 * rate_ss + i; 87 + ewma_snr_add(&dm_info->ewma_snr[idx], 88 + dm_info->rx_snr[i]); 89 + } 90 + pkt_num: 91 + cur_pkt_cnt->num_qry_pkt[pkt_stat->rate]++; 92 + } 93 + 41 94 static void rtw_rx_addr_match_iter(void *data, u8 *mac, 42 95 struct ieee80211_vif *vif) 43 96 { ··· 103 48 struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat; 104 49 u8 *bssid = iter_data->bssid; 105 50 106 - if (ether_addr_equal(vif->bss_conf.bssid, bssid) && 107 - (ether_addr_equal(vif->addr, hdr->addr1) || 108 - ieee80211_is_beacon(hdr->frame_control))) 109 - sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2, 110 - vif->addr); 111 - else 51 + if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) 112 52 return; 113 53 54 + if (!(ether_addr_equal(vif->addr, hdr->addr1) || 55 + ieee80211_is_beacon(hdr->frame_control))) 56 + return; 57 + 58 + rtw_rx_phy_stat(rtwdev, pkt_stat, hdr); 59 + sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2, 60 + vif->addr); 114 61 if (!sta) 115 62 return; 116 63