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); }