Переглянути джерело

qcacld-3.0: Drop packets if suspend in progress

Currently, there is a race condition where packet gets
enqueued when WOW handshake is being done in parallel during
bus suspend resulting in assert in FW as Tx is aborted when
WOW command is received in FW.
To fix this, suspend DP tx path before suspend sequence starts
which will drop tx packets.

Change-Id: I38a6a6bdf9858f627205f75f75f351f7debbb7f7
CRs-Fixed: 3227752
Ananya Gupta 2 роки тому
батько
коміт
d50b45174e

+ 1 - 1
components/dp/core/inc/wlan_dp_priv.h

@@ -386,7 +386,7 @@ struct wlan_dp_psoc_context {
 	uint64_t no_rx_offload_pkt_cnt;
 	uint64_t no_tx_offload_pkt_cnt;
 
-	bool wlan_suspended;
+	bool is_suspend;
 	/* Flag keeps track of wiphy suspend/resume */
 	bool is_wiphy_suspended;
 

+ 1 - 1
components/dp/core/src/wlan_dp_bus_bandwidth.c

@@ -1726,7 +1726,7 @@ static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
 	if (wlan_dp_validate_context(dp_ctx))
 		goto stop_work;
 
-	if (dp_ctx->is_wiphy_suspended)
+	if (dp_ctx->is_suspend)
 		return;
 
 	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;

+ 1 - 1
components/dp/core/src/wlan_dp_nud_tracking.c

@@ -380,7 +380,7 @@ static void dp_nud_filter_netevent(struct qdf_mac_addr *netdev_addr,
 				  gw_mac_addr))
 		return;
 
-	if (dp_ctx->wlan_suspended) {
+	if (dp_ctx->is_wiphy_suspended) {
 		dp_info("wlan is suspended, ignore NUD event");
 		return;
 	}

+ 1 - 1
components/dp/core/src/wlan_dp_txrx.c

@@ -565,7 +565,7 @@ dp_start_xmit(struct wlan_dp_intf *dp_intf, qdf_nbuf_t nbuf)
 		goto drop_pkt;
 	}
 
-	if (qdf_unlikely(dp_ctx->wlan_suspended)) {
+	if (qdf_unlikely(dp_ctx->is_suspend)) {
 		dp_err_rl("Device is system suspended, drop pkt");
 		goto drop_pkt;
 	}

+ 12 - 14
components/dp/dispatcher/src/wlan_dp_ucfg_api.c

@@ -321,6 +321,7 @@ static QDF_STATUS
 ucfg_dp_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 {
 	struct wlan_dp_psoc_context *dp_ctx;
+	struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL;
 
 	dp_ctx = dp_psoc_get_priv(psoc);
 	if (!dp_ctx) {
@@ -328,7 +329,10 @@ ucfg_dp_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	dp_ctx->is_wiphy_suspended = true;
+	dp_ctx->is_suspend = true;
+	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
+		dp_intf->sap_tx_block_mask |= WLAN_DP_SUSPEND;
+	}
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -345,6 +349,7 @@ static QDF_STATUS
 ucfg_dp_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 {
 	struct wlan_dp_psoc_context *dp_ctx;
+	struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL;
 
 	dp_ctx = dp_psoc_get_priv(psoc);
 	if (!dp_ctx) {
@@ -352,7 +357,10 @@ ucfg_dp_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	dp_ctx->is_wiphy_suspended = false;
+	dp_ctx->is_suspend = false;
+	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
+		dp_intf->sap_tx_block_mask &= ~WLAN_DP_SUSPEND;
+	}
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -451,7 +459,6 @@ QDF_STATUS ucfg_dp_psoc_close(struct wlan_objmgr_psoc *psoc)
 void ucfg_dp_suspend_wlan(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx;
-	struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL;
 
 	dp_ctx = dp_psoc_get_priv(psoc);
 	if (!dp_ctx) {
@@ -459,17 +466,12 @@ void ucfg_dp_suspend_wlan(struct wlan_objmgr_psoc *psoc)
 		return;
 	}
 
-	dp_ctx->wlan_suspended = true;
-
-	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
-		dp_intf->sap_tx_block_mask |= WLAN_DP_SUSPEND;
-	}
+	dp_ctx->is_wiphy_suspended = true;
 }
 
 void ucfg_dp_resume_wlan(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_dp_psoc_context *dp_ctx;
-	struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL;
 
 	dp_ctx = dp_psoc_get_priv(psoc);
 	if (!dp_ctx) {
@@ -477,11 +479,7 @@ void ucfg_dp_resume_wlan(struct wlan_objmgr_psoc *psoc)
 		return;
 	}
 
-	dp_ctx->wlan_suspended = false;
-
-	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
-		dp_intf->sap_tx_block_mask &= ~WLAN_DP_SUSPEND;
-	}
+	dp_ctx->is_wiphy_suspended = false;
 }
 
 void ucfg_dp_wait_complete_tasks(void)