1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017-2018 Intel Corporation.
9 #include <rte_memzone.h>
10 #include <rte_memory.h>
12 #include <rte_errno.h>
14 #include "rte_eventdev.h"
15 #include "rte_eventdev_pmd.h"
16 #include "rte_event_timer_adapter.h"
17 #include "rte_event_timer_adapter_pmd.h"
19 #define DATA_MZ_NAME_MAX_LEN 64
20 #define DATA_MZ_NAME_FORMAT "rte_event_timer_adapter_data_%d"
22 static int evtim_logtype;
24 static struct rte_event_timer_adapter adapters[RTE_EVENT_TIMER_ADAPTER_NUM_MAX];
26 #define EVTIM_LOG(level, logtype, ...) \
27 rte_log(RTE_LOG_ ## level, logtype, \
28 RTE_FMT("EVTIMER: %s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) \
29 "\n", __func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,)))
31 #define EVTIM_LOG_ERR(...) EVTIM_LOG(ERR, evtim_logtype, __VA_ARGS__)
33 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
34 #define EVTIM_LOG_DBG(...) \
35 EVTIM_LOG(DEBUG, evtim_logtype, __VA_ARGS__)
37 #define EVTIM_LOG_DBG(...) (void)0
41 default_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id,
44 struct rte_event_timer_adapter *adapter;
45 struct rte_eventdev *dev;
46 struct rte_event_dev_config dev_conf;
47 struct rte_event_port_conf *port_conf, def_port_conf = {0};
53 RTE_SET_USED(event_dev_id);
55 adapter = &adapters[id];
56 dev = &rte_eventdevs[adapter->data->event_dev_id];
57 dev_id = dev->data->dev_id;
58 dev_conf = dev->data->dev_conf;
60 started = dev->data->dev_started;
62 rte_event_dev_stop(dev_id);
64 port_id = dev_conf.nb_event_ports;
65 dev_conf.nb_event_ports += 1;
66 ret = rte_event_dev_configure(dev_id, &dev_conf);
68 EVTIM_LOG_ERR("failed to configure event dev %u\n", dev_id);
70 if (rte_event_dev_start(dev_id))
79 port_conf = &def_port_conf;
80 ret = rte_event_port_default_conf_get(dev_id, port_id,
86 ret = rte_event_port_setup(dev_id, port_id, port_conf);
88 EVTIM_LOG_ERR("failed to setup event port %u on event dev %u\n",
93 *event_port_id = port_id;
96 ret = rte_event_dev_start(dev_id);
101 struct rte_event_timer_adapter * __rte_experimental
102 rte_event_timer_adapter_create(const struct rte_event_timer_adapter_conf *conf)
104 return rte_event_timer_adapter_create_ext(conf, default_port_conf_cb,
108 struct rte_event_timer_adapter * __rte_experimental
109 rte_event_timer_adapter_create_ext(
110 const struct rte_event_timer_adapter_conf *conf,
111 rte_event_timer_adapter_port_conf_cb_t conf_cb,
115 struct rte_event_timer_adapter *adapter;
116 const struct rte_memzone *mz;
117 char mz_name[DATA_MZ_NAME_MAX_LEN];
119 struct rte_eventdev *dev;
126 /* Check eventdev ID */
127 if (!rte_event_pmd_is_valid_dev(conf->event_dev_id)) {
131 dev = &rte_eventdevs[conf->event_dev_id];
133 adapter_id = conf->timer_adapter_id;
135 /* Check that adapter_id is in range */
136 if (adapter_id >= RTE_EVENT_TIMER_ADAPTER_NUM_MAX) {
141 /* Check adapter ID not already allocated */
142 adapter = &adapters[adapter_id];
143 if (adapter->allocated) {
148 /* Create shared data area. */
149 n = snprintf(mz_name, sizeof(mz_name), DATA_MZ_NAME_FORMAT, adapter_id);
150 if (n >= (int)sizeof(mz_name)) {
154 mz = rte_memzone_reserve(mz_name,
155 sizeof(struct rte_event_timer_adapter_data),
158 /* rte_errno set by rte_memzone_reserve */
161 adapter->data = mz->addr;
162 memset(adapter->data, 0, sizeof(struct rte_event_timer_adapter_data));
164 adapter->data->mz = mz;
165 adapter->data->event_dev_id = conf->event_dev_id;
166 adapter->data->id = adapter_id;
167 adapter->data->socket_id = conf->socket_id;
168 adapter->data->conf = *conf; /* copy conf structure */
170 /* Query eventdev PMD for timer adapter capabilities and ops */
171 ret = dev->dev_ops->timer_adapter_caps_get(dev,
172 adapter->data->conf.flags,
173 &adapter->data->caps,
180 if (!(adapter->data->caps &
181 RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
182 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(conf_cb, -EINVAL);
183 ret = conf_cb(adapter->data->id, adapter->data->event_dev_id,
184 &adapter->data->event_port_id, conf_arg);
191 /* Allow driver to do some setup */
192 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(adapter->ops->init, -ENOTSUP);
193 ret = adapter->ops->init(adapter);
199 /* Set fast-path function pointers */
200 adapter->arm_burst = adapter->ops->arm_burst;
201 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
202 adapter->cancel_burst = adapter->ops->cancel_burst;
204 adapter->allocated = 1;
209 rte_memzone_free(adapter->data->mz);
213 int __rte_experimental
214 rte_event_timer_adapter_get_info(const struct rte_event_timer_adapter *adapter,
215 struct rte_event_timer_adapter_info *adapter_info)
217 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
219 if (adapter->ops->get_info)
220 /* let driver set values it knows */
221 adapter->ops->get_info(adapter, adapter_info);
223 /* Set common values */
224 adapter_info->conf = adapter->data->conf;
225 adapter_info->event_dev_port_id = adapter->data->event_port_id;
226 adapter_info->caps = adapter->data->caps;
231 int __rte_experimental
232 rte_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter)
236 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
237 FUNC_PTR_OR_ERR_RET(adapter->ops->start, -EINVAL);
239 ret = adapter->ops->start(adapter);
243 adapter->data->started = 1;
248 int __rte_experimental
249 rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter)
253 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
254 FUNC_PTR_OR_ERR_RET(adapter->ops->stop, -EINVAL);
256 if (adapter->data->started == 0) {
257 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already stopped",
262 ret = adapter->ops->stop(adapter);
266 adapter->data->started = 0;
271 struct rte_event_timer_adapter * __rte_experimental
272 rte_event_timer_adapter_lookup(uint16_t adapter_id)
274 char name[DATA_MZ_NAME_MAX_LEN];
275 const struct rte_memzone *mz;
276 struct rte_event_timer_adapter_data *data;
277 struct rte_event_timer_adapter *adapter;
279 struct rte_eventdev *dev;
281 if (adapters[adapter_id].allocated)
282 return &adapters[adapter_id]; /* Adapter is already loaded */
284 snprintf(name, DATA_MZ_NAME_MAX_LEN, DATA_MZ_NAME_FORMAT, adapter_id);
285 mz = rte_memzone_lookup(name);
293 adapter = &adapters[data->id];
294 adapter->data = data;
296 dev = &rte_eventdevs[adapter->data->event_dev_id];
298 /* Query eventdev PMD for timer adapter capabilities and ops */
299 ret = dev->dev_ops->timer_adapter_caps_get(dev,
300 adapter->data->conf.flags,
301 &adapter->data->caps,
308 /* Set fast-path function pointers */
309 adapter->arm_burst = adapter->ops->arm_burst;
310 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
311 adapter->cancel_burst = adapter->ops->cancel_burst;
313 adapter->allocated = 1;
318 int __rte_experimental
319 rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter)
323 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
324 FUNC_PTR_OR_ERR_RET(adapter->ops->uninit, -EINVAL);
326 if (adapter->data->started == 1) {
327 EVTIM_LOG_ERR("event timer adapter %"PRIu8" must be stopped "
328 "before freeing", adapter->data->id);
332 /* free impl priv data */
333 ret = adapter->ops->uninit(adapter);
337 /* free shared data area */
338 ret = rte_memzone_free(adapter->data->mz);
342 adapter->data = NULL;
343 adapter->allocated = 0;
348 int __rte_experimental
349 rte_event_timer_adapter_service_id_get(struct rte_event_timer_adapter *adapter,
350 uint32_t *service_id)
352 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
354 if (adapter->data->service_inited && service_id != NULL)
355 *service_id = adapter->data->service_id;
357 return adapter->data->service_inited ? 0 : -ESRCH;
360 int __rte_experimental
361 rte_event_timer_adapter_stats_get(struct rte_event_timer_adapter *adapter,
362 struct rte_event_timer_adapter_stats *stats)
364 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
365 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_get, -EINVAL);
369 return adapter->ops->stats_get(adapter, stats);
372 int __rte_experimental
373 rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter)
375 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
376 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_reset, -EINVAL);
377 return adapter->ops->stats_reset(adapter);
380 RTE_INIT(event_timer_adapter_init_log);
382 event_timer_adapter_init_log(void)
384 evtim_logtype = rte_log_register("lib.eventdev.adapter.timer");
385 if (evtim_logtype >= 0)
386 rte_log_set_level(evtim_logtype, RTE_LOG_NOTICE);