1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* @file
8 * @brief NRF Wi-Fi util shell module
9 */
10 #include <stdlib.h>
11 #include "host_rpu_umac_if.h"
12 #include "fmac_api.h"
13 #include "fmac_util.h"
14 #include "fmac_main.h"
15 #include "wifi_util.h"
16
17 extern struct nrf_wifi_drv_priv_zep rpu_drv_priv_zep;
18 struct nrf_wifi_ctx_zep *ctx = &rpu_drv_priv_zep.rpu_ctx_zep;
19
check_valid_data_rate(const struct shell * sh,unsigned char rate_flag,unsigned int data_rate)20 static bool check_valid_data_rate(const struct shell *sh,
21 unsigned char rate_flag,
22 unsigned int data_rate)
23 {
24 bool ret = false;
25
26 switch (rate_flag) {
27 case RPU_TPUT_MODE_LEGACY:
28 if ((data_rate == 1) ||
29 (data_rate == 2) ||
30 (data_rate == 55) ||
31 (data_rate == 11) ||
32 (data_rate == 6) ||
33 (data_rate == 9) ||
34 (data_rate == 12) ||
35 (data_rate == 18) ||
36 (data_rate == 24) ||
37 (data_rate == 36) ||
38 (data_rate == 48) ||
39 (data_rate == 54)) {
40 ret = true;
41 }
42 break;
43 case RPU_TPUT_MODE_HT:
44 case RPU_TPUT_MODE_HE_SU:
45 case RPU_TPUT_MODE_VHT:
46 if ((data_rate >= 0) && (data_rate <= 7)) {
47 ret = true;
48 }
49 break;
50 case RPU_TPUT_MODE_HE_ER_SU:
51 if (data_rate >= 0 && data_rate <= 2) {
52 ret = true;
53 }
54 break;
55 default:
56 shell_fprintf(sh,
57 SHELL_ERROR,
58 "%s: Invalid rate_flag %d\n",
59 __func__,
60 rate_flag);
61 break;
62 }
63
64 return ret;
65 }
66
67
nrf_wifi_util_conf_init(struct rpu_conf_params * conf_params)68 int nrf_wifi_util_conf_init(struct rpu_conf_params *conf_params)
69 {
70 if (!conf_params) {
71 return -ENOEXEC;
72 }
73
74 memset(conf_params, 0, sizeof(*conf_params));
75
76 /* Initialize values which are other than 0 */
77 conf_params->he_ltf = -1;
78 conf_params->he_gi = -1;
79 return 0;
80 }
81
82
nrf_wifi_util_set_he_ltf(const struct shell * sh,size_t argc,const char * argv[])83 static int nrf_wifi_util_set_he_ltf(const struct shell *sh,
84 size_t argc,
85 const char *argv[])
86 {
87 char *ptr = NULL;
88 unsigned long he_ltf = 0;
89
90 if (ctx->conf_params.set_he_ltf_gi) {
91 shell_fprintf(sh,
92 SHELL_ERROR,
93 "Disable 'set_he_ltf_gi', to set 'he_ltf'\n");
94 return -ENOEXEC;
95 }
96
97 he_ltf = strtoul(argv[1], &ptr, 10);
98
99 if (he_ltf > 2) {
100 shell_fprintf(sh,
101 SHELL_ERROR,
102 "Invalid HE LTF value(%lu).\n",
103 he_ltf);
104 shell_help(sh);
105 return -ENOEXEC;
106 }
107
108 ctx->conf_params.he_ltf = he_ltf;
109
110 return 0;
111 }
112
113
nrf_wifi_util_set_he_gi(const struct shell * sh,size_t argc,const char * argv[])114 static int nrf_wifi_util_set_he_gi(const struct shell *sh,
115 size_t argc,
116 const char *argv[])
117 {
118 char *ptr = NULL;
119 unsigned long he_gi = 0;
120
121 if (ctx->conf_params.set_he_ltf_gi) {
122 shell_fprintf(sh,
123 SHELL_ERROR,
124 "Disable 'set_he_ltf_gi', to set 'he_gi'\n");
125 return -ENOEXEC;
126 }
127
128 he_gi = strtoul(argv[1], &ptr, 10);
129
130 if (he_gi > 2) {
131 shell_fprintf(sh,
132 SHELL_ERROR,
133 "Invalid HE GI value(%lu).\n",
134 he_gi);
135 shell_help(sh);
136 return -ENOEXEC;
137 }
138
139 ctx->conf_params.he_gi = he_gi;
140
141 return 0;
142 }
143
144
nrf_wifi_util_set_he_ltf_gi(const struct shell * sh,size_t argc,const char * argv[])145 static int nrf_wifi_util_set_he_ltf_gi(const struct shell *sh,
146 size_t argc,
147 const char *argv[])
148 {
149 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
150 char *ptr = NULL;
151 unsigned long val = 0;
152
153 val = strtoul(argv[1], &ptr, 10);
154
155 if ((val < 0) || (val > 1)) {
156 shell_fprintf(sh,
157 SHELL_ERROR,
158 "Invalid value(%lu).\n",
159 val);
160 shell_help(sh);
161 return -ENOEXEC;
162 }
163
164 status = nrf_wifi_fmac_conf_ltf_gi(ctx->rpu_ctx,
165 ctx->conf_params.he_ltf,
166 ctx->conf_params.he_gi,
167 val);
168
169 if (status != NRF_WIFI_STATUS_SUCCESS) {
170 shell_fprintf(sh,
171 SHELL_ERROR,
172 "Programming ltf_gi failed\n");
173 return -ENOEXEC;
174 }
175
176 ctx->conf_params.set_he_ltf_gi = val;
177
178 return 0;
179 }
180
181 #ifdef CONFIG_NRF70_STA_MODE
nrf_wifi_util_set_uapsd_queue(const struct shell * sh,size_t argc,const char * argv[])182 static int nrf_wifi_util_set_uapsd_queue(const struct shell *sh,
183 size_t argc,
184 const char *argv[])
185 {
186 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
187 char *ptr = NULL;
188 unsigned long val = 0;
189
190 val = strtoul(argv[1], &ptr, 10);
191
192 if ((val < UAPSD_Q_MIN) || (val > UAPSD_Q_MAX)) {
193 shell_fprintf(sh,
194 SHELL_ERROR,
195 "Invalid value(%lu).\n",
196 val);
197 shell_help(sh);
198 return -ENOEXEC;
199 }
200
201 if (ctx->conf_params.uapsd_queue != val) {
202 status = nrf_wifi_fmac_set_uapsd_queue(ctx->rpu_ctx,
203 0,
204 val);
205
206 if (status != NRF_WIFI_STATUS_SUCCESS) {
207 shell_fprintf(sh,
208 SHELL_ERROR,
209 "Programming uapsd_queue failed\n");
210 return -ENOEXEC;
211 }
212
213 ctx->conf_params.uapsd_queue = val;
214 }
215
216 return 0;
217 }
218 #endif /* CONFIG_NRF70_STA_MODE */
219
220
nrf_wifi_util_show_cfg(const struct shell * sh,size_t argc,const char * argv[])221 static int nrf_wifi_util_show_cfg(const struct shell *sh,
222 size_t argc,
223 const char *argv[])
224 {
225 struct rpu_conf_params *conf_params = NULL;
226
227 conf_params = &ctx->conf_params;
228
229 shell_fprintf(sh,
230 SHELL_INFO,
231 "************* Configured Parameters ***********\n");
232 shell_fprintf(sh,
233 SHELL_INFO,
234 "\n");
235
236 shell_fprintf(sh,
237 SHELL_INFO,
238 "he_ltf = %d\n",
239 conf_params->he_ltf);
240
241 shell_fprintf(sh,
242 SHELL_INFO,
243 "he_gi = %u\n",
244 conf_params->he_gi);
245
246 shell_fprintf(sh,
247 SHELL_INFO,
248 "set_he_ltf_gi = %d\n",
249 conf_params->set_he_ltf_gi);
250
251 shell_fprintf(sh,
252 SHELL_INFO,
253 "uapsd_queue = %d\n",
254 conf_params->uapsd_queue);
255
256 shell_fprintf(sh,
257 SHELL_INFO,
258 "rate_flag = %d, rate_val = %d\n",
259 ctx->conf_params.tx_pkt_tput_mode,
260 ctx->conf_params.tx_pkt_rate);
261 return 0;
262 }
263
264 #ifdef CONFIG_NRF70_STA_MODE
nrf_wifi_util_tx_stats(const struct shell * sh,size_t argc,const char * argv[])265 static int nrf_wifi_util_tx_stats(const struct shell *sh,
266 size_t argc,
267 const char *argv[])
268 {
269 int vif_index = -1;
270 int peer_index = 0;
271 int max_vif_index = MAX(MAX_NUM_APS, MAX_NUM_STAS);
272 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
273 void *queue = NULL;
274 unsigned int tx_pending_pkts = 0;
275 struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL;
276 int ret;
277
278 vif_index = atoi(argv[1]);
279 if ((vif_index < 0) || (vif_index >= max_vif_index)) {
280 shell_fprintf(sh,
281 SHELL_ERROR,
282 "Invalid vif index(%d).\n",
283 vif_index);
284 shell_help(sh);
285 return -ENOEXEC;
286 }
287
288 k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
289 if (!ctx->rpu_ctx) {
290 shell_fprintf(sh,
291 SHELL_ERROR,
292 "RPU context not initialized\n");
293 ret = -ENOEXEC;
294 goto unlock;
295 }
296
297 fmac_dev_ctx = ctx->rpu_ctx;
298 def_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
299
300 /* TODO: Get peer_index from shell once AP mode is supported */
301 shell_fprintf(sh,
302 SHELL_INFO,
303 "************* Tx Stats: vif(%d) peer(0) ***********\n",
304 vif_index);
305
306 for (int i = 0; i < NRF_WIFI_FMAC_AC_MAX ; i++) {
307 queue = def_dev_ctx->tx_config.data_pending_txq[peer_index][i];
308 tx_pending_pkts = nrf_wifi_utils_q_len(queue);
309
310 shell_fprintf(
311 sh,
312 SHELL_INFO,
313 "Outstanding tokens: ac: %d -> %d (pending_q_len: %d)\n",
314 i,
315 def_dev_ctx->tx_config.outstanding_descs[i],
316 tx_pending_pkts);
317 }
318
319 ret = 0;
320
321 unlock:
322 k_mutex_unlock(&ctx->rpu_lock);
323 return ret;
324 }
325 #endif /* CONFIG_NRF70_STA_MODE */
326
327
nrf_wifi_util_tx_rate(const struct shell * sh,size_t argc,const char * argv[])328 static int nrf_wifi_util_tx_rate(const struct shell *sh,
329 size_t argc,
330 const char *argv[])
331 {
332 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
333 char *ptr = NULL;
334 long rate_flag = -1;
335 long data_rate = -1;
336
337 rate_flag = strtol(argv[1], &ptr, 10);
338
339 if (rate_flag >= RPU_TPUT_MODE_MAX) {
340 shell_fprintf(sh,
341 SHELL_ERROR,
342 "Invalid value %ld for rate_flags\n",
343 rate_flag);
344 shell_help(sh);
345 return -ENOEXEC;
346 }
347
348
349 if (rate_flag == RPU_TPUT_MODE_HE_TB) {
350 data_rate = -1;
351 } else {
352 if (argc < 3) {
353 shell_fprintf(sh,
354 SHELL_ERROR,
355 "rate_val needed for rate_flag = %ld\n",
356 rate_flag);
357 shell_help(sh);
358 return -ENOEXEC;
359 }
360
361 data_rate = strtol(argv[2], &ptr, 10);
362
363 if (!(check_valid_data_rate(sh,
364 rate_flag,
365 data_rate))) {
366 shell_fprintf(sh,
367 SHELL_ERROR,
368 "Invalid data_rate %ld for rate_flag %ld\n",
369 data_rate,
370 rate_flag);
371 return -ENOEXEC;
372 }
373
374 }
375
376 status = nrf_wifi_fmac_set_tx_rate(ctx->rpu_ctx,
377 rate_flag,
378 data_rate);
379
380 if (status != NRF_WIFI_STATUS_SUCCESS) {
381 shell_fprintf(sh,
382 SHELL_ERROR,
383 "Programming tx_rate failed\n");
384 return -ENOEXEC;
385 }
386
387 ctx->conf_params.tx_pkt_tput_mode = rate_flag;
388 ctx->conf_params.tx_pkt_rate = data_rate;
389
390 return 0;
391 }
392
393
394 #ifdef CONFIG_NRF_WIFI_LOW_POWER
nrf_wifi_util_show_host_rpu_ps_ctrl_state(const struct shell * sh,size_t argc,const char * argv[])395 static int nrf_wifi_util_show_host_rpu_ps_ctrl_state(const struct shell *sh,
396 size_t argc,
397 const char *argv[])
398 {
399 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
400 int rpu_ps_state = -1;
401
402 status = nrf_wifi_fmac_get_host_rpu_ps_ctrl_state(ctx->rpu_ctx,
403 &rpu_ps_state);
404
405 if (status != NRF_WIFI_STATUS_SUCCESS) {
406 shell_fprintf(sh,
407 SHELL_ERROR,
408 "Failed to get PS state\n");
409 return -ENOEXEC;
410 }
411
412 shell_fprintf(sh,
413 SHELL_INFO,
414 "RPU sleep status = %s\n", rpu_ps_state ? "AWAKE" : "SLEEP");
415 return 0;
416 }
417 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
418
419
nrf_wifi_util_show_vers(const struct shell * sh,size_t argc,const char * argv[])420 static int nrf_wifi_util_show_vers(const struct shell *sh,
421 size_t argc,
422 const char *argv[])
423 {
424 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
425 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
426 unsigned int fw_ver;
427
428 fmac_dev_ctx = ctx->rpu_ctx;
429
430 shell_fprintf(sh, SHELL_INFO, "Driver version: %s\n",
431 NRF70_DRIVER_VERSION);
432
433 status = nrf_wifi_fmac_ver_get(fmac_dev_ctx, &fw_ver);
434
435 if (status != NRF_WIFI_STATUS_SUCCESS) {
436 shell_fprintf(sh,
437 SHELL_INFO,
438 "Failed to get firmware version\n");
439 return -ENOEXEC;
440 }
441
442 shell_fprintf(sh, SHELL_INFO,
443 "Firmware version: %d.%d.%d.%d\n",
444 NRF_WIFI_UMAC_VER(fw_ver),
445 NRF_WIFI_UMAC_VER_MAJ(fw_ver),
446 NRF_WIFI_UMAC_VER_MIN(fw_ver),
447 NRF_WIFI_UMAC_VER_EXTRA(fw_ver));
448
449 return status;
450 }
451
452 #if !defined(CONFIG_NRF70_RADIO_TEST) && !defined(CONFIG_NRF70_OFFLOADED_RAW_TX)
nrf_wifi_util_dump_rpu_stats(const struct shell * sh,size_t argc,const char * argv[])453 static int nrf_wifi_util_dump_rpu_stats(const struct shell *sh,
454 size_t argc,
455 const char *argv[])
456 {
457 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
458 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
459 struct rpu_op_stats stats;
460 enum rpu_stats_type stats_type = RPU_STATS_TYPE_ALL;
461 int ret;
462
463 if (argc == 2) {
464 const char *type = argv[1];
465
466 if (!strcmp(type, "umac")) {
467 stats_type = RPU_STATS_TYPE_UMAC;
468 } else if (!strcmp(type, "lmac")) {
469 stats_type = RPU_STATS_TYPE_LMAC;
470 } else if (!strcmp(type, "phy")) {
471 stats_type = RPU_STATS_TYPE_PHY;
472 } else if (!strcmp(type, "all")) {
473 stats_type = RPU_STATS_TYPE_ALL;
474 } else {
475 shell_fprintf(sh,
476 SHELL_ERROR,
477 "Invalid stats type %s\n",
478 type);
479 return -ENOEXEC;
480 }
481 }
482
483 k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
484 if (!ctx->rpu_ctx) {
485 shell_fprintf(sh,
486 SHELL_ERROR,
487 "RPU context not initialized\n");
488 ret = -ENOEXEC;
489 goto unlock;
490 }
491 fmac_dev_ctx = ctx->rpu_ctx;
492
493 memset(&stats, 0, sizeof(struct rpu_op_stats));
494 status = nrf_wifi_fmac_stats_get(fmac_dev_ctx, 0, &stats);
495
496 if (status != NRF_WIFI_STATUS_SUCCESS) {
497 shell_fprintf(sh,
498 SHELL_ERROR,
499 "Failed to get stats\n");
500 ret = -ENOEXEC;
501 goto unlock;
502 }
503
504 if (stats_type == RPU_STATS_TYPE_UMAC || stats_type == RPU_STATS_TYPE_ALL) {
505 struct rpu_umac_stats *umac = &stats.fw.umac;
506
507 shell_fprintf(sh, SHELL_INFO,
508 "UMAC TX debug stats:\n"
509 "======================\n"
510 "tx_cmd: %u\n"
511 "tx_non_coalesce_pkts_rcvd_from_host: %u\n"
512 "tx_coalesce_pkts_rcvd_from_host: %u\n"
513 "tx_max_coalesce_pkts_rcvd_from_host: %u\n"
514 "tx_cmds_max_used: %u\n"
515 "tx_cmds_currently_in_use: %u\n"
516 "tx_done_events_send_to_host: %u\n"
517 "tx_done_success_pkts_to_host: %u\n"
518 "tx_done_failure_pkts_to_host: %u\n"
519 "tx_cmds_with_crypto_pkts_rcvd_from_host: %u\n"
520 "tx_cmds_with_non_crypto_pkts_rcvd_from_host: %u\n"
521 "tx_cmds_with_broadcast_pkts_rcvd_from_host: %u\n"
522 "tx_cmds_with_multicast_pkts_rcvd_from_host: %u\n"
523 "tx_cmds_with_unicast_pkts_rcvd_from_host: %u\n"
524 "xmit: %u\n"
525 "send_addba_req: %u\n"
526 "addba_resp: %u\n"
527 "softmac_tx: %u\n"
528 "internal_pkts: %u\n"
529 "external_pkts: %u\n"
530 "tx_cmds_to_lmac: %u\n"
531 "tx_dones_from_lmac: %u\n"
532 "total_cmds_to_lmac: %u\n"
533 "tx_packet_data_count: %u\n"
534 "tx_packet_mgmt_count: %u\n"
535 "tx_packet_beacon_count: %u\n"
536 "tx_packet_probe_req_count: %u\n"
537 "tx_packet_auth_count: %u\n"
538 "tx_packet_deauth_count: %u\n"
539 "tx_packet_assoc_req_count: %u\n"
540 "tx_packet_disassoc_count: %u\n"
541 "tx_packet_action_count: %u\n"
542 "tx_packet_other_mgmt_count: %u\n"
543 "tx_packet_non_mgmt_data_count: %u\n\n",
544 umac->tx_dbg_params.tx_cmd,
545 umac->tx_dbg_params.tx_non_coalesce_pkts_rcvd_from_host,
546 umac->tx_dbg_params.tx_coalesce_pkts_rcvd_from_host,
547 umac->tx_dbg_params.tx_max_coalesce_pkts_rcvd_from_host,
548 umac->tx_dbg_params.tx_cmds_max_used,
549 umac->tx_dbg_params.tx_cmds_currently_in_use,
550 umac->tx_dbg_params.tx_done_events_send_to_host,
551 umac->tx_dbg_params.tx_done_success_pkts_to_host,
552 umac->tx_dbg_params.tx_done_failure_pkts_to_host,
553 umac->tx_dbg_params.tx_cmds_with_crypto_pkts_rcvd_from_host,
554 umac->tx_dbg_params.tx_cmds_with_non_crypto_pkts_rcvd_from_host,
555 umac->tx_dbg_params.tx_cmds_with_broadcast_pkts_rcvd_from_host,
556 umac->tx_dbg_params.tx_cmds_with_multicast_pkts_rcvd_from_host,
557 umac->tx_dbg_params.tx_cmds_with_unicast_pkts_rcvd_from_host,
558 umac->tx_dbg_params.xmit,
559 umac->tx_dbg_params.send_addba_req,
560 umac->tx_dbg_params.addba_resp,
561 umac->tx_dbg_params.softmac_tx,
562 umac->tx_dbg_params.internal_pkts,
563 umac->tx_dbg_params.external_pkts,
564 umac->tx_dbg_params.tx_cmds_to_lmac,
565 umac->tx_dbg_params.tx_dones_from_lmac,
566 umac->tx_dbg_params.total_cmds_to_lmac,
567 umac->tx_dbg_params.tx_packet_data_count,
568 umac->tx_dbg_params.tx_packet_mgmt_count,
569 umac->tx_dbg_params.tx_packet_beacon_count,
570 umac->tx_dbg_params.tx_packet_probe_req_count,
571 umac->tx_dbg_params.tx_packet_auth_count,
572 umac->tx_dbg_params.tx_packet_deauth_count,
573 umac->tx_dbg_params.tx_packet_assoc_req_count,
574 umac->tx_dbg_params.tx_packet_disassoc_count,
575 umac->tx_dbg_params.tx_packet_action_count,
576 umac->tx_dbg_params.tx_packet_other_mgmt_count,
577 umac->tx_dbg_params.tx_packet_non_mgmt_data_count);
578
579 shell_fprintf(sh, SHELL_INFO,
580 "UMAC RX debug stats\n"
581 "======================\n"
582 "lmac_events: %u\n"
583 "rx_events: %u\n"
584 "rx_coalesce_events: %u\n"
585 "total_rx_pkts_from_lmac: %u\n"
586 "max_refill_gap: %u\n"
587 "current_refill_gap: %u\n"
588 "out_of_order_mpdus: %u\n"
589 "reorder_free_mpdus: %u\n"
590 "umac_consumed_pkts: %u\n"
591 "host_consumed_pkts: %u\n"
592 "rx_mbox_post: %u\n"
593 "rx_mbox_receive: %u\n"
594 "reordering_ampdu: %u\n"
595 "timer_mbox_post: %u\n"
596 "timer_mbox_rcv: %u\n"
597 "work_mbox_post: %u\n"
598 "work_mbox_rcv: %u\n"
599 "tasklet_mbox_post: %u\n"
600 "tasklet_mbox_rcv: %u\n"
601 "userspace_offload_frames: %u\n"
602 "alloc_buf_fail: %u\n"
603 "rx_packet_total_count: %u\n"
604 "rx_packet_data_count: %u\n"
605 "rx_packet_qos_data_count: %u\n"
606 "rx_packet_protected_data_count: %u\n"
607 "rx_packet_mgmt_count: %u\n"
608 "rx_packet_beacon_count: %u\n"
609 "rx_packet_probe_resp_count: %u\n"
610 "rx_packet_auth_count: %u\n"
611 "rx_packet_deauth_count: %u\n"
612 "rx_packet_assoc_resp_count: %u\n"
613 "rx_packet_disassoc_count: %u\n"
614 "rx_packet_action_count: %u\n"
615 "rx_packet_probe_req_count: %u\n"
616 "rx_packet_other_mgmt_count: %u\n"
617 "max_coalesce_pkts: %d\n"
618 "null_skb_pointer_from_lmac: %u\n"
619 "unexpected_mgmt_pkt: %u\n\n",
620 umac->rx_dbg_params.lmac_events,
621 umac->rx_dbg_params.rx_events,
622 umac->rx_dbg_params.rx_coalesce_events,
623 umac->rx_dbg_params.total_rx_pkts_from_lmac,
624 umac->rx_dbg_params.max_refill_gap,
625 umac->rx_dbg_params.current_refill_gap,
626 umac->rx_dbg_params.out_of_order_mpdus,
627 umac->rx_dbg_params.reorder_free_mpdus,
628 umac->rx_dbg_params.umac_consumed_pkts,
629 umac->rx_dbg_params.host_consumed_pkts,
630 umac->rx_dbg_params.rx_mbox_post,
631 umac->rx_dbg_params.rx_mbox_receive,
632 umac->rx_dbg_params.reordering_ampdu,
633 umac->rx_dbg_params.timer_mbox_post,
634 umac->rx_dbg_params.timer_mbox_rcv,
635 umac->rx_dbg_params.work_mbox_post,
636 umac->rx_dbg_params.work_mbox_rcv,
637 umac->rx_dbg_params.tasklet_mbox_post,
638 umac->rx_dbg_params.tasklet_mbox_rcv,
639 umac->rx_dbg_params.userspace_offload_frames,
640 umac->rx_dbg_params.alloc_buf_fail,
641 umac->rx_dbg_params.rx_packet_total_count,
642 umac->rx_dbg_params.rx_packet_data_count,
643 umac->rx_dbg_params.rx_packet_qos_data_count,
644 umac->rx_dbg_params.rx_packet_protected_data_count,
645 umac->rx_dbg_params.rx_packet_mgmt_count,
646 umac->rx_dbg_params.rx_packet_beacon_count,
647 umac->rx_dbg_params.rx_packet_probe_resp_count,
648 umac->rx_dbg_params.rx_packet_auth_count,
649 umac->rx_dbg_params.rx_packet_deauth_count,
650 umac->rx_dbg_params.rx_packet_assoc_resp_count,
651 umac->rx_dbg_params.rx_packet_disassoc_count,
652 umac->rx_dbg_params.rx_packet_action_count,
653 umac->rx_dbg_params.rx_packet_probe_req_count,
654 umac->rx_dbg_params.rx_packet_other_mgmt_count,
655 umac->rx_dbg_params.max_coalesce_pkts,
656 umac->rx_dbg_params.null_skb_pointer_from_lmac,
657 umac->rx_dbg_params.unexpected_mgmt_pkt);
658
659 shell_fprintf(sh, SHELL_INFO,
660 "UMAC control path stats\n"
661 "======================\n"
662 "cmd_init: %u\n"
663 "event_init_done: %u\n"
664 "cmd_rf_test: %u\n"
665 "cmd_connect: %u\n"
666 "cmd_get_stats: %u\n"
667 "event_ps_state: %u\n"
668 "cmd_set_reg: %u\n"
669 "cmd_get_reg: %u\n"
670 "cmd_req_set_reg: %u\n"
671 "cmd_trigger_scan: %u\n"
672 "event_scan_done: %u\n"
673 "cmd_get_scan: %u\n"
674 "umac_scan_req: %u\n"
675 "umac_scan_complete: %u\n"
676 "umac_scan_busy: %u\n"
677 "cmd_auth: %u\n"
678 "cmd_assoc: %u\n"
679 "cmd_deauth: %u\n"
680 "cmd_register_frame: %u\n"
681 "cmd_frame: %u\n"
682 "cmd_del_key: %u\n"
683 "cmd_new_key: %u\n"
684 "cmd_set_key: %u\n"
685 "cmd_get_key: %u\n"
686 "event_beacon_hint: %u\n"
687 "event_reg_change: %u\n"
688 "event_wiphy_reg_change: %u\n"
689 "cmd_set_station: %u\n"
690 "cmd_new_station: %u\n"
691 "cmd_del_station: %u\n"
692 "cmd_new_interface: %u\n"
693 "cmd_set_interface: %u\n"
694 "cmd_get_interface: %u\n"
695 "cmd_set_ifflags: %u\n"
696 "cmd_set_ifflags_done: %u\n"
697 "cmd_set_bss: %u\n"
698 "cmd_set_wiphy: %u\n"
699 "cmd_start_ap: %u\n"
700 "LMAC_CMD_PS: %u\n"
701 "CURR_STATE: %u\n\n",
702 umac->cmd_evnt_dbg_params.cmd_init,
703 umac->cmd_evnt_dbg_params.event_init_done,
704 umac->cmd_evnt_dbg_params.cmd_rf_test,
705 umac->cmd_evnt_dbg_params.cmd_connect,
706 umac->cmd_evnt_dbg_params.cmd_get_stats,
707 umac->cmd_evnt_dbg_params.event_ps_state,
708 umac->cmd_evnt_dbg_params.cmd_set_reg,
709 umac->cmd_evnt_dbg_params.cmd_get_reg,
710 umac->cmd_evnt_dbg_params.cmd_req_set_reg,
711 umac->cmd_evnt_dbg_params.cmd_trigger_scan,
712 umac->cmd_evnt_dbg_params.event_scan_done,
713 umac->cmd_evnt_dbg_params.cmd_get_scan,
714 umac->cmd_evnt_dbg_params.umac_scan_req,
715 umac->cmd_evnt_dbg_params.umac_scan_complete,
716 umac->cmd_evnt_dbg_params.umac_scan_busy,
717 umac->cmd_evnt_dbg_params.cmd_auth,
718 umac->cmd_evnt_dbg_params.cmd_assoc,
719 umac->cmd_evnt_dbg_params.cmd_deauth,
720 umac->cmd_evnt_dbg_params.cmd_register_frame,
721 umac->cmd_evnt_dbg_params.cmd_frame,
722 umac->cmd_evnt_dbg_params.cmd_del_key,
723 umac->cmd_evnt_dbg_params.cmd_new_key,
724 umac->cmd_evnt_dbg_params.cmd_set_key,
725 umac->cmd_evnt_dbg_params.cmd_get_key,
726 umac->cmd_evnt_dbg_params.event_beacon_hint,
727 umac->cmd_evnt_dbg_params.event_reg_change,
728 umac->cmd_evnt_dbg_params.event_wiphy_reg_change,
729 umac->cmd_evnt_dbg_params.cmd_set_station,
730 umac->cmd_evnt_dbg_params.cmd_new_station,
731 umac->cmd_evnt_dbg_params.cmd_del_station,
732 umac->cmd_evnt_dbg_params.cmd_new_interface,
733 umac->cmd_evnt_dbg_params.cmd_set_interface,
734 umac->cmd_evnt_dbg_params.cmd_get_interface,
735 umac->cmd_evnt_dbg_params.cmd_set_ifflags,
736 umac->cmd_evnt_dbg_params.cmd_set_ifflags_done,
737 umac->cmd_evnt_dbg_params.cmd_set_bss,
738 umac->cmd_evnt_dbg_params.cmd_set_wiphy,
739 umac->cmd_evnt_dbg_params.cmd_start_ap,
740 umac->cmd_evnt_dbg_params.LMAC_CMD_PS,
741 umac->cmd_evnt_dbg_params.CURR_STATE);
742
743 shell_fprintf(sh, SHELL_INFO,
744 "UMAC interface stats\n"
745 "======================\n"
746 "tx_unicast_pkt_count: %u\n"
747 "tx_multicast_pkt_count: %u\n"
748 "tx_broadcast_pkt_count: %u\n"
749 "tx_bytes: %u\n"
750 "rx_unicast_pkt_count: %u\n"
751 "rx_multicast_pkt_count: %u\n"
752 "rx_broadcast_pkt_count: %u\n"
753 "rx_beacon_success_count: %u\n"
754 "rx_beacon_miss_count: %u\n"
755 "rx_bytes: %u\n"
756 "rx_checksum_error_count: %u\n\n"
757 "replay_attack_drop_cnt: %u\n\n",
758 umac->interface_data_stats.tx_unicast_pkt_count,
759 umac->interface_data_stats.tx_multicast_pkt_count,
760 umac->interface_data_stats.tx_broadcast_pkt_count,
761 umac->interface_data_stats.tx_bytes,
762 umac->interface_data_stats.rx_unicast_pkt_count,
763 umac->interface_data_stats.rx_multicast_pkt_count,
764 umac->interface_data_stats.rx_broadcast_pkt_count,
765 umac->interface_data_stats.rx_beacon_success_count,
766 umac->interface_data_stats.rx_beacon_miss_count,
767 umac->interface_data_stats.rx_bytes,
768 umac->interface_data_stats.rx_checksum_error_count,
769 umac->interface_data_stats.replay_attack_drop_cnt);
770 }
771
772 if (stats_type == RPU_STATS_TYPE_LMAC || stats_type == RPU_STATS_TYPE_ALL) {
773 struct rpu_lmac_stats *lmac = &stats.fw.lmac;
774
775 shell_fprintf(sh, SHELL_INFO,
776 "LMAC stats\n"
777 "======================\n"
778 "reset_cmd_cnt: %u\n"
779 "reset_complete_event_cnt: %u\n"
780 "unable_gen_event: %u\n"
781 "ch_prog_cmd_cnt: %u\n"
782 "channel_prog_done: %u\n"
783 "tx_pkt_cnt: %u\n"
784 "tx_pkt_done_cnt: %u\n"
785 "scan_pkt_cnt: %u\n"
786 "internal_pkt_cnt: %u\n"
787 "internal_pkt_done_cnt: %u\n"
788 "ack_resp_cnt: %u\n"
789 "tx_timeout: %u\n"
790 "deagg_isr: %u\n"
791 "deagg_inptr_desc_empty: %u\n"
792 "deagg_circular_buffer_full: %u\n"
793 "lmac_rxisr_cnt: %u\n"
794 "rx_decryptcnt: %u\n"
795 "process_decrypt_fail: %u\n"
796 "prepa_rx_event_fail: %u\n"
797 "rx_core_pool_full_cnt: %u\n"
798 "rx_mpdu_crc_success_cnt: %u\n"
799 "rx_mpdu_crc_fail_cnt: %u\n"
800 "rx_ofdm_crc_success_cnt: %u\n"
801 "rx_ofdm_crc_fail_cnt: %u\n"
802 "rxDSSSCrcSuccessCnt: %u\n"
803 "rxDSSSCrcFailCnt: %u\n"
804 "rx_crypto_start_cnt: %u\n"
805 "rx_crypto_done_cnt: %u\n"
806 "rx_event_buf_full: %u\n"
807 "rx_extram_buf_full: %u\n"
808 "scan_req: %u\n"
809 "scan_complete: %u\n"
810 "scan_abort_req: %u\n"
811 "scan_abort_complete: %u\n"
812 "internal_buf_pool_null: %u\n"
813 "rpu_hw_lockup_count: %u\n"
814 "rpu_hw_lockup_recovery_done: %u\n\n",
815 lmac->reset_cmd_cnt,
816 lmac->reset_complete_event_cnt,
817 lmac->unable_gen_event,
818 lmac->ch_prog_cmd_cnt,
819 lmac->channel_prog_done,
820 lmac->tx_pkt_cnt,
821 lmac->tx_pkt_done_cnt,
822 lmac->scan_pkt_cnt,
823 lmac->internal_pkt_cnt,
824 lmac->internal_pkt_done_cnt,
825 lmac->ack_resp_cnt,
826 lmac->tx_timeout,
827 lmac->deagg_isr,
828 lmac->deagg_inptr_desc_empty,
829 lmac->deagg_circular_buffer_full,
830 lmac->lmac_rxisr_cnt,
831 lmac->rx_decryptcnt,
832 lmac->process_decrypt_fail,
833 lmac->prepa_rx_event_fail,
834 lmac->rx_core_pool_full_cnt,
835 lmac->rx_mpdu_crc_success_cnt,
836 lmac->rx_mpdu_crc_fail_cnt,
837 lmac->rx_ofdm_crc_success_cnt,
838 lmac->rx_ofdm_crc_fail_cnt,
839 lmac->rxDSSSCrcSuccessCnt,
840 lmac->rxDSSSCrcFailCnt,
841 lmac->rx_crypto_start_cnt,
842 lmac->rx_crypto_done_cnt,
843 lmac->rx_event_buf_full,
844 lmac->rx_extram_buf_full,
845 lmac->scan_req,
846 lmac->scan_complete,
847 lmac->scan_abort_req,
848 lmac->scan_abort_complete,
849 lmac->internal_buf_pool_null,
850 lmac->rpu_hw_lockup_count,
851 lmac->rpu_hw_lockup_recovery_done);
852 }
853
854 if (stats_type == RPU_STATS_TYPE_PHY || stats_type == RPU_STATS_TYPE_ALL) {
855 struct rpu_phy_stats *phy = &stats.fw.phy;
856
857 shell_fprintf(sh, SHELL_INFO,
858 "PHY stats\n"
859 "======================\n"
860 "rssi_avg: %d\n"
861 "pdout_val: %u\n"
862 "ofdm_crc32_pass_cnt: %u\n"
863 "ofdm_crc32_fail_cnt: %u\n"
864 "dsss_crc32_pass_cnt: %u\n"
865 "dsss_crc32_fail_cnt: %u\n\n",
866 phy->rssi_avg,
867 phy->pdout_val,
868 phy->ofdm_crc32_pass_cnt,
869 phy->ofdm_crc32_fail_cnt,
870 phy->dsss_crc32_pass_cnt,
871 phy->dsss_crc32_fail_cnt);
872 }
873
874 ret = 0;
875 unlock:
876 k_mutex_unlock(&ctx->rpu_lock);
877 return ret;
878 }
879 #endif /* !CONFIG_NRF70_RADIO_TEST && !CONFIG_NRF70_OFFLOADED_RAW_TX */
880
881 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
nrf_wifi_util_trigger_rpu_recovery(const struct shell * sh,size_t argc,const char * argv[])882 static int nrf_wifi_util_trigger_rpu_recovery(const struct shell *sh,
883 size_t argc,
884 const char *argv[])
885 {
886 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
887 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
888 int ret;
889
890 k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
891 if (!ctx || !ctx->rpu_ctx) {
892 shell_fprintf(sh,
893 SHELL_ERROR,
894 "RPU context not initialized\n");
895 ret = -ENOEXEC;
896 goto unlock;
897 }
898
899 fmac_dev_ctx = ctx->rpu_ctx;
900
901 status = nrf_wifi_fmac_rpu_recovery_callback(fmac_dev_ctx, NULL, 0);
902 if (status != NRF_WIFI_STATUS_SUCCESS) {
903 shell_fprintf(sh,
904 SHELL_ERROR,
905 "Failed to trigger RPU recovery\n");
906 return -ENOEXEC;
907 }
908
909 shell_fprintf(sh,
910 SHELL_INFO,
911 "RPU recovery triggered\n");
912
913 ret = 0;
914 unlock:
915 k_mutex_unlock(&ctx->rpu_lock);
916 return ret;
917 }
918
nrf_wifi_util_rpu_recovery_info(const struct shell * sh,size_t argc,const char * argv[])919 static int nrf_wifi_util_rpu_recovery_info(const struct shell *sh,
920 size_t argc,
921 const char *argv[])
922 {
923 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
924 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
925 unsigned long current_time_ms = nrf_wifi_osal_time_get_curr_ms();
926 int ret;
927
928 k_mutex_lock(&ctx->rpu_lock, K_FOREVER);
929 if (!ctx || !ctx->rpu_ctx) {
930 shell_fprintf(sh,
931 SHELL_ERROR,
932 "RPU context not initialized\n");
933 ret = -ENOEXEC;
934 goto unlock;
935 }
936
937 fmac_dev_ctx = ctx->rpu_ctx;
938 hal_dev_ctx = fmac_dev_ctx->hal_dev_ctx;
939
940 shell_fprintf(sh,
941 SHELL_INFO,
942 "wdt_irq_received: %d\n"
943 "wdt_irq_ignored: %d\n"
944 "last_wakeup_now_asserted_time_ms: %lu milliseconds\n"
945 "last_wakeup_now_deasserted_time_ms: %lu milliseconds\n"
946 "last_rpu_sleep_opp_time_ms: %lu milliseconds\n"
947 "current time: %lu milliseconds\n"
948 "rpu_recovery_success: %d\n"
949 "rpu_recovery_failure: %d\n\n",
950 hal_dev_ctx->wdt_irq_received,
951 hal_dev_ctx->wdt_irq_ignored,
952 hal_dev_ctx->last_wakeup_now_asserted_time_ms,
953 hal_dev_ctx->last_wakeup_now_deasserted_time_ms,
954 hal_dev_ctx->last_rpu_sleep_opp_time_ms,
955 current_time_ms,
956 ctx->rpu_recovery_success,
957 ctx->rpu_recovery_failure);
958
959 ret = 0;
960 unlock:
961 k_mutex_unlock(&ctx->rpu_lock);
962 return ret;
963 }
964 #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
965
966 SHELL_STATIC_SUBCMD_SET_CREATE(
967 nrf_wifi_util_subcmds,
968 SHELL_CMD_ARG(he_ltf,
969 NULL,
970 "0 - 1x HE LTF\n"
971 "1 - 2x HE LTF\n"
972 "2 - 4x HE LTF ",
973 nrf_wifi_util_set_he_ltf,
974 2,
975 0),
976 SHELL_CMD_ARG(he_gi,
977 NULL,
978 "0 - 0.8 us\n"
979 "1 - 1.6 us\n"
980 "2 - 3.2 us ",
981 nrf_wifi_util_set_he_gi,
982 2,
983 0),
984 SHELL_CMD_ARG(set_he_ltf_gi,
985 NULL,
986 "0 - Disable\n"
987 "1 - Enable",
988 nrf_wifi_util_set_he_ltf_gi,
989 2,
990 0),
991 #ifdef CONFIG_NRF70_STA_MODE
992 SHELL_CMD_ARG(uapsd_queue,
993 NULL,
994 "<val> - 0 to 15",
995 nrf_wifi_util_set_uapsd_queue,
996 2,
997 0),
998 #endif /* CONFIG_NRF70_STA_MODE */
999 SHELL_CMD_ARG(show_config,
1000 NULL,
1001 "Display the current configuration values",
1002 nrf_wifi_util_show_cfg,
1003 1,
1004 0),
1005 #ifdef CONFIG_NRF70_STA_MODE
1006 SHELL_CMD_ARG(tx_stats,
1007 NULL,
1008 "Displays transmit statistics\n"
1009 "vif_index: 0 - 1\n",
1010 nrf_wifi_util_tx_stats,
1011 2,
1012 0),
1013 #endif /* CONFIG_NRF70_STA_MODE */
1014 SHELL_CMD_ARG(tx_rate,
1015 NULL,
1016 "Sets TX data rate to either a fixed value or AUTO\n"
1017 "Parameters:\n"
1018 " <rate_flag> : The TX data rate type to be set, where:\n"
1019 " 0 - LEGACY\n"
1020 " 1 - HT\n"
1021 " 2 - VHT\n"
1022 " 3 - HE_SU\n"
1023 " 4 - HE_ER_SU\n"
1024 " 5 - AUTO\n"
1025 " <rate_val> : The TX data rate value to be set, valid values are:\n"
1026 " Legacy : <1, 2, 55, 11, 6, 9, 12, 18, 24, 36, 48, 54>\n"
1027 " Non-legacy: <MCS index value between 0 - 7>\n"
1028 " AUTO: <No value needed>\n",
1029 nrf_wifi_util_tx_rate,
1030 2,
1031 1),
1032 #ifdef CONFIG_NRF_WIFI_LOW_POWER
1033 SHELL_CMD_ARG(sleep_state,
1034 NULL,
1035 "Display current sleep status",
1036 nrf_wifi_util_show_host_rpu_ps_ctrl_state,
1037 1,
1038 0),
1039 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
1040 SHELL_CMD_ARG(show_vers,
1041 NULL,
1042 "Display the driver and the firmware versions",
1043 nrf_wifi_util_show_vers,
1044 1,
1045 0),
1046 #if !defined(CONFIG_NRF70_RADIO_TEST) && !defined(CONFIG_NRF70_OFFLOADED_RAW_TX)
1047 SHELL_CMD_ARG(rpu_stats,
1048 NULL,
1049 "Display RPU stats "
1050 "Parameters: umac or lmac or phy or all (default)",
1051 nrf_wifi_util_dump_rpu_stats,
1052 1,
1053 1),
1054 #endif /* !CONFIG_NRF70_RADIO_TEST && !CONFIG_NRF70_OFFLOADED_RAW_TX*/
1055 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
1056 SHELL_CMD_ARG(rpu_recovery_test,
1057 NULL,
1058 "Trigger RPU recovery",
1059 nrf_wifi_util_trigger_rpu_recovery,
1060 1,
1061 0),
1062 SHELL_CMD_ARG(rpu_recovery_info,
1063 NULL,
1064 "Dump RPU recovery information",
1065 nrf_wifi_util_rpu_recovery_info,
1066 1,
1067 0),
1068 #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
1069 SHELL_SUBCMD_SET_END);
1070
1071
1072 SHELL_CMD_REGISTER(wifi_util,
1073 &nrf_wifi_util_subcmds,
1074 "nRF Wi-Fi utility shell commands",
1075 NULL);
1076
1077
nrf_wifi_util_init(void)1078 static int nrf_wifi_util_init(void)
1079 {
1080
1081 if (nrf_wifi_util_conf_init(&ctx->conf_params) < 0) {
1082 return -1;
1083 }
1084
1085 return 0;
1086 }
1087
1088
1089 SYS_INIT(nrf_wifi_util_init,
1090 APPLICATION,
1091 CONFIG_APPLICATION_INIT_PRIORITY);
1092