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