e681bc6b8cce756c240400815804a6e5f2213031
[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_sp(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
79                 timvf_format_event(tim[index], &entry);
80                 ret = timvf_add_entry_sp(timr, tim[index]->timeout_ticks,
81                                 tim[index], &entry);
82                 if (unlikely(ret)) {
83                         rte_errno = -ret;
84                         break;
85                 }
86         }
87
88         return index;
89 }
90
91 uint16_t
92 timvf_timer_arm_burst_sp_stats(const struct rte_event_timer_adapter *adptr,
93                 struct rte_event_timer **tim, const uint16_t nb_timers)
94 {
95         uint16_t ret;
96         struct timvf_ring *timr = adptr->data->adapter_priv;
97
98         ret = timvf_timer_arm_burst_sp(adptr, tim, nb_timers);
99         timr->tim_arm_cnt += ret;
100
101         return ret;
102 }
103
104 uint16_t
105 timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter *adptr,
106                 struct rte_event_timer **tim, const uint16_t nb_timers)
107 {
108         int ret;
109         uint16_t index;
110         struct tim_mem_entry entry;
111         struct timvf_ring *timr = adptr->data->adapter_priv;
112         for (index = 0; index < nb_timers; index++) {
113                 if (timvf_timer_reg_checks(timr, tim[index]))
114                         break;
115                 timvf_format_event(tim[index], &entry);
116                 ret = timvf_add_entry_mp(timr, tim[index]->timeout_ticks,
117                                 tim[index], &entry);
118                 if (unlikely(ret)) {
119                         rte_errno = -ret;
120                         break;
121                 }
122         }
123
124         return index;
125 }
126
127 uint16_t
128 timvf_timer_arm_burst_mp_stats(const struct rte_event_timer_adapter *adptr,
129                 struct rte_event_timer **tim, const uint16_t nb_timers)
130 {
131         uint16_t ret;
132         struct timvf_ring *timr = adptr->data->adapter_priv;
133
134         ret = timvf_timer_arm_burst_mp(adptr, tim, nb_timers);
135         timr->tim_arm_cnt += ret;
136
137         return ret;
138 }
139
140 uint16_t
141 timvf_timer_arm_tmo_brst(const struct rte_event_timer_adapter *adptr,
142                 struct rte_event_timer **tim, const uint64_t timeout_tick,
143                 const uint16_t nb_timers)
144 {
145         int ret;
146         uint16_t set_timers = 0;
147         uint16_t idx;
148         uint16_t arr_idx = 0;
149         struct timvf_ring *timr = adptr->data->adapter_priv;
150         struct tim_mem_entry entry[TIMVF_MAX_BURST] __rte_cache_aligned;
151
152         if (unlikely(!timeout_tick || timeout_tick >= timr->nb_bkts)) {
153                 const enum rte_event_timer_state state = timeout_tick ?
154                         RTE_EVENT_TIMER_ERROR_TOOLATE :
155                         RTE_EVENT_TIMER_ERROR_TOOEARLY;
156                 for (idx = 0; idx < nb_timers; idx++)
157                         tim[idx]->state = state;
158                 rte_errno = EINVAL;
159                 return 0;
160         }
161
162         while (arr_idx < nb_timers) {
163                 for (idx = 0; idx < TIMVF_MAX_BURST && (arr_idx < nb_timers);
164                                 idx++, arr_idx++) {
165                         timvf_format_event(tim[arr_idx], &entry[idx]);
166                 }
167                 ret = timvf_add_entry_brst(timr, timeout_tick, &tim[set_timers],
168                                 entry, idx);
169                 set_timers += ret;
170                 if (ret != idx)
171                         break;
172         }
173
174         return set_timers;
175 }
176
177
178 uint16_t
179 timvf_timer_arm_tmo_brst_stats(const struct rte_event_timer_adapter *adptr,
180                 struct rte_event_timer **tim, const uint64_t timeout_tick,
181                 const uint16_t nb_timers)
182 {
183         uint16_t set_timers;
184         struct timvf_ring *timr = adptr->data->adapter_priv;
185
186         set_timers = timvf_timer_arm_tmo_brst(adptr, tim, timeout_tick,
187                         nb_timers);
188         timr->tim_arm_cnt += set_timers;
189
190         return set_timers;
191 }
192
193 void
194 timvf_set_chunk_refill(struct timvf_ring * const timr, uint8_t use_fpa)
195 {
196         if (use_fpa)
197                 timr->refill_chunk = timvf_refill_chunk_fpa;
198         else
199                 timr->refill_chunk = timvf_refill_chunk_generic;
200 }