event/octeontx: add multiproducer timer arm and cancel
[dpdk.git] / drivers / event / octeontx / timvf_worker.c
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright(c) 2017 Cavium, Inc
4  */
5
6 #include "timvf_worker.h"
7
8 static inline int
9 timvf_timer_reg_checks(const struct timvf_ring * const timr,
10                 struct rte_event_timer * const tim)
11 {
12         if (unlikely(tim->state)) {
13                 tim->state = RTE_EVENT_TIMER_ERROR;
14                 rte_errno = EALREADY;
15                 goto fail;
16         }
17
18         if (unlikely(!tim->timeout_ticks ||
19                                 tim->timeout_ticks >= timr->nb_bkts)) {
20                 tim->state = tim->timeout_ticks ? RTE_EVENT_TIMER_ERROR_TOOLATE
21                         : RTE_EVENT_TIMER_ERROR_TOOEARLY;
22                 rte_errno = EINVAL;
23                 goto fail;
24         }
25
26         return 0;
27 fail:
28         return -EINVAL;
29 }
30
31 static inline void
32 timvf_format_event(const struct rte_event_timer * const tim,
33                 struct tim_mem_entry * const entry)
34 {
35         entry->w0 = (tim->ev.event & 0xFFC000000000) >> 6 |
36                 (tim->ev.event & 0xFFFFFFFFF);
37         entry->wqe = tim->ev.u64;
38 }
39
40 uint16_t
41 timvf_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
42                 struct rte_event_timer **tim, const uint16_t nb_timers)
43 {
44         RTE_SET_USED(adptr);
45         int ret;
46         uint16_t index;
47
48         for (index = 0; index < nb_timers; index++) {
49                 if (tim[index]->state == RTE_EVENT_TIMER_CANCELED) {
50                         rte_errno = EALREADY;
51                         break;
52                 }
53
54                 if (tim[index]->state != RTE_EVENT_TIMER_ARMED) {
55                         rte_errno = EINVAL;
56                         break;
57                 }
58                 ret = timvf_rem_entry(tim[index]);
59                 if (ret) {
60                         rte_errno = -ret;
61                         break;
62                 }
63         }
64         return index;
65 }
66
67 uint16_t
68 timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter *adptr,
69                 struct rte_event_timer **tim, const uint16_t nb_timers)
70 {
71         int ret;
72         uint16_t index;
73         struct tim_mem_entry entry;
74         struct timvf_ring *timr = adptr->data->adapter_priv;
75         for (index = 0; index < nb_timers; index++) {
76                 if (timvf_timer_reg_checks(timr, tim[index]))
77                         break;
78                 timvf_format_event(tim[index], &entry);
79                 ret = timvf_add_entry_mp(timr, tim[index]->timeout_ticks,
80                                 tim[index], &entry);
81                 if (unlikely(ret)) {
82                         rte_errno = -ret;
83                         break;
84                 }
85         }
86
87         return index;
88 }
89
90 uint16_t
91 timvf_timer_arm_burst_mp_stats(const struct rte_event_timer_adapter *adptr,
92                 struct rte_event_timer **tim, const uint16_t nb_timers)
93 {
94         uint16_t ret;
95         struct timvf_ring *timr = adptr->data->adapter_priv;
96
97         ret = timvf_timer_arm_burst_mp(adptr, tim, nb_timers);
98         timr->tim_arm_cnt += ret;
99
100         return ret;
101 }
102
103 void
104 timvf_set_chunk_refill(struct timvf_ring * const timr)
105 {
106         timr->refill_chunk = timvf_refill_chunk_generic;
107 }