Jelajahi Sumber

Merge "qcacmn: Fix assert for flush rx ptk when vdev deleted"

Linux Build Service Account 4 tahun lalu
induk
melakukan
c8b371848e
3 mengubah file dengan 44 tambahan dan 3 penghapusan
  1. 4 2
      dp/wifi3.0/dp_main.c
  2. 9 1
      hif/inc/hif.h
  3. 31 0
      hif/src/hif_main.c

+ 4 - 2
dp/wifi3.0/dp_main.c

@@ -8215,9 +8215,11 @@ void dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_soc_t *soc_hdl,
 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
 						     DP_MOD_ID_CDP);
 
-	if (!vdev)
+	if (qdf_unlikely(!vdev)) {
+		*stack_fn_p = NULL;
+		*osif_vdev_p = NULL;
 		return;
-
+	}
 	*stack_fn_p = vdev->osif_rx_stack;
 	*osif_vdev_p = vdev->osif_vdev;
 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);

+ 9 - 1
hif/inc/hif.h

@@ -48,7 +48,9 @@ typedef void __iomem *A_target_id_t;
 typedef void *hif_handle_t;
 
 #if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
-#define HIF_WORK_DRAIN_WAIT_CNT 10
+#define HIF_WORK_DRAIN_WAIT_CNT 50
+
+#define HIF_EP_WAKE_RESET_WAIT_CNT 10
 #endif
 
 #define HIF_TYPE_AR6002   2
@@ -1738,6 +1740,7 @@ hif_softc_to_hif_opaque_softc(struct hif_softc *hif_handle)
 
 #if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
 QDF_STATUS hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx);
+void hif_set_ep_intermediate_vote_access(struct hif_opaque_softc *hif_ctx);
 void hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx);
 void hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx,
 			    uint8_t type, uint8_t access);
@@ -1750,6 +1753,11 @@ hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx)
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline void
+hif_set_ep_intermediate_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+}
+
 static inline void
 hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx)
 {

+ 31 - 0
hif/src/hif_main.c

@@ -52,6 +52,10 @@
 #endif
 #include <linux/cpumask.h>
 
+#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
+#include <pld_common.h>
+#endif
+
 void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start)
 {
 	hif_trigger_dump(hif_ctx, cmd_id, start);
@@ -1043,6 +1047,7 @@ QDF_STATUS hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx)
 {
 	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
 	uint32_t work_drain_wait_cnt = 0;
+	uint32_t wait_cnt = 0;
 	int work = 0;
 
 	qdf_atomic_set(&scn->dp_ep_vote_access,
@@ -1059,12 +1064,38 @@ QDF_STATUS hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx)
 			hif_err("timeout wait for pending work %d ", work);
 			return QDF_STATUS_E_FAULT;
 		}
+		qdf_sleep(10);
+	}
+
+	while (pld_is_pci_ep_awake(scn->qdf_dev->dev)) {
+		if (++wait_cnt > HIF_EP_WAKE_RESET_WAIT_CNT) {
+			hif_err("Release EP vote is not proceed by Fw");
+			return QDF_STATUS_E_FAULT;
+		}
 		qdf_sleep(5);
 	}
 
 	return QDF_STATUS_SUCCESS;
 }
 
+void hif_set_ep_intermediate_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+	uint8_t vote_access;
+
+	vote_access = qdf_atomic_read(&scn->ep_vote_access);
+
+	if (vote_access != HIF_EP_VOTE_ACCESS_DISABLE)
+		hif_info("EP vote changed from:%u to intermediate state",
+			 vote_access);
+
+	if (QDF_IS_STATUS_ERROR(hif_try_prevent_ep_vote_access(hif_ctx)))
+		QDF_BUG(0);
+
+	qdf_atomic_set(&scn->ep_vote_access,
+		       HIF_EP_VOTE_INTERMEDIATE_ACCESS);
+}
+
 void hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx)
 {
 	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);