Parcourir la source

qcacmn: Restart vdev mgmt rsp timer if UMAC reset is in progress

It is possible that the host queued the peer delete command to FW
but no peer delete event was received within the peer delete
timeout as FW initiated a UMAC reset.

When the vdev mgmt response timer times out, check if umac reset is in
progress. If so, restart the vdev mgmt response timer.
The entire umac reset handshake completes within 200ms if not
FW asserts. Hence no need to add the count check before
restarting the vdev mgmt response timer.

Change-Id: Ief3351b940658a870e303d191a3873bd60499023
CRs-Fixed: 3475168
Shashikala Prabhu il y a 2 ans
Parent
commit
8b6fd27e6e
1 fichiers modifiés avec 51 ajouts et 0 suppressions
  1. 51 0
      target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c

+ 51 - 0
target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c

@@ -37,6 +37,9 @@
 #include <target_if_cm_roam_offload.h>
 #endif
 #include <wlan_reg_services_api.h>
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+#include <cdp_txrx_ctrl.h>
+#endif
 
 static inline
 void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc,
@@ -69,6 +72,43 @@ target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
 }
 #endif
 
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+/**
+ * target_if_check_and_restart_vdev_mgr_rsp_timer - Check and restart the vdev
+ * manager response timer if UMAC reset is in progress
+ * @vdev_rsp: Pointer to vdev response timer structure
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+target_if_check_and_restart_vdev_mgr_rsp_timer(
+		struct vdev_response_timer *vdev_rsp)
+{
+	ol_txrx_soc_handle soc_txrx_handle;
+
+	soc_txrx_handle = wlan_psoc_get_dp_handle(vdev_rsp->psoc);
+
+	if (!soc_txrx_handle)
+		return QDF_STATUS_E_INVAL;
+
+	/* Restart the timer if UMAC reset is inprogress */
+	if (cdp_umac_reset_is_inprogress(soc_txrx_handle)) {
+		mlme_debug("Umac reset is in progress, restart the vdev manager response timer");
+		qdf_timer_mod(&vdev_rsp->rsp_timer, vdev_rsp->expire_time);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+#else
+static inline QDF_STATUS
+target_if_check_and_restart_vdev_mgr_rsp_timer(
+		struct vdev_response_timer *vdev_rsp)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+#endif
+
 void target_if_vdev_mgr_rsp_timer_cb(void *arg)
 {
 	struct wlan_objmgr_psoc *psoc;
@@ -81,6 +121,7 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
 	enum qdf_hang_reason recovery_reason;
 	uint8_t vdev_id;
 	uint16_t rsp_pos = RESPONSE_BIT_MAX;
+	QDF_STATUS status;
 
 	if (!vdev_rsp) {
 		mlme_err("Vdev response timer is NULL");
@@ -155,6 +196,11 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
 		rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp);
 	} else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT,
 				       &vdev_rsp->rsp_status)) {
+		status = target_if_check_and_restart_vdev_mgr_rsp_timer(
+				vdev_rsp);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return;
+
 		del_rsp.vdev_id = vdev_id;
 		rsp_pos = DELETE_RESPONSE_BIT;
 		recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT;
@@ -164,6 +210,11 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
 		rx_ops->vdev_mgr_delete_response(psoc, &del_rsp);
 	} else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
 				&vdev_rsp->rsp_status)) {
+		status = target_if_check_and_restart_vdev_mgr_rsp_timer(
+				vdev_rsp);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			return;
+
 		peer_del_all_rsp.vdev_id = vdev_id;
 		peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
 		rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;