瀏覽代碼

qcacmn: Add buffer window for umac reset in progress

When the peer delete timer/vdev manager response timer expires, host checks
if the umac reset is in progress. If so, host will retrigger the timer.
It is possible that the umac reset is just completed and either of these
two timers got expired. In this case, host will assert saying that the peer
delete response/vdev manager response is not received from FW. FW may take
a few milliseconds to send the peer delete/vdev manager response to the
host after the umac recovery completes.

Hence, to avoid the crash, check if the umac reset was in progress during
the umac reset buffer window.

Add the below changes as well,
1) INI support to get the umac reset buffer window value.
2) Renamed the API dp_umac_reset_is_inprogress as
   dp_get_umac_reset_in_progress_state to return either
   CDP_UMAC_RESET_IN_PROGRESS or
   CDP_UMAC_RESET_IN_PROGRESS_DURING_BUFFER_WINDOW.

Change-Id: Ie15ef0731bad4b0ed955a479f00e297b7ba10729
CRs-Fixed: 3522665
Shashikala Prabhu 2 年之前
父節點
當前提交
7f898dfcc2

+ 14 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -3237,4 +3237,18 @@ struct cdp_txrx_peer_params_update {
 	uint8_t	pdev_id;
 };
 
+/**
+ * enum cdp_umac_reset_state - umac reset in progress state
+ * @CDP_UMAC_RESET_NOT_IN_PROGRESS: Umac reset is not in progress
+ * @CDP_UMAC_RESET_IN_PROGRESS: Umac reset is in progress
+ * @CDP_UMAC_RESET_IN_PROGRESS_DURING_BUFFER_WINDOW: Umac reset was in progress
+ *                                                   during this buffer window.
+ * @CDP_UMAC_RESET_INVALID_STATE: Umac reset invalid state
+ */
+enum cdp_umac_reset_state {
+	CDP_UMAC_RESET_NOT_IN_PROGRESS,
+	CDP_UMAC_RESET_IN_PROGRESS,
+	CDP_UMAC_RESET_IN_PROGRESS_DURING_BUFFER_WINDOW,
+	CDP_UMAC_RESET_INVALID_STATE
+};
 #endif

+ 37 - 9
dp/inc/cdp_txrx_ctrl.h

