Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Cavium, Inc
3 : : */
4 : :
5 : : #include <inttypes.h>
6 : : #include <stdlib.h>
7 : :
8 : : #include <rte_common.h>
9 : : #include <cryptodev_pmd.h>
10 : : #include <rte_debug.h>
11 : : #include <dev_driver.h>
12 : : #include <rte_eal.h>
13 : : #include <ethdev_driver.h>
14 : : #include <rte_event_eth_rx_adapter.h>
15 : : #include <rte_kvargs.h>
16 : : #include <rte_lcore.h>
17 : : #include <rte_log.h>
18 : : #include <rte_malloc.h>
19 : : #include <rte_memory.h>
20 : : #include <bus_vdev_driver.h>
21 : :
22 : : #include "ssovf_evdev.h"
23 : : #include "timvf_evdev.h"
24 : : #include "otx_cryptodev_hw_access.h"
25 : :
26 : : static uint8_t timvf_enable_stats;
27 : :
28 [ - + ]: 235 : RTE_LOG_REGISTER_DEFAULT(otx_logtype_ssovf, NOTICE);
29 : :
30 : : /* SSOPF Mailbox messages */
31 : :
32 : : struct ssovf_mbox_dev_info {
33 : : uint64_t min_deq_timeout_ns;
34 : : uint64_t max_deq_timeout_ns;
35 : : uint32_t max_num_events;
36 : : };
37 : :
38 : : static int
39 : 0 : ssovf_mbox_dev_info(struct ssovf_mbox_dev_info *info)
40 : : {
41 : 0 : struct octeontx_mbox_hdr hdr = {0};
42 : : uint16_t len = sizeof(struct ssovf_mbox_dev_info);
43 : :
44 : 0 : hdr.coproc = SSO_COPROC;
45 : 0 : hdr.msg = SSO_GET_DEV_INFO;
46 : : hdr.vfid = 0;
47 : :
48 : : memset(info, 0, len);
49 : 0 : return octeontx_mbox_send(&hdr, NULL, 0, info, len);
50 : : }
51 : :
52 : : struct ssovf_mbox_getwork_wait {
53 : : uint64_t wait_ns;
54 : : };
55 : :
56 : : static int
57 : 0 : ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns)
58 : : {
59 : 0 : struct octeontx_mbox_hdr hdr = {0};
60 : : struct ssovf_mbox_getwork_wait tmo_set;
61 : : uint16_t len = sizeof(struct ssovf_mbox_getwork_wait);
62 : : int ret;
63 : :
64 : 0 : hdr.coproc = SSO_COPROC;
65 : 0 : hdr.msg = SSO_SET_GETWORK_WAIT;
66 : : hdr.vfid = 0;
67 : :
68 : 0 : tmo_set.wait_ns = timeout_ns;
69 : 0 : ret = octeontx_mbox_send(&hdr, &tmo_set, len, NULL, 0);
70 [ # # ]: 0 : if (ret)
71 : 0 : ssovf_log_err("Failed to set getwork timeout(%d)", ret);
72 : :
73 : 0 : return ret;
74 : : }
75 : :
76 : : struct ssovf_mbox_grp_pri {
77 : : uint8_t vhgrp_id;
78 : : uint8_t wgt_left; /* Read only */
79 : : uint8_t weight;
80 : : uint8_t affinity;
81 : : uint8_t priority;
82 : : };
83 : :
84 : : static int
85 : 0 : ssovf_mbox_priority_set(uint8_t queue, uint8_t prio)
86 : : {
87 : 0 : struct octeontx_mbox_hdr hdr = {0};
88 : : struct ssovf_mbox_grp_pri grp;
89 : : uint16_t len = sizeof(struct ssovf_mbox_grp_pri);
90 : : int ret;
91 : :
92 : 0 : hdr.coproc = SSO_COPROC;
93 : 0 : hdr.msg = SSO_GRP_SET_PRIORITY;
94 : 0 : hdr.vfid = queue;
95 : :
96 : 0 : grp.vhgrp_id = queue;
97 : 0 : grp.weight = 0xff;
98 : 0 : grp.affinity = 0xff;
99 : 0 : grp.priority = prio / 32; /* Normalize to 0 to 7 */
100 : :
101 : 0 : ret = octeontx_mbox_send(&hdr, &grp, len, NULL, 0);
102 [ # # ]: 0 : if (ret)
103 : 0 : ssovf_log_err("Failed to set grp=%d prio=%d", queue, prio);
104 : :
105 : 0 : return ret;
106 : : }
107 : :
108 : : struct ssovf_mbox_convert_ns_getworks_iter {
109 : : uint64_t wait_ns;
110 : : uint32_t getwork_iter;/* Get_work iterations for the given wait_ns */
111 : : };
112 : :
113 : : static int
114 : 0 : ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks)
115 : : {
116 : 0 : struct octeontx_mbox_hdr hdr = {0};
117 : : struct ssovf_mbox_convert_ns_getworks_iter ns2iter;
118 : : uint16_t len = sizeof(ns2iter);
119 : : int ret;
120 : :
121 : 0 : hdr.coproc = SSO_COPROC;
122 : 0 : hdr.msg = SSO_CONVERT_NS_GETWORK_ITER;
123 : : hdr.vfid = 0;
124 : :
125 : : memset(&ns2iter, 0, len);
126 : 0 : ns2iter.wait_ns = ns;
127 : 0 : ret = octeontx_mbox_send(&hdr, &ns2iter, len, &ns2iter, len);
128 [ # # # # ]: 0 : if (ret < 0 || (ret != len)) {
129 : 0 : ssovf_log_err("Failed to get tmo ticks ns=%"PRId64"", ns);
130 : 0 : return -EIO;
131 : : }
132 : :
133 : 0 : *tmo_ticks = ns2iter.getwork_iter;
134 : 0 : return 0;
135 : : }
136 : :
137 : : static void
138 : 0 : ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info)
139 : : {
140 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
141 : :
142 : 0 : dev_info->driver_name = RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD);
143 : 0 : dev_info->min_dequeue_timeout_ns = edev->min_deq_timeout_ns;
144 : 0 : dev_info->max_dequeue_timeout_ns = edev->max_deq_timeout_ns;
145 : 0 : dev_info->max_event_queues = edev->max_event_queues;
146 : 0 : dev_info->max_event_queue_flows = (1ULL << 20);
147 : 0 : dev_info->max_event_queue_priority_levels = 8;
148 : 0 : dev_info->max_event_priority_levels = 1;
149 : 0 : dev_info->max_event_ports = edev->max_event_ports;
150 : 0 : dev_info->max_event_port_dequeue_depth = 1;
151 : 0 : dev_info->max_event_port_enqueue_depth = 1;
152 : 0 : dev_info->max_num_events = edev->max_num_events;
153 : 0 : dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_QUEUE_QOS |
154 : : RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED |
155 : : RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES|
156 : : RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK |
157 : : RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT |
158 : : RTE_EVENT_DEV_CAP_NONSEQ_MODE |
159 : : RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |
160 : : RTE_EVENT_DEV_CAP_MAINTENANCE_FREE;
161 : 0 : dev_info->max_profiles_per_port = 1;
162 : 0 : }
163 : :
164 : : static int
165 : 0 : ssovf_configure(const struct rte_eventdev *dev)
166 : : {
167 : 0 : struct rte_event_dev_config *conf = &dev->data->dev_conf;
168 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
169 : : uint64_t deq_tmo_ns;
170 : :
171 : 0 : ssovf_func_trace();
172 : 0 : deq_tmo_ns = conf->dequeue_timeout_ns;
173 [ # # ]: 0 : if (deq_tmo_ns == 0)
174 : 0 : deq_tmo_ns = edev->min_deq_timeout_ns;
175 : :
176 [ # # ]: 0 : if (conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT) {
177 : 0 : edev->is_timeout_deq = 1;
178 : 0 : deq_tmo_ns = edev->min_deq_timeout_ns;
179 : : }
180 : 0 : edev->nb_event_queues = conf->nb_event_queues;
181 : 0 : edev->nb_event_ports = conf->nb_event_ports;
182 : :
183 : 0 : return ssovf_mbox_getwork_tmo_set(deq_tmo_ns);
184 : : }
185 : :
186 : : static void
187 : 0 : ssovf_queue_def_conf(struct rte_eventdev *dev, uint8_t queue_id,
188 : : struct rte_event_queue_conf *queue_conf)
189 : : {
190 : : RTE_SET_USED(dev);
191 : : RTE_SET_USED(queue_id);
192 : :
193 : 0 : queue_conf->nb_atomic_flows = (1ULL << 20);
194 : 0 : queue_conf->nb_atomic_order_sequences = (1ULL << 20);
195 : 0 : queue_conf->event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
196 : 0 : queue_conf->priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
197 : 0 : }
198 : :
199 : : static void
200 : 0 : ssovf_queue_release(struct rte_eventdev *dev, uint8_t queue_id)
201 : : {
202 : : RTE_SET_USED(dev);
203 : : RTE_SET_USED(queue_id);
204 : 0 : }
205 : :
206 : : static int
207 : 0 : ssovf_queue_setup(struct rte_eventdev *dev, uint8_t queue_id,
208 : : const struct rte_event_queue_conf *queue_conf)
209 : : {
210 : : RTE_SET_USED(dev);
211 : 0 : ssovf_func_trace("queue=%d prio=%d", queue_id, queue_conf->priority);
212 : :
213 : 0 : return ssovf_mbox_priority_set(queue_id, queue_conf->priority);
214 : : }
215 : :
216 : : static void
217 : 0 : ssovf_port_def_conf(struct rte_eventdev *dev, uint8_t port_id,
218 : : struct rte_event_port_conf *port_conf)
219 : : {
220 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
221 : :
222 : : RTE_SET_USED(port_id);
223 : 0 : port_conf->new_event_threshold = edev->max_num_events;
224 : 0 : port_conf->dequeue_depth = 1;
225 : 0 : port_conf->enqueue_depth = 1;
226 : 0 : port_conf->event_port_cfg = 0;
227 : 0 : }
228 : :
229 : : static void
230 : 0 : ssovf_port_release(void *port)
231 : : {
232 : 0 : rte_free(port);
233 : 0 : }
234 : :
235 : : static int
236 : 0 : ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id,
237 : : const struct rte_event_port_conf *port_conf)
238 : : {
239 : : struct ssows *ws;
240 : : uint32_t reg_off;
241 : : uint8_t q;
242 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
243 : :
244 : 0 : ssovf_func_trace("port=%d", port_id);
245 : : RTE_SET_USED(port_conf);
246 : :
247 : : /* Free memory prior to re-allocation if needed */
248 [ # # ]: 0 : if (dev->data->ports[port_id] != NULL) {
249 : : ssovf_port_release(dev->data->ports[port_id]);
250 : 0 : dev->data->ports[port_id] = NULL;
251 : : }
252 : :
253 : : /* Allocate event port memory */
254 : 0 : ws = rte_zmalloc_socket("eventdev ssows",
255 : : sizeof(struct ssows), RTE_CACHE_LINE_SIZE,
256 : 0 : dev->data->socket_id);
257 [ # # ]: 0 : if (ws == NULL) {
258 : 0 : ssovf_log_err("Failed to alloc memory for port=%d", port_id);
259 : 0 : return -ENOMEM;
260 : : }
261 : :
262 : 0 : ws->base = ssovf_bar(OCTEONTX_SSO_HWS, port_id, 0);
263 [ # # ]: 0 : if (ws->base == NULL) {
264 : 0 : rte_free(ws);
265 : 0 : ssovf_log_err("Failed to get hws base addr port=%d", port_id);
266 : 0 : return -EINVAL;
267 : : }
268 : :
269 : : reg_off = SSOW_VHWS_OP_GET_WORK0;
270 : : reg_off |= 1 << 4; /* Index_ggrp_mask (Use maskset zero) */
271 : : reg_off |= 1 << 16; /* Wait */
272 : 0 : ws->getwork = ws->base + reg_off;
273 : 0 : ws->port = port_id;
274 : 0 : ws->lookup_mem = octeontx_fastpath_lookup_mem_get();
275 : :
276 [ # # ]: 0 : for (q = 0; q < edev->nb_event_queues; q++) {
277 : 0 : ws->grps[q] = ssovf_bar(OCTEONTX_SSO_GROUP, q, 2);
278 [ # # ]: 0 : if (ws->grps[q] == NULL) {
279 : 0 : rte_free(ws);
280 : 0 : ssovf_log_err("Failed to get grp%d base addr", q);
281 : 0 : return -EINVAL;
282 : : }
283 : : }
284 : :
285 : 0 : dev->data->ports[port_id] = ws;
286 : 0 : ssovf_log_dbg("port=%d ws=%p", port_id, ws);
287 : 0 : return 0;
288 : : }
289 : :
290 : : static int
291 : 0 : ssovf_port_link(struct rte_eventdev *dev, void *port, const uint8_t queues[],
292 : : const uint8_t priorities[], uint16_t nb_links)
293 : : {
294 : : uint16_t link;
295 : : uint64_t val;
296 : : struct ssows *ws = port;
297 : :
298 : 0 : ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_links);
299 : : RTE_SET_USED(dev);
300 : : RTE_SET_USED(priorities);
301 : :
302 [ # # ]: 0 : for (link = 0; link < nb_links; link++) {
303 : 0 : val = queues[link];
304 : 0 : val |= (1ULL << 24); /* Set membership */
305 : 0 : ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0));
306 : : }
307 : 0 : return (int)nb_links;
308 : : }
309 : :
310 : : static int
311 : 0 : ssovf_port_unlink(struct rte_eventdev *dev, void *port, uint8_t queues[],
312 : : uint16_t nb_unlinks)
313 : : {
314 : : uint16_t unlink;
315 : : uint64_t val;
316 : : struct ssows *ws = port;
317 : :
318 : 0 : ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_unlinks);
319 : : RTE_SET_USED(dev);
320 : :
321 [ # # ]: 0 : for (unlink = 0; unlink < nb_unlinks; unlink++) {
322 : 0 : val = queues[unlink];
323 : : val &= ~(1ULL << 24); /* Clear membership */
324 : 0 : ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0));
325 : : }
326 : 0 : return (int)nb_unlinks;
327 : : }
328 : :
329 : : static int
330 : 0 : ssovf_timeout_ticks(struct rte_eventdev *dev, uint64_t ns, uint64_t *tmo_ticks)
331 : : {
332 : : RTE_SET_USED(dev);
333 : :
334 : 0 : return ssovf_mbox_timeout_ticks(ns, tmo_ticks);
335 : : }
336 : :
337 : : static void
338 : 0 : ssows_dump(struct ssows *ws, FILE *f)
339 : : {
340 : 0 : uint8_t *base = ws->base;
341 : : uint64_t val;
342 : :
343 : 0 : fprintf(f, "\t---------------port%d---------------\n", ws->port);
344 : : val = ssovf_read64(base + SSOW_VHWS_TAG);
345 : 0 : fprintf(f, "\ttag=0x%x tt=%d head=%d tail=%d grp=%d index=%d tail=%d\n",
346 : 0 : (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3,
347 : 0 : (int)(val >> 34) & 0x1, (int)(val >> 35) & 0x1,
348 : 0 : (int)(val >> 36) & 0x3ff, (int)(val >> 48) & 0x3ff,
349 : 0 : (int)(val >> 63) & 0x1);
350 : :
351 : : val = ssovf_read64(base + SSOW_VHWS_WQP);
352 : : fprintf(f, "\twqp=0x%"PRIx64"\n", val);
353 : :
354 : : val = ssovf_read64(base + SSOW_VHWS_LINKS);
355 : 0 : fprintf(f, "\tindex=%d valid=%d revlink=%d tail=%d head=%d grp=%d\n",
356 : 0 : (int)(val & 0x3ff), (int)(val >> 10) & 0x1,
357 : 0 : (int)(val >> 11) & 0x3ff, (int)(val >> 26) & 0x1,
358 : 0 : (int)(val >> 27) & 0x1, (int)(val >> 28) & 0x3ff);
359 : :
360 : : val = ssovf_read64(base + SSOW_VHWS_PENDTAG);
361 : 0 : fprintf(f, "\tptag=0x%x ptt=%d pgwi=%d pdesc=%d pgw=%d pgww=%d ps=%d\n",
362 : 0 : (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3,
363 : 0 : (int)(val >> 56) & 0x1, (int)(val >> 58) & 0x1,
364 : 0 : (int)(val >> 61) & 0x1, (int)(val >> 62) & 0x1,
365 : 0 : (int)(val >> 63) & 0x1);
366 : :
367 : : val = ssovf_read64(base + SSOW_VHWS_PENDWQP);
368 : : fprintf(f, "\tpwqp=0x%"PRIx64"\n", val);
369 : 0 : }
370 : :
371 : : static int
372 : 0 : ssovf_eth_rx_adapter_caps_get(const struct rte_eventdev *dev,
373 : : const struct rte_eth_dev *eth_dev, uint32_t *caps)
374 : : {
375 : : int ret;
376 : : RTE_SET_USED(dev);
377 : :
378 : 0 : ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
379 [ # # ]: 0 : if (ret)
380 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP;
381 : : else
382 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT;
383 : :
384 : 0 : return 0;
385 : : }
386 : :
387 : : static int
388 : 0 : ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev,
389 : : const struct rte_eth_dev *eth_dev, int32_t rx_queue_id,
390 : : const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
391 : : {
392 [ # # ]: 0 : const struct octeontx_nic *nic = eth_dev->data->dev_private;
393 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
394 : : uint16_t free_idx = UINT16_MAX;
395 : : struct octeontx_rxq *rxq;
396 : : pki_mod_qos_t pki_qos;
397 : : uint8_t found = false;
398 : : int i, ret = 0;
399 : : void *old_ptr;
400 : :
401 : 0 : ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
402 [ # # ]: 0 : if (ret)
403 : : return -EINVAL;
404 : :
405 [ # # ]: 0 : if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL)
406 : : return -ENOTSUP;
407 : :
408 : : /* eth_octeontx only supports one rq. */
409 [ # # ]: 0 : rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id;
410 : 0 : rxq = eth_dev->data->rx_queues[rx_queue_id];
411 : : /* Add rxq pool to list of used pools and reduce available events. */
412 [ # # ]: 0 : for (i = 0; i < edev->rxq_pools; i++) {
413 [ # # ]: 0 : if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) {
414 : 0 : edev->rxq_pool_rcnt[i]++;
415 : : found = true;
416 : : break;
417 [ # # # # ]: 0 : } else if (free_idx == UINT16_MAX &&
418 : : edev->rxq_pool_array[i] == 0) {
419 : 0 : free_idx = i;
420 : : }
421 : : }
422 : :
423 : : if (!found) {
424 : : uint16_t idx;
425 : :
426 [ # # ]: 0 : if (edev->available_events < rxq->pool->size) {
427 : 0 : ssovf_log_err(
428 : : "Max available events %"PRIu32" requested events in rxq pool %"PRIu32"",
429 : : edev->available_events, rxq->pool->size);
430 : 0 : return -ENOMEM;
431 : : }
432 : :
433 [ # # ]: 0 : if (free_idx != UINT16_MAX) {
434 : : idx = free_idx;
435 : : } else {
436 : 0 : old_ptr = edev->rxq_pool_array;
437 : 0 : edev->rxq_pools++;
438 : 0 : edev->rxq_pool_array = rte_realloc(
439 : : edev->rxq_pool_array,
440 : 0 : sizeof(uint64_t) * edev->rxq_pools, 0);
441 [ # # ]: 0 : if (edev->rxq_pool_array == NULL) {
442 : 0 : edev->rxq_pools--;
443 : 0 : edev->rxq_pool_array = old_ptr;
444 : 0 : return -ENOMEM;
445 : : }
446 : :
447 : 0 : old_ptr = edev->rxq_pool_rcnt;
448 : 0 : edev->rxq_pool_rcnt = rte_realloc(
449 : : edev->rxq_pool_rcnt,
450 : 0 : sizeof(uint8_t) * edev->rxq_pools, 0);
451 [ # # ]: 0 : if (edev->rxq_pool_rcnt == NULL) {
452 : 0 : edev->rxq_pools--;
453 : 0 : edev->rxq_pool_rcnt = old_ptr;
454 : 0 : return -ENOMEM;
455 : : }
456 : 0 : idx = edev->rxq_pools - 1;
457 : : }
458 : :
459 : 0 : edev->rxq_pool_array[idx] = (uintptr_t)rxq->pool;
460 : 0 : edev->rxq_pool_rcnt[idx] = 1;
461 : 0 : edev->available_events -= rxq->pool->size;
462 : : }
463 : :
464 : : memset(&pki_qos, 0, sizeof(pki_mod_qos_t));
465 : :
466 : : pki_qos.port_type = 0;
467 : : pki_qos.index = 0;
468 : 0 : pki_qos.mmask.f_tag_type = 1;
469 : 0 : pki_qos.mmask.f_port_add = 1;
470 : 0 : pki_qos.mmask.f_grp_ok = 1;
471 : 0 : pki_qos.mmask.f_grp_bad = 1;
472 : 0 : pki_qos.mmask.f_grptag_ok = 1;
473 : 0 : pki_qos.mmask.f_grptag_bad = 1;
474 : :
475 : 0 : pki_qos.qos_entry.tag_type = queue_conf->ev.sched_type;
476 : : pki_qos.qos_entry.port_add = 0;
477 : 0 : pki_qos.qos_entry.ggrp_ok = queue_conf->ev.queue_id;
478 : 0 : pki_qos.qos_entry.ggrp_bad = queue_conf->ev.queue_id;
479 : : pki_qos.qos_entry.grptag_bad = 0;
480 : : pki_qos.qos_entry.grptag_ok = 0;
481 : :
482 : 0 : ret = octeontx_pki_port_modify_qos(nic->port_id, &pki_qos);
483 [ # # ]: 0 : if (ret < 0)
484 : 0 : ssovf_log_err("failed to modify QOS, port=%d, q=%d",
485 : : nic->port_id, queue_conf->ev.queue_id);
486 : :
487 : 0 : edev->rx_offload_flags = nic->rx_offload_flags;
488 : 0 : edev->tx_offload_flags = nic->tx_offload_flags;
489 : 0 : return ret;
490 : : }
491 : :
492 : : static int
493 : 0 : ssovf_eth_rx_adapter_queue_del(const struct rte_eventdev *dev,
494 : : const struct rte_eth_dev *eth_dev, int32_t rx_queue_id)
495 : : {
496 [ # # ]: 0 : const struct octeontx_nic *nic = eth_dev->data->dev_private;
497 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
498 : : struct octeontx_rxq *rxq;
499 : : pki_del_qos_t pki_qos;
500 : : uint8_t found = false;
501 : : int i, ret = 0;
502 : :
503 [ # # ]: 0 : rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id;
504 : 0 : rxq = eth_dev->data->rx_queues[rx_queue_id];
505 [ # # ]: 0 : for (i = 0; i < edev->rxq_pools; i++) {
506 [ # # ]: 0 : if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) {
507 : : found = true;
508 : : break;
509 : : }
510 : : }
511 : :
512 [ # # ]: 0 : if (found) {
513 : 0 : edev->rxq_pool_rcnt[i]--;
514 [ # # ]: 0 : if (edev->rxq_pool_rcnt[i] == 0)
515 : 0 : edev->rxq_pool_array[i] = 0;
516 : 0 : edev->available_events += rxq->pool->size;
517 : : }
518 : :
519 : 0 : ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
520 [ # # ]: 0 : if (ret)
521 : : return -EINVAL;
522 : :
523 : : pki_qos.port_type = 0;
524 : : pki_qos.index = 0;
525 : : memset(&pki_qos, 0, sizeof(pki_del_qos_t));
526 : 0 : ret = octeontx_pki_port_delete_qos(nic->port_id, &pki_qos);
527 [ # # ]: 0 : if (ret < 0)
528 : 0 : ssovf_log_err("Failed to delete QOS port=%d, q=%d",
529 : : nic->port_id, rx_queue_id);
530 : : return ret;
531 : : }
532 : :
533 : : static int
534 : 0 : ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev,
535 : : const struct rte_eth_dev *eth_dev)
536 : : {
537 : : RTE_SET_USED(dev);
538 : : RTE_SET_USED(eth_dev);
539 : :
540 : 0 : return 0;
541 : : }
542 : :
543 : :
544 : : static int
545 : 0 : ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev,
546 : : const struct rte_eth_dev *eth_dev)
547 : : {
548 : : RTE_SET_USED(dev);
549 : : RTE_SET_USED(eth_dev);
550 : :
551 : 0 : return 0;
552 : : }
553 : :
554 : : static int
555 : 0 : ssovf_eth_tx_adapter_caps_get(const struct rte_eventdev *dev,
556 : : const struct rte_eth_dev *eth_dev, uint32_t *caps)
557 : : {
558 : : int ret;
559 : : RTE_SET_USED(dev);
560 : :
561 : 0 : ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
562 [ # # ]: 0 : if (ret)
563 : 0 : *caps = 0;
564 : : else
565 : 0 : *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT;
566 : :
567 : 0 : return 0;
568 : : }
569 : :
570 : : static int
571 : 0 : ssovf_eth_tx_adapter_create(uint8_t id, const struct rte_eventdev *dev)
572 : : {
573 : : RTE_SET_USED(id);
574 : : RTE_SET_USED(dev);
575 : 0 : return 0;
576 : : }
577 : :
578 : : static int
579 : 0 : ssovf_eth_tx_adapter_free(uint8_t id, const struct rte_eventdev *dev)
580 : : {
581 : : RTE_SET_USED(id);
582 : : RTE_SET_USED(dev);
583 : 0 : return 0;
584 : : }
585 : :
586 : : static int
587 : 0 : ssovf_eth_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *dev,
588 : : const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
589 : : {
590 : : RTE_SET_USED(id);
591 : : RTE_SET_USED(dev);
592 : : RTE_SET_USED(eth_dev);
593 : : RTE_SET_USED(tx_queue_id);
594 : 0 : return 0;
595 : : }
596 : :
597 : : static int
598 : 0 : ssovf_eth_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *dev,
599 : : const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
600 : : {
601 : : RTE_SET_USED(id);
602 : : RTE_SET_USED(dev);
603 : : RTE_SET_USED(eth_dev);
604 : : RTE_SET_USED(tx_queue_id);
605 : 0 : return 0;
606 : : }
607 : :
608 : : static int
609 : 0 : ssovf_eth_tx_adapter_start(uint8_t id, const struct rte_eventdev *dev)
610 : : {
611 : : RTE_SET_USED(id);
612 : : RTE_SET_USED(dev);
613 : 0 : return 0;
614 : : }
615 : :
616 : : static int
617 : 0 : ssovf_eth_tx_adapter_stop(uint8_t id, const struct rte_eventdev *dev)
618 : : {
619 : : RTE_SET_USED(id);
620 : : RTE_SET_USED(dev);
621 : 0 : return 0;
622 : : }
623 : :
624 : :
625 : : static void
626 : 0 : ssovf_dump(struct rte_eventdev *dev, FILE *f)
627 : : {
628 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
629 : : uint8_t port;
630 : :
631 : : /* Dump SSOWVF debug registers */
632 [ # # ]: 0 : for (port = 0; port < edev->nb_event_ports; port++)
633 : 0 : ssows_dump(dev->data->ports[port], f);
634 : 0 : }
635 : :
636 : : static int
637 : 0 : ssovf_start(struct rte_eventdev *dev)
638 : : {
639 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
640 : : struct ssows *ws;
641 : : uint8_t *base;
642 : : uint8_t i;
643 : :
644 : 0 : ssovf_func_trace();
645 [ # # ]: 0 : for (i = 0; i < edev->nb_event_ports; i++) {
646 : 0 : ws = dev->data->ports[i];
647 : 0 : ssows_reset(ws);
648 : 0 : ws->swtag_req = 0;
649 : : }
650 : :
651 [ # # ]: 0 : for (i = 0; i < edev->nb_event_queues; i++) {
652 : : /* Consume all the events through HWS0 */
653 : 0 : ssows_flush_events(dev->data->ports[0], i, NULL, NULL);
654 : :
655 : 0 : base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0);
656 : : base += SSO_VHGRP_QCTL;
657 : : ssovf_write64(1, base); /* Enable SSO group */
658 : : }
659 : :
660 : 0 : ssovf_fastpath_fns_set(dev);
661 : 0 : return 0;
662 : : }
663 : :
664 : : static void
665 : 0 : ssows_handle_event(void *arg, struct rte_event event)
666 : : {
667 : : struct rte_eventdev *dev = arg;
668 : :
669 [ # # ]: 0 : if (dev->dev_ops->dev_stop_flush != NULL)
670 : 0 : dev->dev_ops->dev_stop_flush(dev->data->dev_id, event,
671 : 0 : dev->data->dev_stop_flush_arg);
672 : 0 : }
673 : :
674 : : static void
675 : 0 : ssovf_stop(struct rte_eventdev *dev)
676 : : {
677 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
678 : : struct ssows *ws;
679 : : uint8_t *base;
680 : : uint8_t i;
681 : :
682 : 0 : ssovf_func_trace();
683 [ # # ]: 0 : for (i = 0; i < edev->nb_event_ports; i++) {
684 : 0 : ws = dev->data->ports[i];
685 : 0 : ssows_reset(ws);
686 : 0 : ws->swtag_req = 0;
687 : : }
688 : :
689 [ # # ]: 0 : for (i = 0; i < edev->nb_event_queues; i++) {
690 : : /* Consume all the events through HWS0 */
691 : 0 : ssows_flush_events(dev->data->ports[0], i,
692 : : ssows_handle_event, dev);
693 : :
694 : 0 : base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0);
695 : : base += SSO_VHGRP_QCTL;
696 : : ssovf_write64(0, base); /* Disable SSO group */
697 : : }
698 : 0 : }
699 : :
700 : : static int
701 : 0 : ssovf_close(struct rte_eventdev *dev)
702 : : {
703 : : struct ssovf_evdev *edev = ssovf_pmd_priv(dev);
704 : : uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV];
705 : : uint8_t i;
706 : :
707 [ # # ]: 0 : for (i = 0; i < edev->nb_event_queues; i++)
708 : 0 : all_queues[i] = i;
709 : :
710 [ # # ]: 0 : for (i = 0; i < edev->nb_event_ports; i++)
711 : 0 : ssovf_port_unlink(dev, dev->data->ports[i], all_queues,
712 : 0 : edev->nb_event_queues);
713 : 0 : return 0;
714 : : }
715 : :
716 : : static int
717 : 0 : ssovf_parsekv(const char *key __rte_unused, const char *value, void *opaque)
718 : : {
719 : : int *flag = opaque;
720 : 0 : *flag = !!atoi(value);
721 : 0 : return 0;
722 : : }
723 : :
724 : : static int
725 : 0 : ssovf_timvf_caps_get(const struct rte_eventdev *dev, uint64_t flags,
726 : : uint32_t *caps, const struct event_timer_adapter_ops **ops)
727 : : {
728 : 0 : return timvf_timer_adapter_caps_get(dev, flags, caps, ops,
729 : : timvf_enable_stats);
730 : : }
731 : :
732 : : static int
733 : 0 : ssovf_crypto_adapter_caps_get(const struct rte_eventdev *dev,
734 : : const struct rte_cryptodev *cdev, uint32_t *caps)
735 : : {
736 : : RTE_SET_USED(dev);
737 : : RTE_SET_USED(cdev);
738 : :
739 : 0 : *caps = RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD |
740 : : RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA;
741 : :
742 : 0 : return 0;
743 : : }
744 : :
745 : : static int
746 : 0 : ssovf_crypto_adapter_qp_add(const struct rte_eventdev *dev,
747 : : const struct rte_cryptodev *cdev,
748 : : int32_t queue_pair_id,
749 : : const struct rte_event_crypto_adapter_queue_conf *conf)
750 : : {
751 : : struct cpt_instance *qp;
752 : : uint8_t qp_id;
753 : :
754 : : RTE_SET_USED(conf);
755 : :
756 [ # # ]: 0 : if (queue_pair_id == -1) {
757 [ # # ]: 0 : for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) {
758 : 0 : qp = cdev->data->queue_pairs[qp_id];
759 : 0 : qp->ca_enabled = 1;
760 : : }
761 : : } else {
762 : 0 : qp = cdev->data->queue_pairs[queue_pair_id];
763 : 0 : qp->ca_enabled = 1;
764 : : }
765 : :
766 : 0 : ssovf_fastpath_fns_set((struct rte_eventdev *)(uintptr_t)dev);
767 : :
768 : 0 : return 0;
769 : : }
770 : :
771 : : static int
772 : 0 : ssovf_crypto_adapter_qp_del(const struct rte_eventdev *dev,
773 : : const struct rte_cryptodev *cdev,
774 : : int32_t queue_pair_id)
775 : : {
776 : : struct cpt_instance *qp;
777 : : uint8_t qp_id;
778 : :
779 : : RTE_SET_USED(dev);
780 : :
781 [ # # ]: 0 : if (queue_pair_id == -1) {
782 [ # # ]: 0 : for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) {
783 : 0 : qp = cdev->data->queue_pairs[qp_id];
784 : 0 : qp->ca_enabled = 0;
785 : : }
786 : : } else {
787 : 0 : qp = cdev->data->queue_pairs[queue_pair_id];
788 : 0 : qp->ca_enabled = 0;
789 : : }
790 : :
791 : 0 : return 0;
792 : : }
793 : :
794 : : /* Initialize and register event driver with DPDK Application */
795 : : static struct eventdev_ops ssovf_ops = {
796 : : .dev_infos_get = ssovf_info_get,
797 : : .dev_configure = ssovf_configure,
798 : : .queue_def_conf = ssovf_queue_def_conf,
799 : : .queue_setup = ssovf_queue_setup,
800 : : .queue_release = ssovf_queue_release,
801 : : .port_def_conf = ssovf_port_def_conf,
802 : : .port_setup = ssovf_port_setup,
803 : : .port_release = ssovf_port_release,
804 : : .port_link = ssovf_port_link,
805 : : .port_unlink = ssovf_port_unlink,
806 : : .timeout_ticks = ssovf_timeout_ticks,
807 : :
808 : : .eth_rx_adapter_caps_get = ssovf_eth_rx_adapter_caps_get,
809 : : .eth_rx_adapter_queue_add = ssovf_eth_rx_adapter_queue_add,
810 : : .eth_rx_adapter_queue_del = ssovf_eth_rx_adapter_queue_del,
811 : : .eth_rx_adapter_start = ssovf_eth_rx_adapter_start,
812 : : .eth_rx_adapter_stop = ssovf_eth_rx_adapter_stop,
813 : :
814 : : .eth_tx_adapter_caps_get = ssovf_eth_tx_adapter_caps_get,
815 : : .eth_tx_adapter_create = ssovf_eth_tx_adapter_create,
816 : : .eth_tx_adapter_free = ssovf_eth_tx_adapter_free,
817 : : .eth_tx_adapter_queue_add = ssovf_eth_tx_adapter_queue_add,
818 : : .eth_tx_adapter_queue_del = ssovf_eth_tx_adapter_queue_del,
819 : : .eth_tx_adapter_start = ssovf_eth_tx_adapter_start,
820 : : .eth_tx_adapter_stop = ssovf_eth_tx_adapter_stop,
821 : :
822 : : .timer_adapter_caps_get = ssovf_timvf_caps_get,
823 : :
824 : : .crypto_adapter_caps_get = ssovf_crypto_adapter_caps_get,
825 : : .crypto_adapter_queue_pair_add = ssovf_crypto_adapter_qp_add,
826 : : .crypto_adapter_queue_pair_del = ssovf_crypto_adapter_qp_del,
827 : :
828 : : .dev_selftest = test_eventdev_octeontx,
829 : :
830 : : .dump = ssovf_dump,
831 : : .dev_start = ssovf_start,
832 : : .dev_stop = ssovf_stop,
833 : : .dev_close = ssovf_close
834 : : };
835 : :
836 : : static int
837 [ # # ]: 0 : ssovf_vdev_probe(struct rte_vdev_device *vdev)
838 : : {
839 : : struct ssovf_info oinfo;
840 : : struct ssovf_mbox_dev_info info;
841 : : struct ssovf_evdev *edev;
842 : : struct rte_eventdev *eventdev;
843 : : static int ssovf_init_once;
844 : : const char *name;
845 : : const char *params;
846 : : int ret;
847 : :
848 : : static const char *const args[] = {
849 : : TIMVF_ENABLE_STATS_ARG,
850 : : NULL
851 : : };
852 : :
853 : : name = rte_vdev_device_name(vdev);
854 : : /* More than one instance is not supported */
855 [ # # ]: 0 : if (ssovf_init_once) {
856 : 0 : ssovf_log_err("Request to create >1 %s instance", name);
857 : 0 : return -EINVAL;
858 : : }
859 : :
860 : : params = rte_vdev_device_args(vdev);
861 [ # # # # ]: 0 : if (params != NULL && params[0] != '\0') {
862 : 0 : struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
863 : :
864 [ # # ]: 0 : if (!kvlist) {
865 : 0 : ssovf_log_info(
866 : : "Ignoring unsupported params supplied '%s'",
867 : : name);
868 : : } else {
869 : 0 : ret = rte_kvargs_process(kvlist, TIMVF_ENABLE_STATS_ARG,
870 : : ssovf_parsekv,
871 : : &timvf_enable_stats);
872 [ # # ]: 0 : if (ret != 0) {
873 : 0 : ssovf_log_err("%s: Error in timvf stats", name);
874 : 0 : rte_kvargs_free(kvlist);
875 : 0 : return ret;
876 : : }
877 : : }
878 : :
879 : 0 : rte_kvargs_free(kvlist);
880 : : }
881 : :
882 : 0 : eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev),
883 : 0 : rte_socket_id(), vdev);
884 [ # # ]: 0 : if (eventdev == NULL) {
885 : 0 : ssovf_log_err("Failed to create eventdev vdev %s", name);
886 : 0 : return -ENOMEM;
887 : : }
888 : 0 : eventdev->dev_ops = &ssovf_ops;
889 : :
890 : 0 : timvf_set_eventdevice(eventdev);
891 : :
892 : : /* For secondary processes, the primary has done all the work */
893 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
894 : 0 : ssovf_fastpath_fns_set(eventdev);
895 : 0 : return 0;
896 : : }
897 : :
898 : 0 : octeontx_mbox_init();
899 : 0 : ret = ssovf_info(&oinfo);
900 [ # # ]: 0 : if (ret) {
901 : 0 : ssovf_log_err("Failed to probe and validate ssovfs %d", ret);
902 : 0 : goto error;
903 : : }
904 : :
905 : : edev = ssovf_pmd_priv(eventdev);
906 : 0 : edev->max_event_ports = oinfo.total_ssowvfs;
907 : 0 : edev->max_event_queues = oinfo.total_ssovfs;
908 : 0 : edev->is_timeout_deq = 0;
909 : :
910 : 0 : ret = ssovf_mbox_dev_info(&info);
911 [ # # ]: 0 : if (ret < 0 || ret != sizeof(struct ssovf_mbox_dev_info)) {
912 : 0 : ssovf_log_err("Failed to get mbox devinfo %d", ret);
913 : 0 : goto error;
914 : : }
915 : :
916 : 0 : edev->min_deq_timeout_ns = info.min_deq_timeout_ns;
917 : 0 : edev->max_deq_timeout_ns = info.max_deq_timeout_ns;
918 : 0 : edev->max_num_events = info.max_num_events;
919 : 0 : edev->available_events = info.max_num_events;
920 : :
921 : 0 : ssovf_log_dbg("min_deq_tmo=%" PRId64 " max_deq_tmo=%" PRId64
922 : : " max_evts=%d",
923 : : info.min_deq_timeout_ns, info.max_deq_timeout_ns,
924 : : info.max_num_events);
925 : :
926 [ # # # # ]: 0 : if (!edev->max_event_ports || !edev->max_event_queues) {
927 : 0 : ssovf_log_err("Not enough eventdev resource queues=%d ports=%d",
928 : : edev->max_event_queues, edev->max_event_ports);
929 : : ret = -ENODEV;
930 : 0 : goto error;
931 : : }
932 : :
933 : 0 : ssovf_log_info("Initializing %s domain=%d max_queues=%d max_ports=%d",
934 : : name, oinfo.domain, edev->max_event_queues,
935 : : edev->max_event_ports);
936 : :
937 : 0 : ssovf_init_once = 1;
938 : 0 : event_dev_probing_finish(eventdev);
939 : 0 : return 0;
940 : :
941 : 0 : error:
942 : 0 : rte_event_pmd_vdev_uninit(name);
943 : 0 : return ret;
944 : : }
945 : :
946 : : static int
947 [ # # ]: 0 : ssovf_vdev_remove(struct rte_vdev_device *vdev)
948 : : {
949 : : const char *name;
950 : :
951 : : name = rte_vdev_device_name(vdev);
952 : 0 : ssovf_log_info("Closing %s", name);
953 : 0 : return rte_event_pmd_vdev_uninit(name);
954 : : }
955 : :
956 : : static struct rte_vdev_driver vdev_ssovf_pmd = {
957 : : .probe = ssovf_vdev_probe,
958 : : .remove = ssovf_vdev_remove
959 : : };
960 : :
961 : 235 : RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_OCTEONTX_PMD, vdev_ssovf_pmd);
|