Browse Source

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
Ananya Gupta 4 years ago
parent
commit
9423436d12
2 changed files with 81 additions and 2 deletions
  1. 1 0
      components/ipa/core/inc/wlan_ipa_priv.h
  2. 80 2
      components/ipa/core/src/wlan_ipa_core.c

+ 1 - 0
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;

+ 80 - 2
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);