blob: 528c41fa1843bccb478af54153e6fdf0ceb41b4a [file] [log] [blame]
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/* @file
* @brief NRF Wi-Fi util shell module
*/
#include <stdlib.h>
#include "host_rpu_umac_if.h"
#include "fmac_api.h"
#include "fmac_util.h"
#include "fmac_main.h"
#include "wifi_util.h"
extern struct nrf_wifi_drv_priv_zep rpu_drv_priv_zep;
struct nrf_wifi_ctx_zep *ctx = &rpu_drv_priv_zep.rpu_ctx_zep;
static bool check_valid_data_rate(const struct shell *sh,
unsigned char rate_flag,
unsigned int data_rate)
{
bool ret = false;
switch (rate_flag) {
case RPU_TPUT_MODE_LEGACY:
if ((data_rate == 1) ||
(data_rate == 2) ||
(data_rate == 55) ||
(data_rate == 11) ||
(data_rate == 6) ||
(data_rate == 9) ||
(data_rate == 12) ||
(data_rate == 18) ||
(data_rate == 24) ||
(data_rate == 36) ||
(data_rate == 48) ||
(data_rate == 54)) {
ret = true;
}
break;
case RPU_TPUT_MODE_HT:
case RPU_TPUT_MODE_HE_SU:
case RPU_TPUT_MODE_VHT:
if ((data_rate >= 0) && (data_rate <= 7)) {
ret = true;
}
break;
case RPU_TPUT_MODE_HE_ER_SU:
if (data_rate >= 0 && data_rate <= 2) {
ret = true;
}
break;
default:
shell_fprintf(sh,
SHELL_ERROR,
"%s: Invalid rate_flag %d\n",
__func__,
rate_flag);
break;
}
return ret;
}
int nrf_wifi_util_conf_init(struct rpu_conf_params *conf_params)
{
if (!conf_params) {
return -ENOEXEC;
}
memset(conf_params, 0, sizeof(*conf_params));
/* Initialize values which are other than 0 */
conf_params->he_ltf = -1;
conf_params->he_gi = -1;
return 0;
}
static int nrf_wifi_util_set_he_ltf(const struct shell *sh,
size_t argc,
const char *argv[])
{
char *ptr = NULL;
unsigned long he_ltf = 0;
if (ctx->conf_params.set_he_ltf_gi) {
shell_fprintf(sh,
SHELL_ERROR,
"Disable 'set_he_ltf_gi', to set 'he_ltf'\n");
return -ENOEXEC;
}
he_ltf = strtoul(argv[1], &ptr, 10);
if (he_ltf > 2) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid HE LTF value(%lu).\n",
he_ltf);
shell_help(sh);
return -ENOEXEC;
}
ctx->conf_params.he_ltf = he_ltf;
return 0;
}
static int nrf_wifi_util_set_he_gi(const struct shell *sh,
size_t argc,
const char *argv[])
{
char *ptr = NULL;
unsigned long he_gi = 0;
if (ctx->conf_params.set_he_ltf_gi) {
shell_fprintf(sh,
SHELL_ERROR,
"Disable 'set_he_ltf_gi', to set 'he_gi'\n");
return -ENOEXEC;
}
he_gi = strtoul(argv[1], &ptr, 10);
if (he_gi > 2) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid HE GI value(%lu).\n",
he_gi);
shell_help(sh);
return -ENOEXEC;
}
ctx->conf_params.he_gi = he_gi;
return 0;
}
static int nrf_wifi_util_set_he_ltf_gi(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
char *ptr = NULL;
unsigned long val = 0;
val = strtoul(argv[1], &ptr, 10);
if ((val < 0) || (val > 1)) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid value(%lu).\n",
val);
shell_help(sh);
return -ENOEXEC;
}
status = nrf_wifi_fmac_conf_ltf_gi(ctx->rpu_ctx,
ctx->conf_params.he_ltf,
ctx->conf_params.he_gi,
val);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Programming ltf_gi failed\n");
return -ENOEXEC;
}
ctx->conf_params.set_he_ltf_gi = val;
return 0;
}
#ifdef CONFIG_NRF70_STA_MODE
static int nrf_wifi_util_set_uapsd_queue(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
char *ptr = NULL;
unsigned long val = 0;
val = strtoul(argv[1], &ptr, 10);
if ((val < UAPSD_Q_MIN) || (val > UAPSD_Q_MAX)) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid value(%lu).\n",
val);
shell_help(sh);
return -ENOEXEC;
}
if (ctx->conf_params.uapsd_queue != val) {
status = nrf_wifi_fmac_set_uapsd_queue(ctx->rpu_ctx,
0,
val);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Programming uapsd_queue failed\n");
return -ENOEXEC;
}
ctx->conf_params.uapsd_queue = val;
}
return 0;
}
#endif /* CONFIG_NRF70_STA_MODE */
static int nrf_wifi_util_show_cfg(const struct shell *sh,
size_t argc,
const char *argv[])
{
struct rpu_conf_params *conf_params = NULL;
conf_params = &ctx->conf_params;
shell_fprintf(sh,
SHELL_INFO,
"************* Configured Parameters ***********\n");
shell_fprintf(sh,
SHELL_INFO,
"\n");
shell_fprintf(sh,
SHELL_INFO,
"he_ltf = %d\n",
conf_params->he_ltf);
shell_fprintf(sh,
SHELL_INFO,
"he_gi = %u\n",
conf_params->he_gi);
shell_fprintf(sh,
SHELL_INFO,
"set_he_ltf_gi = %d\n",
conf_params->set_he_ltf_gi);
shell_fprintf(sh,
SHELL_INFO,
"uapsd_queue = %d\n",
conf_params->uapsd_queue);
shell_fprintf(sh,
SHELL_INFO,
"rate_flag = %d, rate_val = %d\n",
ctx->conf_params.tx_pkt_tput_mode,
ctx->conf_params.tx_pkt_rate);
return 0;
}
#ifdef CONFIG_NRF70_STA_MODE
static int nrf_wifi_util_tx_stats(const struct shell *sh,
size_t argc,
const char *argv[])
{
int vif_index = -1;
int peer_index = 0;
int max_vif_index = MAX(MAX_NUM_APS, MAX_NUM_STAS);
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
void *queue = NULL;
unsigned int tx_pending_pkts = 0;
struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL;
int ret;
vif_index = atoi(argv[1]);
if ((vif_index < 0) || (vif_index >= max_vif_index)) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid vif index(%d).\n",
vif_index);
shell_help(sh);
return -ENOEXEC;
}
k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
if (!ctx->rpu_ctx) {
shell_fprintf(sh,
SHELL_ERROR,
"RPU context not initialized\n");
ret = -ENOEXEC;
goto unlock;
}
fmac_dev_ctx = ctx->rpu_ctx;
def_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
/* TODO: Get peer_index from shell once AP mode is supported */
shell_fprintf(sh,
SHELL_INFO,
"************* Tx Stats: vif(%d) peer(0) ***********\n",
vif_index);
for (int i = 0; i < NRF_WIFI_FMAC_AC_MAX ; i++) {
queue = def_dev_ctx->tx_config.data_pending_txq[peer_index][i];
tx_pending_pkts = nrf_wifi_utils_q_len(queue);
shell_fprintf(
sh,
SHELL_INFO,
"Outstanding tokens: ac: %d -> %d (pending_q_len: %d)\n",
i,
def_dev_ctx->tx_config.outstanding_descs[i],
tx_pending_pkts);
}
ret = 0;
unlock:
k_mutex_unlock(&ctx->rpu_lock);
return ret;
}
#endif /* CONFIG_NRF70_STA_MODE */
static int nrf_wifi_util_tx_rate(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
char *ptr = NULL;
long rate_flag = -1;
long data_rate = -1;
rate_flag = strtol(argv[1], &ptr, 10);
if (rate_flag >= RPU_TPUT_MODE_MAX) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid value %ld for rate_flags\n",
rate_flag);
shell_help(sh);
return -ENOEXEC;
}
if (rate_flag == RPU_TPUT_MODE_HE_TB) {
data_rate = -1;
} else {
if (argc < 3) {
shell_fprintf(sh,
SHELL_ERROR,
"rate_val needed for rate_flag = %ld\n",
rate_flag);
shell_help(sh);
return -ENOEXEC;
}
data_rate = strtol(argv[2], &ptr, 10);
if (!(check_valid_data_rate(sh,
rate_flag,
data_rate))) {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid data_rate %ld for rate_flag %ld\n",
data_rate,
rate_flag);
return -ENOEXEC;
}
}
status = nrf_wifi_fmac_set_tx_rate(ctx->rpu_ctx,
rate_flag,
data_rate);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Programming tx_rate failed\n");
return -ENOEXEC;
}
ctx->conf_params.tx_pkt_tput_mode = rate_flag;
ctx->conf_params.tx_pkt_rate = data_rate;
return 0;
}
#ifdef CONFIG_NRF_WIFI_LOW_POWER
static int nrf_wifi_util_show_host_rpu_ps_ctrl_state(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
int rpu_ps_state = -1;
status = nrf_wifi_fmac_get_host_rpu_ps_ctrl_state(ctx->rpu_ctx,
&rpu_ps_state);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Failed to get PS state\n");
return -ENOEXEC;
}
shell_fprintf(sh,
SHELL_INFO,
"RPU sleep status = %s\n", rpu_ps_state ? "AWAKE" : "SLEEP");
return 0;
}
#endif /* CONFIG_NRF_WIFI_LOW_POWER */
static int nrf_wifi_util_show_vers(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
unsigned int fw_ver;
fmac_dev_ctx = ctx->rpu_ctx;
shell_fprintf(sh, SHELL_INFO, "Driver version: %s\n",
NRF70_DRIVER_VERSION);
status = nrf_wifi_fmac_ver_get(fmac_dev_ctx, &fw_ver);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_INFO,
"Failed to get firmware version\n");
return -ENOEXEC;
}
shell_fprintf(sh, SHELL_INFO,
"Firmware version: %d.%d.%d.%d\n",
NRF_WIFI_UMAC_VER(fw_ver),
NRF_WIFI_UMAC_VER_MAJ(fw_ver),
NRF_WIFI_UMAC_VER_MIN(fw_ver),
NRF_WIFI_UMAC_VER_EXTRA(fw_ver));
return status;
}
#if !defined(CONFIG_NRF70_RADIO_TEST) && !defined(CONFIG_NRF70_OFFLOADED_RAW_TX)
static int nrf_wifi_util_dump_rpu_stats(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
struct rpu_op_stats stats;
enum rpu_stats_type stats_type = RPU_STATS_TYPE_ALL;
int ret;
if (argc == 2) {
const char *type = argv[1];
if (!strcmp(type, "umac")) {
stats_type = RPU_STATS_TYPE_UMAC;
} else if (!strcmp(type, "lmac")) {
stats_type = RPU_STATS_TYPE_LMAC;
} else if (!strcmp(type, "phy")) {
stats_type = RPU_STATS_TYPE_PHY;
} else if (!strcmp(type, "all")) {
stats_type = RPU_STATS_TYPE_ALL;
} else {
shell_fprintf(sh,
SHELL_ERROR,
"Invalid stats type %s\n",
type);
return -ENOEXEC;
}
}
k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
if (!ctx->rpu_ctx) {
shell_fprintf(sh,
SHELL_ERROR,
"RPU context not initialized\n");
ret = -ENOEXEC;
goto unlock;
}
fmac_dev_ctx = ctx->rpu_ctx;
memset(&stats, 0, sizeof(struct rpu_op_stats));
status = nrf_wifi_fmac_stats_get(fmac_dev_ctx, 0, &stats);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Failed to get stats\n");
ret = -ENOEXEC;
goto unlock;
}
if (stats_type == RPU_STATS_TYPE_UMAC || stats_type == RPU_STATS_TYPE_ALL) {
struct rpu_umac_stats *umac = &stats.fw.umac;
shell_fprintf(sh, SHELL_INFO,
"UMAC TX debug stats:\n"
"======================\n"
"tx_cmd: %u\n"
"tx_non_coalesce_pkts_rcvd_from_host: %u\n"
"tx_coalesce_pkts_rcvd_from_host: %u\n"
"tx_max_coalesce_pkts_rcvd_from_host: %u\n"
"tx_cmds_max_used: %u\n"
"tx_cmds_currently_in_use: %u\n"
"tx_done_events_send_to_host: %u\n"
"tx_done_success_pkts_to_host: %u\n"
"tx_done_failure_pkts_to_host: %u\n"
"tx_cmds_with_crypto_pkts_rcvd_from_host: %u\n"
"tx_cmds_with_non_crypto_pkts_rcvd_from_host: %u\n"
"tx_cmds_with_broadcast_pkts_rcvd_from_host: %u\n"
"tx_cmds_with_multicast_pkts_rcvd_from_host: %u\n"
"tx_cmds_with_unicast_pkts_rcvd_from_host: %u\n"
"xmit: %u\n"
"send_addba_req: %u\n"
"addba_resp: %u\n"
"softmac_tx: %u\n"
"internal_pkts: %u\n"
"external_pkts: %u\n"
"tx_cmds_to_lmac: %u\n"
"tx_dones_from_lmac: %u\n"
"total_cmds_to_lmac: %u\n"
"tx_packet_data_count: %u\n"
"tx_packet_mgmt_count: %u\n"
"tx_packet_beacon_count: %u\n"
"tx_packet_probe_req_count: %u\n"
"tx_packet_auth_count: %u\n"
"tx_packet_deauth_count: %u\n"
"tx_packet_assoc_req_count: %u\n"
"tx_packet_disassoc_count: %u\n"
"tx_packet_action_count: %u\n"
"tx_packet_other_mgmt_count: %u\n"
"tx_packet_non_mgmt_data_count: %u\n\n",
umac->tx_dbg_params.tx_cmd,
umac->tx_dbg_params.tx_non_coalesce_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_coalesce_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_max_coalesce_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_cmds_max_used,
umac->tx_dbg_params.tx_cmds_currently_in_use,
umac->tx_dbg_params.tx_done_events_send_to_host,
umac->tx_dbg_params.tx_done_success_pkts_to_host,
umac->tx_dbg_params.tx_done_failure_pkts_to_host,
umac->tx_dbg_params.tx_cmds_with_crypto_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_cmds_with_non_crypto_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_cmds_with_broadcast_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_cmds_with_multicast_pkts_rcvd_from_host,
umac->tx_dbg_params.tx_cmds_with_unicast_pkts_rcvd_from_host,
umac->tx_dbg_params.xmit,
umac->tx_dbg_params.send_addba_req,
umac->tx_dbg_params.addba_resp,
umac->tx_dbg_params.softmac_tx,
umac->tx_dbg_params.internal_pkts,
umac->tx_dbg_params.external_pkts,
umac->tx_dbg_params.tx_cmds_to_lmac,
umac->tx_dbg_params.tx_dones_from_lmac,
umac->tx_dbg_params.total_cmds_to_lmac,
umac->tx_dbg_params.tx_packet_data_count,
umac->tx_dbg_params.tx_packet_mgmt_count,
umac->tx_dbg_params.tx_packet_beacon_count,
umac->tx_dbg_params.tx_packet_probe_req_count,
umac->tx_dbg_params.tx_packet_auth_count,
umac->tx_dbg_params.tx_packet_deauth_count,
umac->tx_dbg_params.tx_packet_assoc_req_count,
umac->tx_dbg_params.tx_packet_disassoc_count,
umac->tx_dbg_params.tx_packet_action_count,
umac->tx_dbg_params.tx_packet_other_mgmt_count,
umac->tx_dbg_params.tx_packet_non_mgmt_data_count);
shell_fprintf(sh, SHELL_INFO,
"UMAC RX debug stats\n"
"======================\n"
"lmac_events: %u\n"
"rx_events: %u\n"
"rx_coalesce_events: %u\n"
"total_rx_pkts_from_lmac: %u\n"
"max_refill_gap: %u\n"
"current_refill_gap: %u\n"
"out_of_order_mpdus: %u\n"
"reorder_free_mpdus: %u\n"
"umac_consumed_pkts: %u\n"
"host_consumed_pkts: %u\n"
"rx_mbox_post: %u\n"
"rx_mbox_receive: %u\n"
"reordering_ampdu: %u\n"
"timer_mbox_post: %u\n"
"timer_mbox_rcv: %u\n"
"work_mbox_post: %u\n"
"work_mbox_rcv: %u\n"
"tasklet_mbox_post: %u\n"
"tasklet_mbox_rcv: %u\n"
"userspace_offload_frames: %u\n"
"alloc_buf_fail: %u\n"
"rx_packet_total_count: %u\n"
"rx_packet_data_count: %u\n"
"rx_packet_qos_data_count: %u\n"
"rx_packet_protected_data_count: %u\n"
"rx_packet_mgmt_count: %u\n"
"rx_packet_beacon_count: %u\n"
"rx_packet_probe_resp_count: %u\n"
"rx_packet_auth_count: %u\n"
"rx_packet_deauth_count: %u\n"
"rx_packet_assoc_resp_count: %u\n"
"rx_packet_disassoc_count: %u\n"
"rx_packet_action_count: %u\n"
"rx_packet_probe_req_count: %u\n"
"rx_packet_other_mgmt_count: %u\n"
"max_coalesce_pkts: %d\n"
"null_skb_pointer_from_lmac: %u\n"
"unexpected_mgmt_pkt: %u\n\n",
umac->rx_dbg_params.lmac_events,
umac->rx_dbg_params.rx_events,
umac->rx_dbg_params.rx_coalesce_events,
umac->rx_dbg_params.total_rx_pkts_from_lmac,
umac->rx_dbg_params.max_refill_gap,
umac->rx_dbg_params.current_refill_gap,
umac->rx_dbg_params.out_of_order_mpdus,
umac->rx_dbg_params.reorder_free_mpdus,
umac->rx_dbg_params.umac_consumed_pkts,
umac->rx_dbg_params.host_consumed_pkts,
umac->rx_dbg_params.rx_mbox_post,
umac->rx_dbg_params.rx_mbox_receive,
umac->rx_dbg_params.reordering_ampdu,
umac->rx_dbg_params.timer_mbox_post,
umac->rx_dbg_params.timer_mbox_rcv,
umac->rx_dbg_params.work_mbox_post,
umac->rx_dbg_params.work_mbox_rcv,
umac->rx_dbg_params.tasklet_mbox_post,
umac->rx_dbg_params.tasklet_mbox_rcv,
umac->rx_dbg_params.userspace_offload_frames,
umac->rx_dbg_params.alloc_buf_fail,
umac->rx_dbg_params.rx_packet_total_count,
umac->rx_dbg_params.rx_packet_data_count,
umac->rx_dbg_params.rx_packet_qos_data_count,
umac->rx_dbg_params.rx_packet_protected_data_count,
umac->rx_dbg_params.rx_packet_mgmt_count,
umac->rx_dbg_params.rx_packet_beacon_count,
umac->rx_dbg_params.rx_packet_probe_resp_count,
umac->rx_dbg_params.rx_packet_auth_count,
umac->rx_dbg_params.rx_packet_deauth_count,
umac->rx_dbg_params.rx_packet_assoc_resp_count,
umac->rx_dbg_params.rx_packet_disassoc_count,
umac->rx_dbg_params.rx_packet_action_count,
umac->rx_dbg_params.rx_packet_probe_req_count,
umac->rx_dbg_params.rx_packet_other_mgmt_count,
umac->rx_dbg_params.max_coalesce_pkts,
umac->rx_dbg_params.null_skb_pointer_from_lmac,
umac->rx_dbg_params.unexpected_mgmt_pkt);
shell_fprintf(sh, SHELL_INFO,
"UMAC control path stats\n"
"======================\n"
"cmd_init: %u\n"
"event_init_done: %u\n"
"cmd_rf_test: %u\n"
"cmd_connect: %u\n"
"cmd_get_stats: %u\n"
"event_ps_state: %u\n"
"cmd_set_reg: %u\n"
"cmd_get_reg: %u\n"
"cmd_req_set_reg: %u\n"
"cmd_trigger_scan: %u\n"
"event_scan_done: %u\n"
"cmd_get_scan: %u\n"
"umac_scan_req: %u\n"
"umac_scan_complete: %u\n"
"umac_scan_busy: %u\n"
"cmd_auth: %u\n"
"cmd_assoc: %u\n"
"cmd_deauth: %u\n"
"cmd_register_frame: %u\n"
"cmd_frame: %u\n"
"cmd_del_key: %u\n"
"cmd_new_key: %u\n"
"cmd_set_key: %u\n"
"cmd_get_key: %u\n"
"event_beacon_hint: %u\n"
"event_reg_change: %u\n"
"event_wiphy_reg_change: %u\n"
"cmd_set_station: %u\n"
"cmd_new_station: %u\n"
"cmd_del_station: %u\n"
"cmd_new_interface: %u\n"
"cmd_set_interface: %u\n"
"cmd_get_interface: %u\n"
"cmd_set_ifflags: %u\n"
"cmd_set_ifflags_done: %u\n"
"cmd_set_bss: %u\n"
"cmd_set_wiphy: %u\n"
"cmd_start_ap: %u\n"
"LMAC_CMD_PS: %u\n"
"CURR_STATE: %u\n\n",
umac->cmd_evnt_dbg_params.cmd_init,
umac->cmd_evnt_dbg_params.event_init_done,
umac->cmd_evnt_dbg_params.cmd_rf_test,
umac->cmd_evnt_dbg_params.cmd_connect,
umac->cmd_evnt_dbg_params.cmd_get_stats,
umac->cmd_evnt_dbg_params.event_ps_state,
umac->cmd_evnt_dbg_params.cmd_set_reg,
umac->cmd_evnt_dbg_params.cmd_get_reg,
umac->cmd_evnt_dbg_params.cmd_req_set_reg,
umac->cmd_evnt_dbg_params.cmd_trigger_scan,
umac->cmd_evnt_dbg_params.event_scan_done,
umac->cmd_evnt_dbg_params.cmd_get_scan,
umac->cmd_evnt_dbg_params.umac_scan_req,
umac->cmd_evnt_dbg_params.umac_scan_complete,
umac->cmd_evnt_dbg_params.umac_scan_busy,
umac->cmd_evnt_dbg_params.cmd_auth,
umac->cmd_evnt_dbg_params.cmd_assoc,
umac->cmd_evnt_dbg_params.cmd_deauth,
umac->cmd_evnt_dbg_params.cmd_register_frame,
umac->cmd_evnt_dbg_params.cmd_frame,
umac->cmd_evnt_dbg_params.cmd_del_key,
umac->cmd_evnt_dbg_params.cmd_new_key,
umac->cmd_evnt_dbg_params.cmd_set_key,
umac->cmd_evnt_dbg_params.cmd_get_key,
umac->cmd_evnt_dbg_params.event_beacon_hint,
umac->cmd_evnt_dbg_params.event_reg_change,
umac->cmd_evnt_dbg_params.event_wiphy_reg_change,
umac->cmd_evnt_dbg_params.cmd_set_station,
umac->cmd_evnt_dbg_params.cmd_new_station,
umac->cmd_evnt_dbg_params.cmd_del_station,
umac->cmd_evnt_dbg_params.cmd_new_interface,
umac->cmd_evnt_dbg_params.cmd_set_interface,
umac->cmd_evnt_dbg_params.cmd_get_interface,
umac->cmd_evnt_dbg_params.cmd_set_ifflags,
umac->cmd_evnt_dbg_params.cmd_set_ifflags_done,
umac->cmd_evnt_dbg_params.cmd_set_bss,
umac->cmd_evnt_dbg_params.cmd_set_wiphy,
umac->cmd_evnt_dbg_params.cmd_start_ap,
umac->cmd_evnt_dbg_params.LMAC_CMD_PS,
umac->cmd_evnt_dbg_params.CURR_STATE);
shell_fprintf(sh, SHELL_INFO,
"UMAC interface stats\n"
"======================\n"
"tx_unicast_pkt_count: %u\n"
"tx_multicast_pkt_count: %u\n"
"tx_broadcast_pkt_count: %u\n"
"tx_bytes: %u\n"
"rx_unicast_pkt_count: %u\n"
"rx_multicast_pkt_count: %u\n"
"rx_broadcast_pkt_count: %u\n"
"rx_beacon_success_count: %u\n"
"rx_beacon_miss_count: %u\n"
"rx_bytes: %u\n"
"rx_checksum_error_count: %u\n\n"
"replay_attack_drop_cnt: %u\n\n",
umac->interface_data_stats.tx_unicast_pkt_count,
umac->interface_data_stats.tx_multicast_pkt_count,
umac->interface_data_stats.tx_broadcast_pkt_count,
umac->interface_data_stats.tx_bytes,
umac->interface_data_stats.rx_unicast_pkt_count,
umac->interface_data_stats.rx_multicast_pkt_count,
umac->interface_data_stats.rx_broadcast_pkt_count,
umac->interface_data_stats.rx_beacon_success_count,
umac->interface_data_stats.rx_beacon_miss_count,
umac->interface_data_stats.rx_bytes,
umac->interface_data_stats.rx_checksum_error_count,
umac->interface_data_stats.replay_attack_drop_cnt);
}
if (stats_type == RPU_STATS_TYPE_LMAC || stats_type == RPU_STATS_TYPE_ALL) {
struct rpu_lmac_stats *lmac = &stats.fw.lmac;
shell_fprintf(sh, SHELL_INFO,
"LMAC stats\n"
"======================\n"
"reset_cmd_cnt: %u\n"
"reset_complete_event_cnt: %u\n"
"unable_gen_event: %u\n"
"ch_prog_cmd_cnt: %u\n"
"channel_prog_done: %u\n"
"tx_pkt_cnt: %u\n"
"tx_pkt_done_cnt: %u\n"
"scan_pkt_cnt: %u\n"
"internal_pkt_cnt: %u\n"
"internal_pkt_done_cnt: %u\n"
"ack_resp_cnt: %u\n"
"tx_timeout: %u\n"
"deagg_isr: %u\n"
"deagg_inptr_desc_empty: %u\n"
"deagg_circular_buffer_full: %u\n"
"lmac_rxisr_cnt: %u\n"
"rx_decryptcnt: %u\n"
"process_decrypt_fail: %u\n"
"prepa_rx_event_fail: %u\n"
"rx_core_pool_full_cnt: %u\n"
"rx_mpdu_crc_success_cnt: %u\n"
"rx_mpdu_crc_fail_cnt: %u\n"
"rx_ofdm_crc_success_cnt: %u\n"
"rx_ofdm_crc_fail_cnt: %u\n"
"rxDSSSCrcSuccessCnt: %u\n"
"rxDSSSCrcFailCnt: %u\n"
"rx_crypto_start_cnt: %u\n"
"rx_crypto_done_cnt: %u\n"
"rx_event_buf_full: %u\n"
"rx_extram_buf_full: %u\n"
"scan_req: %u\n"
"scan_complete: %u\n"
"scan_abort_req: %u\n"
"scan_abort_complete: %u\n"
"internal_buf_pool_null: %u\n"
"rpu_hw_lockup_count: %u\n"
"rpu_hw_lockup_recovery_done: %u\n\n",
lmac->reset_cmd_cnt,
lmac->reset_complete_event_cnt,
lmac->unable_gen_event,
lmac->ch_prog_cmd_cnt,
lmac->channel_prog_done,
lmac->tx_pkt_cnt,
lmac->tx_pkt_done_cnt,
lmac->scan_pkt_cnt,
lmac->internal_pkt_cnt,
lmac->internal_pkt_done_cnt,
lmac->ack_resp_cnt,
lmac->tx_timeout,
lmac->deagg_isr,
lmac->deagg_inptr_desc_empty,
lmac->deagg_circular_buffer_full,
lmac->lmac_rxisr_cnt,
lmac->rx_decryptcnt,
lmac->process_decrypt_fail,
lmac->prepa_rx_event_fail,
lmac->rx_core_pool_full_cnt,
lmac->rx_mpdu_crc_success_cnt,
lmac->rx_mpdu_crc_fail_cnt,
lmac->rx_ofdm_crc_success_cnt,
lmac->rx_ofdm_crc_fail_cnt,
lmac->rxDSSSCrcSuccessCnt,
lmac->rxDSSSCrcFailCnt,
lmac->rx_crypto_start_cnt,
lmac->rx_crypto_done_cnt,
lmac->rx_event_buf_full,
lmac->rx_extram_buf_full,
lmac->scan_req,
lmac->scan_complete,
lmac->scan_abort_req,
lmac->scan_abort_complete,
lmac->internal_buf_pool_null,
lmac->rpu_hw_lockup_count,
lmac->rpu_hw_lockup_recovery_done);
}
if (stats_type == RPU_STATS_TYPE_PHY || stats_type == RPU_STATS_TYPE_ALL) {
struct rpu_phy_stats *phy = &stats.fw.phy;
shell_fprintf(sh, SHELL_INFO,
"PHY stats\n"
"======================\n"
"rssi_avg: %d\n"
"pdout_val: %u\n"
"ofdm_crc32_pass_cnt: %u\n"
"ofdm_crc32_fail_cnt: %u\n"
"dsss_crc32_pass_cnt: %u\n"
"dsss_crc32_fail_cnt: %u\n\n",
phy->rssi_avg,
phy->pdout_val,
phy->ofdm_crc32_pass_cnt,
phy->ofdm_crc32_fail_cnt,
phy->dsss_crc32_pass_cnt,
phy->dsss_crc32_fail_cnt);
}
ret = 0;
unlock:
k_mutex_unlock(&ctx->rpu_lock);
return ret;
}
#endif /* !CONFIG_NRF70_RADIO_TEST && !CONFIG_NRF70_OFFLOADED_RAW_TX */
#ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
static int nrf_wifi_util_trigger_rpu_recovery(const struct shell *sh,
size_t argc,
const char *argv[])
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
int ret;
k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
if (!ctx || !ctx->rpu_ctx) {
shell_fprintf(sh,
SHELL_ERROR,
"RPU context not initialized\n");
ret = -ENOEXEC;
goto unlock;
}
fmac_dev_ctx = ctx->rpu_ctx;
status = nrf_wifi_fmac_rpu_recovery_callback(fmac_dev_ctx, NULL, 0);
if (status != NRF_WIFI_STATUS_SUCCESS) {
shell_fprintf(sh,
SHELL_ERROR,
"Failed to trigger RPU recovery\n");
return -ENOEXEC;
}
shell_fprintf(sh,
SHELL_INFO,
"RPU recovery triggered\n");
ret = 0;
unlock:
k_mutex_unlock(&ctx->rpu_lock);
return ret;
}
#endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
SHELL_STATIC_SUBCMD_SET_CREATE(
nrf_wifi_util_subcmds,
SHELL_CMD_ARG(he_ltf,
NULL,
"0 - 1x HE LTF\n"
"1 - 2x HE LTF\n"
"2 - 4x HE LTF ",
nrf_wifi_util_set_he_ltf,
2,
0),
SHELL_CMD_ARG(he_gi,
NULL,
"0 - 0.8 us\n"
"1 - 1.6 us\n"
"2 - 3.2 us ",
nrf_wifi_util_set_he_gi,
2,
0),
SHELL_CMD_ARG(set_he_ltf_gi,
NULL,
"0 - Disable\n"
"1 - Enable",
nrf_wifi_util_set_he_ltf_gi,
2,
0),
#ifdef CONFIG_NRF70_STA_MODE
SHELL_CMD_ARG(uapsd_queue,
NULL,
"<val> - 0 to 15",
nrf_wifi_util_set_uapsd_queue,
2,
0),
#endif /* CONFIG_NRF70_STA_MODE */
SHELL_CMD_ARG(show_config,
NULL,
"Display the current configuration values",
nrf_wifi_util_show_cfg,
1,
0),
#ifdef CONFIG_NRF70_STA_MODE
SHELL_CMD_ARG(tx_stats,
NULL,
"Displays transmit statistics\n"
"vif_index: 0 - 1\n",
nrf_wifi_util_tx_stats,
2,
0),
#endif /* CONFIG_NRF70_STA_MODE */
SHELL_CMD_ARG(tx_rate,
NULL,
"Sets TX data rate to either a fixed value or AUTO\n"
"Parameters:\n"
" <rate_flag> : The TX data rate type to be set, where:\n"
" 0 - LEGACY\n"
" 1 - HT\n"
" 2 - VHT\n"
" 3 - HE_SU\n"
" 4 - HE_ER_SU\n"
" 5 - AUTO\n"
" <rate_val> : The TX data rate value to be set, valid values are:\n"
" Legacy : <1, 2, 55, 11, 6, 9, 12, 18, 24, 36, 48, 54>\n"
" Non-legacy: <MCS index value between 0 - 7>\n"
" AUTO: <No value needed>\n",
nrf_wifi_util_tx_rate,
2,
1),
#ifdef CONFIG_NRF_WIFI_LOW_POWER
SHELL_CMD_ARG(sleep_state,
NULL,
"Display current sleep status",
nrf_wifi_util_show_host_rpu_ps_ctrl_state,
1,
0),
#endif /* CONFIG_NRF_WIFI_LOW_POWER */
SHELL_CMD_ARG(show_vers,
NULL,
"Display the driver and the firmware versions",
nrf_wifi_util_show_vers,
1,
0),
#if !defined(CONFIG_NRF70_RADIO_TEST) && !defined(CONFIG_NRF70_OFFLOADED_RAW_TX)
SHELL_CMD_ARG(rpu_stats,
NULL,
"Display RPU stats "
"Parameters: umac or lmac or phy or all (default)",
nrf_wifi_util_dump_rpu_stats,
1,
1),
#endif /* !CONFIG_NRF70_RADIO_TEST && !CONFIG_NRF70_OFFLOADED_RAW_TX*/
#ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
SHELL_CMD_ARG(rpu_recovery_test,
NULL,
"Trigger RPU recovery",
nrf_wifi_util_trigger_rpu_recovery,
1,
0),
#endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
SHELL_SUBCMD_SET_END);
SHELL_CMD_REGISTER(wifi_util,
&nrf_wifi_util_subcmds,
"nRF Wi-Fi utility shell commands",
NULL);
static int nrf_wifi_util_init(void)
{
if (nrf_wifi_util_conf_init(&ctx->conf_params) < 0) {
return -1;
}
return 0;
}
SYS_INIT(nrf_wifi_util_init,
APPLICATION,
CONFIG_APPLICATION_INIT_PRIORITY);