qcacmn: Reo-Cmd: Donot write to reg if no src desc

For reo_cmd ring, in current implementation, we call hal_srng_access_end
in case a descriptor is not available before baling out. This may cause
a write to the shadow register for the reo_cmd ring. In case we are in
the middle of WOW, this can be problematic.
Modify existing implementation to use hal_srng_access_end_reap, which
will not schedule a write to the register and simply return.

Change-Id: Ifb83d904e39b3d749522cd246a5ab3fe51a3104e
CRs-Fixed: 3194289
This commit is contained in:
Mohit Khanna
2022-05-20 07:47:47 -07:00
committed by Madan Koyyalamudi
parent 0130242aed
commit 04bf8070da
4 changed files with 92 additions and 60 deletions

View File

@@ -991,7 +991,7 @@ struct reo_desc_deferred_freelist_node {
struct reo_cmd_event_record { struct reo_cmd_event_record {
enum hal_reo_cmd_type cmd_type; enum hal_reo_cmd_type cmd_type;
uint8_t cmd_return_status; uint8_t cmd_return_status;
uint32_t timestamp; uint64_t timestamp;
}; };
/** /**

View File

@@ -284,7 +284,7 @@ void hal_set_ba_aging_timeout_be(hal_soc_handle_t hal_soc_hdl, uint8_t ac,
} }
qdf_export_symbol(hal_set_ba_aging_timeout_be); qdf_export_symbol(hal_set_ba_aging_timeout_be);
static inline void static void
hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc, hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc,
enum hal_reo_cmd_type type, enum hal_reo_cmd_type type,
uint32_t paddr_lo, uint32_t paddr_lo,
@@ -322,7 +322,7 @@ hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc,
} }
} }
static inline int static int
hal_reo_cmd_queue_stats_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_queue_stats_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -333,9 +333,8 @@ hal_reo_cmd_queue_stats_be(hal_ring_handle_t hal_ring_hdl,
hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
"%s: Out of cmd ring entries", __func__); hal_warn_rl("Out of cmd ring entries");
hal_srng_access_end(hal_soc, hal_ring_hdl);
return -EBUSY; return -EBUSY;
} }
@@ -361,23 +360,15 @@ hal_reo_cmd_queue_stats_be(hal_ring_handle_t hal_ring_hdl,
HAL_DESC_64_SET_FIELD(reo_desc, REO_GET_QUEUE_STATS, CLEAR_STATS, HAL_DESC_64_SET_FIELD(reo_desc, REO_GET_QUEUE_STATS, CLEAR_STATS,
cmd->u.stats_params.clear); cmd->u.stats_params.clear);
if (hif_pm_runtime_get(hal_soc->hif_handle, hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
RTPM_ID_HAL_REO_CMD, true) == 0) { true);
hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
hif_pm_runtime_put(hal_soc->hif_handle,
RTPM_ID_HAL_REO_CMD);
} else {
hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
hal_srng_inc_flush_cnt(hal_ring_hdl);
}
val = reo_desc[CMD_HEADER_DW_OFFSET]; val = reo_desc[CMD_HEADER_DW_OFFSET];
return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER, return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
val); val);
} }
static inline int static int
hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -388,9 +379,8 @@ hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
"%s: Out of cmd ring entries", __func__); hal_warn_rl("Out of cmd ring entries");
hal_srng_access_end(hal_soc, hal_ring_hdl);
return -EBUSY; return -EBUSY;
} }
@@ -422,13 +412,14 @@ hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
cmd->u.fl_queue_params.index); cmd->u.fl_queue_params.index);
} }
hal_srng_access_end(hal_soc, hal_ring_hdl); hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
false);
val = reo_desc[CMD_HEADER_DW_OFFSET]; val = reo_desc[CMD_HEADER_DW_OFFSET];
return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER, return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
val); val);
} }
static inline int static int
hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -449,8 +440,8 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
if (cp->block_use_after_flush) { if (cp->block_use_after_flush) {
index = hal_find_zero_bit(hal_soc->reo_res_bitmap); index = hal_find_zero_bit(hal_soc->reo_res_bitmap);
if (index > 3) { if (index > 3) {
qdf_print("No blocking resource available!"); hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
hal_srng_access_end(hal_soc, hal_ring_hdl); hal_warn_rl("No blocking resource available!");
return -EBUSY; return -EBUSY;
} }
hal_soc->index = index; hal_soc->index = index;
@@ -458,7 +449,7 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
hal_srng_access_end(hal_soc, hal_ring_hdl); hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
hal_srng_dump(hal_ring_handle_to_hal_srng(hal_ring_hdl)); hal_srng_dump(hal_ring_handle_to_hal_srng(hal_ring_hdl));
return -EBUSY; return -EBUSY;
} }
@@ -505,23 +496,15 @@ hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
HAL_DESC_64_SET_FIELD(reo_desc, REO_FLUSH_CACHE, FLUSH_ENTIRE_CACHE, HAL_DESC_64_SET_FIELD(reo_desc, REO_FLUSH_CACHE, FLUSH_ENTIRE_CACHE,
cp->flush_entire_cache); cp->flush_entire_cache);
if (hif_pm_runtime_get(hal_soc->hif_handle, hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
RTPM_ID_HAL_REO_CMD, true) == 0) { false);
hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
hif_pm_runtime_put(hal_soc->hif_handle,
RTPM_ID_HAL_REO_CMD);
} else {
hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
hal_srng_inc_flush_cnt(hal_ring_hdl);
}
val = reo_desc[CMD_HEADER_DW_OFFSET]; val = reo_desc[CMD_HEADER_DW_OFFSET];
return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER, return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
val); val);
} }
static inline int static int
hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -544,9 +527,8 @@ hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
"%s: Out of cmd ring entries", __func__); hal_warn_rl("Out of cmd ring entries");
hal_srng_access_end(hal_soc, hal_ring_hdl);
return -EBUSY; return -EBUSY;
} }
@@ -580,7 +562,7 @@ hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
val); val);
} }
static inline int static int
hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -591,9 +573,8 @@ hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
"%s: Out of cmd ring entries", __func__); hal_warn_rl("Out of cmd ring entries");
hal_srng_access_end(hal_soc, hal_ring_hdl);
return -EBUSY; return -EBUSY;
} }
@@ -629,7 +610,7 @@ hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
val); val);
} }
static inline int static int
hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl, hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
hal_soc_handle_t hal_soc_hdl, hal_soc_handle_t hal_soc_hdl,
struct hal_reo_cmd_params *cmd) struct hal_reo_cmd_params *cmd)
@@ -643,9 +624,8 @@ hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
if (!reo_desc) { if (!reo_desc) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
"%s: Out of cmd ring entries", __func__); hal_warn_rl("Out of cmd ring entries");
hal_srng_access_end(hal_soc, hal_ring_hdl);
return -EBUSY; return -EBUSY;
} }
@@ -832,17 +812,8 @@ hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
HAL_DESC_64_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE, HAL_DESC_64_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE,
PN_127_96, p->pn_127_96); PN_127_96, p->pn_127_96);
if (hif_pm_runtime_get(hal_soc->hif_handle, hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, RTPM_ID_HAL_REO_CMD,
RTPM_ID_HAL_REO_CMD, false) == 0) { false);
hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
hif_pm_runtime_put(hal_soc->hif_handle,
RTPM_ID_HAL_REO_CMD);
} else {
hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
hal_srng_inc_flush_cnt(hal_ring_hdl);
}
val = reo_desc[CMD_HEADER_DW_OFFSET]; val = reo_desc[CMD_HEADER_DW_OFFSET];
return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER, return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
val); val);

View File

@@ -2202,7 +2202,6 @@ hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
* This API should be used only if hal_srng_access_start was used to * This API should be used only if hal_srng_access_start was used to
* start ring access * start ring access
* *
* Return: 0 on success; error on failire
*/ */
static inline void static inline void
hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl) hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
@@ -2218,6 +2217,40 @@ hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
SRNG_UNLOCK(&(srng->lock)); SRNG_UNLOCK(&(srng->lock));
} }
void hal_srng_access_end_v1(hal_soc_handle_t hal_soc_hdl,
hal_ring_handle_t hal_ring_hdl,
wlan_rtpm_dbgid rtpm_dbgid,
bool is_critical_ctx);
#ifdef FEATURE_RUNTIME_PM
#define hal_srng_access_end_v1 hal_srng_rtpm_access_end
/**
* hal_srng_rtpm_access_end - RTPM aware, Unlock ring access
* @hal_soc: Opaque HAL SOC handle
* @hal_ring_hdl: Ring pointer (Source or Destination ring)
* @rtpm_dbgid: RTPM debug id
* @is_critical_ctx: Whether the calling context is critical
*
* Function updates the HP/TP value to the hardware register.
* The target expects cached head/tail pointer to be updated to the
* shared location in the little-endian order, This API ensures that.
* This API should be used only if hal_srng_access_start was used to
* start ring access
*
* Return: None
*/
void
hal_srng_rtpm_access_end(hal_soc_handle_t hal_soc_hdl,
hal_ring_handle_t hal_ring_hdl,
wlan_rtpm_dbgid rtpm_dbgid,
bool is_critical_ctx);
#else
#define hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl, rtpm_dbgid, \
is_critical_ctx)\
hal_srng_access_end(hal_soc_hdl, hal_ring_hdl)
#endif
/* hal_srng_access_end already handles endianness conversion, so use the same */ /* hal_srng_access_end already handles endianness conversion, so use the same */
#define hal_le_srng_access_end_in_cpu_order \ #define hal_le_srng_access_end_in_cpu_order \
hal_srng_access_end hal_srng_access_end

