summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c89
1 files changed, 78 insertions, 11 deletions
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 03da26eebc20..e0196dd83ef5 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -805,6 +805,34 @@ static inline bool hdd_ipa_uc_sta_is_enabled(hdd_context_t *hdd_ctx)
return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_UC_STA_ENABLE_MASK);
}
+
+/**
+ * hdd_ipa_uc_sta_only_offload_is_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, HDD_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 hdd_ipa_uc_sta_only_offload_is_enabled(void)
+{
+ return true;
+}
+#else
+static inline bool hdd_ipa_uc_sta_only_offload_is_enabled(void)
+{
+ return false;
+}
+#endif
+
/**
* hdd_ipa_uc_sta_reset_sta_connected() - Reset sta_connected flag
* @hdd_ipa: Global HDD IPA context
@@ -6749,7 +6777,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
struct ipa_msg_meta meta;
struct ipa_wlan_msg *msg;
struct ipa_wlan_msg_ex *msg_ex = NULL;
- int ret;
+ int ret = 0;
if (hdd_validate_adapter(adapter)) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%pK",
@@ -6874,7 +6902,8 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
}
if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) &&
- (hdd_ipa->sap_num_connected_sta > 0) &&
+ (hdd_ipa->sap_num_connected_sta > 0 ||
+ hdd_ipa_uc_sta_only_offload_is_enabled()) &&
!hdd_ipa->sta_connected) {
qdf_mutex_release(&hdd_ipa->event_lock);
hdd_ipa_uc_offload_enable_disable(adapter,
@@ -6882,6 +6911,22 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
qdf_mutex_acquire(&hdd_ipa->event_lock);
}
+ if (!hdd_ipa_uc_sta_only_offload_is_enabled()) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
+ "IPA uC STA only offload not enabled");
+ } else if (!hdd_ipa->sap_num_connected_sta &&
+ !hdd_ipa->sta_connected) {
+ ret = hdd_ipa_uc_handle_first_con(hdd_ipa);
+ if (ret) {
+ qdf_mutex_release(&hdd_ipa->event_lock);
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "handle 1st conn ret %d", ret);
+ hdd_ipa_uc_offload_enable_disable(adapter,
+ SIR_STA_RX_DATA_OFFLOAD, false);
+ goto end;
+ }
+ }
+
hdd_ipa->vdev_to_iface[adapter->sessionId] =
((struct hdd_ipa_iface_context *)
(adapter->ipa_context))->iface_id;
@@ -6946,15 +6991,23 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
hdd_debug("%s: IPA UC OFFLOAD NOT ENABLED",
msg_ex->name);
} else {
- /* Disable IPA UC TX PIPE when STA disconnected */
- if ((1 == hdd_ipa->num_iface) &&
+ /*
+ * Disable IPA UC TX PIPE when
+ * 1. STA is the last interface, Or
+ * 2. STA only offload enabled and no clients connected
+ * to SAP
+ */
+ if (((1 == hdd_ipa->num_iface) ||
+ (hdd_ipa_uc_sta_only_offload_is_enabled() &&
+ !hdd_ipa->sap_num_connected_sta)) &&
hdd_ipa_is_fw_wdi_actived(hdd_ipa->hdd_ctx) &&
!hdd_ipa->ipa_pipes_down)
hdd_ipa_uc_handle_last_discon(hdd_ipa);
}
if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) &&
- (hdd_ipa->sap_num_connected_sta > 0)) {
+ (hdd_ipa->sap_num_connected_sta > 0 ||
+ hdd_ipa_uc_sta_only_offload_is_enabled())) {
qdf_mutex_release(&hdd_ipa->event_lock);
hdd_ipa_uc_offload_enable_disable(adapter,
SIR_STA_RX_DATA_OFFLOAD, false);
@@ -7042,7 +7095,8 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (hdd_ipa->sap_num_connected_sta == 0 &&
hdd_ipa->uc_loaded == true) {
if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) &&
- hdd_ipa->sta_connected) {
+ hdd_ipa->sta_connected &&
+ !hdd_ipa_uc_sta_only_offload_is_enabled()) {
qdf_mutex_release(&hdd_ipa->event_lock);
hdd_ipa_uc_offload_enable_disable(
hdd_get_adapter(hdd_ipa->hdd_ctx,
@@ -7051,8 +7105,15 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
qdf_mutex_acquire(&hdd_ipa->event_lock);
}
- ret = hdd_ipa_uc_handle_first_con(hdd_ipa);
- if (ret) {
+ /*
+ * IPA pipes already enabled if STA only offload
+ * is enabled and STA is connected.
+ */
+ if (hdd_ipa_uc_sta_only_offload_is_enabled() &&
+ hdd_ipa->sta_connected) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
+ "IPA pipes already enabled");
+ } else if (hdd_ipa_uc_handle_first_con(hdd_ipa)) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: handle 1st con ret %d",
adapter->dev->name, ret);
@@ -7070,7 +7131,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
qdf_mutex_release(&hdd_ipa->event_lock);
}
- return ret;
+ return -EPERM;
}
}
@@ -7139,9 +7200,15 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
}
hdd_ipa->sap_num_connected_sta--;
- /* Disable IPA UC TX PIPE when last STA disconnected */
+ /*
+ * Disable IPA UC TX PIPE when
+ * 1. last client disconnected SAP and
+ * 2. STA is not connected
+ */
if (!hdd_ipa->sap_num_connected_sta &&
- hdd_ipa->uc_loaded == true) {
+ (hdd_ipa->uc_loaded == true) &&
+ !(hdd_ipa_uc_sta_only_offload_is_enabled() &&
+ hdd_ipa->sta_connected)) {
if ((false == hdd_ipa->resource_unloading) &&
hdd_ipa_is_fw_wdi_actived(hdd_ipa->hdd_ctx) &&
!hdd_ipa->ipa_pipes_down) {