diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index 18e478456a1..cbd75ce5af6 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -182,6 +182,18 @@ config NRF70_SR_COEX_RF_SWITCH If this GPIO is asserted (1), the SR side RF switch is connected to the Wi-Fi side (shared antenna). If this GPIO is de-asserted (0), the SR side RF switch is connected to the SR side (separate antenna). +config NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL + bool "Configuration of GPIO control for coexistence" + default y + +config NRF70_SR_COEX_SWCTRL1_OUTPUT + int "Configure SWCTRIL1 as output" + default 0 + +config NRF70_SR_COEX_BT_GRANT_ACTIVE_LOW + int "Configure BT grant active low" + default 1 + config NRF70_WORKQ_STACK_SIZE int "Stack size for workqueue" default 4096 @@ -842,4 +854,17 @@ config NRF_WIFI_ZERO_COPY_TX endif # NETWORKING +config NRF_WIFI_MAX_PS_POLL_FAIL_CNT + int "Maximum number of PS-Poll failures" + default 10 + range 10 4294967295 + help + Maximum number of PS-Poll failures before entering qos null-based power save. + +config NRF_WIFI_RX_STBC_HT + bool "Receive packets encoded with STBC in HT (Wi-Fi4) mode" + default y + help + Receive packets encoded with STBC (Space-Time Block Coding) + in HT (Wi-Fi4) mode. endif # WIFI_NRF70 diff --git a/drivers/wifi/nrf_wifi/src/coex.c b/drivers/wifi/nrf_wifi/src/coex.c index 8177fb6f85b..a9147aad5dc 100644 --- a/drivers/wifi/nrf_wifi/src/coex.c +++ b/drivers/wifi/nrf_wifi/src/coex.c @@ -103,7 +103,7 @@ const uint16_t config_buffer_5G[] = { /* Shared antenna */ const uint32_t ch_config_sha[] = { 0x00000028, 0x00000000, 0x001e1023, 0x00000000, 0x00000000, - 0x00000000, 0x00000021, 0x000002ca, 0x00000050, 0x00000000, + 0x00000000, 0x00000021, 0x000002ca, 0x0000005A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index 5a7d79141bc..cc3a40c81ab 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -581,6 +581,13 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv unsigned int fw_ver = 0; +#if defined(CONFIG_NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL) && \ + defined(CONFIG_NRF70_SYSTEM_MODE) + unsigned int alt_swctrl1_function_bt_coex_status1 = + (~CONFIG_NRF70_SR_COEX_SWCTRL1_OUTPUT) & 0x1; + unsigned int invert_bt_coex_grant_output = CONFIG_NRF70_SR_COEX_BT_GRANT_ACTIVE_LOW; +#endif /* CONFIG_NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL && CONFIG_NRF70_SYSTEM_MODE */ + rpu_ctx_zep = &drv_priv_zep->rpu_ctx_zep; rpu_ctx_zep->drv_priv_zep = drv_priv_zep; @@ -624,6 +631,18 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv configure_board_dep_params(&board_params); +#if defined(CONFIG_NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL) && \ + defined(CONFIG_NRF70_SYSTEM_MODE) + LOG_INF("Configuring SLEEP CTRL GPIO control register\n"); + status = nrf_wifi_coex_config_sleep_ctrl_gpio_ctrl(rpu_ctx_zep->rpu_ctx, + alt_swctrl1_function_bt_coex_status1, + invert_bt_coex_grant_output); + if (status != NRF_WIFI_STATUS_SUCCESS) { + LOG_ERR("%s: Failed to configure GPIO control register", __func__); + goto err; + } +#endif /* CONFIG_NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL && CONFIG_NRF70_SYSTEM_MODE */ + #ifdef CONFIG_NRF70_RADIO_TEST status = nrf_wifi_rt_fmac_dev_init(rpu_ctx_zep->rpu_ctx, #ifdef CONFIG_NRF_WIFI_LOW_POWER diff --git a/drivers/wifi/nrf_wifi/src/wifi_util.c b/drivers/wifi/nrf_wifi/src/wifi_util.c index ec1dccb2a72..4a31cae8121 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_util.c +++ b/drivers/wifi/nrf_wifi/src/wifi_util.c @@ -14,6 +14,9 @@ #include "fmac_main.h" #include "wifi_util.h" +#include "rpu_lmac_phy_stats.h" +#include "rpu_umac_stats.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; @@ -963,6 +966,129 @@ static int nrf_wifi_util_rpu_recovery_info(const struct shell *sh, } #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ +static int nrf_wifi_dump_stats(const struct shell *sh, + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + const char *name, + struct rpu_stat_global *rpu_stat_g) +{ + int i; + int j; + int ret = 0; + + for (i = 0; rpu_stat_g[i].stats != NULL; i++) { + struct rpu_stat_from_mem *rpu_stat = rpu_stat_g[i].stats; + + shell_fprintf(sh, SHELL_INFO, "RPU %s - %s\n", name, rpu_stat_g[i].name); + shell_fprintf(sh, SHELL_INFO, "======================\n"); + + for (j = 0; rpu_stat[j].name[0] != '\0'; j++) { + uint32_t value = 0; + + if (hal_rpu_mem_read(hal_dev_ctx, &value, + rpu_stat[j].addr, sizeof(value)) != 0) { + shell_fprintf(sh, SHELL_ERROR, + "Failed to read stat %s\n", + rpu_stat[j].name); + continue; + } + + shell_fprintf(sh, SHELL_INFO, "%s: %u\n", + rpu_stat[j].name, + value); + } + + shell_fprintf(sh, SHELL_INFO, "\n"); + } + + return ret; +} + +static int nrf_wifi_util_dump_rpu_stats_mem(const struct shell *sh, + size_t argc, + const char *argv[]) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx; + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx; + struct rpu_sys_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, "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; + if (!fmac_dev_ctx) { + shell_fprintf(sh, + SHELL_ERROR, + "RPU context not initialized\n"); + ret = -ENOEXEC; + goto unlock; + } + hal_dev_ctx = fmac_dev_ctx->hal_dev_ctx; + if (!hal_dev_ctx) { + shell_fprintf(sh, + SHELL_ERROR, + "HAL context not initialized\n"); + ret = -ENOEXEC; + goto unlock; + } + + + memset(&stats, 0, sizeof(struct rpu_sys_op_stats)); + + if (stats_type == RPU_STATS_TYPE_UMAC || stats_type == RPU_STATS_TYPE_ALL) { + nrf_wifi_hal_proc_ctx_set(hal_dev_ctx, RPU_PROC_TYPE_MCU_UMAC); + ret = nrf_wifi_dump_stats(sh, hal_dev_ctx, "UMAC", rpu_all_umac_stats); + if (ret != 0) { + shell_fprintf(sh, + SHELL_ERROR, + "Failed to dump UMAC stats\n"); + goto unlock; + } + } + + if (stats_type == RPU_STATS_TYPE_LMAC || stats_type == RPU_STATS_TYPE_ALL) { + nrf_wifi_hal_proc_ctx_set(hal_dev_ctx, RPU_PROC_TYPE_MCU_LMAC); + ret = nrf_wifi_dump_stats(sh, hal_dev_ctx, "LMAC", rpu_all_lmac_stats); + if (ret != 0) { + shell_fprintf(sh, + SHELL_ERROR, + "Failed to dump LMAC stats\n"); + goto unlock; + } + } + + /* Reset the proc context to default */ + nrf_wifi_hal_proc_ctx_set(hal_dev_ctx, RPU_PROC_TYPE_MCU_LMAC); + +unlock: + k_mutex_unlock(&ctx->rpu_lock); + return ret; +} + SHELL_STATIC_SUBCMD_SET_CREATE( nrf70_util, SHELL_CMD_ARG(he_ltf, @@ -1066,6 +1192,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE( 1, 0), #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ + SHELL_CMD_ARG(rpu_stats_mem, + NULL, + "Display RPU stats by reading from memory " + "Parameters: umac or lmac or or all (default)", + nrf_wifi_util_dump_rpu_stats_mem, + 1, + 1), SHELL_SUBCMD_SET_END); diff --git a/west.yml b/west.yml index d4bbd738e6a..b20f0460722 100644 --- a/west.yml +++ b/west.yml @@ -318,7 +318,7 @@ manifest: revision: b84bd7314a239f818e78f6927f5673247816df53 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: f8dbe23c2af8eb06b7a4bd9aa928e93d032a8578 + revision: 8fd3cd7b088d62f145b8b9f5ecc985dd73bd9e77 path: modules/lib/nrf_wifi - name: open-amp revision: 52bb1783521c62c019451cee9b05b8eda9d7425f