View File

@@ -1784,11 +1784,39 @@ void hal_set_low_threshold(hal_ring_handle_t hal_ring_hdl,
} }
qdf_export_symbol(hal_set_low_threshold); qdf_export_symbol(hal_set_low_threshold);
#ifdef FEATURE_RUNTIME_PM
void
hal_srng_rtpm_access_end(hal_soc_handle_t hal_soc_hdl,
hal_ring_handle_t hal_ring_hdl,
wlan_rtpm_dbgid rtpm_dbgid,
bool is_critical_ctx)
{
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
if (qdf_unlikely(!hal_ring_hdl)) {
qdf_print("Error: Invalid hal_ring\n");
return;
}
if (hif_pm_runtime_get(hal_soc->hif_handle,
rtpm_dbgid, is_critical_ctx) == 0) {
hal_srng_access_end(hal_soc_hdl, hal_ring_hdl);
hif_pm_runtime_put(hal_soc->hif_handle,
rtpm_dbgid);
} else {
hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl);
hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT);
hal_srng_inc_flush_cnt(hal_ring_hdl);
}
}
qdf_export_symbol(hal_srng_rtpm_access_end);
#endif /* FEATURE_RUNTIME_PM */
#ifdef FORCE_WAKE #ifdef FORCE_WAKE
void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase) void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase)
{ {
struct hal_soc *hal_soc = (struct hal_soc *)soc; struct hal_soc *hal_soc = (struct hal_soc *)soc;
hal_soc->init_phase = init_phase; hal_soc->init_phase = init_phase;
} }
#endif /* FORCE_WAKE */ #endif /* FORCE_WAKE */