From 278cb31c1b052cda33370cc2cec5c07f7c06b5f1 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 2 Apr 2024 00:36:41 +0530 Subject: [PATCH 1/5] nrf_wifi: Move interrupt de-registration to de-init Interrupts should be disabled early to avoid further events coming up the driver. Signed-off-by: Chaitanya Tata --- nrf_wifi/bus_if/bus/qspi/src/qspi.c | 48 ++++++++++++----------------- nrf_wifi/bus_if/bus/spi/src/spi.c | 45 +++++++++++---------------- 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/nrf_wifi/bus_if/bus/qspi/src/qspi.c b/nrf_wifi/bus_if/bus/qspi/src/qspi.c index 6999bfaa27..6889d52901 100644 --- a/nrf_wifi/bus_if/bus/qspi/src/qspi.c +++ b/nrf_wifi/bus_if/bus/qspi/src/qspi.c @@ -32,7 +32,6 @@ static int nrf_wifi_bus_qspi_irq_handler(void *data) static void *nrf_wifi_bus_qspi_dev_add(void *bus_priv, void *bal_dev_ctx) { - enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL; struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; struct nrf_wifi_osal_host_map host_map; @@ -76,30 +75,6 @@ static void *nrf_wifi_bus_qspi_dev_add(void *bus_priv, qspi_dev_ctx->addr_pktram_base = qspi_dev_ctx->host_addr_base + qspi_priv->cfg_params.addr_pktram_base; - status = nrf_wifi_osal_bus_qspi_dev_intr_reg(qspi_dev_ctx->qspi_priv->opriv, - qspi_dev_ctx->os_qspi_dev_ctx, - qspi_dev_ctx, - &nrf_wifi_bus_qspi_irq_handler); - - if (status != NRF_WIFI_STATUS_SUCCESS) { - nrf_wifi_osal_log_err(qspi_dev_ctx->qspi_priv->opriv, - "%s: Unable to register interrupt to the OS", - __func__); - - nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, - qspi_dev_ctx->os_qspi_dev_ctx); - - nrf_wifi_osal_bus_qspi_dev_rem(qspi_dev_ctx->qspi_priv->opriv, - qspi_dev_ctx->os_qspi_dev_ctx); - - nrf_wifi_osal_mem_free(qspi_priv->opriv, - qspi_dev_ctx); - - qspi_dev_ctx = NULL; - - goto out; - } - out: return qspi_dev_ctx; } @@ -111,9 +86,6 @@ static void nrf_wifi_bus_qspi_dev_rem(void *bus_dev_ctx) qspi_dev_ctx = bus_dev_ctx; - nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, - qspi_dev_ctx->os_qspi_dev_ctx); - nrf_wifi_osal_bus_qspi_dev_rem(qspi_dev_ctx->qspi_priv->opriv, qspi_dev_ctx->os_qspi_dev_ctx); @@ -129,6 +101,21 @@ static enum nrf_wifi_status nrf_wifi_bus_qspi_dev_init(void *bus_dev_ctx) qspi_dev_ctx = bus_dev_ctx; + + status = nrf_wifi_osal_bus_qspi_dev_intr_reg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + qspi_dev_ctx, + &nrf_wifi_bus_qspi_irq_handler); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(qspi_dev_ctx->qspi_priv->opriv, + "%s: Unable to register interrupt to the OS", + __func__); + qspi_dev_ctx = NULL; + + goto out; + } + status = nrf_wifi_osal_bus_qspi_dev_init(qspi_dev_ctx->qspi_priv->opriv, qspi_dev_ctx->os_qspi_dev_ctx); @@ -136,6 +123,8 @@ static enum nrf_wifi_status nrf_wifi_bus_qspi_dev_init(void *bus_dev_ctx) nrf_wifi_osal_log_err(qspi_dev_ctx->qspi_priv->opriv, "%s: nrf_wifi_osal_qspi_dev_init failed", __func__); + nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); goto out; } out: @@ -149,6 +138,9 @@ static void nrf_wifi_bus_qspi_dev_deinit(void *bus_dev_ctx) qspi_dev_ctx = bus_dev_ctx; + nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + nrf_wifi_osal_bus_qspi_dev_deinit(qspi_dev_ctx->qspi_priv->opriv, qspi_dev_ctx->os_qspi_dev_ctx); } diff --git a/nrf_wifi/bus_if/bus/spi/src/spi.c b/nrf_wifi/bus_if/bus/spi/src/spi.c index bc47c82c81..d2da21eb95 100644 --- a/nrf_wifi/bus_if/bus/spi/src/spi.c +++ b/nrf_wifi/bus_if/bus/spi/src/spi.c @@ -76,30 +76,6 @@ static void *nrf_wifi_bus_spi_dev_add(void *bus_priv, spi_dev_ctx->addr_pktram_base = spi_dev_ctx->host_addr_base + spi_priv->cfg_params.addr_pktram_base; - status = nrf_wifi_osal_bus_spi_dev_intr_reg(spi_dev_ctx->spi_priv->opriv, - spi_dev_ctx->os_spi_dev_ctx, - spi_dev_ctx, - &nrf_wifi_bus_spi_irq_handler); - - if (status != NRF_WIFI_STATUS_SUCCESS) { - nrf_wifi_osal_log_err(spi_dev_ctx->spi_priv->opriv, - "%s: Unable to register interrupt to the OS", - __func__); - - nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, - spi_dev_ctx->os_spi_dev_ctx); - - nrf_wifi_osal_bus_spi_dev_rem(spi_dev_ctx->spi_priv->opriv, - spi_dev_ctx->os_spi_dev_ctx); - - nrf_wifi_osal_mem_free(spi_priv->opriv, - spi_dev_ctx); - - spi_dev_ctx = NULL; - - goto out; - } - out: return spi_dev_ctx; } @@ -111,9 +87,6 @@ static void nrf_wifi_bus_spi_dev_rem(void *bus_dev_ctx) spi_dev_ctx = bus_dev_ctx; - nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, - spi_dev_ctx->os_spi_dev_ctx); - nrf_wifi_osal_mem_free(spi_dev_ctx->spi_priv->opriv, spi_dev_ctx); } @@ -126,6 +99,19 @@ static enum nrf_wifi_status nrf_wifi_bus_spi_dev_init(void *bus_dev_ctx) spi_dev_ctx = bus_dev_ctx; + + status = nrf_wifi_osal_bus_spi_dev_intr_reg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + spi_dev_ctx, + &nrf_wifi_bus_spi_irq_handler); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(spi_dev_ctx->spi_priv->opriv, + "%s: Unable to register interrupt to the OS", + __func__); + goto out; + } + status = nrf_wifi_osal_bus_spi_dev_init(spi_dev_ctx->spi_priv->opriv, spi_dev_ctx->os_spi_dev_ctx); @@ -133,6 +119,8 @@ static enum nrf_wifi_status nrf_wifi_bus_spi_dev_init(void *bus_dev_ctx) nrf_wifi_osal_log_err(spi_dev_ctx->spi_priv->opriv, "%s: nrf_wifi_osal_spi_dev_init failed", __func__); + nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); goto out; } out: @@ -146,6 +134,9 @@ static void nrf_wifi_bus_spi_dev_deinit(void *bus_dev_ctx) spi_dev_ctx = bus_dev_ctx; + nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); + nrf_wifi_osal_bus_spi_dev_deinit(spi_dev_ctx->spi_priv->opriv, spi_dev_ctx->os_spi_dev_ctx); } From 03251d583950b350ca46890a7a00e0e1e7061996 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 2 Apr 2024 00:41:55 +0530 Subject: [PATCH 2/5] nrf_wifi: Pluging the newly added API The HAL status is used internally, but the API was never called, so, hook up the API to dev init/deinit. Signed-off-by: Chaitanya Tata --- nrf_wifi/hw_if/hal/src/hal_api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nrf_wifi/hw_if/hal/src/hal_api.c b/nrf_wifi/hw_if/hal/src/hal_api.c index 9d774de53c..c3f0fd3393 100644 --- a/nrf_wifi/hw_if/hal/src/hal_api.c +++ b/nrf_wifi/hw_if/hal/src/hal_api.c @@ -1388,6 +1388,7 @@ enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ } hal_dev_ctx->rpu_info.tx_cmd_base = RPU_MEM_TX_CMD_BASE; + nrf_wifi_hal_enable(hal_dev_ctx); out: return status; } @@ -1395,6 +1396,7 @@ enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ void nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) { + nrf_wifi_hal_disable(hal_dev_ctx); nrf_wifi_bal_dev_deinit(hal_dev_ctx->bal_dev_ctx); } From 3824ed4b360b456d4dfa8494d8aaa8380a3004e8 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 2 Apr 2024 00:49:10 +0530 Subject: [PATCH 3/5] nrf_wifi: Move draining of event queue to deinit Draining should be done early to avoid any event handlers being called after, also, remove the check for HAL status, as drain doesn't invoke the event handlers, this fixes the memory leak. Signed-off-by: Chaitanya Tata --- nrf_wifi/hw_if/hal/src/hal_api.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/nrf_wifi/hw_if/hal/src/hal_api.c b/nrf_wifi/hw_if/hal/src/hal_api.c index c3f0fd3393..141887a452 100644 --- a/nrf_wifi/hw_if/hal/src/hal_api.c +++ b/nrf_wifi/hw_if/hal/src/hal_api.c @@ -1060,14 +1060,6 @@ void hal_rpu_eventq_drain(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) hal_dev_ctx->lock_rx, &flags); - if (hal_dev_ctx->hal_status != NRF_WIFI_HAL_STATUS_ENABLED) { - /* Ignore the interrupt if the HAL is not enabled */ - nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, - hal_dev_ctx->lock_rx, - &flags); - goto out; - } - event = nrf_wifi_utils_q_dequeue(hal_dev_ctx->hpriv->opriv, hal_dev_ctx->event_q); @@ -1305,8 +1297,6 @@ void nrf_wifi_hal_dev_rem(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) nrf_wifi_osal_tasklet_kill(hal_dev_ctx->hpriv->opriv, hal_dev_ctx->event_tasklet); - hal_rpu_eventq_drain(hal_dev_ctx); - nrf_wifi_osal_tasklet_free(hal_dev_ctx->hpriv->opriv, hal_dev_ctx->event_tasklet); @@ -1398,6 +1388,7 @@ void nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) { nrf_wifi_hal_disable(hal_dev_ctx); nrf_wifi_bal_dev_deinit(hal_dev_ctx->bal_dev_ctx); + hal_rpu_eventq_drain(hal_dev_ctx); } From bdc14843d800c673cc010f6a933cc4fc9efd3e72 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 31 May 2024 01:32:40 +0530 Subject: [PATCH 4/5] nrf_wifi: Fix de-initialization of HAL Use the unused HAL de-init API before proceeding with FMAC de-init, this way we can move the entire logic and locking to HAL de-init, so, remove the HAL locks in FMAC. Signed-off-by: Chaitanya Tata --- nrf_wifi/fw_if/umac_if/src/default/fmac_api.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c index 6f43e07e2f..c8f82e7b1a 100644 --- a/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c +++ b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c @@ -433,11 +433,10 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx *fmac_d void nrf_wifi_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) { - nrf_wifi_hal_lock_rx(fmac_dev_ctx->hal_dev_ctx); + nrf_wifi_hal_dev_deinit(fmac_dev_ctx->hal_dev_ctx); nrf_wifi_fmac_fw_deinit(fmac_dev_ctx); nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, fmac_dev_ctx->tx_pwr_ceil_params); - nrf_wifi_hal_unlock_rx(fmac_dev_ctx->hal_dev_ctx); } #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY From f4ec455e47046af059a3f050015c1b5d5decf781 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 31 May 2024 01:33:06 +0530 Subject: [PATCH 5/5] nrf_wifi: Fix VIF type count update In current SAP implementation based on a single VIF, we modify the VIF type from STA->AP and vice-versa, so, call the API to update the counts properly. The counts are crucial to remove the RPU during interface down. Signed-off-by: Chaitanya Tata --- nrf_wifi/fw_if/umac_if/src/default/fmac_api.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c index c8f82e7b1a..0f32979b61 100644 --- a/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c +++ b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c @@ -2256,6 +2256,10 @@ enum nrf_wifi_status nrf_wifi_fmac_chg_vif(void *dev_ctx, def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + nrf_wifi_fmac_vif_update_if_type(fmac_dev_ctx, + if_idx, + vif_info->iftype); + def_dev_ctx->vif_ctx[if_idx]->if_type = vif_info->iftype; }