Loading dp/wifi3.0/dp_internal.h +67 −0 Original line number Diff line number Diff line Loading @@ -2234,6 +2234,73 @@ void dp_desc_multi_pages_mem_free(struct dp_soc *soc, } #endif #ifdef FEATURE_RUNTIME_PM /** * dp_runtime_get() - Get dp runtime refcount * @soc: Datapath soc handle * * Get dp runtime refcount by increment of an atomic variable, which can block * dp runtime resume to wait to flush pending tx by runtime suspend. * * Return: Current refcount */ static inline int32_t dp_runtime_get(struct dp_soc *soc) { return qdf_atomic_inc_return(&soc->dp_runtime_refcount); } /** * dp_runtime_put() - Return dp runtime refcount * @soc: Datapath soc handle * * Return dp runtime refcount by decrement of an atomic variable, allow dp * runtime resume finish. * * Return: Current refcount */ static inline int32_t dp_runtime_put(struct dp_soc *soc) { return qdf_atomic_dec_return(&soc->dp_runtime_refcount); } /** * dp_runtime_get_refcount() - Get dp runtime refcount * @soc: Datapath soc handle * * Get dp runtime refcount by returning an atomic variable * * Return: Current refcount */ static inline int32_t dp_runtime_get_refcount(struct dp_soc *soc) { return qdf_atomic_read(&soc->dp_runtime_refcount); } /** * dp_runtime_init() - Init dp runtime refcount when dp soc init * @soc: Datapath soc handle * * Return: QDF_STATUS */ static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) { return qdf_atomic_init(&soc->dp_runtime_refcount); } #else static inline int32_t dp_runtime_get(struct dp_soc *soc) { return 0; } static inline int32_t dp_runtime_put(struct dp_soc *soc) { return 0; } static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) { return QDF_STATUS_SUCCESS; } #endif #endif /* #ifndef _DP_INTERNAL_H_ */ dp/wifi3.0/dp_main.c +22 −1 Original line number Diff line number Diff line Loading @@ -5349,6 +5349,8 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) DP_STATS_INIT(soc); dp_runtime_init(soc); /* initialize work queue for stats processing */ qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); Loading Loading @@ -10545,6 +10547,12 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_E_AGAIN; } if (dp_runtime_get_refcount(soc)) { dp_info("refcount: %d", dp_runtime_get_refcount(soc)); return QDF_STATUS_E_AGAIN; } if (soc->intr_mode == DP_INTR_POLL) qdf_timer_stop(&soc->int_timer); Loading @@ -10570,9 +10578,12 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } #define DP_FLUSH_WAIT_CNT 10 #define DP_RUNTIME_SUSPEND_WAIT_MS 10 /** * dp_runtime_resume() - ensure DP is ready to runtime resume * @soc_hdl: Datapath soc handle Loading @@ -10585,11 +10596,21 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); int i; int i, suspend_wait = 0; if (soc->intr_mode == DP_INTR_POLL) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); /* * Wait until dp runtime refcount becomes zero or time out, then flush * pending tx for runtime suspend. */ while (dp_runtime_get_refcount(soc) && suspend_wait < DP_FLUSH_WAIT_CNT) { qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS); suspend_wait++; } for (i = 0; i < MAX_TCL_DATA_RINGS; i++) { dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); } Loading dp/wifi3.0/dp_tx.c +63 −10 Original line number Diff line number Diff line Loading @@ -1100,6 +1100,68 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc, #define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb) #endif #ifdef FEATURE_RUNTIME_PM /** * dp_tx_ring_access_end_wrapper() - Wrapper for ring access end * @soc: Datapath soc handle * @hal_ring_hdl: HAL ring handle * * Wrapper for HAL ring access end for data transmission for * FEATURE_RUNTIME_PM * * Returns: none */ static inline void dp_tx_ring_access_end_wrapper(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl) { int ret; ret = hif_pm_runtime_get(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); switch (ret) { case 0: hal_srng_access_end(soc->hal_soc, hal_ring_hdl); hif_pm_runtime_put(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); break; /* * If hif_pm_runtime_get returns -EBUSY or -EINPROGRESS, * take the dp runtime refcount using dp_runtime_get, * check link state,if up, write TX ring HP, else just set flush event. * In dp_runtime_resume, wait until dp runtime refcount becomes * zero or time out, then flush pending tx. */ case -EBUSY: case -EINPROGRESS: dp_runtime_get(soc); if (hif_pm_get_link_state(soc->hif_handle) == HIF_PM_LINK_STATE_UP) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); } dp_runtime_put(soc); break; default: dp_runtime_get(soc); hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); dp_runtime_put(soc); } } #else static inline void dp_tx_ring_access_end_wrapper(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); } #endif /** * dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit * @soc: DP Soc Handle Loading Loading @@ -1688,16 +1750,7 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, nbuf = NULL; fail_return: if (hif_pm_runtime_get(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE) == 0) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); hif_pm_runtime_put(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); } dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl); return nbuf; } Loading dp/wifi3.0/dp_types.h +4 −0 Original line number Diff line number Diff line Loading @@ -1410,6 +1410,10 @@ struct dp_soc { #endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */ /* Save recent operation related variable */ struct dp_last_op_info last_op_info; #ifdef FEATURE_RUNTIME_PM /* Dp runtime refcount */ qdf_atomic_t dp_runtime_refcount; #endif }; #ifdef IPA_OFFLOAD Loading hif/inc/hif.h +31 −0 Original line number Diff line number Diff line Loading @@ -933,8 +933,19 @@ static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id) return (char *)strings[id]; } /** * enum hif_pm_link_state - hif link state * HIF_PM_LINK_STATE_DOWN: hif link state is down * HIF_PM_LINK_STATE_UP: hif link state is up */ enum hif_pm_link_state { HIF_PM_LINK_STATE_DOWN, HIF_PM_LINK_STATE_UP }; #ifdef FEATURE_RUNTIME_PM struct hif_pm_runtime_lock; void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, wlan_rtpm_dbgid rtpm_dbgid); Loading Loading @@ -967,6 +978,22 @@ void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx); qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx); /** * hif_pm_set_link_state() - set link state during RTPM * @hif_sc: HIF Context * * Return: None */ void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val); /** * hif_is_link_state_up() - Is link state up * @hif_sc: HIF Context * * Return: 1 link is up, 0 link is down */ uint8_t hif_pm_get_link_state(struct hif_opaque_softc *hif_handle); #else struct hif_pm_runtime_lock { const char *name; Loading Loading @@ -1035,6 +1062,10 @@ hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) { return 0; } static inline int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx) { return 0; } static inline void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val) {} #endif void hif_enable_power_management(struct hif_opaque_softc *hif_ctx, Loading Loading
dp/wifi3.0/dp_internal.h +67 −0 Original line number Diff line number Diff line Loading @@ -2234,6 +2234,73 @@ void dp_desc_multi_pages_mem_free(struct dp_soc *soc, } #endif #ifdef FEATURE_RUNTIME_PM /** * dp_runtime_get() - Get dp runtime refcount * @soc: Datapath soc handle * * Get dp runtime refcount by increment of an atomic variable, which can block * dp runtime resume to wait to flush pending tx by runtime suspend. * * Return: Current refcount */ static inline int32_t dp_runtime_get(struct dp_soc *soc) { return qdf_atomic_inc_return(&soc->dp_runtime_refcount); } /** * dp_runtime_put() - Return dp runtime refcount * @soc: Datapath soc handle * * Return dp runtime refcount by decrement of an atomic variable, allow dp * runtime resume finish. * * Return: Current refcount */ static inline int32_t dp_runtime_put(struct dp_soc *soc) { return qdf_atomic_dec_return(&soc->dp_runtime_refcount); } /** * dp_runtime_get_refcount() - Get dp runtime refcount * @soc: Datapath soc handle * * Get dp runtime refcount by returning an atomic variable * * Return: Current refcount */ static inline int32_t dp_runtime_get_refcount(struct dp_soc *soc) { return qdf_atomic_read(&soc->dp_runtime_refcount); } /** * dp_runtime_init() - Init dp runtime refcount when dp soc init * @soc: Datapath soc handle * * Return: QDF_STATUS */ static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) { return qdf_atomic_init(&soc->dp_runtime_refcount); } #else static inline int32_t dp_runtime_get(struct dp_soc *soc) { return 0; } static inline int32_t dp_runtime_put(struct dp_soc *soc) { return 0; } static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) { return QDF_STATUS_SUCCESS; } #endif #endif /* #ifndef _DP_INTERNAL_H_ */
dp/wifi3.0/dp_main.c +22 −1 Original line number Diff line number Diff line Loading @@ -5349,6 +5349,8 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) DP_STATS_INIT(soc); dp_runtime_init(soc); /* initialize work queue for stats processing */ qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); Loading Loading @@ -10545,6 +10547,12 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_E_AGAIN; } if (dp_runtime_get_refcount(soc)) { dp_info("refcount: %d", dp_runtime_get_refcount(soc)); return QDF_STATUS_E_AGAIN; } if (soc->intr_mode == DP_INTR_POLL) qdf_timer_stop(&soc->int_timer); Loading @@ -10570,9 +10578,12 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } #define DP_FLUSH_WAIT_CNT 10 #define DP_RUNTIME_SUSPEND_WAIT_MS 10 /** * dp_runtime_resume() - ensure DP is ready to runtime resume * @soc_hdl: Datapath soc handle Loading @@ -10585,11 +10596,21 @@ void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); int i; int i, suspend_wait = 0; if (soc->intr_mode == DP_INTR_POLL) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); /* * Wait until dp runtime refcount becomes zero or time out, then flush * pending tx for runtime suspend. */ while (dp_runtime_get_refcount(soc) && suspend_wait < DP_FLUSH_WAIT_CNT) { qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS); suspend_wait++; } for (i = 0; i < MAX_TCL_DATA_RINGS; i++) { dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); } Loading
dp/wifi3.0/dp_tx.c +63 −10 Original line number Diff line number Diff line Loading @@ -1100,6 +1100,68 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc, #define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb) #endif #ifdef FEATURE_RUNTIME_PM /** * dp_tx_ring_access_end_wrapper() - Wrapper for ring access end * @soc: Datapath soc handle * @hal_ring_hdl: HAL ring handle * * Wrapper for HAL ring access end for data transmission for * FEATURE_RUNTIME_PM * * Returns: none */ static inline void dp_tx_ring_access_end_wrapper(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl) { int ret; ret = hif_pm_runtime_get(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); switch (ret) { case 0: hal_srng_access_end(soc->hal_soc, hal_ring_hdl); hif_pm_runtime_put(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); break; /* * If hif_pm_runtime_get returns -EBUSY or -EINPROGRESS, * take the dp runtime refcount using dp_runtime_get, * check link state,if up, write TX ring HP, else just set flush event. * In dp_runtime_resume, wait until dp runtime refcount becomes * zero or time out, then flush pending tx. */ case -EBUSY: case -EINPROGRESS: dp_runtime_get(soc); if (hif_pm_get_link_state(soc->hif_handle) == HIF_PM_LINK_STATE_UP) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); } dp_runtime_put(soc); break; default: dp_runtime_get(soc); hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); dp_runtime_put(soc); } } #else static inline void dp_tx_ring_access_end_wrapper(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); } #endif /** * dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit * @soc: DP Soc Handle Loading Loading @@ -1688,16 +1750,7 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, nbuf = NULL; fail_return: if (hif_pm_runtime_get(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE) == 0) { hal_srng_access_end(soc->hal_soc, hal_ring_hdl); hif_pm_runtime_put(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); } else { hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); hal_srng_inc_flush_cnt(hal_ring_hdl); } dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl); return nbuf; } Loading
dp/wifi3.0/dp_types.h +4 −0 Original line number Diff line number Diff line Loading @@ -1410,6 +1410,10 @@ struct dp_soc { #endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */ /* Save recent operation related variable */ struct dp_last_op_info last_op_info; #ifdef FEATURE_RUNTIME_PM /* Dp runtime refcount */ qdf_atomic_t dp_runtime_refcount; #endif }; #ifdef IPA_OFFLOAD Loading
hif/inc/hif.h +31 −0 Original line number Diff line number Diff line Loading @@ -933,8 +933,19 @@ static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id) return (char *)strings[id]; } /** * enum hif_pm_link_state - hif link state * HIF_PM_LINK_STATE_DOWN: hif link state is down * HIF_PM_LINK_STATE_UP: hif link state is up */ enum hif_pm_link_state { HIF_PM_LINK_STATE_DOWN, HIF_PM_LINK_STATE_UP }; #ifdef FEATURE_RUNTIME_PM struct hif_pm_runtime_lock; void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, wlan_rtpm_dbgid rtpm_dbgid); Loading Loading @@ -967,6 +978,22 @@ void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx); qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx); /** * hif_pm_set_link_state() - set link state during RTPM * @hif_sc: HIF Context * * Return: None */ void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val); /** * hif_is_link_state_up() - Is link state up * @hif_sc: HIF Context * * Return: 1 link is up, 0 link is down */ uint8_t hif_pm_get_link_state(struct hif_opaque_softc *hif_handle); #else struct hif_pm_runtime_lock { const char *name; Loading Loading @@ -1035,6 +1062,10 @@ hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) { return 0; } static inline int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx) { return 0; } static inline void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val) {} #endif void hif_enable_power_management(struct hif_opaque_softc *hif_ctx, Loading