Browse Source

qcacld-3.0: Prevent runtime suspend during disconnect

In MLO cases, system enters into runtime suspend in
between the disconnect processing of two links. This
leads to delay/timeouts in MLO disconnect processing.

To fix this, acquire runtime lock between disconnect
start and disconnect complete if_manager events.

Keep the runtime lock at vdev level to handle async
disconnects triggered by the driver and link-only
disconnects during roaming.

CRs-Fixed: 3588246
Change-Id: Ida48127d8597aecd8b6f5347c70ba5e9a2045d11
Surya Prakash Sivaraj 1 year ago
parent
commit
f3969f6436

+ 13 - 1
components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c

@@ -198,6 +198,7 @@ QDF_STATUS if_mgr_disconnect_start(struct wlan_objmgr_vdev *vdev,
 {
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_pdev *pdev;
+	struct mlme_legacy_priv *mlme_priv;
 
 	pdev = wlan_vdev_get_pdev(vdev);
 	if (!pdev)
@@ -207,7 +208,11 @@ QDF_STATUS if_mgr_disconnect_start(struct wlan_objmgr_vdev *vdev,
 	if (!psoc)
 		return QDF_STATUS_E_FAILURE;
 
-	/* Leaving as stub to fill in later */
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_runtime_pm_prevent_suspend(&mlme_priv->disconnect_runtime_lock);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -217,6 +222,7 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev,
 {
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_pdev *pdev;
+	struct mlme_legacy_priv *mlme_priv;
 	QDF_STATUS status;
 
 	pdev = wlan_vdev_get_pdev(vdev);
@@ -227,6 +233,12 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev,
 	if (!psoc)
 		return QDF_STATUS_E_FAILURE;
 
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return QDF_STATUS_E_FAILURE;
+
+	qdf_runtime_pm_allow_suspend(&mlme_priv->disconnect_runtime_lock);
+
 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
 	    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE)
 		wlan_handle_emlsr_sta_concurrency(psoc, false, true);

+ 2 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -774,6 +774,7 @@ struct enhance_roam_info {
  * @bss_color_change_wakelock: wakelock to complete bss color change
  *				operation on bss color collision detection
  * @bss_color_change_runtime_lock: runtime lock to complete bss color change
+ * @disconnect_runtime_lock: runtime lock to complete disconnection
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
@@ -844,6 +845,7 @@ struct mlme_legacy_priv {
 #endif
 	qdf_wake_lock_t bss_color_change_wakelock;
 	qdf_runtime_lock_t bss_color_change_runtime_lock;
+	qdf_runtime_lock_t disconnect_runtime_lock;
 };
 
 /**

+ 4 - 0
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -1561,6 +1561,8 @@ static void mlme_ext_handler_destroy(struct vdev_mlme_obj *vdev_mlme)
 		&vdev_mlme->ext_vdev_ptr->bss_color_change_runtime_lock);
 	qdf_wake_lock_destroy(
 		&vdev_mlme->ext_vdev_ptr->bss_color_change_wakelock);
+	qdf_runtime_lock_deinit(
+		&vdev_mlme->ext_vdev_ptr->disconnect_runtime_lock);
 	mlme_free_self_disconnect_ies(vdev_mlme->vdev);
 	mlme_free_peer_disconnect_ies(vdev_mlme->vdev);
 	mlme_free_sae_auth_retry(vdev_mlme->vdev);
@@ -1600,6 +1602,8 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme)
 			"bss_color_change_wakelock");
 	qdf_runtime_lock_init(
 		&vdev_mlme->ext_vdev_ptr->bss_color_change_runtime_lock);
+	qdf_runtime_lock_init(
+		&vdev_mlme->ext_vdev_ptr->disconnect_runtime_lock);
 
 	sme_get_vdev_type_nss(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev),
 			      &vdev_mlme->proto.generic.nss_2g,