mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
586 lines
28 KiB
C
586 lines
28 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "esp_log.h"
|
|
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
|
|
|
#include "esp_console.h"
|
|
#include "argtable3/argtable3.h"
|
|
#include "esp_event.h"
|
|
#include "esp_wifi.h"
|
|
#include "esp_wifi_types.h"
|
|
#include "wifi_stats.h"
|
|
#include "esp_private/esp_wifi_he_private.h"
|
|
|
|
/*******************************************************
|
|
* Macros
|
|
*******************************************************/
|
|
/*
|
|
* enable/disable rx/tx statistics after Wi-Fi started:
|
|
* (1) esp_wifi_enable_rx_statistics(true, true); //rx_stats=true, rx_mu_stats=true
|
|
* (2) esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //aci=ESP_WIFI_ACI_BE, tx_stats=true
|
|
*/
|
|
|
|
/*******************************************************
|
|
* Constants
|
|
*******************************************************/
|
|
static const char *TAG = "stats";
|
|
|
|
/*******************************************************
|
|
* Structures
|
|
*******************************************************/
|
|
|
|
/*******************************************************
|
|
* Variable Definitions
|
|
*******************************************************/
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
|
esp_test_rx_mu_statistics_t rx_mu_stats = { 0, }; //10932 bytes
|
|
#endif
|
|
|
|
/*******************************************************
|
|
* Function Declarations
|
|
*******************************************************/
|
|
|
|
/*******************************************************
|
|
* Function Definitions
|
|
*******************************************************/
|
|
const char *tx_fail_error2str(esp_test_tx_fail_error_t error)
|
|
{
|
|
switch (error) {
|
|
case TEST_TX_FAIL_ERROR_H00:
|
|
return "0x00";
|
|
case TEST_TX_FAIL_ERROR_H53:
|
|
return "0x53";
|
|
case TEST_TX_FAIL_ERROR_H63:
|
|
return "0x63";
|
|
case TEST_TX_FAIL_ERROR_H75:
|
|
return "0x75";
|
|
case TEST_TX_FAIL_ERROR_H41:
|
|
return "0x41";
|
|
case TEST_TX_FAIL_ERROR_H42:
|
|
return "0x42";
|
|
case TEST_TX_FAIL_ERROR_H47:
|
|
return "0x47";
|
|
case TEST_TX_FAIL_ERROR_H80:
|
|
return "0x80";
|
|
case TEST_TX_FAIL_ERROR_H5A:
|
|
return "0x5A";
|
|
case TEST_TX_FAIL_ERROR_HXX:
|
|
return "Others";
|
|
case TEST_TX_FAIL_ERROR_MAX:
|
|
return "Undefined";
|
|
}
|
|
return "Undefined";
|
|
}
|
|
|
|
const char *tx_fail_match2str(esp_test_tx_fail_match_t match)
|
|
{
|
|
switch (match) {
|
|
case TEST_TX_WAIT_MATCH:
|
|
return "MATCH";
|
|
case TEST_TX_WAIT_NOT2SELF:
|
|
return "NOT2SELF";
|
|
case TEST_TX_MISMATCH:
|
|
return "MISMATCH";
|
|
case TEST_TX_WAIT_TIMEOUT:
|
|
return "TIMEOUT";
|
|
case TEST_TX_WAIT_MAX:
|
|
return "Undefined";
|
|
}
|
|
return "Undefined";
|
|
}
|
|
|
|
const char *tx_fail_state2str(esp_test_tx_fail_state_t state)
|
|
{
|
|
switch (state) {
|
|
case TEST_TX_SUCCESS:
|
|
return "TX Success";
|
|
case TEST_TX_FAIL_RTS:
|
|
return "TX RTS";
|
|
case TEST_TX_WAIT_CTS: //RX
|
|
return "Wait CTS";
|
|
case TEST_TX_FAIL_CTS:
|
|
return "TX RTS";
|
|
case TEST_TX_FAIL_DATA:
|
|
return "TX DATA";
|
|
case TEST_TX_WAIT_ACK: //RX
|
|
return "Wait ACK/BA";
|
|
case TEST_TX_FAIL_MAX:
|
|
return "Undefined";
|
|
}
|
|
return "Undefined";
|
|
}
|
|
|
|
int wifi_cmd_clr_tx_statistics(int argc, char **argv)
|
|
{
|
|
ESP_LOGW(TAG, "Clear tx statistics");
|
|
int i;
|
|
for (i = 0; i < 3; i++) {
|
|
esp_wifi_clr_tx_statistics(i); //BE
|
|
esp_wifi_clr_tx_tb_statistics(i);
|
|
}
|
|
esp_test_clr_hw_statistics();
|
|
return 0;
|
|
}
|
|
|
|
void print_hw_tb_statistics(void)
|
|
{
|
|
esp_test_hw_tb_statistics_t hw_tb_stats = { 0, };
|
|
esp_test_get_hw_tb_statistics(&hw_tb_stats);
|
|
printf("(test)rx_trig:%d, tx_bfrpt:%d, tb_times:%d, tb_qos_null:%d, tb_qos_data:%d, tb_cca_cancel:%d, tb_sifs_abort:%d, tb_pwr_outof_range:%d\n",
|
|
hw_tb_stats.rx_trig,
|
|
hw_tb_stats.tx_bfrpt, //including TB and Non-TB
|
|
hw_tb_stats.tb_times,
|
|
hw_tb_stats.tb_qos_null,
|
|
hw_tb_stats.tb_times - hw_tb_stats.tb_qos_null,
|
|
hw_tb_stats.tb_cca_cancel,
|
|
hw_tb_stats.tb_sifs_abort,
|
|
hw_tb_stats.tb_pwr_outof_range);
|
|
}
|
|
|
|
int wifi_cmd_get_tx_statistics(int argc, char **argv)
|
|
{
|
|
uint8_t i, h, j, k;
|
|
|
|
ESP_LOGW(TAG, "Get tx statistics\n");
|
|
esp_test_tx_tb_statistics_t tb_stats = { 0, }; //32 bytes
|
|
esp_test_tx_statistics_t tx_stats = { 0, }; //136 bytes
|
|
esp_test_tx_fail_statistics_t tx_fail[TEST_TX_FAIL_MAX] = { 0, }; //TEST_TX_FAIL_MAX * 164 bytes
|
|
|
|
print_hw_tb_statistics();
|
|
//only check BE
|
|
for (i = 2; i < 3; i++) {
|
|
esp_wifi_get_tx_tb_statistics(i, &tb_stats);
|
|
/* TB */
|
|
printf("(test)aci:%d, tb(suc:%d, ack:%d, err:%d), "
|
|
"count(suc:%d, ack:%d, err:%d, tot:%d, max_sent:%d)\n",
|
|
i,
|
|
tb_stats.complete_suc_tb,
|
|
tb_stats.complete_ack_tb,
|
|
tb_stats.complete_err_tb,
|
|
tb_stats.complete_tb_suc_count,
|
|
tb_stats.complete_tb_ack_count,
|
|
tb_stats.complete_tb_err_count,
|
|
tb_stats.complete_tb_tot_count,
|
|
tb_stats.complete_tb_pack_sent);
|
|
|
|
esp_wifi_get_tx_statistics(i, &tx_stats, (esp_test_tx_fail_statistics_t *) &tx_fail);
|
|
int tot_tx_times = tx_stats.tb_times + (tx_stats.tx_enable - tx_stats.tb_last); //TB + EDCA
|
|
int tot_fail = tx_fail[1].count + tx_fail[2].count + tx_fail[3].count + tx_fail[4].count + tx_fail[5].count;
|
|
printf("(test)aci:%d, enable:%d, complete:%d, tb_times:%d, tb_last:%d, edca:%d, "
|
|
"succ:%d, fail(%d,%d,%d, cts:%d/%2.2f%%, ack:%d/%2.2f%%, tot:%d, %.2f%%), "
|
|
"edca(ack:%d, ba:%d), tb(hw-ba:%d, sw-ba:%d)\n",
|
|
i, tx_stats.tx_enable,
|
|
tx_stats.tx_complete,
|
|
tx_stats.tb_times,
|
|
tx_stats.tb_last,
|
|
tx_stats.tx_enable - tx_stats.tb_last,
|
|
tx_fail[0].count,
|
|
tx_fail[1].count,
|
|
tx_fail[3].count,
|
|
tx_fail[4].count,
|
|
tx_fail[2].count,
|
|
(float) ((float) tx_fail[2].count / (float) tot_tx_times) * 100, //rx cts
|
|
tx_fail[5].count, (float) ((float) tx_fail[5].count / (float) tot_tx_times) * 100, //rx ack
|
|
tot_fail,
|
|
(float) ((float) tot_fail / (float) tot_tx_times) * 100,
|
|
tx_stats.rx_ack,
|
|
tx_stats.rx_ba,
|
|
tx_stats.tb_rx_ba, //including ACKs
|
|
tx_stats.rx_dump_ba);
|
|
|
|
printf("(test)aci:%d, txFrames:%d, s-mpdu:%d(%.2f%%), "
|
|
"bitmap(max:%d, min:%d, tot:%d, avg:%.2f), "
|
|
"retry(edca:%d, tb:%d, %.2f%%), collision:%d, timeout:%d\n",
|
|
i,
|
|
tx_stats.tx_succ,
|
|
tx_stats.rx_ack,
|
|
((float) (tx_stats.rx_ack) / (float) tot_tx_times) * 100,
|
|
tx_stats.rx_max_bitmap,
|
|
tx_stats.rx_min_bitmap,
|
|
tx_stats.rx_tot_bitmap,
|
|
(float) tx_stats.rx_tot_bitmap / (float) (tx_stats.tb_rx_ba + tx_stats.rx_ba),
|
|
tx_stats.retry_edca, tx_stats.retry_tb, (float) (tx_stats.retry_edca + tx_stats.retry_tb) / (float) tx_stats.tx_succ * 100,
|
|
tx_stats.collision, tx_stats.timeout);
|
|
|
|
float tot_rtt_ms = (float) tx_stats.tx_tot_rtt / (float) 1000;
|
|
printf("(test)aci:%d, seqno_rtt[%d,%d], hw_rtt[%d, %d], muedca[enable:%d, times:%d, %.2f, %.2f, tot:%.2f], avg:%.3f ms, tot:%.3f secs\n",
|
|
i,
|
|
tx_stats.tx_seq_min_rtt,
|
|
tx_stats.tx_seq_max_rtt,
|
|
tx_stats.tx_min_rtt,
|
|
tx_stats.tx_max_rtt,
|
|
tx_stats.tx_muedca_enable,
|
|
tx_stats.muedca_times,
|
|
(float) tx_stats.tx_min_muedca_time / (float) 1000,
|
|
(float) tx_stats.tx_max_muedca_time / (float) 1000,
|
|
(float) tx_stats.tx_tot_muedca_time / (float) 1000, //ms
|
|
(float) tot_rtt_ms / (float) tot_tx_times, //ms
|
|
(float) tot_rtt_ms / (float) 1000); //seconds
|
|
/* fail state */
|
|
for (h = 1; h < TEST_TX_FAIL_MAX; h++) { //state
|
|
for (j = 0; j < TEST_TX_WAIT_MAX; j++) { //match
|
|
for (k = 0; k < TEST_TX_FAIL_ERROR_MAX; k++) { //error
|
|
if (tx_fail[h].match[j][k]) {
|
|
printf("(test)[%d][%d][%d](%16s + %16s + %16s)%3d/%3d(%.2f%%)\n", h, j, k, tx_fail_state2str(h),
|
|
tx_fail_match2str(j), tx_fail_error2str(k),
|
|
tx_fail[h].match[j][k], tx_fail[h].count,
|
|
((float) tx_fail[h].match[j][k] / (float) tx_fail[h].count) * 100);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
wifi_cmd_clr_tx_statistics(0, 0);
|
|
return 0;
|
|
}
|
|
|
|
void print_rx_statistics_nonmimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
|
{
|
|
if (!mu_stats->nonmimo_rx) {
|
|
return;
|
|
}
|
|
|
|
int i, j;
|
|
int tot_rx_nonmimo = 0;
|
|
ESP_LOGW(TAG, "(nonmimo)dut rx:%d", mu_stats->nonmimo_rx);
|
|
ESP_LOGW(TAG, "(nonmimo)ru_alloc_96_num_2046:%d, ru_alloc_112_num_2046:%d", mu_stats->ru_alloc_96_num_2046, mu_stats->ru_alloc_112_num_2046);
|
|
ESP_LOGW(TAG, "(nonmimo)sigb, mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), mcs5:%d(%2.2f%%)",
|
|
mu_stats->nonmimo_sigb_mcs[0], ((float) mu_stats->nonmimo_sigb_mcs[0] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_sigb_mcs[1], ((float) mu_stats->nonmimo_sigb_mcs[1] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_sigb_mcs[2], ((float) mu_stats->nonmimo_sigb_mcs[2] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_sigb_mcs[3], ((float) mu_stats->nonmimo_sigb_mcs[3] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_sigb_mcs[4], ((float) mu_stats->nonmimo_sigb_mcs[4] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_sigb_mcs[5], ((float) mu_stats->nonmimo_sigb_mcs[5] / (float) mu_stats->nonmimo_rx) * 100);
|
|
ESP_LOGW(TAG, "(nonmimo)users, num1:%d(%2.2f%%), num2:%d(%2.2f%%), num3:%d(%2.2f%%), num4:%d(%2.2f%%), num5:%d(%2.2f%%), num6:%d(%2.2f%%), num7:%d(%2.2f%%), num8:%d(%2.2f%%), num9:%d(%2.2f%%)",
|
|
mu_stats->nonmimo_user_num_occu[0], ((float) mu_stats->nonmimo_user_num_occu[0] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[1], ((float) mu_stats->nonmimo_user_num_occu[1] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[2], ((float) mu_stats->nonmimo_user_num_occu[2] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[3], ((float) mu_stats->nonmimo_user_num_occu[3] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[4], ((float) mu_stats->nonmimo_user_num_occu[4] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[5], ((float) mu_stats->nonmimo_user_num_occu[5] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[6], ((float) mu_stats->nonmimo_user_num_occu[6] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[7], ((float) mu_stats->nonmimo_user_num_occu[7] / (float) mu_stats->nonmimo_rx) * 100,
|
|
mu_stats->nonmimo_user_num_occu[8], ((float) mu_stats->nonmimo_user_num_occu[8] / (float) mu_stats->nonmimo_rx) * 100);
|
|
for (i = 0; i < 256; i++) {
|
|
for (j = 0; j < 9; j++) {
|
|
if (!mu_stats->nonmimo_ru_alloc[i][j]) {
|
|
continue;
|
|
}
|
|
ESP_LOGI(TAG, "(nonmimo)ru_allocation:0x%2x(%3d), position:%d, %5d(%2.2f%%)", i, i, j + 1, mu_stats->nonmimo_ru_alloc[i][j],
|
|
((float) mu_stats->nonmimo_ru_alloc[i][j] / (float) mu_stats->nonmimo_rx) * 100);
|
|
}
|
|
}
|
|
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
|
if (!mu_stats->nonmimo[i].aid) {
|
|
continue;
|
|
}
|
|
if (mu_stats->aid != mu_stats->nonmimo[i].aid) {
|
|
continue;
|
|
}
|
|
tot_rx_nonmimo = mu_stats->nonmimo[i].occu_nsts[0] + mu_stats->nonmimo[i].occu_nsts[1] + mu_stats->nonmimo[i].occu_nsts[2] + mu_stats->nonmimo[i].occu_nsts[3];
|
|
printf("[%d]%said:0x%x, txbf:%d, dcm:%d\n", i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
|
mu_stats->nonmimo[i].txbf, mu_stats->nonmimo[i].dcm);
|
|
printf("[%d]%said:0x%x, "
|
|
"mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), "
|
|
"mcs5:%d(%2.2f%%), mcs6:%d(%2.2f%%), mcs7:%d(%2.2f%%), mcs8:%d(%2.2f%%), mcs9:%d(%2.2f%%), "
|
|
"mcs10:%d(%2.2f%%), mcs11:%d(%2.2f%%)\n",
|
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
|
mu_stats->nonmimo[i].occu_mcs[0], ((float) mu_stats->nonmimo[i].occu_mcs[0] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[1], ((float) mu_stats->nonmimo[i].occu_mcs[1] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[2], ((float) mu_stats->nonmimo[i].occu_mcs[2] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[3], ((float) mu_stats->nonmimo[i].occu_mcs[3] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[4], ((float) mu_stats->nonmimo[i].occu_mcs[4] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[5], ((float) mu_stats->nonmimo[i].occu_mcs[5] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[6], ((float) mu_stats->nonmimo[i].occu_mcs[6] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[7], ((float) mu_stats->nonmimo[i].occu_mcs[7] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[8], ((float) mu_stats->nonmimo[i].occu_mcs[8] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[9], ((float) mu_stats->nonmimo[i].occu_mcs[9] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[10], ((float) mu_stats->nonmimo[i].occu_mcs[10] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_mcs[11], ((float) mu_stats->nonmimo[i].occu_mcs[11] / (float) tot_rx_nonmimo) * 100);
|
|
printf("[%d]%said:0x%x, "
|
|
"nsts0:%d(%2.2f%%), nsts1:%d(%2.2f%%), nsts2:%d(%2.2f%%), nsts3:%d(%2.2f%%)\n",
|
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
|
mu_stats->nonmimo[i].occu_nsts[0], ((float) mu_stats->nonmimo[i].occu_nsts[0] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_nsts[1], ((float) mu_stats->nonmimo[i].occu_nsts[1] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_nsts[2], ((float) mu_stats->nonmimo[i].occu_nsts[2] / (float) tot_rx_nonmimo) * 100,
|
|
mu_stats->nonmimo[i].occu_nsts[3], ((float) mu_stats->nonmimo[i].occu_nsts[3] / (float) tot_rx_nonmimo) * 100);
|
|
printf("[%d]%said:0x%x, "
|
|
"tot_rx_nonmimo:%8d, sta/dut:%2.2f%%\n",
|
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
|
tot_rx_nonmimo, ((float) tot_rx_nonmimo / (float) mu_stats->nonmimo_rx) * 100);
|
|
}
|
|
}
|
|
|
|
void print_rx_statistics_mimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
|
{
|
|
if (!mu_stats->mimo_rx) {
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
int tot_rx_mimo = 0;
|
|
ESP_LOGW(TAG, "(mimo)dut rx:%d", mu_stats->mimo_rx);
|
|
ESP_LOGW(TAG, "(mimo)sigb, mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), mcs5:%d(%2.2f%%)",
|
|
mu_stats->mimo_sigb_mcs[0], ((float) mu_stats->mimo_sigb_mcs[0] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_sigb_mcs[1], ((float) mu_stats->mimo_sigb_mcs[1] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_sigb_mcs[2], ((float) mu_stats->mimo_sigb_mcs[2] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_sigb_mcs[3], ((float) mu_stats->mimo_sigb_mcs[3] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_sigb_mcs[4], ((float) mu_stats->mimo_sigb_mcs[4] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_sigb_mcs[5], ((float) mu_stats->mimo_sigb_mcs[5] / (float) mu_stats->mimo_rx) * 100);
|
|
ESP_LOGW(TAG, "(mimo)users num2:%d(%2.2f%%), num3:%d(%2.2f%%), num4:%d(%2.2f%%), num5:%d(%2.2f%%), num6:%d(%2.2f%%), num7:%d(%2.2f%%), num8:%d(%2.2f%%)",
|
|
mu_stats->mimo_user_num_occu[0], ((float) mu_stats->mimo_user_num_occu[0] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[1], ((float) mu_stats->mimo_user_num_occu[1] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[2], ((float) mu_stats->mimo_user_num_occu[2] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[3], ((float) mu_stats->mimo_user_num_occu[3] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[4], ((float) mu_stats->mimo_user_num_occu[4] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[5], ((float) mu_stats->mimo_user_num_occu[5] / (float) mu_stats->mimo_rx) * 100,
|
|
mu_stats->mimo_user_num_occu[6], ((float) mu_stats->mimo_user_num_occu[6] / (float) mu_stats->mimo_rx) * 100);
|
|
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
|
if (!mu_stats->mimo[i].aid) {
|
|
continue;
|
|
}
|
|
tot_rx_mimo = mu_stats->mimo[i].occu_ss[0] + mu_stats->mimo[i].occu_ss[1] + mu_stats->mimo[i].occu_ss[2] + mu_stats->mimo[i].occu_ss[3];
|
|
printf("[%d]%said:0x%x, "
|
|
"mcs0:%d(%2.2f%%), mcs1:%d(%2.2f%%), mcs2:%d(%2.2f%%), mcs3:%d(%2.2f%%), mcs4:%d(%2.2f%%), "
|
|
"mcs5:%d(%2.2f%%), mcs6:%d(%2.2f%%), mcs7:%d(%2.2f%%), mcs8:%d(%2.2f%%), mcs9:%d(%2.2f%%), "
|
|
"mcs10:%d(%2.2f%%), mcs11:%d(%2.2f%%)\n",
|
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
|
mu_stats->mimo[i].occu_mcs[0], ((float) mu_stats->mimo[i].occu_mcs[0] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[1], ((float) mu_stats->mimo[i].occu_mcs[1] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[2], ((float) mu_stats->mimo[i].occu_mcs[2] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[3], ((float) mu_stats->mimo[i].occu_mcs[3] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[4], ((float) mu_stats->mimo[i].occu_mcs[4] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[5], ((float) mu_stats->mimo[i].occu_mcs[5] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[6], ((float) mu_stats->mimo[i].occu_mcs[6] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[7], ((float) mu_stats->mimo[i].occu_mcs[7] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[8], ((float) mu_stats->mimo[i].occu_mcs[8] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[9], ((float) mu_stats->mimo[i].occu_mcs[9] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[10], ((float) mu_stats->mimo[i].occu_mcs[10] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_mcs[11], ((float) mu_stats->mimo[i].occu_mcs[11] / (float) tot_rx_mimo) * 100);
|
|
printf("[%d]%said:0x%x, "
|
|
"ss0:%d(%2.2f%%), ss1:%d(%2.2f%%), ss2:%d(%2.2f%%), ss3:%d(%2.2f%%)\n",
|
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
|
mu_stats->mimo[i].occu_ss[0], ((float) mu_stats->mimo[i].occu_ss[0] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_ss[1], ((float) mu_stats->mimo[i].occu_ss[1] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_ss[2], ((float) mu_stats->mimo[i].occu_ss[2] / (float) tot_rx_mimo) * 100,
|
|
mu_stats->mimo[i].occu_ss[3], ((float) mu_stats->mimo[i].occu_ss[3] / (float) tot_rx_mimo) * 100);
|
|
printf("[%d]%said:0x%x, "
|
|
"tot_rx_mimo:%8d, sta/dut:%2.2f%%\n",
|
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
|
tot_rx_mimo, ((float) tot_rx_mimo / (float) mu_stats->mimo_rx) * 100);
|
|
}
|
|
}
|
|
|
|
void print_hw_rx_statistics(void)
|
|
{
|
|
esp_test_hw_rx_statistics_t hw_rx_stats = { 0, };
|
|
esp_test_get_hw_rx_statistics(&hw_rx_stats);
|
|
printf(
|
|
"WDEVRX_FCS_ERR :%d\n"
|
|
"WDEVRX_ABORT :%d\n"
|
|
"WDEVRX_ABORT_FCS_PASS :%d\n"
|
|
"NRX_ERR_PWRDROP :%d\n"
|
|
"NRX_HESIGB_ERR :%d\n"
|
|
"WDEVRX_SAMEBM_ERRCNT :%d\n"
|
|
"WDEVRX_MPDU :%d\n"
|
|
"WDEVRX_END_CNT :%d\n"
|
|
"WDEVRX_DATASUC :%d\n"
|
|
"WDEVRX_LASTUNMATCH_ERR :%d\n"
|
|
"RXHUNG_STATIS :%d\n"
|
|
"TXHUNG_STATIS :%d\n"
|
|
"RXTXHUNG :%d\n"
|
|
"WDEVRX_CFO :%d\n"
|
|
"WDEVRX_SF :%d\n"
|
|
"WDEVRX_OTHER_UCAST :%d\n"
|
|
"WDEVRX_BUF_FULLCNT :%d\n"
|
|
"WDEVRX_FIFO_OVFCNT :%d\n"
|
|
"WDEVRX_TKIP_ERRCNT :%d\n"
|
|
"WDEVRX_BTBLOCK_ERR :%d\n"
|
|
"WDEVRX_FREQHOP_ERR :%d\n"
|
|
"WDEVRX_ACK_INT_CNT :%d\n"
|
|
"WDEVRX_RTS_INT_CNT :%d\n"
|
|
"BRX_ERR_AGC :%d\n"
|
|
"BRX_ERR :%d\n"
|
|
"NRX_ERR :%d\n"
|
|
"NRX_ERR_ABORT :%d\n"
|
|
"NRX_ERR_AGCEXIT :%d\n"
|
|
"NRX_ERR_BBOFF :%d\n"
|
|
"NRX_ERR_FDM_WDG :%d\n"
|
|
"NRX_ERR_RESTART :%d\n"
|
|
"NRX_ERR_SERV :%d\n"
|
|
"NRX_ERR_TXOVER :%d\n"
|
|
"NRX_HE_UNSUPPORT :%d\n"
|
|
"NRX_HTSIG_ERR :%d\n"
|
|
"NRX_HEUNSUPPORT :%d\n"
|
|
"NRX_HESIGA_CRC :%d\n",
|
|
hw_rx_stats.rx_fcs_err,
|
|
hw_rx_stats.rx_abort,
|
|
hw_rx_stats.rx_abort_fcs_pass,
|
|
hw_rx_stats.nrx_err_pwrdrop,
|
|
hw_rx_stats.nrx_hesigb_err,
|
|
hw_rx_stats.rx_samebm_errcnt,
|
|
hw_rx_stats.rx_mpdu,
|
|
hw_rx_stats.rx_end_cnt,
|
|
hw_rx_stats.rx_datasuc,
|
|
hw_rx_stats.rx_lastunmatch_err,
|
|
hw_rx_stats.rxhung_statis,
|
|
hw_rx_stats.txhung_statis,
|
|
hw_rx_stats.rxtxhung,
|
|
hw_rx_stats.rx_cfo_hz,
|
|
hw_rx_stats.rx_sf,
|
|
hw_rx_stats.rx_other_ucast,
|
|
hw_rx_stats.rx_buf_fullcnt,
|
|
hw_rx_stats.rx_fifo_ovfcnt,
|
|
hw_rx_stats.rx_tkip_errcnt,
|
|
hw_rx_stats.rx_btblock_err,
|
|
hw_rx_stats.rx_freqhop_err,
|
|
hw_rx_stats.rx_ack_int_cnt,
|
|
hw_rx_stats.rx_rts_int_cnt,
|
|
hw_rx_stats.brx_err_agc,
|
|
hw_rx_stats.brx_err,
|
|
hw_rx_stats.nrx_err,
|
|
hw_rx_stats.nrx_err_abort,
|
|
hw_rx_stats.nrx_err_agcexit,
|
|
hw_rx_stats.nrx_err_bboff,
|
|
hw_rx_stats.nrx_err_fdm_wdg,
|
|
hw_rx_stats.nrx_err_restart,
|
|
hw_rx_stats.nrx_err_serv,
|
|
hw_rx_stats.nrx_err_txover,
|
|
hw_rx_stats.nrx_err_unsupport,
|
|
hw_rx_stats.nrx_htsig_err,
|
|
hw_rx_stats.nrx_heunsupport,
|
|
hw_rx_stats.nrx_hesiga_crc
|
|
);
|
|
}
|
|
|
|
int wifi_cmd_clr_rx_statistics(int argc, char **argv)
|
|
{
|
|
ESP_LOGW(TAG, "Clear rx statistics");
|
|
esp_wifi_clr_rx_statistics(0);
|
|
esp_wifi_clr_rx_statistics(7);
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
|
esp_test_clr_rx_error_occurs();
|
|
esp_wifi_clr_rx_mu_statistics();
|
|
#endif
|
|
esp_test_clr_hw_statistics();
|
|
return 0;
|
|
}
|
|
|
|
void print_rx_mu_statistics(void)
|
|
{
|
|
/* mu */
|
|
esp_wifi_get_rx_mu_statistics(&rx_mu_stats);
|
|
/* MIMO */
|
|
print_rx_statistics_mimo(&rx_mu_stats);
|
|
/* non-MIMO */
|
|
print_rx_statistics_nonmimo(&rx_mu_stats);
|
|
}
|
|
|
|
int wifi_cmd_get_rx_statistics(int argc, char **argv)
|
|
{
|
|
ESP_LOGW(TAG, "Get rx statistics");
|
|
esp_test_rx_statistics_t rx_stats = { 0, };
|
|
esp_test_rx_error_occurs_t rx_error_occurs = { 0, };
|
|
|
|
esp_wifi_get_rx_statistics(0, &rx_stats); //tid=0
|
|
print_hw_tb_statistics();
|
|
|
|
ESP_LOGW(TAG, "(0)legacy:%d, ht(ht:%d, ht_retry:%d/%2.2f%%, ht_noeb:%d/%2.2f%%)",
|
|
rx_stats.legacy,
|
|
rx_stats.ht, rx_stats.ht_retry,
|
|
rx_stats.ht_retry ? ((float) ((float) rx_stats.ht_retry / (float) rx_stats.ht) * 100) : 0,
|
|
rx_stats.ht_noeb, rx_stats.ht_noeb ? ((float) ((float) rx_stats.ht_noeb / (float) rx_stats.ht) * 100) : 0);
|
|
ESP_LOGW(TAG, "(0)su(su:%d, su_txbf:%d, su_stbc:%d, su_retry:%d/%2.2f%%, ersu:%d, ersu_dcm:%d, su_noeb:%d/%2.2f%%)",
|
|
rx_stats.su,
|
|
rx_stats.su_txbf, rx_stats.su_stbc,
|
|
rx_stats.su_retry,
|
|
rx_stats.su_retry ? ((float) ((float) rx_stats.su_retry / (float) rx_stats.su) * 100) : 0,
|
|
rx_stats.ersu,
|
|
rx_stats.ersu_dcm,
|
|
rx_stats.su_noeb, rx_stats.su_noeb ? ((float) ((float) rx_stats.su_noeb / (float) rx_stats.su) * 100) : 0);
|
|
ESP_LOGW(TAG, "(0)mu(mu:%d, mimo:%d, non-mimo:%d, txbf:%d, stbc:%d, mu_retry:%d/%2.2f%%, mu_noeb:%d/%2.2f%%)",
|
|
rx_stats.mu,
|
|
rx_stats.mu_mimo,
|
|
rx_stats.mu_ofdma, rx_stats.mu_txbf, rx_stats.mu_stbc,
|
|
rx_stats.mu_retry,
|
|
rx_stats.mu_retry ? ((float) ((float) rx_stats.mu_retry / (float) rx_stats.mu) * 100) : 0,
|
|
rx_stats.mu_noeb, rx_stats.mu_noeb ? ((float) ((float) rx_stats.mu_noeb / (float) rx_stats.mu) * 100) : 0);
|
|
|
|
memset(&rx_stats, 0, sizeof(rx_stats));
|
|
esp_wifi_get_rx_statistics(7, &rx_stats); //tid=7
|
|
ESP_LOGW(TAG, "(7)legacy:%d, ht:%d, su:%d, su_txbf:%d, ersu:%d, mu:%d", rx_stats.legacy,
|
|
rx_stats.ht, rx_stats.su, rx_stats.su_txbf, rx_stats.ersu, rx_stats.mu);
|
|
ESP_LOGW(TAG, "(hw)isr:%d, nblks:%d", rx_stats.rx_isr, rx_stats.rx_nblks);
|
|
/* hw rx statistics */
|
|
print_hw_rx_statistics();
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
|
print_rx_mu_statistics();
|
|
#endif
|
|
esp_test_get_rx_error_occurs(&rx_error_occurs);
|
|
ESP_LOGW(TAG, "(rx)tot_errors:%d", rx_error_occurs.tot);
|
|
int known_errors = 0; //rx error: 0x40-0xff
|
|
int i;
|
|
for (i = 0; i < 2; i++) {
|
|
if (rx_error_occurs.occurs[i]) {
|
|
known_errors += rx_error_occurs.occurs[i];
|
|
printf("[%3d] 0x%x, %8d, %2.2f%%\n", i, (i ? 0xf5 : 0xc6), rx_error_occurs.occurs[i], ((float) rx_error_occurs.occurs[i] / (float) rx_error_occurs.tot) * 100);
|
|
}
|
|
}
|
|
if (rx_error_occurs.tot - known_errors) {
|
|
printf("[%3d]others, %8d, %2.2f%%\n\n", i, rx_error_occurs.tot - known_errors, ((float) known_errors / (float) rx_error_occurs.tot) * 100);
|
|
}
|
|
wifi_cmd_clr_rx_statistics(0, 0);
|
|
return 0;
|
|
}
|
|
|
|
#endif /* CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS */
|
|
|
|
void register_wifi_stats(void)
|
|
{
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
|
/* get tx statistics */
|
|
const esp_console_cmd_t tx_stats_cmd = {
|
|
.command = "tx",
|
|
.help = "get tx statistics",
|
|
.hint = NULL,
|
|
.func = &wifi_cmd_get_tx_statistics,
|
|
};
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&tx_stats_cmd));
|
|
/* clear tx statistics */
|
|
const esp_console_cmd_t clr_cmd = {
|
|
.command = "clrtx",
|
|
.help = "clear tx statistics",
|
|
.hint = NULL,
|
|
.func = &wifi_cmd_clr_tx_statistics,
|
|
};
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_cmd));
|
|
#endif
|
|
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
|
/* get rx statistics */
|
|
const esp_console_cmd_t rx_stats_cmd = {
|
|
.command = "rx",
|
|
.help = "get rx statistics",
|
|
.hint = NULL,
|
|
.func = &wifi_cmd_get_rx_statistics,
|
|
};
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&rx_stats_cmd));
|
|
/* clear rx statistics */
|
|
const esp_console_cmd_t clr_rx_cmd = {
|
|
.command = "clrrx",
|
|
.help = "clear rx statistics",
|
|
.hint = NULL,
|
|
.func = &wifi_cmd_clr_rx_statistics,
|
|
};
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_rx_cmd));
|
|
#endif
|
|
}
|