diff --git a/hif/inc/hif.h b/hif/inc/hif.h index d098dd148c..29565906a0 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -45,6 +45,10 @@ extern "C" { 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 +#endif + #define HIF_TYPE_AR6002 2 #define HIF_TYPE_AR6003 3 #define HIF_TYPE_AR6004 5 @@ -1064,6 +1068,26 @@ static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id) return (char *)strings[id]; } +/** + * enum hif_ep_vote_type - hif ep vote type + * HIF_EP_VOTE_DP_ACCESS: vote type is specific DP + * HIF_EP_VOTE_NONDP_ACCESS: ep vote for over all access + */ +enum hif_ep_vote_type { + HIF_EP_VOTE_DP_ACCESS, + HIF_EP_VOTE_NONDP_ACCESS +}; + +/** + * enum hif_ep_vote_access - hif ep vote access + * HIF_EP_VOTE_ACCESS_ENABLE: Enable ep voting + * HIF_EP_VOTE_ACCESS_DISABLE: disable ep voting + */ +enum hif_ep_vote_access { + HIF_EP_VOTE_ACCESS_ENABLE, + HIF_EP_VOTE_ACCESS_DISABLE +}; + /** * enum hif_pm_link_state - hif link state * HIF_PM_LINK_STATE_DOWN: hif link state is down @@ -1677,6 +1701,39 @@ hif_softc_to_hif_opaque_softc(struct hif_softc *hif_handle) return (struct hif_opaque_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_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); +uint8_t hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx, + uint8_t type); +#else +static inline QDF_STATUS +hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx) +{ +} + +static inline void +hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx, + uint8_t type, uint8_t access) +{ +} + +static inline uint8_t +hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx, + uint8_t type) +{ + return HIF_EP_VOTE_ACCESS_ENABLE; +} +#endif + #ifdef FORCE_WAKE /** * hif_srng_init_phase(): Indicate srng initialization phase diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index d02aff57ca..7e449ba357 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -904,6 +904,7 @@ struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, scn->bus_type = bus_type; hif_pm_set_link_state(GET_HIF_OPAQUE_HDL(scn), HIF_PM_LINK_STATE_DOWN); + hif_allow_ep_vote_access(GET_HIF_OPAQUE_HDL(scn)); hif_get_cfg_from_psoc(scn, psoc); hif_set_event_hist_mask(GET_HIF_OPAQUE_HDL(scn)); @@ -1048,6 +1049,66 @@ QDF_STATUS hif_try_complete_tasks(struct hif_softc *scn) return QDF_STATUS_SUCCESS; } +#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE) +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; + int work = 0; + + qdf_atomic_set(&scn->dp_ep_vote_access, + HIF_EP_VOTE_ACCESS_DISABLE); + qdf_atomic_set(&scn->ep_vote_access, + HIF_EP_VOTE_ACCESS_DISABLE); + + while ((work = hif_get_num_pending_work(scn))) { + if (++work_drain_wait_cnt > HIF_WORK_DRAIN_WAIT_CNT) { + qdf_atomic_set(&scn->dp_ep_vote_access, + HIF_EP_VOTE_ACCESS_ENABLE); + qdf_atomic_set(&scn->ep_vote_access, + HIF_EP_VOTE_ACCESS_ENABLE); + hif_err("timeout wait for pending work %d ", work); + return QDF_STATUS_E_FAULT; + } + qdf_sleep(5); + } + + return QDF_STATUS_SUCCESS; +} + +void hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + qdf_atomic_set(&scn->dp_ep_vote_access, + HIF_EP_VOTE_ACCESS_ENABLE); + qdf_atomic_set(&scn->ep_vote_access, + HIF_EP_VOTE_ACCESS_ENABLE); +} + +void hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx, + uint8_t type, uint8_t access) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + if (type == HIF_EP_VOTE_DP_ACCESS) + qdf_atomic_set(&scn->dp_ep_vote_access, access); + else + qdf_atomic_set(&scn->ep_vote_access, access); +} + +uint8_t hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx, + uint8_t type) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + if (type == HIF_EP_VOTE_DP_ACCESS) + return qdf_atomic_read(&scn->dp_ep_vote_access); + else + return qdf_atomic_read(&scn->ep_vote_access); +} +#endif + #if (defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \ defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ defined(QCA_WIFI_QCN9000) || defined(QCA_WIFI_QCA6490) || \ diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 87ffd627d8..14dd5146f9 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -296,6 +296,10 @@ struct hif_softc { #ifdef SYSTEM_PM_CHECK qdf_atomic_t sys_pm_state; #endif +#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE) + qdf_atomic_t dp_ep_vote_access; + qdf_atomic_t ep_vote_access; +#endif }; static inline