@@ -1408,6 +1408,29 @@ QDF_STATUS cdp_txrx_get_pdev_phyrx_error_mask(ol_txrx_soc_handle soc,
 }
 #endif
 
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+/**
+ * cdp_get_umac_reset_in_progress_state() - API to get the umac reset in
+ *                                          progress state
+ * @soc: opaque soc handle
+ *
+ * Return: Umac reset in progress state
+ */
+static inline enum cdp_umac_reset_state
+cdp_get_umac_reset_in_progress_state(ol_txrx_soc_handle soc)
+{
+	if (!soc || !soc->ops) {
+		dp_cdp_debug("Invalid soc or soc->ops:");
+		return CDP_UMAC_RESET_INVALID_STATE;
+	}
+
+	if (!soc->ops->ctrl_ops ||
+	    !soc->ops->ctrl_ops->get_umac_reset_in_progress_state)
+		return CDP_UMAC_RESET_INVALID_STATE;
+
+	return soc->ops->ctrl_ops->get_umac_reset_in_progress_state(soc);
+}
+
 /**
  * cdp_umac_reset_is_inprogress() - API to check if umac reset is in progress
  * @soc: opaque soc handle
@@ -1417,18 +1440,23 @@ QDF_STATUS cdp_txrx_get_pdev_phyrx_error_mask(ol_txrx_soc_handle soc,
 static inline bool
 cdp_umac_reset_is_inprogress(ol_txrx_soc_handle soc)
 {
-	if (!soc || !soc->ops) {
-		dp_cdp_debug("Invalid Instance:");
-		QDF_BUG(0);
-		return false;
-	}
+	enum cdp_umac_reset_state state;
 
-	if (!soc->ops->ctrl_ops ||
-	    !soc->ops->ctrl_ops->umac_reset_is_inprogress)
-		return false;
+	state = cdp_get_umac_reset_in_progress_state(soc);
 
-	return soc->ops->ctrl_ops->umac_reset_is_inprogress(soc);
+	if (state == CDP_UMAC_RESET_IN_PROGRESS ||
+	    state == CDP_UMAC_RESET_IN_PROGRESS_DURING_BUFFER_WINDOW)
+		return true;
+	else
+		return false;
 }
+#else
+static inline bool
+cdp_umac_reset_is_inprogress(ol_txrx_soc_handle soc)
+{
+	return false;
+}
+#endif
 
 #ifdef WLAN_SUPPORT_RX_FISA
 static inline

+ 4 - 1
dp/inc/cdp_txrx_ops.h

@@ -954,12 +954,15 @@ struct cdp_ctrl_ops {
 						     uint32_t *mask,
 						     uint32_t *mask_cont);
 #endif
-	bool (*umac_reset_is_inprogress)(struct cdp_soc_t *psoc);
 #ifdef WLAN_SUPPORT_RX_FISA
 	QDF_STATUS (*txrx_fisa_config)(struct cdp_soc_t *soc, uint8_t pdev_id,
 				       enum cdp_fisa_config_id config_id,
 				       union cdp_fisa_config *cfg);
 #endif
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+	enum cdp_umac_reset_state (*get_umac_reset_in_progress_state)(
+				   struct cdp_soc_t *psoc);
+#endif
 };
 
 struct cdp_me_ops {

+ 24 - 5
dp/wifi3.0/be/mlo/dp_mlo.c

@@ -1659,17 +1659,19 @@ QDF_STATUS dp_mlo_umac_reset_stats_print(struct dp_soc *soc)
 	return QDF_STATUS_SUCCESS;
 }
 
-bool dp_umac_reset_is_inprogress(struct cdp_soc_t *psoc)
+enum cdp_umac_reset_state
+dp_get_umac_reset_in_progress_state(struct cdp_soc_t *psoc)
 {
 	struct dp_soc_umac_reset_ctx *umac_reset_ctx;
 	struct dp_soc *soc = (struct dp_soc *)psoc;
 	struct dp_soc_mlo_umac_reset_ctx *grp_umac_reset_ctx;
 	struct dp_soc_be *be_soc = NULL;
 	struct dp_mlo_ctxt *mlo_ctx = NULL;
+	enum cdp_umac_reset_state umac_reset_is_inprogress;
 
 	if (!soc) {
 		dp_umac_reset_err("DP SOC is null");
-		return false;
+		return CDP_UMAC_RESET_INVALID_STATE;
 	}
 
 	umac_reset_ctx = &soc->umac_reset_ctx;
@@ -1680,11 +1682,28 @@ bool dp_umac_reset_is_inprogress(struct cdp_soc_t *psoc)
 
 	if (mlo_ctx) {
 		grp_umac_reset_ctx = &mlo_ctx->grp_umac_reset_ctx;
-		return grp_umac_reset_ctx->umac_reset_in_progress;
+		umac_reset_is_inprogress =
+			grp_umac_reset_ctx->umac_reset_in_progress;
 	} else {
-		return (umac_reset_ctx->current_state !=
-				UMAC_RESET_STATE_WAIT_FOR_TRIGGER);
+		umac_reset_is_inprogress = (umac_reset_ctx->current_state !=
+					    UMAC_RESET_STATE_WAIT_FOR_TRIGGER);
 	}
+
+	if (umac_reset_is_inprogress)
+		return CDP_UMAC_RESET_IN_PROGRESS;
+
+	/* Check if the umac reset was in progress during the buffer
+	 * window.
+	 */
+	umac_reset_is_inprogress =
+		((qdf_get_log_timestamp_usecs() -
+		  umac_reset_ctx->ts.post_reset_complete_done) <=
+		 (wlan_cfg_get_umac_reset_buffer_window_ms(soc->wlan_cfg_ctx) *
+		  1000));
+
+	return (umac_reset_is_inprogress ?
+			CDP_UMAC_RESET_IN_PROGRESS_DURING_BUFFER_WINDOW :
+			CDP_UMAC_RESET_NOT_IN_PROGRESS);
 }
 #endif
 

+ 8 - 6
dp/wifi3.0/dp_internal.h

