1db6a330bSPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause
2b6d814d8SPavan Nikhilesh * Copyright(c) 2017 Cavium, Inc
3b6d814d8SPavan Nikhilesh */
4b6d814d8SPavan Nikhilesh
5b6d814d8SPavan Nikhilesh #include "timvf_worker.h"
6b6d814d8SPavan Nikhilesh
7b6d814d8SPavan Nikhilesh static inline int
timvf_timer_reg_checks(const struct timvf_ring * const timr,struct rte_event_timer * const tim)8b6d814d8SPavan Nikhilesh timvf_timer_reg_checks(const struct timvf_ring * const timr,
9b6d814d8SPavan Nikhilesh struct rte_event_timer * const tim)
10b6d814d8SPavan Nikhilesh {
11b6d814d8SPavan Nikhilesh if (unlikely(tim->state)) {
12b6d814d8SPavan Nikhilesh tim->state = RTE_EVENT_TIMER_ERROR;
13b6d814d8SPavan Nikhilesh rte_errno = EALREADY;
14b6d814d8SPavan Nikhilesh goto fail;
15b6d814d8SPavan Nikhilesh }
16b6d814d8SPavan Nikhilesh
17b6d814d8SPavan Nikhilesh if (unlikely(!tim->timeout_ticks ||
18b6d814d8SPavan Nikhilesh tim->timeout_ticks >= timr->nb_bkts)) {
19b6d814d8SPavan Nikhilesh tim->state = tim->timeout_ticks ? RTE_EVENT_TIMER_ERROR_TOOLATE
20b6d814d8SPavan Nikhilesh : RTE_EVENT_TIMER_ERROR_TOOEARLY;
21b6d814d8SPavan Nikhilesh rte_errno = EINVAL;
22b6d814d8SPavan Nikhilesh goto fail;
23b6d814d8SPavan Nikhilesh }
24b6d814d8SPavan Nikhilesh
25b6d814d8SPavan Nikhilesh return 0;
26b6d814d8SPavan Nikhilesh fail:
27b6d814d8SPavan Nikhilesh return -EINVAL;
28b6d814d8SPavan Nikhilesh }
29b6d814d8SPavan Nikhilesh
30b6d814d8SPavan Nikhilesh static inline void
timvf_format_event(const struct rte_event_timer * const tim,struct tim_mem_entry * const entry)31b6d814d8SPavan Nikhilesh timvf_format_event(const struct rte_event_timer * const tim,
32b6d814d8SPavan Nikhilesh struct tim_mem_entry * const entry)
33b6d814d8SPavan Nikhilesh {
34b6d814d8SPavan Nikhilesh entry->w0 = (tim->ev.event & 0xFFC000000000) >> 6 |
35b6d814d8SPavan Nikhilesh (tim->ev.event & 0xFFFFFFFFF);
36b6d814d8SPavan Nikhilesh entry->wqe = tim->ev.u64;
37b6d814d8SPavan Nikhilesh }
38b6d814d8SPavan Nikhilesh
39b6d814d8SPavan Nikhilesh uint16_t
timvf_timer_cancel_burst(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint16_t nb_timers)40b6d814d8SPavan Nikhilesh timvf_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
41b6d814d8SPavan Nikhilesh struct rte_event_timer **tim, const uint16_t nb_timers)
42b6d814d8SPavan Nikhilesh {
43b6d814d8SPavan Nikhilesh RTE_SET_USED(adptr);
44b6d814d8SPavan Nikhilesh int ret;
45b6d814d8SPavan Nikhilesh uint16_t index;
46b6d814d8SPavan Nikhilesh
47b6d814d8SPavan Nikhilesh for (index = 0; index < nb_timers; index++) {
48b6d814d8SPavan Nikhilesh if (tim[index]->state == RTE_EVENT_TIMER_CANCELED) {
49b6d814d8SPavan Nikhilesh rte_errno = EALREADY;
50b6d814d8SPavan Nikhilesh break;
51b6d814d8SPavan Nikhilesh }
52b6d814d8SPavan Nikhilesh
53b6d814d8SPavan Nikhilesh if (tim[index]->state != RTE_EVENT_TIMER_ARMED) {
54b6d814d8SPavan Nikhilesh rte_errno = EINVAL;
55b6d814d8SPavan Nikhilesh break;
56b6d814d8SPavan Nikhilesh }
57b6d814d8SPavan Nikhilesh ret = timvf_rem_entry(tim[index]);
58b6d814d8SPavan Nikhilesh if (ret) {
59b6d814d8SPavan Nikhilesh rte_errno = -ret;
60b6d814d8SPavan Nikhilesh break;
61b6d814d8SPavan Nikhilesh }
62b6d814d8SPavan Nikhilesh }
63b6d814d8SPavan Nikhilesh return index;
64b6d814d8SPavan Nikhilesh }
65b6d814d8SPavan Nikhilesh
66b6d814d8SPavan Nikhilesh uint16_t
timvf_timer_arm_burst_sp(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint16_t nb_timers)677684fcf1SPavan Nikhilesh timvf_timer_arm_burst_sp(const struct rte_event_timer_adapter *adptr,
687684fcf1SPavan Nikhilesh struct rte_event_timer **tim, const uint16_t nb_timers)
697684fcf1SPavan Nikhilesh {
707684fcf1SPavan Nikhilesh int ret;
717684fcf1SPavan Nikhilesh uint16_t index;
727684fcf1SPavan Nikhilesh struct tim_mem_entry entry;
737684fcf1SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
747684fcf1SPavan Nikhilesh for (index = 0; index < nb_timers; index++) {
757684fcf1SPavan Nikhilesh if (timvf_timer_reg_checks(timr, tim[index]))
767684fcf1SPavan Nikhilesh break;
777684fcf1SPavan Nikhilesh
787684fcf1SPavan Nikhilesh timvf_format_event(tim[index], &entry);
797684fcf1SPavan Nikhilesh ret = timvf_add_entry_sp(timr, tim[index]->timeout_ticks,
807684fcf1SPavan Nikhilesh tim[index], &entry);
817684fcf1SPavan Nikhilesh if (unlikely(ret)) {
827684fcf1SPavan Nikhilesh rte_errno = -ret;
837684fcf1SPavan Nikhilesh break;
847684fcf1SPavan Nikhilesh }
857684fcf1SPavan Nikhilesh }
867684fcf1SPavan Nikhilesh
877684fcf1SPavan Nikhilesh return index;
887684fcf1SPavan Nikhilesh }
897684fcf1SPavan Nikhilesh
907684fcf1SPavan Nikhilesh uint16_t
timvf_timer_arm_burst_sp_stats(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint16_t nb_timers)917684fcf1SPavan Nikhilesh timvf_timer_arm_burst_sp_stats(const struct rte_event_timer_adapter *adptr,
927684fcf1SPavan Nikhilesh struct rte_event_timer **tim, const uint16_t nb_timers)
937684fcf1SPavan Nikhilesh {
947684fcf1SPavan Nikhilesh uint16_t ret;
957684fcf1SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
967684fcf1SPavan Nikhilesh
977684fcf1SPavan Nikhilesh ret = timvf_timer_arm_burst_sp(adptr, tim, nb_timers);
987684fcf1SPavan Nikhilesh timr->tim_arm_cnt += ret;
997684fcf1SPavan Nikhilesh
1007684fcf1SPavan Nikhilesh return ret;
1017684fcf1SPavan Nikhilesh }
1027684fcf1SPavan Nikhilesh
1037684fcf1SPavan Nikhilesh uint16_t
timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint16_t nb_timers)104b6d814d8SPavan Nikhilesh timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter *adptr,
105b6d814d8SPavan Nikhilesh struct rte_event_timer **tim, const uint16_t nb_timers)
106b6d814d8SPavan Nikhilesh {
107b6d814d8SPavan Nikhilesh int ret;
108b6d814d8SPavan Nikhilesh uint16_t index;
109b6d814d8SPavan Nikhilesh struct tim_mem_entry entry;
110b6d814d8SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
111b6d814d8SPavan Nikhilesh for (index = 0; index < nb_timers; index++) {
112b6d814d8SPavan Nikhilesh if (timvf_timer_reg_checks(timr, tim[index]))
113b6d814d8SPavan Nikhilesh break;
114b6d814d8SPavan Nikhilesh timvf_format_event(tim[index], &entry);
115b6d814d8SPavan Nikhilesh ret = timvf_add_entry_mp(timr, tim[index]->timeout_ticks,
116b6d814d8SPavan Nikhilesh tim[index], &entry);
117b6d814d8SPavan Nikhilesh if (unlikely(ret)) {
118b6d814d8SPavan Nikhilesh rte_errno = -ret;
119b6d814d8SPavan Nikhilesh break;
120b6d814d8SPavan Nikhilesh }
121b6d814d8SPavan Nikhilesh }
122b6d814d8SPavan Nikhilesh
123b6d814d8SPavan Nikhilesh return index;
124b6d814d8SPavan Nikhilesh }
125b6d814d8SPavan Nikhilesh
126b6d814d8SPavan Nikhilesh uint16_t
timvf_timer_arm_burst_mp_stats(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint16_t nb_timers)127b6d814d8SPavan Nikhilesh timvf_timer_arm_burst_mp_stats(const struct rte_event_timer_adapter *adptr,
128b6d814d8SPavan Nikhilesh struct rte_event_timer **tim, const uint16_t nb_timers)
129b6d814d8SPavan Nikhilesh {
130b6d814d8SPavan Nikhilesh uint16_t ret;
131b6d814d8SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
132b6d814d8SPavan Nikhilesh
133b6d814d8SPavan Nikhilesh ret = timvf_timer_arm_burst_mp(adptr, tim, nb_timers);
134b6d814d8SPavan Nikhilesh timr->tim_arm_cnt += ret;
135b6d814d8SPavan Nikhilesh
136b6d814d8SPavan Nikhilesh return ret;
137b6d814d8SPavan Nikhilesh }
138b6d814d8SPavan Nikhilesh
1390896f7e0SPavan Nikhilesh uint16_t
timvf_timer_arm_tmo_brst(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint64_t timeout_tick,const uint16_t nb_timers)1400896f7e0SPavan Nikhilesh timvf_timer_arm_tmo_brst(const struct rte_event_timer_adapter *adptr,
1410896f7e0SPavan Nikhilesh struct rte_event_timer **tim, const uint64_t timeout_tick,
1420896f7e0SPavan Nikhilesh const uint16_t nb_timers)
1430896f7e0SPavan Nikhilesh {
1440896f7e0SPavan Nikhilesh int ret;
1450896f7e0SPavan Nikhilesh uint16_t set_timers = 0;
1460896f7e0SPavan Nikhilesh uint16_t idx;
1470896f7e0SPavan Nikhilesh uint16_t arr_idx = 0;
1480896f7e0SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
149*27595cd8STyler Retzlaff alignas(RTE_CACHE_LINE_SIZE) struct tim_mem_entry entry[TIMVF_MAX_BURST];
1500896f7e0SPavan Nikhilesh
1510896f7e0SPavan Nikhilesh if (unlikely(!timeout_tick || timeout_tick >= timr->nb_bkts)) {
1520896f7e0SPavan Nikhilesh const enum rte_event_timer_state state = timeout_tick ?
1530896f7e0SPavan Nikhilesh RTE_EVENT_TIMER_ERROR_TOOLATE :
1540896f7e0SPavan Nikhilesh RTE_EVENT_TIMER_ERROR_TOOEARLY;
1550896f7e0SPavan Nikhilesh for (idx = 0; idx < nb_timers; idx++)
1560896f7e0SPavan Nikhilesh tim[idx]->state = state;
1570896f7e0SPavan Nikhilesh rte_errno = EINVAL;
1580896f7e0SPavan Nikhilesh return 0;
1590896f7e0SPavan Nikhilesh }
1600896f7e0SPavan Nikhilesh
1610896f7e0SPavan Nikhilesh while (arr_idx < nb_timers) {
1620896f7e0SPavan Nikhilesh for (idx = 0; idx < TIMVF_MAX_BURST && (arr_idx < nb_timers);
1630896f7e0SPavan Nikhilesh idx++, arr_idx++) {
1640896f7e0SPavan Nikhilesh timvf_format_event(tim[arr_idx], &entry[idx]);
1650896f7e0SPavan Nikhilesh }
1660896f7e0SPavan Nikhilesh ret = timvf_add_entry_brst(timr, timeout_tick, &tim[set_timers],
1670896f7e0SPavan Nikhilesh entry, idx);
1680896f7e0SPavan Nikhilesh set_timers += ret;
1690896f7e0SPavan Nikhilesh if (ret != idx)
1700896f7e0SPavan Nikhilesh break;
1710896f7e0SPavan Nikhilesh }
1720896f7e0SPavan Nikhilesh
1730896f7e0SPavan Nikhilesh return set_timers;
1740896f7e0SPavan Nikhilesh }
1750896f7e0SPavan Nikhilesh
1760896f7e0SPavan Nikhilesh
1770896f7e0SPavan Nikhilesh uint16_t
timvf_timer_arm_tmo_brst_stats(const struct rte_event_timer_adapter * adptr,struct rte_event_timer ** tim,const uint64_t timeout_tick,const uint16_t nb_timers)1780896f7e0SPavan Nikhilesh timvf_timer_arm_tmo_brst_stats(const struct rte_event_timer_adapter *adptr,
1790896f7e0SPavan Nikhilesh struct rte_event_timer **tim, const uint64_t timeout_tick,
1800896f7e0SPavan Nikhilesh const uint16_t nb_timers)
1810896f7e0SPavan Nikhilesh {
1820896f7e0SPavan Nikhilesh uint16_t set_timers;
1830896f7e0SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv;
1840896f7e0SPavan Nikhilesh
1850896f7e0SPavan Nikhilesh set_timers = timvf_timer_arm_tmo_brst(adptr, tim, timeout_tick,
1860896f7e0SPavan Nikhilesh nb_timers);
1870896f7e0SPavan Nikhilesh timr->tim_arm_cnt += set_timers;
1880896f7e0SPavan Nikhilesh
1890896f7e0SPavan Nikhilesh return set_timers;
1900896f7e0SPavan Nikhilesh }
1910896f7e0SPavan Nikhilesh
192b6d814d8SPavan Nikhilesh void
timvf_set_chunk_refill(struct timvf_ring * const timr,uint8_t use_fpa)1933e249bc5SPavan Nikhilesh timvf_set_chunk_refill(struct timvf_ring * const timr, uint8_t use_fpa)
194b6d814d8SPavan Nikhilesh {
1953e249bc5SPavan Nikhilesh if (use_fpa)
1963e249bc5SPavan Nikhilesh timr->refill_chunk = timvf_refill_chunk_fpa;
1973e249bc5SPavan Nikhilesh else
198b6d814d8SPavan Nikhilesh timr->refill_chunk = timvf_refill_chunk_generic;
199b6d814d8SPavan Nikhilesh }
200