From 71121713be8b464adee395bd9b3104dc40a09fa4 Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Sat, 15 Apr 2017 00:34:42 +0530 Subject: [PATCH] qcacld-3.0: At interface down disconnect IPA WDI pipes Currently IPA WDI TX and RX pipes are set up when the interface is up but during interface down there is no disconnect of the IPA WDI pipes. So again when interface up after interface down IPA driver returns error that endpoints are already have allocated. As a result the TX and RX WDI pipe handle values will be zero which is invalid. In this change disconnect WDI pipes at interface down instead of during wlan exit or ssr deinit. Change-Id: I1fb7520467f1b5a6c43bab3b16b002fa0f534d75 CRs-fixed: 2033329 --- core/hdd/inc/wlan_hdd_ipa.h | 11 +++++++++ core/hdd/src/wlan_hdd_ipa.c | 48 +++++++++++++++++++++--------------- core/hdd/src/wlan_hdd_main.c | 5 ++++ 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_ipa.h b/core/hdd/inc/wlan_hdd_ipa.h index 506669d0233d..929810b18fe0 100644 --- a/core/hdd/inc/wlan_hdd_ipa.h +++ b/core/hdd/inc/wlan_hdd_ipa.h @@ -122,6 +122,7 @@ bool hdd_ipa_is_present(hdd_context_t *hdd_ctx); void hdd_ipa_dump_info(hdd_context_t *hdd_ctx); QDF_STATUS hdd_ipa_uc_ol_init(hdd_context_t *hdd_ctx); void hdd_ipa_set_tx_flow_info(void); +int hdd_ipa_uc_ol_deinit(hdd_context_t *hdd_ctx); #else static inline QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) { @@ -262,5 +263,15 @@ static inline void hdd_ipa_set_tx_flow_info(void) return; } +/** + * hdd_ipa_uc_ol_deinit() - Disconnect IPA TX and RX pipes + * @hdd_ctx: Global HDD context + * + * Return: 0 on success, negativer errno on error + */ +static int hdd_ipa_uc_ol_deinit(hdd_context_t *hdd_ctx) +{ + return 0; +} #endif /* IPA_OFFLOAD */ #endif /* #ifndef HDD_IPA_H__ */ diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index d1b911e9afc6..a2f59d567aca 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -3123,6 +3123,34 @@ fail_return: return stat; } +/** + * hdd_ipa_uc_ol_deinit() - Disconnect IPA TX and RX pipes + * @hdd_ctx: Global HDD context + * + * Return: 0 on success, negativer errno on error + */ +int hdd_ipa_uc_ol_deinit(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + int ret = 0; + + if (!hdd_ipa_uc_is_enabled(hdd_ctx)) + return ret; + + if (true == hdd_ipa->uc_loaded) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, + "%s: Disconnect TX PIPE tx_pipe_handle=0x%x", + __func__, hdd_ipa->tx_pipe_handle); + ret = ipa_disconnect_wdi_pipe(hdd_ipa->tx_pipe_handle); + HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, + "%s: Disconnect RX PIPE rx_pipe_handle=0x%x", + __func__, hdd_ipa->rx_pipe_handle); + ret = ipa_disconnect_wdi_pipe(hdd_ipa->rx_pipe_handle); + } + + return ret; +} + /** * __hdd_ipa_uc_force_pipe_shutdown() - Force shutdown IPA pipe * @hdd_ctx: hdd main context @@ -3386,16 +3414,6 @@ static int __hdd_ipa_uc_ssr_deinit(void) } qdf_mutex_release(&hdd_ipa->ipa_lock); - HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, - "%s: Disconnect TX PIPE tx_pipe_handle=0x%x", - __func__, hdd_ipa->tx_pipe_handle); - ipa_disconnect_wdi_pipe(hdd_ipa->tx_pipe_handle); - - HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, - "%s: Disconnect RX PIPE rx_pipe_handle=0x%x", - __func__, hdd_ipa->rx_pipe_handle); - ipa_disconnect_wdi_pipe(hdd_ipa->rx_pipe_handle); - if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx)) hdd_ipa_uc_sta_reset_sta_connected(hdd_ipa); @@ -6257,16 +6275,6 @@ static QDF_STATUS __hdd_ipa_cleanup(hdd_context_t *hdd_ctx) HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "UC Ready CB deregister fail"); hdd_ipa_uc_rt_debug_deinit(hdd_ctx); - if (true == hdd_ipa->uc_loaded) { - HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, - "%s: Disconnect TX PIPE tx_pipe_handle=0x%x", - __func__, hdd_ipa->tx_pipe_handle); - ipa_disconnect_wdi_pipe(hdd_ipa->tx_pipe_handle); - HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, - "%s: Disconnect RX PIPE rx_pipe_handle=0x%x", - __func__, hdd_ipa->rx_pipe_handle); - ipa_disconnect_wdi_pipe(hdd_ipa->rx_pipe_handle); - } qdf_mutex_destroy(&hdd_ipa->event_lock); qdf_mutex_destroy(&hdd_ipa->ipa_lock); hdd_ipa_cleanup_pending_event(hdd_ipa); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 8ecbeba15d2a..9156ecb983ab 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -9050,6 +9050,11 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx) ret = -EINVAL; } + if (hdd_ipa_uc_ol_deinit(hdd_ctx)) { + hdd_err("Failed to disconnect pipes"); + ret = -EINVAL; + } + EXIT(); return ret; }