@@ -2825,12 +2825,14 @@ QDF_STATUS dp_mlo_umac_reset_stats_print(struct dp_soc *soc)
 QDF_STATUS dp_umac_reset_notify_asserted_soc(struct dp_soc *soc);
 
 /**
- * dp_umac_reset_is_inprogress() - Check if umac reset is in progress
+ * dp_get_umac_reset_in_progress_state() - API to check umac reset in progress
+ * state
  * @psoc: dp soc handle
  *
- * Return: true if umac reset is in progress, else false.
+ * Return: umac reset state
  */
-bool dp_umac_reset_is_inprogress(struct cdp_soc_t *psoc);
+enum cdp_umac_reset_state
+dp_get_umac_reset_in_progress_state(struct cdp_soc_t *psoc);
 #else
 static inline
 QDF_STATUS dp_umac_reset_notify_asserted_soc(struct dp_soc *soc)
@@ -2838,10 +2840,10 @@ QDF_STATUS dp_umac_reset_notify_asserted_soc(struct dp_soc *soc)
 	return QDF_STATUS_SUCCESS;
 }
 
-static inline
-bool dp_umac_reset_is_inprogress(struct cdp_soc_t *psoc)
+static inline enum cdp_umac_reset_state
+dp_get_umac_reset_in_progress_state(struct cdp_soc_t *psoc)
 {
-	return false;
+	return CDP_UMAC_RESET_NOT_IN_PROGRESS;
 }
 #endif
 

+ 3 - 1
dp/wifi3.0/dp_main.c

@@ -11296,7 +11296,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
 	.txrx_get_pdev_phyrx_error_mask = dp_get_pdev_phyrx_error_mask,
 #endif
 	.txrx_peer_flush_frags = dp_peer_flush_frags,
-	.umac_reset_is_inprogress = dp_umac_reset_is_inprogress,
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+	.get_umac_reset_in_progress_state = dp_get_umac_reset_in_progress_state,
+#endif
 #ifdef WLAN_SUPPORT_RX_FISA
 	.txrx_fisa_config = dp_fisa_config,
 #endif

+ 19 - 1
wlan_cfg/cfg_dp.h

@@ -1936,6 +1936,23 @@
 		WLAN_CFG_SPECIAL_MSK, \
 		CFG_VALUE_OR_DEFAULT, "special frame to deliver to stack")
 
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW_MIN 100
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW_MAX 10000
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW_DEFAULT 1000
+
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW \
+	CFG_INI_UINT("umac_reset_buffer_window", \
+	CFG_DP_UMAC_RESET_BUFFER_WINDOW_MIN, \
+	CFG_DP_UMAC_RESET_BUFFER_WINDOW_MAX, \
+	CFG_DP_UMAC_RESET_BUFFER_WINDOW_DEFAULT, \
+	CFG_VALUE_OR_DEFAULT, \
+	"Buffer time to check if umac reset was in progress during this window, configured time is in milliseconds")
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW_CFG CFG(CFG_DP_UMAC_RESET_BUFFER_WINDOW)
+#else
+#define CFG_DP_UMAC_RESET_BUFFER_WINDOW_CFG
+#endif /* DP_UMAC_HW_RESET_SUPPORT */
+
 #define CFG_DP \
 		CFG(CFG_DP_HTT_PACKET_TYPE) \
 		CFG(CFG_DP_INT_BATCH_THRESHOLD_OTHER) \
@@ -2066,5 +2083,6 @@
 		CFG(CFG_DP_POINTER_NUM_THRESHOLD_RX) \
 		CFG_DP_LOCAL_PKT_CAPTURE_CONFIG \
 		CFG(CFG_SPECIAL_FRAME_MSK) \
-		CFG(CFG_DP_SW2RXDMA_LINK_RING)
+		CFG(CFG_DP_SW2RXDMA_LINK_RING) \
+		CFG_DP_UMAC_RESET_BUFFER_WINDOW_CFG
 #endif /* _CFG_DP_H_ */

+ 33 - 0
wlan_cfg/wlan_cfg.c

