From 72b69a952e14b254b8a8614f0e22f0522ae724ef Mon Sep 17 00:00:00 2001 From: jiad Date: Thu, 11 Apr 2019 17:23:10 +0800 Subject: [PATCH] qcacld-3.0: Enable STA IPA offload for MDM platforms In STA-SAP config, IPA offload is enabled only when first client is connected to SAP. This is OK for MSM platforms. But for MDM platforms, this is not the case. There's STA tethering cases, where traffic is routed between STA and USB tethering devices while SAP is idle and no wifi clients are connected to SAP. In such case, IPA offload needs to be enabled for STA to promote performance. Fix is to use available MDM_PLATFORM marco and STA only IPA support is decided upon driver build time. Change-Id: If2bc016aa941f2c0651a2669f1169e631208326b CRs-Fixed: 2433608 --- components/ipa/core/src/wlan_ipa_core.c | 107 ++++++++++++++++++++---- 1 file changed, 90 insertions(+), 17 deletions(-) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 5dda91238377..a778385f2361 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -82,6 +82,33 @@ static inline bool wlan_ipa_is_ipv6_enabled(struct wlan_ipa_config *ipa_cfg) return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_IPV6_ENABLE_MASK); } +/** + * wlan_ipa_is_sta_only_offload_enabled() - Is IPA STA only offload enabled + * + * STA only IPA offload is needed on MDM platforms to support + * tethering scenarios in STA-SAP configurations when SAP is idle. + * + * Currently in STA-SAP configurations, IPA pipes are enabled only + * when a wifi client is connected to SAP. + * + * Impact of this API is only limited to when IPA pipes are enabled + * and disabled. To take effect, WLAN_IPA_UC_STA_ENABLE_MASK needs to + * set to 1. + * + * Return: true if MDM_PLATFORM is defined, false otherwise + */ +#ifdef MDM_PLATFORM +static inline bool wlan_ipa_is_sta_only_offload_enabled(void) +{ + return true; +} +#else +static inline bool wlan_ipa_is_sta_only_offload_enabled(void) +{ + return false; +} +#endif + /** * wlan_ipa_msg_free_fn() - Free an IPA message * @buff: pointer to the IPA message @@ -1718,7 +1745,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && - (ipa_ctx->sap_num_connected_sta > 0) && + (ipa_ctx->sap_num_connected_sta > 0 || + wlan_ipa_is_sta_only_offload_enabled()) && !ipa_ctx->sta_connected) { qdf_mutex_release(&ipa_ctx->event_lock); wlan_ipa_uc_offload_enable_disable(ipa_ctx, @@ -1727,6 +1755,24 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, qdf_mutex_acquire(&ipa_ctx->event_lock); } + if (!wlan_ipa_is_sta_only_offload_enabled()) { + ipa_debug("IPA STA only offload not enabled"); + } else if (ipa_ctx->uc_loaded && + !ipa_ctx->sap_num_connected_sta && + !ipa_ctx->sta_connected) { + status = wlan_ipa_uc_handle_first_con(ipa_ctx); + if (status) { + qdf_mutex_release(&ipa_ctx->event_lock); + ipa_info("handle 1st conn failed %d", status); + wlan_ipa_uc_offload_enable_disable( + ipa_ctx, + SIR_STA_RX_DATA_OFFLOAD, + session_id, + false); + goto end; + } + } + ipa_ctx->vdev_to_iface[session_id] = wlan_ipa_get_ifaceid(ipa_ctx, session_id); @@ -1802,8 +1848,15 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED", msg_ex->name); } else { - /* Disable IPA UC TX PIPE when STA disconnected */ - if ((ipa_ctx->num_iface == 1) && + /* + * Disable IPA pipes when + * 1. STA is the last interface or + * 2. STA only offload enabled and no clients connected + * to SAP + */ + if ((ipa_ctx->num_iface == 1 || + (wlan_ipa_is_sta_only_offload_enabled() && + !ipa_ctx->sap_num_connected_sta)) && wlan_ipa_is_fw_wdi_activated(ipa_ctx) && !ipa_ctx->ipa_pipes_down && (ipa_ctx->resource_unloading == false)) { @@ -1822,7 +1875,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && - (ipa_ctx->sap_num_connected_sta > 0)) { + (ipa_ctx->sap_num_connected_sta > 0 || + wlan_ipa_is_sta_only_offload_enabled())) { qdf_mutex_release(&ipa_ctx->event_lock); wlan_ipa_uc_offload_enable_disable(ipa_ctx, SIR_STA_RX_DATA_OFFLOAD, session_id, false); @@ -1918,7 +1972,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, ipa_ctx->uc_loaded == true) { if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && - ipa_ctx->sta_connected) { + ipa_ctx->sta_connected && + !wlan_ipa_is_sta_only_offload_enabled()) { qdf_mutex_release(&ipa_ctx->event_lock); wlan_ipa_uc_offload_enable_disable(ipa_ctx, SIR_STA_RX_DATA_OFFLOAD, @@ -1926,14 +1981,21 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, qdf_mutex_acquire(&ipa_ctx->event_lock); } - status = wlan_ipa_uc_handle_first_con(ipa_ctx); - if (status != QDF_STATUS_SUCCESS) { + /* + * IPA pipes already enabled if STA only offload + * is enabled and STA is connected to remote AP. + */ + if (wlan_ipa_is_sta_only_offload_enabled() && + ipa_ctx->sta_connected) { + ipa_debug("IPA pipes already enabled"); + } else if (wlan_ipa_uc_handle_first_con(ipa_ctx)) { ipa_info("%s: handle 1st con fail", net_dev->name); if (wlan_ipa_uc_sta_is_enabled( ipa_ctx->config) && - ipa_ctx->sta_connected) { + ipa_ctx->sta_connected && + !wlan_ipa_is_sta_only_offload_enabled()) { qdf_mutex_release(&ipa_ctx->event_lock); wlan_ipa_uc_offload_enable_disable( ipa_ctx, @@ -1943,10 +2005,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, qdf_mutex_release(&ipa_ctx->event_lock); } - return status; - } else - ipa_debug("%s: handle 1st con success", - net_dev->name); + return QDF_STATUS_E_BUSY; + } } ipa_ctx->sap_num_connected_sta++; @@ -2016,9 +2076,15 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } ipa_ctx->sap_num_connected_sta--; - /* Disable IPA UC TX PIPE when last STA disconnected */ + /* + * Disable IPA pipes when + * 1. last client disconnected and + * 2. STA is not connected if STA only offload is enabled + */ if (!ipa_ctx->sap_num_connected_sta && - ipa_ctx->uc_loaded == true) { + ipa_ctx->uc_loaded && + !(wlan_ipa_is_sta_only_offload_enabled() && + ipa_ctx->sta_connected)) { if ((false == ipa_ctx->resource_unloading) && wlan_ipa_is_fw_wdi_activated(ipa_ctx) && !ipa_ctx->ipa_pipes_down) { @@ -2036,7 +2102,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && - ipa_ctx->sta_connected) { + ipa_ctx->sta_connected && + !wlan_ipa_is_sta_only_offload_enabled()) { qdf_mutex_release(&ipa_ctx->event_lock); wlan_ipa_uc_offload_enable_disable(ipa_ctx, SIR_STA_RX_DATA_OFFLOAD, @@ -2797,8 +2864,14 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx) cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev); - /* If already any STA connected, enable IPA/FW PIPEs */ - if (ipa_ctx->sap_num_connected_sta) { + /* + * Enable IPA/FW PIPEs if + * 1. any clients connected to SAP or + * 2. STA connected to remote AP if STA only offload is enabled + */ + if (ipa_ctx->sap_num_connected_sta || + (wlan_ipa_is_sta_only_offload_enabled() && + ipa_ctx->sta_connected)) { ipa_debug("Client already connected, enable IPA/FW PIPEs"); wlan_ipa_uc_handle_first_con(ipa_ctx); }