1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2017 Cavium, Inc.
3d30ea906Sjfb8856606 * Copyright(c) 2017-2018 Intel Corporation.
4d30ea906Sjfb8856606 * All rights reserved.
5d30ea906Sjfb8856606 */
6d30ea906Sjfb8856606
7d30ea906Sjfb8856606 #ifndef __RTE_EVENT_TIMER_ADAPTER_H__
8d30ea906Sjfb8856606 #define __RTE_EVENT_TIMER_ADAPTER_H__
9d30ea906Sjfb8856606
10d30ea906Sjfb8856606 /**
11d30ea906Sjfb8856606 * @file
12d30ea906Sjfb8856606 *
13d30ea906Sjfb8856606 * RTE Event Timer Adapter
14d30ea906Sjfb8856606 *
15d30ea906Sjfb8856606 * An event timer adapter has the following abstract working model:
16d30ea906Sjfb8856606 *
17d30ea906Sjfb8856606 * timer_tick_ns
18d30ea906Sjfb8856606 * +
19d30ea906Sjfb8856606 * +-------+ |
20d30ea906Sjfb8856606 * | | |
21d30ea906Sjfb8856606 * +-------+ bkt 0 +----v---+
22d30ea906Sjfb8856606 * | | | |
23d30ea906Sjfb8856606 * | +-------+ |
24d30ea906Sjfb8856606 * +---+---+ +---+---+ +---+---+---+---+
25d30ea906Sjfb8856606 * | | | | | | | | |
26d30ea906Sjfb8856606 * | bkt n | | bkt 1 |<-> t0| t1| t2| tn|
27d30ea906Sjfb8856606 * | | | | | | | | |
28d30ea906Sjfb8856606 * +---+---+ +---+---+ +---+---+---+---+
29d30ea906Sjfb8856606 * | Timer adapter |
30d30ea906Sjfb8856606 * +---+---+ +---+---+
31d30ea906Sjfb8856606 * | | | |
32d30ea906Sjfb8856606 * | bkt 4 | | bkt 2 |<--- Current bucket
33d30ea906Sjfb8856606 * | | | |
34d30ea906Sjfb8856606 * +---+---+ +---+---+
35d30ea906Sjfb8856606 * | +-------+ |
36d30ea906Sjfb8856606 * | | | |
37d30ea906Sjfb8856606 * +------+ bkt 3 +-------+
38d30ea906Sjfb8856606 * | |
39d30ea906Sjfb8856606 * +-------+
40d30ea906Sjfb8856606 *
41d30ea906Sjfb8856606 * - It has a virtual monotonically increasing 64-bit timer adapter clock based
42d30ea906Sjfb8856606 * on *enum rte_event_timer_adapter_clk_src* clock source. The clock source
43d30ea906Sjfb8856606 * could be a CPU clock, or a platform dependent external clock.
44d30ea906Sjfb8856606 *
45d30ea906Sjfb8856606 * - The application creates a timer adapter instance with given the clock
46d30ea906Sjfb8856606 * source, the total number of event timers, and a resolution(expressed in ns)
47d30ea906Sjfb8856606 * to traverse between the buckets.
48d30ea906Sjfb8856606 *
49d30ea906Sjfb8856606 * - Each timer adapter may have 0 to n buckets based on the configured
50d30ea906Sjfb8856606 * max timeout(max_tmo_ns) and resolution(timer_tick_ns). Upon starting the
51d30ea906Sjfb8856606 * timer adapter, the adapter starts ticking at *timer_tick_ns* resolution.
52d30ea906Sjfb8856606 *
53d30ea906Sjfb8856606 * - The application arms an event timer that will expire *timer_tick_ns*
54d30ea906Sjfb8856606 * from now.
55d30ea906Sjfb8856606 *
56d30ea906Sjfb8856606 * - The application can cancel an armed timer and no timer expiry event will be
57d30ea906Sjfb8856606 * generated.
58d30ea906Sjfb8856606 *
59d30ea906Sjfb8856606 * - If a timer expires then the library injects the timer expiry event in
60d30ea906Sjfb8856606 * the designated event queue.
61d30ea906Sjfb8856606 *
62d30ea906Sjfb8856606 * - The timer expiry event will be received through *rte_event_dequeue_burst*.
63d30ea906Sjfb8856606 *
64d30ea906Sjfb8856606 * - The application frees the timer adapter instance.
65d30ea906Sjfb8856606 *
66d30ea906Sjfb8856606 * Multiple timer adapters can be created with a varying level of resolution
67d30ea906Sjfb8856606 * for various expiry use cases that run in parallel.
68d30ea906Sjfb8856606 *
69d30ea906Sjfb8856606 * Before using the timer adapter, the application has to create and configure
70d30ea906Sjfb8856606 * an event device along with the event port. Based on the event device
71d30ea906Sjfb8856606 * capability it might require creating an additional event port to be used
72d30ea906Sjfb8856606 * by the timer adapter.
73d30ea906Sjfb8856606 *
74d30ea906Sjfb8856606 * The application creates the event timer adapter using the
75d30ea906Sjfb8856606 * ``rte_event_timer_adapter_create()``. The event device id is passed to this
76d30ea906Sjfb8856606 * function, inside this function the event device capability is checked,
77d30ea906Sjfb8856606 * and if an in-built port is absent the application uses the default
78d30ea906Sjfb8856606 * function to create a new producer port.
79d30ea906Sjfb8856606 *
80d30ea906Sjfb8856606 * The application may also use the function
81d30ea906Sjfb8856606 * ``rte_event_timer_adapter_create_ext()`` to have granular control over
82d30ea906Sjfb8856606 * producer port creation in a case where the in-built port is absent.
83d30ea906Sjfb8856606 *
84d30ea906Sjfb8856606 * After creating the timer adapter, the application has to start it
85d30ea906Sjfb8856606 * using ``rte_event_timer_adapter_start()``. The buckets are traversed from
86d30ea906Sjfb8856606 * 0 to n; when the adapter ticks, the next bucket is visited. Each time,
87d30ea906Sjfb8856606 * the list per bucket is processed, and timer expiry events are sent to the
88d30ea906Sjfb8856606 * designated event queue.
89d30ea906Sjfb8856606 *
90d30ea906Sjfb8856606 * The application can arm one or more event timers using the
91d30ea906Sjfb8856606 * ``rte_event_timer_arm_burst()``. The *timeout_ticks* represents the number
92d30ea906Sjfb8856606 * of *timer_tick_ns* after which the timer has to expire. The timeout at
93d30ea906Sjfb8856606 * which the timers expire can be grouped or be independent of each
94d30ea906Sjfb8856606 * event timer instance. ``rte_event_timer_arm_tmo_tick_burst()`` addresses the
95d30ea906Sjfb8856606 * former case and ``rte_event_timer_arm_burst()`` addresses the latter case.
96d30ea906Sjfb8856606 *
97d30ea906Sjfb8856606 * The application can cancel the timers from expiring using the
98d30ea906Sjfb8856606 * ``rte_event_timer_cancel_burst()``.
99d30ea906Sjfb8856606 *
100d30ea906Sjfb8856606 * On the secondary process, ``rte_event_timer_adapter_lookup()`` can be used
101d30ea906Sjfb8856606 * to get the timer adapter pointer from its id and use it to invoke fastpath
102d30ea906Sjfb8856606 * operations such as arm and cancel.
103d30ea906Sjfb8856606 *
104d30ea906Sjfb8856606 * Some of the use cases of event timer adapter are Beacon Timers,
105d30ea906Sjfb8856606 * Generic SW Timeout, Wireless MAC Scheduling, 3G Frame Protocols,
106d30ea906Sjfb8856606 * Packet Scheduling, Protocol Retransmission Timers, Supervision Timers.
107d30ea906Sjfb8856606 * All these use cases require high resolution and low time drift.
108d30ea906Sjfb8856606 */
109d30ea906Sjfb8856606
110d30ea906Sjfb8856606 #ifdef __cplusplus
111d30ea906Sjfb8856606 extern "C" {
112d30ea906Sjfb8856606 #endif
113d30ea906Sjfb8856606
114d30ea906Sjfb8856606 #include <rte_spinlock.h>
115d30ea906Sjfb8856606 #include <rte_memory.h>
116d30ea906Sjfb8856606
117d30ea906Sjfb8856606 #include "rte_eventdev.h"
118*2d9fd380Sjfb8856606 #include "rte_eventdev_trace_fp.h"
119d30ea906Sjfb8856606
120d30ea906Sjfb8856606 /**
121d30ea906Sjfb8856606 * Timer adapter clock source
122d30ea906Sjfb8856606 */
123d30ea906Sjfb8856606 enum rte_event_timer_adapter_clk_src {
124d30ea906Sjfb8856606 RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
125d30ea906Sjfb8856606 /**< Use CPU clock as the clock source. */
126d30ea906Sjfb8856606 RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
127d30ea906Sjfb8856606 /**< Platform dependent external clock source 0. */
128d30ea906Sjfb8856606 RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
129d30ea906Sjfb8856606 /**< Platform dependent external clock source 1. */
130d30ea906Sjfb8856606 RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
131d30ea906Sjfb8856606 /**< Platform dependent external clock source 2. */
132d30ea906Sjfb8856606 RTE_EVENT_TIMER_ADAPTER_EXT_CLK3,
133d30ea906Sjfb8856606 /**< Platform dependent external clock source 3. */
134d30ea906Sjfb8856606 };
135d30ea906Sjfb8856606
136d30ea906Sjfb8856606 #define RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES (1ULL << 0)
137d30ea906Sjfb8856606 /**< The event timer adapter implementation may have constraints on the
138d30ea906Sjfb8856606 * resolution (timer_tick_ns) and maximum timer expiry timeout(max_tmo_ns)
139d30ea906Sjfb8856606 * based on the given timer adapter or system. If this flag is set, the
140d30ea906Sjfb8856606 * implementation adjusts the resolution and maximum timeout to the best
141d30ea906Sjfb8856606 * possible configuration. On successful timer adapter creation, the
142d30ea906Sjfb8856606 * application can get the configured resolution and max timeout with
143d30ea906Sjfb8856606 * ``rte_event_timer_adapter_get_info()``.
144d30ea906Sjfb8856606 *
145d30ea906Sjfb8856606 * @see struct rte_event_timer_adapter_info::min_resolution_ns
146d30ea906Sjfb8856606 * @see struct rte_event_timer_adapter_info::max_tmo_ns
147d30ea906Sjfb8856606 */
148d30ea906Sjfb8856606 #define RTE_EVENT_TIMER_ADAPTER_F_SP_PUT (1ULL << 1)
149d30ea906Sjfb8856606 /**< ``rte_event_timer_arm_burst()`` API to be used in single producer mode.
150d30ea906Sjfb8856606 *
151d30ea906Sjfb8856606 * @see struct rte_event_timer_adapter_conf::flags
152d30ea906Sjfb8856606 */
153d30ea906Sjfb8856606
154d30ea906Sjfb8856606 /**
155d30ea906Sjfb8856606 * Timer adapter configuration structure
156d30ea906Sjfb8856606 */
157d30ea906Sjfb8856606 struct rte_event_timer_adapter_conf {
158d30ea906Sjfb8856606 uint8_t event_dev_id;
159d30ea906Sjfb8856606 /**< Event device identifier */
160d30ea906Sjfb8856606 uint16_t timer_adapter_id;
161d30ea906Sjfb8856606 /**< Event timer adapter identifier */
162d30ea906Sjfb8856606 uint32_t socket_id;
163d30ea906Sjfb8856606 /**< Identifier of socket from which to allocate memory for adapter */
164d30ea906Sjfb8856606 enum rte_event_timer_adapter_clk_src clk_src;
165d30ea906Sjfb8856606 /**< Clock source for timer adapter */
166d30ea906Sjfb8856606 uint64_t timer_tick_ns;
167d30ea906Sjfb8856606 /**< Timer adapter resolution in ns */
168d30ea906Sjfb8856606 uint64_t max_tmo_ns;
169d30ea906Sjfb8856606 /**< Maximum timer timeout(expiry) in ns */
170d30ea906Sjfb8856606 uint64_t nb_timers;
171d30ea906Sjfb8856606 /**< Total number of timers per adapter */
172d30ea906Sjfb8856606 uint64_t flags;
173d30ea906Sjfb8856606 /**< Timer adapter config flags (RTE_EVENT_TIMER_ADAPTER_F_*) */
174d30ea906Sjfb8856606 };
175d30ea906Sjfb8856606
176d30ea906Sjfb8856606 /**
177d30ea906Sjfb8856606 * Event timer adapter stats structure
178d30ea906Sjfb8856606 */
179d30ea906Sjfb8856606 struct rte_event_timer_adapter_stats {
180d30ea906Sjfb8856606 uint64_t evtim_exp_count;
181d30ea906Sjfb8856606 /**< Number of event timers that have expired. */
182d30ea906Sjfb8856606 uint64_t ev_enq_count;
183d30ea906Sjfb8856606 /**< Eventdev enqueue count */
184d30ea906Sjfb8856606 uint64_t ev_inv_count;
185d30ea906Sjfb8856606 /**< Invalid expiry event count */
186d30ea906Sjfb8856606 uint64_t evtim_retry_count;
187d30ea906Sjfb8856606 /**< Event timer retry count */
188d30ea906Sjfb8856606 uint64_t adapter_tick_count;
189d30ea906Sjfb8856606 /**< Tick count for the adapter, at its resolution */
190d30ea906Sjfb8856606 };
191d30ea906Sjfb8856606
192d30ea906Sjfb8856606 struct rte_event_timer_adapter;
193d30ea906Sjfb8856606
194d30ea906Sjfb8856606 /**
195d30ea906Sjfb8856606 * Callback function type for producer port creation.
196d30ea906Sjfb8856606 */
197d30ea906Sjfb8856606 typedef int (*rte_event_timer_adapter_port_conf_cb_t)(uint16_t id,
198d30ea906Sjfb8856606 uint8_t event_dev_id,
199d30ea906Sjfb8856606 uint8_t *event_port_id,
200d30ea906Sjfb8856606 void *conf_arg);
201d30ea906Sjfb8856606
202d30ea906Sjfb8856606 /**
203d30ea906Sjfb8856606 * Create an event timer adapter.
204d30ea906Sjfb8856606 *
205d30ea906Sjfb8856606 * This function must be invoked first before any other function in the API.
206d30ea906Sjfb8856606 *
207d30ea906Sjfb8856606 * @param conf
208d30ea906Sjfb8856606 * The event timer adapter configuration structure.
209d30ea906Sjfb8856606 *
210d30ea906Sjfb8856606 * @return
211d30ea906Sjfb8856606 * A pointer to the new allocated event timer adapter on success.
212d30ea906Sjfb8856606 * NULL on error with rte_errno set appropriately.
213d30ea906Sjfb8856606 * Possible rte_errno values include:
214d30ea906Sjfb8856606 * - ERANGE: timer_tick_ns is not in supported range.
215d30ea906Sjfb8856606 * - ENOMEM: unable to allocate sufficient memory for adapter instances
216d30ea906Sjfb8856606 * - EINVAL: invalid event device identifier specified in config
217d30ea906Sjfb8856606 * - ENOSPC: maximum number of adapters already created
218d30ea906Sjfb8856606 * - EIO: event device reconfiguration and restart error. The adapter
219d30ea906Sjfb8856606 * reconfigures the event device with an additional port by default if it is
220d30ea906Sjfb8856606 * required to use a service to manage timers. If the device had been started
221d30ea906Sjfb8856606 * before this call, this error code indicates an error in restart following
222d30ea906Sjfb8856606 * an error in reconfiguration, i.e., a combination of the two error codes.
223d30ea906Sjfb8856606 */
2244418919fSjohnjiang struct rte_event_timer_adapter *
225d30ea906Sjfb8856606 rte_event_timer_adapter_create(const struct rte_event_timer_adapter_conf *conf);
226d30ea906Sjfb8856606
227d30ea906Sjfb8856606 /**
228d30ea906Sjfb8856606 * Create a timer adapter with the supplied callback.
229d30ea906Sjfb8856606 *
230d30ea906Sjfb8856606 * This function can be used to have a more granular control over the timer
231d30ea906Sjfb8856606 * adapter creation. If a built-in port is absent, then the function uses the
232d30ea906Sjfb8856606 * callback provided to create and get the port id to be used as a producer
233d30ea906Sjfb8856606 * port.
234d30ea906Sjfb8856606 *
235d30ea906Sjfb8856606 * @param conf
236d30ea906Sjfb8856606 * The timer adapter configuration structure
237d30ea906Sjfb8856606 * @param conf_cb
238d30ea906Sjfb8856606 * The port config callback function.
239d30ea906Sjfb8856606 * @param conf_arg
240d30ea906Sjfb8856606 * Opaque pointer to the argument for the callback function
241d30ea906Sjfb8856606 *
242d30ea906Sjfb8856606 * @return
243d30ea906Sjfb8856606 * A pointer to the new allocated event timer adapter on success.
244d30ea906Sjfb8856606 * NULL on error with rte_errno set appropriately.
245d30ea906Sjfb8856606 * Possible rte_errno values include:
246d30ea906Sjfb8856606 * - ERANGE: timer_tick_ns is not in supported range.
247d30ea906Sjfb8856606 * - ENOMEM: unable to allocate sufficient memory for adapter instances
248d30ea906Sjfb8856606 * - EINVAL: invalid event device identifier specified in config
249d30ea906Sjfb8856606 * - ENOSPC: maximum number of adapters already created
250d30ea906Sjfb8856606 */
2514418919fSjohnjiang struct rte_event_timer_adapter *
252d30ea906Sjfb8856606 rte_event_timer_adapter_create_ext(
253d30ea906Sjfb8856606 const struct rte_event_timer_adapter_conf *conf,
254d30ea906Sjfb8856606 rte_event_timer_adapter_port_conf_cb_t conf_cb,
255d30ea906Sjfb8856606 void *conf_arg);
256d30ea906Sjfb8856606
257d30ea906Sjfb8856606 /**
258d30ea906Sjfb8856606 * Timer adapter info structure.
259d30ea906Sjfb8856606 */
260d30ea906Sjfb8856606 struct rte_event_timer_adapter_info {
261d30ea906Sjfb8856606 uint64_t min_resolution_ns;
262d30ea906Sjfb8856606 /**< Minimum timer adapter resolution in ns */
263d30ea906Sjfb8856606 uint64_t max_tmo_ns;
264d30ea906Sjfb8856606 /**< Maximum timer timeout(expire) in ns */
265d30ea906Sjfb8856606 struct rte_event_timer_adapter_conf conf;
266d30ea906Sjfb8856606 /**< Configured timer adapter attributes */
267d30ea906Sjfb8856606 uint32_t caps;
268d30ea906Sjfb8856606 /**< Event timer adapter capabilities */
269d30ea906Sjfb8856606 int16_t event_dev_port_id;
270d30ea906Sjfb8856606 /**< Event device port ID, if applicable */
271d30ea906Sjfb8856606 };
272d30ea906Sjfb8856606
273d30ea906Sjfb8856606 /**
274d30ea906Sjfb8856606 * Retrieve the contextual information of an event timer adapter.
275d30ea906Sjfb8856606 *
276d30ea906Sjfb8856606 * @param adapter
277d30ea906Sjfb8856606 * A pointer to the event timer adapter structure.
278d30ea906Sjfb8856606 *
279d30ea906Sjfb8856606 * @param[out] adapter_info
280d30ea906Sjfb8856606 * A pointer to a structure of type *rte_event_timer_adapter_info* to be
281d30ea906Sjfb8856606 * filled with the contextual information of the adapter.
282d30ea906Sjfb8856606 *
283d30ea906Sjfb8856606 * @return
284d30ea906Sjfb8856606 * - 0: Success, driver updates the contextual information of the
285d30ea906Sjfb8856606 * timer adapter
286d30ea906Sjfb8856606 * - <0: Error code returned by the driver info get function.
287d30ea906Sjfb8856606 * - -EINVAL: adapter identifier invalid
288d30ea906Sjfb8856606 *
289d30ea906Sjfb8856606 * @see RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES,
290d30ea906Sjfb8856606 * struct rte_event_timer_adapter_info
291d30ea906Sjfb8856606 *
292d30ea906Sjfb8856606 */
2934418919fSjohnjiang int
294d30ea906Sjfb8856606 rte_event_timer_adapter_get_info(
295d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter,
296d30ea906Sjfb8856606 struct rte_event_timer_adapter_info *adapter_info);
297d30ea906Sjfb8856606
298d30ea906Sjfb8856606 /**
299d30ea906Sjfb8856606 * Start a timer adapter.
300d30ea906Sjfb8856606 *
301d30ea906Sjfb8856606 * The adapter start step is the last one and consists of setting the timer
302d30ea906Sjfb8856606 * adapter to start accepting the timers and schedules to event queues.
303d30ea906Sjfb8856606 *
304d30ea906Sjfb8856606 * On success, all basic functions exported by the API (timer arm,
305d30ea906Sjfb8856606 * timer cancel and so on) can be invoked.
306d30ea906Sjfb8856606 *
307d30ea906Sjfb8856606 * @param adapter
308d30ea906Sjfb8856606 * A pointer to the event timer adapter structure.
309d30ea906Sjfb8856606 *
310d30ea906Sjfb8856606 * @return
311d30ea906Sjfb8856606 * - 0: Success, adapter started.
312d30ea906Sjfb8856606 * - <0: Error code returned by the driver start function.
313d30ea906Sjfb8856606 * - -EINVAL if adapter identifier invalid
314d30ea906Sjfb8856606 * - -ENOENT if software adapter but no service core mapped
315d30ea906Sjfb8856606 * - -ENOTSUP if software adapter and more than one service core mapped
3164418919fSjohnjiang * - -EALREADY if adapter has already been started
3174418919fSjohnjiang *
3184418919fSjohnjiang * @note
3194418919fSjohnjiang * The eventdev to which the event_timer_adapter is connected needs to
3204418919fSjohnjiang * be started before calling rte_event_timer_adapter_start().
321d30ea906Sjfb8856606 */
3224418919fSjohnjiang int
323d30ea906Sjfb8856606 rte_event_timer_adapter_start(
324d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter);
325d30ea906Sjfb8856606
326d30ea906Sjfb8856606 /**
327d30ea906Sjfb8856606 * Stop an event timer adapter.
328d30ea906Sjfb8856606 *
329d30ea906Sjfb8856606 * The adapter can be restarted with a call to
330d30ea906Sjfb8856606 * ``rte_event_timer_adapter_start()``.
331d30ea906Sjfb8856606 *
332d30ea906Sjfb8856606 * @param adapter
333d30ea906Sjfb8856606 * A pointer to the event timer adapter structure.
334d30ea906Sjfb8856606 *
335d30ea906Sjfb8856606 * @return
336d30ea906Sjfb8856606 * - 0: Success, adapter stopped.
337d30ea906Sjfb8856606 * - <0: Error code returned by the driver stop function.
338d30ea906Sjfb8856606 * - -EINVAL if adapter identifier invalid
339d30ea906Sjfb8856606 */
3404418919fSjohnjiang int
341d30ea906Sjfb8856606 rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter);
342d30ea906Sjfb8856606
343d30ea906Sjfb8856606 /**
344d30ea906Sjfb8856606 * Lookup an event timer adapter using its identifier.
345d30ea906Sjfb8856606 *
346d30ea906Sjfb8856606 * If an event timer adapter was created in another process with the same
347d30ea906Sjfb8856606 * identifier, this function will locate its state and set up access to it
348d30ea906Sjfb8856606 * so that it can be used in this process.
349d30ea906Sjfb8856606 *
350d30ea906Sjfb8856606 * @param adapter_id
351d30ea906Sjfb8856606 * The event timer adapter identifier.
352d30ea906Sjfb8856606 *
353d30ea906Sjfb8856606 * @return
354d30ea906Sjfb8856606 * A pointer to the event timer adapter matching the identifier on success.
355d30ea906Sjfb8856606 * NULL on error with rte_errno set appropriately.
356d30ea906Sjfb8856606 * Possible rte_errno values include:
357d30ea906Sjfb8856606 * - ENOENT - requested entry not available to return.
358d30ea906Sjfb8856606 */
3594418919fSjohnjiang struct rte_event_timer_adapter *
360d30ea906Sjfb8856606 rte_event_timer_adapter_lookup(uint16_t adapter_id);
361d30ea906Sjfb8856606
362d30ea906Sjfb8856606 /**
363d30ea906Sjfb8856606 * Free an event timer adapter.
364d30ea906Sjfb8856606 *
365d30ea906Sjfb8856606 * Destroy an event timer adapter, freeing all resources.
366d30ea906Sjfb8856606 *
367d30ea906Sjfb8856606 * Before invoking this function, the application must wait for all the
368d30ea906Sjfb8856606 * armed timers to expire or cancel the outstanding armed timers.
369d30ea906Sjfb8856606 *
370d30ea906Sjfb8856606 * @param adapter
371d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
372d30ea906Sjfb8856606 *
373d30ea906Sjfb8856606 * @return
374d30ea906Sjfb8856606 * - 0: Successfully freed the event timer adapter resources.
375d30ea906Sjfb8856606 * - <0: Failed to free the event timer adapter resources.
376d30ea906Sjfb8856606 * - -EAGAIN: adapter is busy; timers outstanding
377d30ea906Sjfb8856606 * - -EBUSY: stop hasn't been called for this adapter yet
378d30ea906Sjfb8856606 * - -EINVAL: adapter id invalid, or adapter invalid
379d30ea906Sjfb8856606 */
3804418919fSjohnjiang int
381d30ea906Sjfb8856606 rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter);
382d30ea906Sjfb8856606
383d30ea906Sjfb8856606 /**
384d30ea906Sjfb8856606 * Retrieve the service ID of the event timer adapter. If the adapter doesn't
385d30ea906Sjfb8856606 * use an rte_service function, this function returns -ESRCH.
386d30ea906Sjfb8856606 *
387d30ea906Sjfb8856606 * @param adapter
388d30ea906Sjfb8856606 * A pointer to an event timer adapter.
389d30ea906Sjfb8856606 *
390d30ea906Sjfb8856606 * @param [out] service_id
391d30ea906Sjfb8856606 * A pointer to a uint32_t, to be filled in with the service id.
392d30ea906Sjfb8856606 *
393d30ea906Sjfb8856606 * @return
394d30ea906Sjfb8856606 * - 0: Success
395d30ea906Sjfb8856606 * - <0: Error code on failure
396d30ea906Sjfb8856606 * - -ESRCH: the adapter does not require a service to operate
397d30ea906Sjfb8856606 */
3984418919fSjohnjiang int
399d30ea906Sjfb8856606 rte_event_timer_adapter_service_id_get(struct rte_event_timer_adapter *adapter,
400d30ea906Sjfb8856606 uint32_t *service_id);
401d30ea906Sjfb8856606
402d30ea906Sjfb8856606 /**
403d30ea906Sjfb8856606 * Retrieve statistics for an event timer adapter instance.
404d30ea906Sjfb8856606 *
405d30ea906Sjfb8856606 * @param adapter
406d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
407d30ea906Sjfb8856606 * @param[out] stats
408d30ea906Sjfb8856606 * A pointer to a structure to fill with statistics.
409d30ea906Sjfb8856606 *
410d30ea906Sjfb8856606 * @return
411d30ea906Sjfb8856606 * - 0: Successfully retrieved.
412d30ea906Sjfb8856606 * - <0: Failure; error code returned.
413d30ea906Sjfb8856606 */
4144418919fSjohnjiang int
415d30ea906Sjfb8856606 rte_event_timer_adapter_stats_get(struct rte_event_timer_adapter *adapter,
416d30ea906Sjfb8856606 struct rte_event_timer_adapter_stats *stats);
417d30ea906Sjfb8856606
418d30ea906Sjfb8856606 /**
419d30ea906Sjfb8856606 * Reset statistics for an event timer adapter instance.
420d30ea906Sjfb8856606 *
421d30ea906Sjfb8856606 * @param adapter
422d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
423d30ea906Sjfb8856606 *
424d30ea906Sjfb8856606 * @return
425d30ea906Sjfb8856606 * - 0: Successfully reset;
426d30ea906Sjfb8856606 * - <0: Failure; error code returned.
427d30ea906Sjfb8856606 */
4284418919fSjohnjiang int
4291646932aSjfb8856606 rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter);
430d30ea906Sjfb8856606
431d30ea906Sjfb8856606 /**
432d30ea906Sjfb8856606 * Event timer state.
433d30ea906Sjfb8856606 */
434d30ea906Sjfb8856606 enum rte_event_timer_state {
435d30ea906Sjfb8856606 RTE_EVENT_TIMER_NOT_ARMED = 0,
436d30ea906Sjfb8856606 /**< Event timer not armed. */
437d30ea906Sjfb8856606 RTE_EVENT_TIMER_ARMED = 1,
438d30ea906Sjfb8856606 /**< Event timer successfully armed. */
439d30ea906Sjfb8856606 RTE_EVENT_TIMER_CANCELED = 2,
440d30ea906Sjfb8856606 /**< Event timer successfully canceled. */
441d30ea906Sjfb8856606 RTE_EVENT_TIMER_ERROR = -1,
442d30ea906Sjfb8856606 /**< Generic event timer error. */
443d30ea906Sjfb8856606 RTE_EVENT_TIMER_ERROR_TOOEARLY = -2,
444d30ea906Sjfb8856606 /**< Event timer timeout tick value is too small for the adapter to
445d30ea906Sjfb8856606 * handle, given its configured resolution.
446d30ea906Sjfb8856606 */
447d30ea906Sjfb8856606 RTE_EVENT_TIMER_ERROR_TOOLATE = -3,
448d30ea906Sjfb8856606 /**< Event timer timeout tick is greater than the maximum timeout.*/
449d30ea906Sjfb8856606 };
450d30ea906Sjfb8856606
451d30ea906Sjfb8856606 /**
452d30ea906Sjfb8856606 * The generic *rte_event_timer* structure to hold the event timer attributes
453d30ea906Sjfb8856606 * for arm and cancel operations.
454d30ea906Sjfb8856606 */
455d30ea906Sjfb8856606 RTE_STD_C11
456d30ea906Sjfb8856606 struct rte_event_timer {
457d30ea906Sjfb8856606 struct rte_event ev;
458d30ea906Sjfb8856606 /**<
459d30ea906Sjfb8856606 * Expiry event attributes. On successful event timer timeout,
460d30ea906Sjfb8856606 * the following attributes will be used to inject the expiry event to
461d30ea906Sjfb8856606 * the eventdev:
462d30ea906Sjfb8856606 * - event_queue_id: Targeted event queue id for expiry events.
463d30ea906Sjfb8856606 * - event_priority: Event priority of the event expiry event in the
464d30ea906Sjfb8856606 * event queue relative to other events.
465d30ea906Sjfb8856606 * - sched_type: Scheduling type of the expiry event.
466d30ea906Sjfb8856606 * - flow_id: Flow id of the expiry event.
467d30ea906Sjfb8856606 * - op: RTE_EVENT_OP_NEW
468d30ea906Sjfb8856606 * - event_type: RTE_EVENT_TYPE_TIMER
469d30ea906Sjfb8856606 */
470d30ea906Sjfb8856606 volatile enum rte_event_timer_state state;
471d30ea906Sjfb8856606 /**< State of the event timer. */
472d30ea906Sjfb8856606 uint64_t timeout_ticks;
473d30ea906Sjfb8856606 /**< Expiry timer ticks expressed in number of *timer_ticks_ns* from
474d30ea906Sjfb8856606 * now.
475d30ea906Sjfb8856606 * @see struct rte_event_timer_adapter_info::adapter_conf::timer_tick_ns
476d30ea906Sjfb8856606 */
477d30ea906Sjfb8856606 uint64_t impl_opaque[2];
478d30ea906Sjfb8856606 /**< Implementation-specific opaque data.
479d30ea906Sjfb8856606 * An event timer adapter implementation use this field to hold
480d30ea906Sjfb8856606 * implementation specific values to share between the arm and cancel
481d30ea906Sjfb8856606 * operations. The application should not modify this field.
482d30ea906Sjfb8856606 */
483d30ea906Sjfb8856606 uint8_t user_meta[0];
484d30ea906Sjfb8856606 /**< Memory to store user specific metadata.
485d30ea906Sjfb8856606 * The event timer adapter implementation should not modify this area.
486d30ea906Sjfb8856606 */
487d30ea906Sjfb8856606 } __rte_cache_aligned;
488d30ea906Sjfb8856606
489d30ea906Sjfb8856606 typedef uint16_t (*rte_event_timer_arm_burst_t)(
490d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter,
491d30ea906Sjfb8856606 struct rte_event_timer **tims,
492d30ea906Sjfb8856606 uint16_t nb_tims);
493d30ea906Sjfb8856606 /**< @internal Enable event timers to enqueue timer events upon expiry */
494d30ea906Sjfb8856606 typedef uint16_t (*rte_event_timer_arm_tmo_tick_burst_t)(
495d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter,
496d30ea906Sjfb8856606 struct rte_event_timer **tims,
497d30ea906Sjfb8856606 uint64_t timeout_tick,
498d30ea906Sjfb8856606 uint16_t nb_tims);
499d30ea906Sjfb8856606 /**< @internal Enable event timers with common expiration time */
500d30ea906Sjfb8856606 typedef uint16_t (*rte_event_timer_cancel_burst_t)(
501d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter,
502d30ea906Sjfb8856606 struct rte_event_timer **tims,
503d30ea906Sjfb8856606 uint16_t nb_tims);
504d30ea906Sjfb8856606 /**< @internal Prevent event timers from enqueuing timer events */
505d30ea906Sjfb8856606
506d30ea906Sjfb8856606 /**
507d30ea906Sjfb8856606 * @internal Data structure associated with each event timer adapter.
508d30ea906Sjfb8856606 */
509d30ea906Sjfb8856606 struct rte_event_timer_adapter {
510d30ea906Sjfb8856606 rte_event_timer_arm_burst_t arm_burst;
511d30ea906Sjfb8856606 /**< Pointer to driver arm_burst function. */
512d30ea906Sjfb8856606 rte_event_timer_arm_tmo_tick_burst_t arm_tmo_tick_burst;
513d30ea906Sjfb8856606 /**< Pointer to driver arm_tmo_tick_burst function. */
514d30ea906Sjfb8856606 rte_event_timer_cancel_burst_t cancel_burst;
515d30ea906Sjfb8856606 /**< Pointer to driver cancel function. */
516d30ea906Sjfb8856606 struct rte_event_timer_adapter_data *data;
517d30ea906Sjfb8856606 /**< Pointer to shared adapter data */
518d30ea906Sjfb8856606 const struct rte_event_timer_adapter_ops *ops;
519d30ea906Sjfb8856606 /**< Functions exported by adapter driver */
520d30ea906Sjfb8856606
521d30ea906Sjfb8856606 RTE_STD_C11
522d30ea906Sjfb8856606 uint8_t allocated : 1;
523d30ea906Sjfb8856606 /**< Flag to indicate that this adapter has been allocated */
524d30ea906Sjfb8856606 } __rte_cache_aligned;
525d30ea906Sjfb8856606
526d30ea906Sjfb8856606 #define ADAPTER_VALID_OR_ERR_RET(adapter, retval) do { \
527d30ea906Sjfb8856606 if (adapter == NULL || !adapter->allocated) \
528d30ea906Sjfb8856606 return retval; \
529d30ea906Sjfb8856606 } while (0)
530d30ea906Sjfb8856606
531d30ea906Sjfb8856606 #define FUNC_PTR_OR_ERR_RET(func, errval) do { \
532d30ea906Sjfb8856606 if ((func) == NULL) \
533d30ea906Sjfb8856606 return errval; \
534d30ea906Sjfb8856606 } while (0)
535d30ea906Sjfb8856606
536d30ea906Sjfb8856606 #define FUNC_PTR_OR_NULL_RET_WITH_ERRNO(func, errval) do { \
537d30ea906Sjfb8856606 if ((func) == NULL) { \
538d30ea906Sjfb8856606 rte_errno = errval; \
539d30ea906Sjfb8856606 return NULL; \
540d30ea906Sjfb8856606 } \
541d30ea906Sjfb8856606 } while (0)
542d30ea906Sjfb8856606
543d30ea906Sjfb8856606 /**
544d30ea906Sjfb8856606 * Arm a burst of event timers with separate expiration timeout tick for each
545d30ea906Sjfb8856606 * event timer.
546d30ea906Sjfb8856606 *
547d30ea906Sjfb8856606 * Before calling this function, the application allocates
548d30ea906Sjfb8856606 * ``struct rte_event_timer`` objects from mempool or huge page backed
549d30ea906Sjfb8856606 * application buffers of desired size. On successful allocation,
550d30ea906Sjfb8856606 * application updates the `struct rte_event_timer`` attributes such as
551d30ea906Sjfb8856606 * expiry event attributes, timeout ticks from now.
552d30ea906Sjfb8856606 * This function submits the event timer arm requests to the event timer adapter
553d30ea906Sjfb8856606 * and on expiry, the events will be injected to designated event queue.
554d30ea906Sjfb8856606 *
555d30ea906Sjfb8856606 * @param adapter
556d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
557d30ea906Sjfb8856606 * @param evtims
558d30ea906Sjfb8856606 * Pointer to an array of objects of type *rte_event_timer* structure.
559d30ea906Sjfb8856606 * @param nb_evtims
560d30ea906Sjfb8856606 * Number of event timers in the supplied array.
561d30ea906Sjfb8856606 *
562d30ea906Sjfb8856606 * @return
563d30ea906Sjfb8856606 * The number of successfully armed event timers. The return value can be less
564d30ea906Sjfb8856606 * than the value of the *nb_evtims* parameter. If the return value is less
565d30ea906Sjfb8856606 * than *nb_evtims*, the remaining event timers at the end of *evtims*
566d30ea906Sjfb8856606 * are not consumed, and the caller has to take care of them, and rte_errno
567d30ea906Sjfb8856606 * is set accordingly. Possible errno values include:
568d30ea906Sjfb8856606 * - EINVAL Invalid timer adapter, expiry event queue ID is invalid, or an
569d30ea906Sjfb8856606 * expiry event's sched type doesn't match the capabilities of the
570d30ea906Sjfb8856606 * destination event queue.
571d30ea906Sjfb8856606 * - EAGAIN Specified timer adapter is not running
572d30ea906Sjfb8856606 * - EALREADY A timer was encountered that was already armed
573d30ea906Sjfb8856606 */
5744418919fSjohnjiang static inline uint16_t
rte_event_timer_arm_burst(const struct rte_event_timer_adapter * adapter,struct rte_event_timer ** evtims,uint16_t nb_evtims)575d30ea906Sjfb8856606 rte_event_timer_arm_burst(const struct rte_event_timer_adapter *adapter,
576d30ea906Sjfb8856606 struct rte_event_timer **evtims,
577d30ea906Sjfb8856606 uint16_t nb_evtims)
578d30ea906Sjfb8856606 {
579d30ea906Sjfb8856606 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
580d30ea906Sjfb8856606 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
581d30ea906Sjfb8856606 FUNC_PTR_OR_ERR_RET(adapter->arm_burst, -EINVAL);
582d30ea906Sjfb8856606 #endif
583*2d9fd380Sjfb8856606 rte_eventdev_trace_timer_arm_burst(adapter, (void **)evtims,
584*2d9fd380Sjfb8856606 nb_evtims);
585d30ea906Sjfb8856606 return adapter->arm_burst(adapter, evtims, nb_evtims);
586d30ea906Sjfb8856606 }
587d30ea906Sjfb8856606
588d30ea906Sjfb8856606 /**
589d30ea906Sjfb8856606 * Arm a burst of event timers with same expiration timeout tick.
590d30ea906Sjfb8856606 *
591d30ea906Sjfb8856606 * Provides the same functionality as ``rte_event_timer_arm_burst()``, except
592d30ea906Sjfb8856606 * that application can use this API when all the event timers have the
593d30ea906Sjfb8856606 * same timeout expiration tick. This specialized function can provide the
594d30ea906Sjfb8856606 * additional hint to the adapter implementation and optimize if possible.
595d30ea906Sjfb8856606 *
596d30ea906Sjfb8856606 * @param adapter
597d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
598d30ea906Sjfb8856606 * @param evtims
599d30ea906Sjfb8856606 * Points to an array of objects of type *rte_event_timer* structure.
600d30ea906Sjfb8856606 * @param timeout_ticks
601d30ea906Sjfb8856606 * The number of ticks in which the timers should expire.
602d30ea906Sjfb8856606 * @param nb_evtims
603d30ea906Sjfb8856606 * Number of event timers in the supplied array.
604d30ea906Sjfb8856606 *
605d30ea906Sjfb8856606 * @return
606d30ea906Sjfb8856606 * The number of successfully armed event timers. The return value can be less
607d30ea906Sjfb8856606 * than the value of the *nb_evtims* parameter. If the return value is less
608d30ea906Sjfb8856606 * than *nb_evtims*, the remaining event timers at the end of *evtims*
609d30ea906Sjfb8856606 * are not consumed, and the caller has to take care of them, and rte_errno
610d30ea906Sjfb8856606 * is set accordingly. Possible errno values include:
611d30ea906Sjfb8856606 * - EINVAL Invalid timer adapter, expiry event queue ID is invalid, or an
612d30ea906Sjfb8856606 * expiry event's sched type doesn't match the capabilities of the
613d30ea906Sjfb8856606 * destination event queue.
614d30ea906Sjfb8856606 * - EAGAIN Specified event timer adapter is not running
615d30ea906Sjfb8856606 * - EALREADY A timer was encountered that was already armed
616d30ea906Sjfb8856606 */
6174418919fSjohnjiang static inline uint16_t
rte_event_timer_arm_tmo_tick_burst(const struct rte_event_timer_adapter * adapter,struct rte_event_timer ** evtims,const uint64_t timeout_ticks,const uint16_t nb_evtims)618d30ea906Sjfb8856606 rte_event_timer_arm_tmo_tick_burst(
619d30ea906Sjfb8856606 const struct rte_event_timer_adapter *adapter,
620d30ea906Sjfb8856606 struct rte_event_timer **evtims,
621d30ea906Sjfb8856606 const uint64_t timeout_ticks,
622d30ea906Sjfb8856606 const uint16_t nb_evtims)
623d30ea906Sjfb8856606 {
624d30ea906Sjfb8856606 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
625d30ea906Sjfb8856606 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
626d30ea906Sjfb8856606 FUNC_PTR_OR_ERR_RET(adapter->arm_tmo_tick_burst, -EINVAL);
627d30ea906Sjfb8856606 #endif
628*2d9fd380Sjfb8856606 rte_eventdev_trace_timer_arm_tmo_tick_burst(adapter, timeout_ticks,
629*2d9fd380Sjfb8856606 (void **)evtims, nb_evtims);
630d30ea906Sjfb8856606 return adapter->arm_tmo_tick_burst(adapter, evtims, timeout_ticks,
631d30ea906Sjfb8856606 nb_evtims);
632d30ea906Sjfb8856606 }
633d30ea906Sjfb8856606
634d30ea906Sjfb8856606 /**
635d30ea906Sjfb8856606 * Cancel a burst of event timers from being scheduled to the event device.
636d30ea906Sjfb8856606 *
637d30ea906Sjfb8856606 * @param adapter
638d30ea906Sjfb8856606 * A pointer to an event timer adapter structure.
639d30ea906Sjfb8856606 * @param evtims
640d30ea906Sjfb8856606 * Points to an array of objects of type *rte_event_timer* structure
641d30ea906Sjfb8856606 * @param nb_evtims
642d30ea906Sjfb8856606 * Number of event timer instances in the supplied array.
643d30ea906Sjfb8856606 *
644d30ea906Sjfb8856606 * @return
645d30ea906Sjfb8856606 * The number of successfully canceled event timers. The return value can be
646d30ea906Sjfb8856606 * less than the value of the *nb_evtims* parameter. If the return value is
647d30ea906Sjfb8856606 * less than *nb_evtims*, the remaining event timers at the end of *evtims*
648d30ea906Sjfb8856606 * are not consumed, and the caller has to take care of them, and rte_errno
649d30ea906Sjfb8856606 * is set accordingly. Possible errno values include:
650d30ea906Sjfb8856606 * - EINVAL Invalid timer adapter identifier
651d30ea906Sjfb8856606 * - EAGAIN Specified timer adapter is not running
652d30ea906Sjfb8856606 * - EALREADY A timer was encountered that was already canceled
653d30ea906Sjfb8856606 */
6544418919fSjohnjiang static inline uint16_t
rte_event_timer_cancel_burst(const struct rte_event_timer_adapter * adapter,struct rte_event_timer ** evtims,uint16_t nb_evtims)655d30ea906Sjfb8856606 rte_event_timer_cancel_burst(const struct rte_event_timer_adapter *adapter,
656d30ea906Sjfb8856606 struct rte_event_timer **evtims,
657d30ea906Sjfb8856606 uint16_t nb_evtims)
658d30ea906Sjfb8856606 {
659d30ea906Sjfb8856606 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
660d30ea906Sjfb8856606 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
661d30ea906Sjfb8856606 FUNC_PTR_OR_ERR_RET(adapter->cancel_burst, -EINVAL);
662d30ea906Sjfb8856606 #endif
663*2d9fd380Sjfb8856606 rte_eventdev_trace_timer_cancel_burst(adapter, (void **)evtims,
664*2d9fd380Sjfb8856606 nb_evtims);
665d30ea906Sjfb8856606 return adapter->cancel_burst(adapter, evtims, nb_evtims);
666d30ea906Sjfb8856606 }
667d30ea906Sjfb8856606
668d30ea906Sjfb8856606 #endif /* __RTE_EVENT_TIMER_ADAPTER_H__ */
669