Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00be65d3 authored by Jinwei Chen's avatar Jinwei Chen Committed by snandini
Browse files

qcacmn: Retry reo_dst_ctrl register writing if fails

If reo_dst_ctrl register writing failed, this is a fatal error for
IPA pipe going to down case as RX frames will still be routed to
IPA rings then hit NOC error. retry register writing to see any
chance to write successfully, if fail always, trigger SSR or panic.

Change-Id: I3c03faa28e6cc93f396944579a360d5405c8138e
CRs-Fixed: 2774789
parent 0a453192
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -527,6 +527,51 @@ uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
}
#endif

/* Max times allowed for register writing retry */
#define HAL_REG_WRITE_RETRY_MAX		5
/* Delay milliseconds for each time retry */
#define HAL_REG_WRITE_RETRY_DELAY	1

/**
 * hal_write32_mb_confirm_retry() - write register with confirming and
				    do retry/recovery if writing failed
 * @hal_soc: hal soc handle
 * @offset: offset address from the BAR
 * @value: value to write
 * @recovery: is recovery needed or not.
 *
 * Write the register value with confirming and read it back, if
 * read back value is not as expected, do retry for writing, if
 * retry hit max times allowed but still fail, check if recovery
 * needed.
 *
 * Return: None
 */
static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc,
						uint32_t offset,
						uint32_t value,
						bool recovery)
{
	uint8_t retry_cnt = 0;
	uint32_t read_value;

	while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) {
		hal_write32_mb_confirm(hal_soc, offset, value);
		read_value = hal_read32_mb(hal_soc, offset);
		if (qdf_likely(read_value == value))
			break;

		/* write failed, do retry */
		hal_warn("Retry reg offset 0x%x, value 0x%x, read value 0x%x",
			 offset, value, read_value);
		qdf_mdelay(HAL_REG_WRITE_RETRY_DELAY);
		retry_cnt++;
	}

	if (retry_cnt > HAL_REG_WRITE_RETRY_MAX && recovery)
		qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE);
}

#ifdef FEATURE_HAL_DELAYED_REG_WRITE
/**
 * hal_dump_reg_write_srng_stats() - dump SRNG reg write stats
+3 −0
Original line number Diff line number Diff line
@@ -116,6 +116,9 @@
#define HAL_REG_WRITE_CONFIRM(_soc, _reg, _value) \
	hal_write32_mb_confirm(_soc, (_reg), (_value))

#define HAL_REG_WRITE_CONFIRM_RETRY(_soc, _reg, _value, _recovery) \
	hal_write32_mb_confirm_retry(_soc, (_reg), (_value), (_recovery))

#define HAL_REG_READ(_soc, _offset) \
	hal_read32_mb(_soc, (_offset))

+8 −4
Original line number Diff line number Diff line
@@ -942,28 +942,32 @@ void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read,
			reg_offset =
				HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR(
						SEQ_WCSS_UMAC_REO_REG_OFFSET);
			HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix0);
			HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset,
						    *ix0, true);
		}

		if (ix1) {
			reg_offset =
				HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR(
						SEQ_WCSS_UMAC_REO_REG_OFFSET);
			HAL_REG_WRITE(hal, reg_offset, *ix1);
			HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset,
						    *ix1, true);
		}

		if (ix2) {
			reg_offset =
				HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
						SEQ_WCSS_UMAC_REO_REG_OFFSET);
			HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix2);
			HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset,
						    *ix2, true);
		}

		if (ix3) {
			reg_offset =
				HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
						SEQ_WCSS_UMAC_REO_REG_OFFSET);
			HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix3);
			HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset,
						    *ix3, true);
		}
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -1311,6 +1311,7 @@ enum qdf_suspend_type {
 * @QDF_VDEV_STOP_RESPONSE_TIMED_OUT: Stop response timeout from FW
 * @QDF_VDEV_DELETE_RESPONSE_TIMED_OUT: Delete response timeout from FW
 * @QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT: Peer delete all resp timeout
 * @QDF_HAL_REG_WRITE_FAILURE: HAL register writing failures
 */
enum qdf_hang_reason {
	QDF_REASON_UNSPECIFIED,
@@ -1333,6 +1334,7 @@ enum qdf_hang_reason {
	QDF_VDEV_STOP_RESPONSE_TIMED_OUT,
	QDF_VDEV_DELETE_RESPONSE_TIMED_OUT,
	QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT,
	QDF_HAL_REG_WRITE_FAILURE,
};

/**