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