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
2023-06-28 17:26:35 +05:30
зафіксовано Rahul Choudhary
джерело 0d36189af1
коміт 7f898dfcc2
9 змінених файлів з 165 додано та 23 видалено

Переглянути файл

@@ -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

Переглянути файл

@@ -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

Переглянути файл

@@ -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 {

Переглянути файл

@@ -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

Переглянути файл

@@ -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

Переглянути файл

@@ -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

Переглянути файл

@@ -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_ */

Переглянути файл

@@ -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)

Переглянути файл

@@ -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*/