From 9423436d12b1cf02a6b1902bb817a78f25e09758 Mon Sep 17 00:00:00 2001 From: Ananya Gupta Date: Fri, 11 Sep 2020 18:24:37 +0530 Subject: [PATCH] qcacld-3.0: Disable IPA when 2nd SAP is turned on When 2nd SAP is turned on throughput is dropping as rps is not getting enabled on wifi bridge interface. A bridge interface is a virtual interface created, when 2 SAP are turned on else, there is no bridge interface. To fix this, Disable IPA when 2nd SAP is turned on, so that packets are not re-routed through IPA which is reducing throughput. Change-Id: I250056338cec0924e97ff79d2d9e6ac513f50d66 CRs-Fixed: 2769539 --- components/ipa/core/inc/wlan_ipa_priv.h | 1 + components/ipa/core/src/wlan_ipa_core.c | 82 ++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index 51729c479faf..586a81f2b87c 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/components/ipa/core/inc/wlan_ipa_priv.h @@ -640,6 +640,7 @@ struct wlan_ipa_priv { uint32_t curr_cons_bw; uint8_t activated_fw_pipe; + uint8_t num_sap_connected; uint8_t sap_num_connected_sta; uint8_t sta_connected; uint32_t tx_pipe_handle; diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 2ba22fc392d4..cbabe741675f 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -1409,6 +1409,9 @@ static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context) iface_context->dev->name, wlan_ipa_is_ipv6_enabled(ipa_ctx->config)); + if (iface_context->device_mode == QDF_SAP_MODE) + ipa_ctx->num_sap_connected--; + qdf_spin_lock_bh(&iface_context->interface_lock); iface_context->dev = NULL; iface_context->device_mode = QDF_MAX_NO_OF_MODE; @@ -1571,6 +1574,9 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->num_iface++; + if (device_mode == QDF_SAP_MODE) + ipa_ctx->num_sap_connected++; + ipa_debug("exit: num_iface=%d", ipa_ctx->num_iface); return status; @@ -1594,6 +1600,11 @@ static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx) { ipa_debug("enter"); + if (ipa_ctx->num_sap_connected > 1) { + ipa_debug("Multiple SAP connected. Not enabling pipes. Exit"); + return QDF_STATUS_E_PERM; + } + if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) { ipa_err("IPA WDI Pipe activation failed"); return QDF_STATUS_E_BUSY; @@ -1900,6 +1911,59 @@ static QDF_STATUS wlan_ipa_send_msg(qdf_netdev_t net_dev, return QDF_STATUS_SUCCESS; } +/** + * wlan_ipa_handle_multiple_sap_evt() - Handle multiple SAP connect/disconnect + * @ipa_ctx: IPA global context + * @type: IPA event type. + * + * This function is used to disable pipes when multiple SAP are connected and + * enable pipes back when only one SAP is connected. + * + * Return: None + */ +static inline +void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx, + qdf_ipa_wlan_event type) +{ + struct wlan_ipa_iface_context *iface_ctx; + int i; + + if (type == QDF_IPA_AP_DISCONNECT) { + ipa_debug("Multiple SAP disconnecting. Enabling IPA"); + + if (ipa_ctx->sap_num_connected_sta > 0) + wlan_ipa_uc_handle_first_con(ipa_ctx); + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + + if (iface_ctx->device_mode == QDF_SAP_MODE) { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + iface_ctx->session_id, + true); + break; + } + } + } else if (type == QDF_IPA_AP_CONNECT) { + ipa_debug("Multiple SAP connected. Disabling IPA"); + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + + if (iface_ctx->device_mode == QDF_SAP_MODE) { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + iface_ctx->session_id, + false); + } + } + + if (!ipa_ctx->ipa_pipes_down) + wlan_ipa_uc_disable_pipes(ipa_ctx, true); + } +} + /** * __wlan_ipa_wlan_evt() - IPA event handler * @net_dev: Interface net device @@ -2048,6 +2112,11 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, break; } } + + if (ipa_ctx->num_sap_connected == 1) { + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, + type); + } } return QDF_STATUS_SUCCESS; @@ -2162,8 +2231,13 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { qdf_mutex_release(&ipa_ctx->event_lock); - wlan_ipa_uc_offload_enable_disable(ipa_ctx, - SIR_AP_RX_DATA_OFFLOAD, session_id, true); + if (ipa_ctx->num_sap_connected == 1) { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + session_id, true); + } else { + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); + } qdf_mutex_acquire(&ipa_ctx->event_lock); } @@ -2300,6 +2374,9 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } } + if (ipa_ctx->num_sap_connected == 1) + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); + qdf_mutex_release(&ipa_ctx->event_lock); break; @@ -3080,6 +3157,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->ipa_p_rx_packets = 0; ipa_ctx->resource_loading = false; ipa_ctx->resource_unloading = false; + ipa_ctx->num_sap_connected = 0; ipa_ctx->sta_connected = 0; ipa_ctx->ipa_pipes_down = true; qdf_atomic_set(&ipa_ctx->pipes_disabled, 1);