Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : :
7 : : #include "cnxk_eventdev.h"
8 : : #include "cnxk_eventdev_dp.h"
9 : :
10 : : void
11 : 0 : cnxk_sso_info_get(struct cnxk_sso_evdev *dev,
12 : : struct rte_event_dev_info *dev_info)
13 : : {
14 : :
15 : 0 : dev_info->min_dequeue_timeout_ns = dev->min_dequeue_timeout_ns;
16 : 0 : dev_info->max_dequeue_timeout_ns = dev->max_dequeue_timeout_ns;
17 : 0 : dev_info->max_event_queues = dev->max_event_queues;
18 : 0 : dev_info->max_event_queue_flows = (1ULL << 20);
19 : 0 : dev_info->max_event_queue_priority_levels = 8;
20 : 0 : dev_info->max_event_priority_levels = 1;
21 : 0 : dev_info->max_event_ports = dev->max_event_ports;
22 : 0 : dev_info->max_event_port_dequeue_depth = 1;
23 : 0 : dev_info->max_event_port_enqueue_depth = 1;
24 : 0 : dev_info->max_num_events = dev->max_num_events;
25 : 0 : dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_ATOMIC |
26 : : RTE_EVENT_DEV_CAP_ORDERED |
27 : : RTE_EVENT_DEV_CAP_PARALLEL |
28 : : RTE_EVENT_DEV_CAP_QUEUE_QOS |
29 : : RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED |
30 : : RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES |
31 : : RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK |
32 : : RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT |
33 : : RTE_EVENT_DEV_CAP_NONSEQ_MODE |
34 : : RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |
35 : : RTE_EVENT_DEV_CAP_MAINTENANCE_FREE |
36 : : RTE_EVENT_DEV_CAP_RUNTIME_QUEUE_ATTR |
37 : : RTE_EVENT_DEV_CAP_PROFILE_LINK;
38 : 0 : dev_info->max_profiles_per_port = CNXK_SSO_MAX_PROFILES;
39 : 0 : }
40 : :
41 : : int
42 : 0 : cnxk_sso_xaq_allocate(struct cnxk_sso_evdev *dev)
43 : : {
44 : : uint32_t xae_cnt;
45 : : int rc;
46 : :
47 [ # # ]: 0 : if (dev->num_events > 0)
48 : 0 : xae_cnt = dev->num_events;
49 : : else
50 : 0 : xae_cnt = dev->sso.feat.iue;
51 : :
52 [ # # ]: 0 : if (dev->xae_cnt)
53 : 0 : xae_cnt += dev->xae_cnt;
54 [ # # ]: 0 : if (dev->adptr_xae_cnt)
55 : 0 : xae_cnt += (dev->adptr_xae_cnt);
56 : :
57 : 0 : plt_sso_dbg("Configuring %d xae buffers", xae_cnt);
58 : 0 : rc = roc_sso_hwgrp_init_xaq_aura(&dev->sso, xae_cnt);
59 [ # # ]: 0 : if (rc < 0) {
60 : 0 : plt_err("Failed to configure XAQ aura");
61 : 0 : return rc;
62 : : }
63 : 0 : dev->xaq_lmt = dev->sso.xaq.xaq_lmt;
64 : 0 : dev->fc_iova = (uint64_t)dev->sso.xaq.fc;
65 : :
66 : 0 : return roc_sso_hwgrp_alloc_xaq(
67 : : &dev->sso,
68 : 0 : roc_npa_aura_handle_to_aura(dev->sso.xaq.aura_handle),
69 : 0 : dev->nb_event_queues);
70 : : }
71 : :
72 : : int
73 [ # # ]: 0 : cnxk_sso_xae_reconfigure(struct rte_eventdev *event_dev)
74 : : {
75 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
76 : : int rc = 0;
77 : :
78 [ # # ]: 0 : if (event_dev->data->dev_started)
79 : 0 : event_dev->dev_ops->dev_stop(event_dev);
80 : :
81 : 0 : rc = cnxk_sso_xaq_allocate(dev);
82 [ # # ]: 0 : if (rc < 0) {
83 : 0 : plt_err("Failed to alloc XAQ %d", rc);
84 : 0 : return rc;
85 : : }
86 : :
87 : : rte_mb();
88 [ # # ]: 0 : if (event_dev->data->dev_started)
89 : 0 : event_dev->dev_ops->dev_start(event_dev);
90 : :
91 : : return 0;
92 : : }
93 : :
94 : : int
95 : 0 : cnxk_setup_event_ports(const struct rte_eventdev *event_dev,
96 : : cnxk_sso_init_hws_mem_t init_hws_fn,
97 : : cnxk_sso_hws_setup_t setup_hws_fn)
98 : : {
99 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
100 : : int i;
101 : :
102 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
103 : : struct cnxk_sso_hws_cookie *ws_cookie;
104 : : void *ws;
105 : :
106 : : /* Free memory prior to re-allocation if needed */
107 [ # # ]: 0 : if (event_dev->data->ports[i] != NULL)
108 : : ws = event_dev->data->ports[i];
109 : : else
110 : 0 : ws = init_hws_fn(dev, i);
111 [ # # ]: 0 : if (ws == NULL)
112 : 0 : goto hws_fini;
113 : : ws_cookie = cnxk_sso_hws_get_cookie(ws);
114 : 0 : ws_cookie->event_dev = event_dev;
115 : 0 : ws_cookie->configured = 1;
116 : 0 : event_dev->data->ports[i] = ws;
117 : 0 : cnxk_sso_port_setup((struct rte_eventdev *)(uintptr_t)event_dev,
118 : : i, setup_hws_fn);
119 : : }
120 : :
121 : : return 0;
122 : : hws_fini:
123 [ # # ]: 0 : for (i = i - 1; i >= 0; i--) {
124 : 0 : rte_free(cnxk_sso_hws_get_cookie(event_dev->data->ports[i]));
125 : 0 : event_dev->data->ports[i] = NULL;
126 : : }
127 : : return -ENOMEM;
128 : : }
129 : :
130 : : void
131 : 0 : cnxk_sso_restore_links(const struct rte_eventdev *event_dev,
132 : : cnxk_sso_link_t link_fn)
133 : : {
134 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
135 : : uint16_t *links_map, hwgrp[CNXK_SSO_MAX_HWGRP];
136 : : int i, j, k;
137 : :
138 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
139 [ # # ]: 0 : for (k = 0; k < CNXK_SSO_MAX_PROFILES; k++) {
140 : : uint16_t nb_hwgrp = 0;
141 : :
142 : 0 : links_map = event_dev->data->links_map[k];
143 : : /* Point links_map to this port specific area */
144 : 0 : links_map += (i * RTE_EVENT_MAX_QUEUES_PER_DEV);
145 : :
146 [ # # ]: 0 : for (j = 0; j < dev->nb_event_queues; j++) {
147 [ # # ]: 0 : if (links_map[j] == 0xdead)
148 : 0 : continue;
149 : 0 : hwgrp[nb_hwgrp] = j;
150 : 0 : nb_hwgrp++;
151 : : }
152 : :
153 : 0 : link_fn(dev, event_dev->data->ports[i], hwgrp, nb_hwgrp, k);
154 : : }
155 : : }
156 : 0 : }
157 : :
158 : : int
159 : 0 : cnxk_sso_dev_validate(const struct rte_eventdev *event_dev, uint32_t deq_depth,
160 : : uint32_t enq_depth)
161 : : {
162 [ # # ]: 0 : struct rte_event_dev_config *conf = &event_dev->data->dev_conf;
163 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
164 : : uint32_t deq_tmo_ns;
165 : :
166 : 0 : deq_tmo_ns = conf->dequeue_timeout_ns;
167 : :
168 [ # # # # ]: 0 : if (deq_tmo_ns && (deq_tmo_ns < dev->min_dequeue_timeout_ns ||
169 [ # # ]: 0 : deq_tmo_ns > dev->max_dequeue_timeout_ns)) {
170 : 0 : plt_err("Unsupported dequeue timeout requested");
171 : 0 : return -EINVAL;
172 : : }
173 : :
174 [ # # ]: 0 : if (conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT) {
175 [ # # ]: 0 : if (deq_tmo_ns == 0)
176 : 0 : deq_tmo_ns = dev->min_dequeue_timeout_ns;
177 : 0 : dev->is_timeout_deq = 1;
178 : : }
179 : :
180 : 0 : dev->deq_tmo_ns = deq_tmo_ns;
181 : :
182 [ # # # # ]: 0 : if (!conf->nb_event_queues || !conf->nb_event_ports ||
183 [ # # ]: 0 : conf->nb_event_ports > dev->max_event_ports ||
184 [ # # ]: 0 : conf->nb_event_queues > dev->max_event_queues) {
185 : 0 : plt_err("Unsupported event queues/ports requested");
186 : 0 : return -EINVAL;
187 : : }
188 : :
189 [ # # ]: 0 : if (conf->nb_event_port_dequeue_depth > deq_depth) {
190 : 0 : plt_err("Unsupported event port deq depth requested");
191 : 0 : return -EINVAL;
192 : : }
193 : :
194 [ # # ]: 0 : if (conf->nb_event_port_enqueue_depth > enq_depth) {
195 : 0 : plt_err("Unsupported event port enq depth requested");
196 : 0 : return -EINVAL;
197 : : }
198 : :
199 : 0 : roc_sso_rsrc_fini(&dev->sso);
200 : 0 : roc_sso_hwgrp_free_xaq_aura(&dev->sso, dev->sso.nb_hwgrp);
201 : :
202 : 0 : dev->nb_event_queues = conf->nb_event_queues;
203 : 0 : dev->nb_event_ports = conf->nb_event_ports;
204 : 0 : dev->num_events = conf->nb_events_limit;
205 : :
206 : 0 : return 0;
207 : : }
208 : :
209 : : void
210 : 0 : cnxk_sso_queue_def_conf(struct rte_eventdev *event_dev, uint8_t queue_id,
211 : : struct rte_event_queue_conf *queue_conf)
212 : : {
213 : : RTE_SET_USED(event_dev);
214 : : RTE_SET_USED(queue_id);
215 : :
216 : 0 : queue_conf->nb_atomic_flows = (1ULL << 20);
217 : 0 : queue_conf->nb_atomic_order_sequences = (1ULL << 20);
218 : 0 : queue_conf->event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
219 : 0 : queue_conf->priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
220 : 0 : queue_conf->weight = RTE_EVENT_QUEUE_WEIGHT_LOWEST;
221 : 0 : queue_conf->affinity = RTE_EVENT_QUEUE_AFFINITY_HIGHEST;
222 : 0 : }
223 : :
224 : : int
225 : 0 : cnxk_sso_queue_setup(struct rte_eventdev *event_dev, uint8_t queue_id,
226 : : const struct rte_event_queue_conf *queue_conf)
227 : : {
228 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
229 : : uint8_t priority, weight, affinity;
230 : :
231 : 0 : priority = CNXK_QOS_NORMALIZE(queue_conf->priority, 0,
232 : : RTE_EVENT_DEV_PRIORITY_LOWEST,
233 : : CNXK_SSO_PRIORITY_CNT);
234 : 0 : weight = CNXK_QOS_NORMALIZE(queue_conf->weight, CNXK_SSO_WEIGHT_MIN,
235 : : RTE_EVENT_QUEUE_WEIGHT_HIGHEST, CNXK_SSO_WEIGHT_CNT);
236 : 0 : affinity = CNXK_QOS_NORMALIZE(queue_conf->affinity, 0, RTE_EVENT_QUEUE_AFFINITY_HIGHEST,
237 : : CNXK_SSO_AFFINITY_CNT);
238 : :
239 : 0 : plt_sso_dbg("Queue=%u prio=%u weight=%u affinity=%u", queue_id,
240 : : priority, weight, affinity);
241 : :
242 : 0 : return roc_sso_hwgrp_set_priority(&dev->sso, queue_id, weight, affinity,
243 : : priority);
244 : : }
245 : :
246 : : void
247 : 0 : cnxk_sso_queue_release(struct rte_eventdev *event_dev, uint8_t queue_id)
248 : : {
249 : : RTE_SET_USED(event_dev);
250 : : RTE_SET_USED(queue_id);
251 : 0 : }
252 : :
253 : : int
254 [ # # # # : 0 : cnxk_sso_queue_attribute_set(struct rte_eventdev *event_dev, uint8_t queue_id,
# ]
255 : : uint32_t attr_id, uint64_t attr_value)
256 : : {
257 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
258 : : uint8_t priority, weight, affinity;
259 : : struct rte_event_queue_conf *conf;
260 : :
261 : 0 : conf = &event_dev->data->queues_cfg[queue_id];
262 : :
263 [ # # # # : 0 : switch (attr_id) {
# ]
264 : 0 : case RTE_EVENT_QUEUE_ATTR_PRIORITY:
265 : 0 : conf->priority = attr_value;
266 : 0 : break;
267 : 0 : case RTE_EVENT_QUEUE_ATTR_WEIGHT:
268 : 0 : conf->weight = attr_value;
269 : 0 : break;
270 : 0 : case RTE_EVENT_QUEUE_ATTR_AFFINITY:
271 : 0 : conf->affinity = attr_value;
272 : 0 : break;
273 : 0 : case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_FLOWS:
274 : : case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_ORDER_SEQUENCES:
275 : : case RTE_EVENT_QUEUE_ATTR_EVENT_QUEUE_CFG:
276 : : case RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE:
277 : : /* FALLTHROUGH */
278 : 0 : plt_sso_dbg("Unsupported attribute id %u", attr_id);
279 : 0 : return -ENOTSUP;
280 : 0 : default:
281 : 0 : plt_err("Invalid attribute id %u", attr_id);
282 : 0 : return -EINVAL;
283 : : }
284 : :
285 : 0 : priority = CNXK_QOS_NORMALIZE(conf->priority, 0,
286 : : RTE_EVENT_DEV_PRIORITY_LOWEST,
287 : : CNXK_SSO_PRIORITY_CNT);
288 : 0 : weight = CNXK_QOS_NORMALIZE(conf->weight, CNXK_SSO_WEIGHT_MIN,
289 : : RTE_EVENT_QUEUE_WEIGHT_HIGHEST, CNXK_SSO_WEIGHT_CNT);
290 : 0 : affinity = CNXK_QOS_NORMALIZE(conf->affinity, 0, RTE_EVENT_QUEUE_AFFINITY_HIGHEST,
291 : : CNXK_SSO_AFFINITY_CNT);
292 : :
293 : 0 : return roc_sso_hwgrp_set_priority(&dev->sso, queue_id, weight, affinity,
294 : : priority);
295 : : }
296 : :
297 : : void
298 : 0 : cnxk_sso_port_def_conf(struct rte_eventdev *event_dev, uint8_t port_id,
299 : : struct rte_event_port_conf *port_conf)
300 : : {
301 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
302 : :
303 : : RTE_SET_USED(port_id);
304 : 0 : port_conf->new_event_threshold = dev->max_num_events;
305 : 0 : port_conf->dequeue_depth = 1;
306 : 0 : port_conf->enqueue_depth = 1;
307 : 0 : }
308 : :
309 : : int
310 : 0 : cnxk_sso_port_setup(struct rte_eventdev *event_dev, uint8_t port_id,
311 : : cnxk_sso_hws_setup_t hws_setup_fn)
312 : : {
313 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
314 : : uintptr_t grp_base = 0;
315 : :
316 : 0 : plt_sso_dbg("Port=%d", port_id);
317 [ # # ]: 0 : if (event_dev->data->ports[port_id] == NULL) {
318 : 0 : plt_err("Invalid port Id %d", port_id);
319 : 0 : return -EINVAL;
320 : : }
321 : :
322 : 0 : grp_base = roc_sso_hwgrp_base_get(&dev->sso, 0);
323 [ # # ]: 0 : if (grp_base == 0) {
324 : 0 : plt_err("Failed to get grp base addr");
325 : 0 : return -EINVAL;
326 : : }
327 : :
328 : 0 : hws_setup_fn(dev, event_dev->data->ports[port_id], grp_base);
329 : 0 : plt_sso_dbg("Port=%d ws=%p", port_id, event_dev->data->ports[port_id]);
330 : : rte_mb();
331 : :
332 : 0 : return 0;
333 : : }
334 : :
335 : : int
336 [ # # ]: 0 : cnxk_sso_timeout_ticks(struct rte_eventdev *event_dev, uint64_t ns,
337 : : uint64_t *tmo_ticks)
338 : : {
339 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
340 : :
341 [ # # ]: 0 : *tmo_ticks = dev->deq_tmo_ns ? ns / dev->deq_tmo_ns : 0;
342 : 0 : return 0;
343 : : }
344 : :
345 : : void
346 : 0 : cnxk_sso_dump(struct rte_eventdev *event_dev, FILE *f)
347 : : {
348 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
349 : :
350 : 0 : roc_sso_dump(&dev->sso, dev->sso.nb_hws, dev->sso.nb_hwgrp, f);
351 : 0 : }
352 : :
353 : : static void
354 : 0 : cnxk_handle_event(void *arg, struct rte_event event)
355 : : {
356 : : struct rte_eventdev *event_dev = arg;
357 : :
358 [ # # ]: 0 : if (event_dev->dev_ops->dev_stop_flush != NULL)
359 : 0 : event_dev->dev_ops->dev_stop_flush(
360 : 0 : event_dev->data->dev_id, event,
361 : 0 : event_dev->data->dev_stop_flush_arg);
362 : 0 : }
363 : :
364 : : static void
365 : 0 : cnxk_sso_cleanup(struct rte_eventdev *event_dev, cnxk_sso_hws_reset_t reset_fn,
366 : : cnxk_sso_hws_flush_t flush_fn, uint8_t enable)
367 : : {
368 : : uint8_t pend_list[RTE_EVENT_MAX_QUEUES_PER_DEV], pend_cnt, new_pcnt;
369 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
370 : : uintptr_t hwgrp_base;
371 : : uint8_t queue_id, i;
372 : : void *ws;
373 : :
374 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
375 : 0 : ws = event_dev->data->ports[i];
376 : 0 : reset_fn(dev, ws);
377 : : }
378 : :
379 : : rte_mb();
380 : :
381 : : /* Consume all the events through HWS0 */
382 : 0 : ws = event_dev->data->ports[0];
383 : :
384 : : /* Starting list of queues to flush */
385 : 0 : pend_cnt = dev->nb_event_queues;
386 [ # # ]: 0 : for (i = 0; i < dev->nb_event_queues; i++)
387 : 0 : pend_list[i] = i;
388 : :
389 [ # # ]: 0 : while (pend_cnt) {
390 : : new_pcnt = 0;
391 [ # # ]: 0 : for (i = 0; i < pend_cnt; i++) {
392 : 0 : queue_id = pend_list[i];
393 : : hwgrp_base =
394 : 0 : roc_sso_hwgrp_base_get(&dev->sso, queue_id);
395 [ # # ]: 0 : if (flush_fn(ws, queue_id, hwgrp_base,
396 : : cnxk_handle_event, event_dev)) {
397 : 0 : pend_list[new_pcnt++] = queue_id;
398 : 0 : continue;
399 : : }
400 : : /* Enable/Disable SSO GGRP */
401 : 0 : plt_write64(enable, hwgrp_base + SSO_LF_GGRP_QCTL);
402 : : }
403 : : pend_cnt = new_pcnt;
404 : : }
405 : 0 : }
406 : :
407 : : int
408 : 0 : cnxk_sso_start(struct rte_eventdev *event_dev, cnxk_sso_hws_reset_t reset_fn,
409 : : cnxk_sso_hws_flush_t flush_fn)
410 : 0 : {
411 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
412 : 0 : struct roc_sso_hwgrp_qos qos[dev->qos_queue_cnt];
413 : : int i, rc;
414 : :
415 : 0 : plt_sso_dbg();
416 [ # # ]: 0 : for (i = 0; i < dev->qos_queue_cnt; i++) {
417 : 0 : qos[i].hwgrp = dev->qos_parse_data[i].queue;
418 : 0 : qos[i].iaq_prcnt = dev->qos_parse_data[i].iaq_prcnt;
419 : 0 : qos[i].taq_prcnt = dev->qos_parse_data[i].taq_prcnt;
420 : : }
421 : 0 : rc = roc_sso_hwgrp_qos_config(&dev->sso, qos, dev->qos_queue_cnt);
422 [ # # ]: 0 : if (rc < 0) {
423 : 0 : plt_sso_dbg("failed to configure HWGRP QoS rc = %d", rc);
424 : 0 : return -EINVAL;
425 : : }
426 : 0 : cnxk_sso_cleanup(event_dev, reset_fn, flush_fn, true);
427 : : rte_mb();
428 : :
429 : 0 : return 0;
430 : : }
431 : :
432 : : void
433 : 0 : cnxk_sso_stop(struct rte_eventdev *event_dev, cnxk_sso_hws_reset_t reset_fn,
434 : : cnxk_sso_hws_flush_t flush_fn)
435 : : {
436 : 0 : plt_sso_dbg();
437 : 0 : cnxk_sso_cleanup(event_dev, reset_fn, flush_fn, false);
438 : : rte_mb();
439 : 0 : }
440 : :
441 : : int
442 [ # # ]: 0 : cnxk_sso_close(struct rte_eventdev *event_dev, cnxk_sso_unlink_t unlink_fn)
443 : : {
444 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
445 : : uint16_t all_queues[CNXK_SSO_MAX_HWGRP];
446 : : uint16_t i, j;
447 : : void *ws;
448 : :
449 [ # # ]: 0 : if (!dev->configured)
450 : : return 0;
451 : :
452 [ # # ]: 0 : for (i = 0; i < dev->nb_event_queues; i++)
453 : 0 : all_queues[i] = i;
454 : :
455 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
456 : 0 : ws = event_dev->data->ports[i];
457 [ # # ]: 0 : for (j = 0; j < CNXK_SSO_MAX_PROFILES; j++)
458 : 0 : unlink_fn(dev, ws, all_queues, dev->nb_event_queues, j);
459 : 0 : rte_free(cnxk_sso_hws_get_cookie(ws));
460 : 0 : event_dev->data->ports[i] = NULL;
461 : : }
462 : :
463 : 0 : roc_sso_rsrc_fini(&dev->sso);
464 : :
465 : 0 : dev->fc_iova = 0;
466 : 0 : dev->configured = false;
467 : 0 : dev->is_timeout_deq = 0;
468 : 0 : dev->nb_event_ports = 0;
469 : 0 : dev->max_num_events = -1;
470 : 0 : dev->nb_event_queues = 0;
471 : 0 : dev->min_dequeue_timeout_ns = USEC2NSEC(1);
472 : 0 : dev->max_dequeue_timeout_ns = USEC2NSEC(0x3FF);
473 : :
474 : 0 : return 0;
475 : : }
476 : :
477 : : typedef void (*param_parse_t)(char *value, void *opaque);
478 : :
479 : : static void
480 : 0 : parse_queue_param(char *value, void *opaque)
481 : : {
482 : 0 : struct cnxk_sso_qos queue_qos = {0};
483 : : uint16_t *val = (uint16_t *)&queue_qos;
484 : : struct cnxk_sso_evdev *dev = opaque;
485 : 0 : char *tok = strtok(value, "-");
486 : : struct cnxk_sso_qos *old_ptr;
487 : :
488 [ # # ]: 0 : if (!strlen(value))
489 : 0 : return;
490 : :
491 [ # # ]: 0 : while (tok != NULL) {
492 : 0 : *val = atoi(tok);
493 : 0 : tok = strtok(NULL, "-");
494 : 0 : val++;
495 : : }
496 : :
497 [ # # ]: 0 : if (val != (&queue_qos.iaq_prcnt + 1)) {
498 : 0 : plt_err("Invalid QoS parameter expected [Qx-TAQ-IAQ]");
499 : 0 : return;
500 : : }
501 : :
502 : 0 : dev->qos_queue_cnt++;
503 : 0 : old_ptr = dev->qos_parse_data;
504 : 0 : dev->qos_parse_data = rte_realloc(
505 : : dev->qos_parse_data,
506 : 0 : sizeof(struct cnxk_sso_qos) * dev->qos_queue_cnt, 0);
507 [ # # ]: 0 : if (dev->qos_parse_data == NULL) {
508 : 0 : dev->qos_parse_data = old_ptr;
509 : 0 : dev->qos_queue_cnt--;
510 : 0 : return;
511 : : }
512 : 0 : dev->qos_parse_data[dev->qos_queue_cnt - 1] = queue_qos;
513 : : }
514 : :
515 : : static void
516 : 0 : parse_stash_param(char *value, void *opaque)
517 : : {
518 : 0 : struct cnxk_sso_stash queue_stash = {0};
519 : : struct cnxk_sso_evdev *dev = opaque;
520 : : struct cnxk_sso_stash *old_ptr;
521 : 0 : char *tok = strtok(value, "|");
522 : : uint16_t *val;
523 : :
524 [ # # ]: 0 : if (!strlen(value))
525 : 0 : return;
526 : :
527 : : val = (uint16_t *)&queue_stash;
528 [ # # ]: 0 : while (tok != NULL) {
529 : 0 : *val = atoi(tok);
530 : 0 : tok = strtok(NULL, "|");
531 : 0 : val++;
532 : : }
533 : :
534 [ # # ]: 0 : if (val != (&queue_stash.stash_length + 1)) {
535 : 0 : plt_err("Invalid QoS parameter expected [Qx|stash_offset|stash_length]");
536 : 0 : return;
537 : : }
538 : :
539 : 0 : dev->stash_cnt++;
540 : 0 : old_ptr = dev->stash_parse_data;
541 : 0 : dev->stash_parse_data =
542 : 0 : rte_realloc(dev->stash_parse_data,
543 : 0 : sizeof(struct cnxk_sso_stash) * dev->stash_cnt, 0);
544 [ # # ]: 0 : if (dev->stash_parse_data == NULL) {
545 : 0 : dev->stash_parse_data = old_ptr;
546 : 0 : dev->stash_cnt--;
547 : 0 : return;
548 : : }
549 : 0 : dev->stash_parse_data[dev->stash_cnt - 1] = queue_stash;
550 : : }
551 : :
552 : : static void
553 : 0 : parse_list(const char *value, void *opaque, param_parse_t fn)
554 : : {
555 : 0 : char *s = strdup(value);
556 : : char *start = NULL;
557 : : char *end = NULL;
558 : : char *f = s;
559 : :
560 [ # # ]: 0 : if (s == NULL)
561 : : return;
562 : :
563 [ # # ]: 0 : while (*s) {
564 [ # # ]: 0 : if (*s == '[')
565 : : start = s;
566 [ # # ]: 0 : else if (*s == ']')
567 : : end = s;
568 : :
569 [ # # ]: 0 : if (start && start < end) {
570 : 0 : *end = 0;
571 : 0 : fn(start + 1, opaque);
572 : : s = end;
573 : : start = end;
574 : : }
575 : 0 : s++;
576 : : }
577 : :
578 : 0 : free(f);
579 : : }
580 : :
581 : : static int
582 : 0 : parse_sso_kvargs_qos_dict(const char *key, const char *value, void *opaque)
583 : : {
584 : : RTE_SET_USED(key);
585 : :
586 : : /* Dict format [Qx-TAQ-IAQ][Qz-TAQ-IAQ] use '-' cause ',' isn't allowed.
587 : : * Everything is expressed in percentages, 0 represents default.
588 : : */
589 : 0 : parse_list(value, opaque, parse_queue_param);
590 : :
591 : 0 : return 0;
592 : : }
593 : :
594 : : static int
595 : 0 : parse_sso_kvargs_stash_dict(const char *key, const char *value, void *opaque)
596 : : {
597 : : RTE_SET_USED(key);
598 : :
599 : : /* Dict format [Qx|<stash_offset>|<stash_length>] use '|' cause ','
600 : : * isn't allowed.
601 : : */
602 : 0 : parse_list(value, opaque, parse_stash_param);
603 : :
604 : 0 : return 0;
605 : : }
606 : :
607 : : static void
608 : 0 : cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs)
609 : : {
610 : : struct rte_kvargs *kvlist;
611 : 0 : uint8_t single_ws = 0;
612 : :
613 [ # # ]: 0 : if (devargs == NULL)
614 : 0 : return;
615 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
616 [ # # ]: 0 : if (kvlist == NULL)
617 : : return;
618 : :
619 : 0 : rte_kvargs_process(kvlist, CNXK_SSO_XAE_CNT, &parse_kvargs_value,
620 : 0 : &dev->xae_cnt);
621 : 0 : rte_kvargs_process(kvlist, CNXK_SSO_GGRP_QOS,
622 : : &parse_sso_kvargs_qos_dict, dev);
623 : 0 : rte_kvargs_process(kvlist, CNXK_SSO_FORCE_BP, &parse_kvargs_flag,
624 : 0 : &dev->force_ena_bp);
625 : 0 : rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag,
626 : : &single_ws);
627 : 0 : rte_kvargs_process(kvlist, CNXK_SSO_STASH, &parse_sso_kvargs_stash_dict,
628 : : dev);
629 : 0 : dev->dual_ws = !single_ws;
630 : 0 : rte_kvargs_free(kvlist);
631 : : }
632 : :
633 : : int
634 : 0 : cnxk_sso_init(struct rte_eventdev *event_dev)
635 : : {
636 : : const struct rte_memzone *mz = NULL;
637 : : struct rte_pci_device *pci_dev;
638 : : struct cnxk_sso_evdev *dev;
639 : : int rc;
640 : :
641 : 0 : mz = rte_memzone_reserve(CNXK_SSO_MZ_NAME, sizeof(uint64_t),
642 : : SOCKET_ID_ANY, 0);
643 [ # # ]: 0 : if (mz == NULL) {
644 : 0 : plt_err("Failed to create eventdev memzone");
645 : 0 : return -ENOMEM;
646 : : }
647 : :
648 : : dev = cnxk_sso_pmd_priv(event_dev);
649 : 0 : dev->fc_cache_space = rte_zmalloc("fc_cache", PLT_CACHE_LINE_SIZE,
650 : : PLT_CACHE_LINE_SIZE);
651 [ # # ]: 0 : if (dev->fc_cache_space == NULL) {
652 : 0 : plt_memzone_free(mz);
653 : 0 : plt_err("Failed to reserve memory for XAQ fc cache");
654 : 0 : return -ENOMEM;
655 : : }
656 : :
657 : 0 : pci_dev = container_of(event_dev->dev, struct rte_pci_device, device);
658 : 0 : dev->sso.pci_dev = pci_dev;
659 : :
660 : 0 : *(uint64_t *)mz->addr = (uint64_t)dev;
661 : 0 : cnxk_sso_parse_devargs(dev, pci_dev->device.devargs);
662 : :
663 : : /* Initialize the base cnxk_dev object */
664 : 0 : rc = roc_sso_dev_init(&dev->sso);
665 [ # # ]: 0 : if (rc < 0) {
666 : 0 : plt_err("Failed to initialize RoC SSO rc=%d", rc);
667 : 0 : goto error;
668 : : }
669 : :
670 : 0 : dev->is_timeout_deq = 0;
671 : 0 : dev->min_dequeue_timeout_ns = USEC2NSEC(1);
672 : 0 : dev->max_dequeue_timeout_ns = USEC2NSEC(0x3FF);
673 : 0 : dev->max_num_events = -1;
674 : 0 : dev->nb_event_queues = 0;
675 : 0 : dev->nb_event_ports = 0;
676 : :
677 : 0 : cnxk_tim_init(&dev->sso);
678 : :
679 : 0 : return 0;
680 : :
681 : : error:
682 : 0 : rte_memzone_free(mz);
683 : 0 : return rc;
684 : : }
685 : :
686 : : int
687 : 0 : cnxk_sso_fini(struct rte_eventdev *event_dev)
688 : : {
689 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
690 : :
691 : : /* For secondary processes, nothing to be done */
692 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
693 : : return 0;
694 : :
695 : 0 : cnxk_tim_fini();
696 : 0 : roc_sso_rsrc_fini(&dev->sso);
697 : :
698 : 0 : return roc_sso_dev_fini(&dev->sso);
699 : : }
700 : :
701 : : int
702 : 0 : cnxk_sso_remove(struct rte_pci_device *pci_dev)
703 : : {
704 : 0 : return rte_event_pmd_pci_remove(pci_dev, cnxk_sso_fini);
705 : : }
706 : :
707 : : void
708 : 0 : cn9k_sso_set_rsrc(void *arg)
709 : : {
710 : : struct cnxk_sso_evdev *dev = arg;
711 : :
712 [ # # ]: 0 : if (dev->dual_ws)
713 : 0 : dev->max_event_ports = dev->sso.max_hws / CN9K_DUAL_WS_NB_WS;
714 : : else
715 : 0 : dev->max_event_ports = dev->sso.max_hws;
716 : 0 : dev->max_event_queues = dev->sso.max_hwgrp > RTE_EVENT_MAX_QUEUES_PER_DEV ?
717 : 0 : RTE_EVENT_MAX_QUEUES_PER_DEV :
718 : : dev->sso.max_hwgrp;
719 : 0 : }
|