@@ -3963,6 +3963,29 @@ wlan_soc_tx_packet_inspect_attach(struct cdp_ctrl_objmgr_psoc *psoc,
 }
 #endif
 
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+/**
+ * wlan_soc_umac_reset_cfg_attach() - Update umac reset buffer window config
+ * @psoc: object manager psoc
+ * @wlan_cfg_ctx: dp soc cfg ctx
+ *
+ * Return: None
+ */
+static void
+wlan_soc_umac_reset_cfg_attach(struct cdp_ctrl_objmgr_psoc *psoc,
+			       struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx)
+{
+	wlan_cfg_ctx->umac_reset_buffer_window =
+		cfg_get(psoc, CFG_DP_UMAC_RESET_BUFFER_WINDOW);
+}
+#else
+static void
+wlan_soc_umac_reset_cfg_attach(struct cdp_ctrl_objmgr_psoc *psoc,
+			       struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx)
+{
+}
+#endif /* DP_UMAC_HW_RESET_SUPPORT */
+
 #ifdef WLAN_SOFTUMAC_SUPPORT
 struct wlan_cfg_dp_soc_ctxt *
 wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
@@ -4137,6 +4160,7 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
 			cfg_get(psoc, CFG_DP_TXMON_SW_PEER_FILTERING);
 	wlan_soc_tx_packet_inspect_attach(psoc, wlan_cfg_ctx);
 	wlan_soc_local_pkt_capture_cfg_attach(psoc, wlan_cfg_ctx);
+	wlan_soc_umac_reset_cfg_attach(psoc, wlan_cfg_ctx);
 	return wlan_cfg_ctx;
 }
 
@@ -4383,6 +4407,7 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
 	wlan_soc_local_pkt_capture_cfg_attach(psoc, wlan_cfg_ctx);
 	wlan_cfg_ctx->special_frame_msk =
 			cfg_get(psoc, CFG_SPECIAL_FRAME_MSK);
+	wlan_soc_umac_reset_cfg_attach(psoc, wlan_cfg_ctx);
 
 	return wlan_cfg_ctx;
 }
@@ -5257,6 +5282,14 @@ wlan_cfg_get_rx_rings_mapping(struct wlan_cfg_dp_soc_ctxt *cfg)
 	return cfg->rx_rings_mapping;
 }
 
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+uint32_t
+wlan_cfg_get_umac_reset_buffer_window_ms(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->umac_reset_buffer_window;
+}
+#endif
+
 bool
 wlan_cfg_get_dp_caps(struct wlan_cfg_dp_soc_ctxt *cfg,
 		     enum cdp_capabilities dp_caps)

+ 23 - 0
wlan_cfg/wlan_cfg.h

@@ -343,6 +343,9 @@ struct wlan_srng_cfg {
  * @local_pkt_capture: flag indicating enable/disable of local packet capture
  * @special_frame_msk: Special frame mask
  * @rx_rr: rx round robin enable / disable
+ * @umac_reset_buffer_window: Buffer time to check if umac reset was in progress
+ *                            during this window, configured time is in
+ *                            milliseconds.
  */
 struct wlan_cfg_dp_soc_ctxt {
 	int num_int_ctxts;
@@ -549,6 +552,9 @@ struct wlan_cfg_dp_soc_ctxt {
 #ifdef WLAN_SUPPORT_RX_FLOW_TAG
 	bool rx_rr;
 #endif
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+	uint32_t umac_reset_buffer_window;
+#endif
 };
 
 /**
@@ -2633,4 +2639,21 @@ bool wlan_cfg_get_local_pkt_capture(struct wlan_cfg_dp_soc_ctxt *cfg)
  */
 uint32_t
 wlan_cfg_get_special_frame_cfg(struct wlan_cfg_dp_soc_ctxt *cfg);
+
+#ifdef DP_UMAC_HW_RESET_SUPPORT
+/**
+ * wlan_cfg_get_umac_reset_buffer_window_ms() - Get umac reset buffer window
+ * @cfg: soc configuration context
+ *
+ * Return: Umac reset buffer window in milliseconds
+ */
+uint32_t
+wlan_cfg_get_umac_reset_buffer_window_ms(struct wlan_cfg_dp_soc_ctxt *cfg);
+#else
+static inline uint32_t
+wlan_cfg_get_umac_reset_buffer_window_ms(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return 0;
+}
+#endif /* DP_UMAC_HW_RESET_SUPPORT */
 #endif /*__WLAN_CFG_H*/