Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : :
7 : : #include "cn20k_cryptodev_ops.h"
8 : : #include "cn20k_ethdev.h"
9 : : #include "cn20k_eventdev.h"
10 : : #include "cn20k_tx_worker.h"
11 : : #include "cn20k_worker.h"
12 : : #include "cnxk_common.h"
13 : : #include "cnxk_eventdev.h"
14 : : #include "cnxk_vector_adptr.h"
15 : : #include "cnxk_worker.h"
16 : :
17 : : #define CN20K_SET_EVDEV_DEQ_OP(dev, deq_op, deq_ops) \
18 : : deq_op = deq_ops[dev->rx_offloads & (NIX_RX_OFFLOAD_MAX - 1)]
19 : :
20 : : #define CN20K_SET_EVDEV_ENQ_OP(dev, enq_op, enq_ops) \
21 : : enq_op = enq_ops[dev->tx_offloads & (NIX_TX_OFFLOAD_MAX - 1)]
22 : :
23 : : static void *
24 : 0 : cn20k_sso_init_hws_mem(void *arg, uint8_t port_id)
25 : : {
26 : : struct cnxk_sso_evdev *dev = arg;
27 : : struct cn20k_sso_hws *ws;
28 : :
29 : : /* Allocate event port memory */
30 : 0 : ws = rte_zmalloc("cn20k_ws", sizeof(struct cn20k_sso_hws) + RTE_CACHE_LINE_SIZE,
31 : : RTE_CACHE_LINE_SIZE);
32 [ # # ]: 0 : if (ws == NULL) {
33 : 0 : plt_err("Failed to alloc memory for port=%d", port_id);
34 : 0 : return NULL;
35 : : }
36 : :
37 : : /* First cache line is reserved for cookie */
38 : 0 : ws = (struct cn20k_sso_hws *)((uint8_t *)ws + RTE_CACHE_LINE_SIZE);
39 : 0 : ws->base = roc_sso_hws_base_get(&dev->sso, port_id);
40 : 0 : ws->hws_id = port_id;
41 [ # # ]: 0 : ws->swtag_req = 0;
42 : 0 : ws->gw_wdata = cnxk_sso_hws_prf_wdata(dev);
43 : 0 : ws->gw_rdata = SSO_TT_EMPTY << 32;
44 : 0 : ws->xae_waes = dev->sso.feat.xaq_wq_entries;
45 : :
46 : 0 : return ws;
47 : : }
48 : :
49 : : static int
50 : 0 : cn20k_sso_hws_link(void *arg, void *port, uint16_t *map, uint16_t nb_link, uint8_t profile)
51 : : {
52 : : struct cnxk_sso_evdev *dev = arg;
53 : : struct cn20k_sso_hws *ws = port;
54 : :
55 : 0 : return roc_sso_hws_link(&dev->sso, ws->hws_id, map, nb_link, profile, 0);
56 : : }
57 : :
58 : : static int
59 : 0 : cn20k_sso_hws_unlink(void *arg, void *port, uint16_t *map, uint16_t nb_link, uint8_t profile)
60 : : {
61 : : struct cnxk_sso_evdev *dev = arg;
62 : : struct cn20k_sso_hws *ws = port;
63 : :
64 : 0 : return roc_sso_hws_unlink(&dev->sso, ws->hws_id, map, nb_link, profile, 0);
65 : : }
66 : :
67 : : static void
68 : 0 : cn20k_sso_hws_setup(void *arg, void *hws, uintptr_t grp_base)
69 : : {
70 : : struct cnxk_sso_evdev *dev = arg;
71 : : struct cn20k_sso_hws *ws = hws;
72 : : uint64_t val;
73 : :
74 : 0 : ws->grp_base = grp_base;
75 : 0 : ws->fc_mem = (int64_t __rte_atomic *)dev->fc_iova;
76 : 0 : ws->xaq_lmt = dev->xaq_lmt;
77 : 0 : ws->fc_cache_space = (int64_t __rte_atomic *)dev->fc_cache_space;
78 [ # # ]: 0 : ws->aw_lmt = dev->sso.lmt_base;
79 : 0 : ws->gw_wdata = cnxk_sso_hws_prf_wdata(dev);
80 : 0 : ws->lmt_base = dev->sso.lmt_base;
81 : :
82 : : /* Set get_work timeout for HWS */
83 : 0 : val = NSEC2USEC(dev->deq_tmo_ns);
84 [ # # ]: 0 : val = val ? val - 1 : 0;
85 : 0 : plt_write64(val, ws->base + SSOW_LF_GWS_NW_TIM);
86 : 0 : }
87 : :
88 : : static void
89 : 0 : cn20k_sso_hws_release(void *arg, void *hws)
90 : : {
91 : : struct cnxk_sso_evdev *dev = arg;
92 : : struct cn20k_sso_hws *ws = hws;
93 : : uint16_t i, j;
94 : :
95 [ # # ]: 0 : for (i = 0; i < CNXK_SSO_MAX_PROFILES; i++)
96 [ # # ]: 0 : for (j = 0; j < dev->nb_event_queues; j++)
97 : 0 : roc_sso_hws_unlink(&dev->sso, ws->hws_id, &j, 1, i, 0);
98 : : memset(ws, 0, sizeof(*ws));
99 : 0 : }
100 : :
101 : : static int
102 : 0 : cn20k_sso_hws_flush_events(void *hws, uint8_t queue_id, uintptr_t base, cnxk_handle_event_t fn,
103 : : void *arg)
104 : : {
105 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(arg);
106 : : uint64_t retry = CNXK_SSO_FLUSH_RETRY_MAX;
107 : : struct cn20k_sso_hws *ws = hws;
108 : : uint64_t cq_ds_cnt = 1;
109 : : uint64_t aq_cnt = 1;
110 : : uint64_t ds_cnt = 1;
111 : : struct rte_event ev;
112 : : uint64_t val, req;
113 : :
114 : 0 : plt_write64(0, base + SSO_LF_GGRP_QCTL);
115 : :
116 : 0 : roc_sso_hws_gwc_invalidate(&dev->sso, &ws->hws_id, 1);
117 : 0 : plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
118 : 0 : req = queue_id; /* GGRP ID */
119 : : req |= BIT_ULL(18); /* Grouped */
120 : 0 : req |= BIT_ULL(16); /* WAIT */
121 : :
122 : 0 : aq_cnt = plt_read64(base + SSO_LF_GGRP_AQ_CNT);
123 : 0 : ds_cnt = plt_read64(base + SSO_LF_GGRP_MISC_CNT);
124 : 0 : cq_ds_cnt = plt_read64(base + SSO_LF_GGRP_INT_CNT);
125 : 0 : cq_ds_cnt &= 0x3FFF3FFF0000;
126 : :
127 [ # # ]: 0 : while (aq_cnt || cq_ds_cnt || ds_cnt) {
128 : 0 : plt_write64(req, ws->base + SSOW_LF_GWS_OP_GET_WORK0);
129 : : cn20k_sso_hws_get_work_empty(ws, &ev, 0);
130 [ # # # # ]: 0 : if (fn != NULL && ev.u64 != 0)
131 : 0 : fn(arg, ev);
132 [ # # ]: 0 : if (ev.sched_type != SSO_TT_EMPTY)
133 : 0 : cnxk_sso_hws_swtag_flush(ws->base);
134 [ # # ]: 0 : else if (retry-- == 0)
135 : : break;
136 : : do {
137 [ # # ]: 0 : val = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
138 [ # # ]: 0 : } while (val & BIT_ULL(56));
139 : : aq_cnt = plt_read64(base + SSO_LF_GGRP_AQ_CNT);
140 : : ds_cnt = plt_read64(base + SSO_LF_GGRP_MISC_CNT);
141 : : cq_ds_cnt = plt_read64(base + SSO_LF_GGRP_INT_CNT);
142 : : /* Extract cq and ds count */
143 : 0 : cq_ds_cnt &= 0x3FFF3FFF0000;
144 : : }
145 : :
146 [ # # ]: 0 : if (aq_cnt || cq_ds_cnt || ds_cnt)
147 : : return -EAGAIN;
148 : :
149 : 0 : plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
150 : 0 : roc_sso_hws_gwc_invalidate(&dev->sso, &ws->hws_id, 1);
151 : : rte_mb();
152 : :
153 : 0 : return 0;
154 : : }
155 : :
156 : : static void
157 : : cn20k_sso_set_rsrc(void *arg)
158 : : {
159 : : struct cnxk_sso_evdev *dev = arg;
160 : :
161 : 0 : dev->max_event_ports = dev->sso.max_hws;
162 : 0 : dev->max_event_queues = dev->sso.max_hwgrp > RTE_EVENT_MAX_QUEUES_PER_DEV ?
163 : 0 : RTE_EVENT_MAX_QUEUES_PER_DEV :
164 : : dev->sso.max_hwgrp;
165 : : }
166 : :
167 : : static int
168 : 0 : cn20k_sso_rsrc_init(void *arg, uint8_t hws, uint8_t hwgrp)
169 : : {
170 : : struct cnxk_tim_evdev *tim_dev = cnxk_tim_priv_get();
171 : : struct cnxk_sso_evdev *dev = arg;
172 : : uint16_t nb_tim_lfs;
173 : :
174 [ # # ]: 0 : nb_tim_lfs = tim_dev ? tim_dev->nb_rings : 0;
175 : 0 : return roc_sso_rsrc_init(&dev->sso, hws, hwgrp, nb_tim_lfs);
176 : : }
177 : :
178 : : static int
179 [ # # ]: 0 : cn20k_sso_updt_tx_adptr_data(const struct rte_eventdev *event_dev)
180 : : {
181 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
182 : : int i;
183 : :
184 [ # # ]: 0 : if (dev->tx_adptr_data == NULL)
185 : : return 0;
186 : :
187 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
188 : 0 : struct cn20k_sso_hws *ws = event_dev->data->ports[i];
189 : : void *ws_cookie;
190 : :
191 : : ws_cookie = cnxk_sso_hws_get_cookie(ws);
192 : 0 : ws_cookie = rte_realloc_socket(ws_cookie,
193 : : sizeof(struct cnxk_sso_hws_cookie) +
194 : : sizeof(struct cn20k_sso_hws) +
195 : 0 : dev->tx_adptr_data_sz,
196 : : RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
197 [ # # ]: 0 : if (ws_cookie == NULL)
198 : : return -ENOMEM;
199 : 0 : ws = RTE_PTR_ADD(ws_cookie, sizeof(struct cnxk_sso_hws_cookie));
200 : 0 : memcpy(&ws->tx_adptr_data, dev->tx_adptr_data, dev->tx_adptr_data_sz);
201 : 0 : event_dev->data->ports[i] = ws;
202 : : }
203 : :
204 : : return 0;
205 : : }
206 : :
207 : : #if defined(RTE_ARCH_ARM64)
208 : : static inline void
209 : : cn20k_sso_fp_tmplt_fns_set(struct rte_eventdev *event_dev)
210 : : {
211 : : #if !defined(CNXK_DIS_TMPLT_FUNC)
212 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
213 : :
214 : : const event_dequeue_burst_t sso_hws_deq_burst[NIX_RX_OFFLOAD_MAX] = {
215 : : #define R(name, flags) [flags] = cn20k_sso_hws_deq_burst_##name,
216 : : NIX_RX_FASTPATH_MODES
217 : : #undef R
218 : : };
219 : :
220 : : const event_dequeue_burst_t sso_hws_deq_tmo_burst[NIX_RX_OFFLOAD_MAX] = {
221 : : #define R(name, flags) [flags] = cn20k_sso_hws_deq_tmo_burst_##name,
222 : : NIX_RX_FASTPATH_MODES
223 : : #undef R
224 : : };
225 : :
226 : : const event_dequeue_burst_t sso_hws_deq_seg_burst[NIX_RX_OFFLOAD_MAX] = {
227 : : #define R(name, flags) [flags] = cn20k_sso_hws_deq_seg_burst_##name,
228 : : NIX_RX_FASTPATH_MODES
229 : : #undef R
230 : : };
231 : :
232 : : const event_dequeue_burst_t sso_hws_deq_tmo_seg_burst[NIX_RX_OFFLOAD_MAX] = {
233 : : #define R(name, flags) [flags] = cn20k_sso_hws_deq_tmo_seg_burst_##name,
234 : : NIX_RX_FASTPATH_MODES
235 : : #undef R
236 : : };
237 : :
238 : : const event_dequeue_burst_t sso_hws_reas_deq_burst[NIX_RX_OFFLOAD_MAX] = {
239 : : #define R(name, flags) [flags] = cn20k_sso_hws_reas_deq_burst_##name,
240 : : NIX_RX_FASTPATH_MODES
241 : : #undef R
242 : : };
243 : :
244 : : const event_dequeue_burst_t sso_hws_reas_deq_tmo_burst[NIX_RX_OFFLOAD_MAX] = {
245 : : #define R(name, flags) [flags] = cn20k_sso_hws_reas_deq_tmo_burst_##name,
246 : : NIX_RX_FASTPATH_MODES
247 : : #undef R
248 : : };
249 : :
250 : : const event_dequeue_burst_t sso_hws_reas_deq_seg_burst[NIX_RX_OFFLOAD_MAX] = {
251 : : #define R(name, flags) [flags] = cn20k_sso_hws_reas_deq_seg_burst_##name,
252 : : NIX_RX_FASTPATH_MODES
253 : : #undef R
254 : : };
255 : :
256 : : const event_dequeue_burst_t sso_hws_reas_deq_tmo_seg_burst[NIX_RX_OFFLOAD_MAX] = {
257 : : #define R(name, flags) [flags] = cn20k_sso_hws_reas_deq_tmo_seg_burst_##name,
258 : : NIX_RX_FASTPATH_MODES
259 : : #undef R
260 : : };
261 : :
262 : : /* Tx modes */
263 : : const event_tx_adapter_enqueue_t sso_hws_tx_adptr_enq[NIX_TX_OFFLOAD_MAX] = {
264 : : #define T(name, sz, flags) [flags] = cn20k_sso_hws_tx_adptr_enq_##name,
265 : : NIX_TX_FASTPATH_MODES
266 : : #undef T
267 : : };
268 : :
269 : : const event_tx_adapter_enqueue_t sso_hws_tx_adptr_enq_seg[NIX_TX_OFFLOAD_MAX] = {
270 : : #define T(name, sz, flags) [flags] = cn20k_sso_hws_tx_adptr_enq_seg_##name,
271 : : NIX_TX_FASTPATH_MODES
272 : : #undef T
273 : : };
274 : :
275 : : if (dev->rx_offloads & NIX_RX_MULTI_SEG_F) {
276 : : if (dev->rx_offloads & NIX_RX_REAS_F) {
277 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
278 : : sso_hws_reas_deq_seg_burst);
279 : : if (dev->is_timeout_deq)
280 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
281 : : sso_hws_reas_deq_tmo_seg_burst);
282 : : } else {
283 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
284 : : sso_hws_deq_seg_burst);
285 : :
286 : : if (dev->is_timeout_deq)
287 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
288 : : sso_hws_deq_tmo_seg_burst);
289 : : }
290 : : } else {
291 : : if (dev->rx_offloads & NIX_RX_REAS_F) {
292 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
293 : : sso_hws_reas_deq_burst);
294 : :
295 : : if (dev->is_timeout_deq)
296 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
297 : : sso_hws_reas_deq_tmo_burst);
298 : : } else {
299 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst, sso_hws_deq_burst);
300 : :
301 : : if (dev->is_timeout_deq)
302 : : CN20K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
303 : : sso_hws_deq_tmo_burst);
304 : : }
305 : : }
306 : :
307 : : if (dev->tx_offloads & NIX_TX_MULTI_SEG_F)
308 : : CN20K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue, sso_hws_tx_adptr_enq_seg);
309 : : else
310 : : CN20K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue, sso_hws_tx_adptr_enq);
311 : :
312 : : event_dev->txa_enqueue_same_dest = event_dev->txa_enqueue;
313 : : #else
314 : : RTE_SET_USED(event_dev);
315 : : #endif
316 : : }
317 : :
318 : : static inline void
319 : : cn20k_sso_fp_blk_fns_set(struct rte_eventdev *event_dev)
320 : : {
321 : : #if defined(CNXK_DIS_TMPLT_FUNC)
322 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
323 : :
324 : : event_dev->dequeue_burst = cn20k_sso_hws_deq_burst_all_offload;
325 : : if (dev->rx_offloads & NIX_RX_OFFLOAD_TSTAMP_F)
326 : : event_dev->dequeue_burst = cn20k_sso_hws_deq_burst_all_offload_tst;
327 : : event_dev->txa_enqueue = cn20k_sso_hws_tx_adptr_enq_seg_all_offload;
328 : : event_dev->txa_enqueue_same_dest = cn20k_sso_hws_tx_adptr_enq_seg_all_offload;
329 : : if (dev->tx_offloads & (NIX_TX_OFFLOAD_OL3_OL4_CSUM_F | NIX_TX_OFFLOAD_VLAN_QINQ_F |
330 : : NIX_TX_OFFLOAD_TSO_F | NIX_TX_OFFLOAD_TSTAMP_F)) {
331 : : event_dev->txa_enqueue = cn20k_sso_hws_tx_adptr_enq_seg_all_offload_tst;
332 : : event_dev->txa_enqueue_same_dest = cn20k_sso_hws_tx_adptr_enq_seg_all_offload_tst;
333 : : }
334 : : #else
335 : : RTE_SET_USED(event_dev);
336 : : #endif
337 : : }
338 : : #endif
339 : :
340 : : static void
341 : : cn20k_sso_fp_fns_set(struct rte_eventdev *event_dev)
342 : : {
343 : : #if defined(RTE_ARCH_ARM64)
344 : : cn20k_sso_fp_blk_fns_set(event_dev);
345 : : cn20k_sso_fp_tmplt_fns_set(event_dev);
346 : :
347 : : event_dev->enqueue_burst = cn20k_sso_hws_enq_burst;
348 : : event_dev->enqueue_new_burst = cn20k_sso_hws_enq_new_burst;
349 : : event_dev->enqueue_forward_burst = cn20k_sso_hws_enq_fwd_burst;
350 : :
351 : : event_dev->ca_enqueue = cn20k_cpt_crypto_adapter_enqueue;
352 : : event_dev->profile_switch = cn20k_sso_hws_profile_switch;
353 : : event_dev->preschedule_modify = cn20k_sso_hws_preschedule_modify;
354 : : event_dev->preschedule = cn20k_sso_hws_preschedule;
355 : : #else
356 : : RTE_SET_USED(event_dev);
357 : : #endif
358 : : }
359 : :
360 : : static void
361 : 0 : cn20k_sso_info_get(struct rte_eventdev *event_dev, struct rte_event_dev_info *dev_info)
362 : : {
363 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
364 : :
365 : 0 : dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN20K_PMD);
366 : 0 : cnxk_sso_info_get(dev, dev_info);
367 : 0 : dev_info->max_event_port_enqueue_depth = UINT32_MAX;
368 : 0 : }
369 : :
370 : : static int
371 : 0 : cn20k_sso_dev_configure(const struct rte_eventdev *event_dev)
372 : : {
373 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
374 : : int rc;
375 : :
376 : 0 : rc = cnxk_sso_dev_validate(event_dev, 1, UINT32_MAX);
377 [ # # ]: 0 : if (rc < 0) {
378 : 0 : plt_err("Invalid event device configuration");
379 : 0 : return -EINVAL;
380 : : }
381 : :
382 : 0 : rc = cn20k_sso_rsrc_init(dev, dev->nb_event_ports, dev->nb_event_queues);
383 [ # # ]: 0 : if (rc < 0) {
384 : 0 : plt_err("Failed to initialize SSO resources");
385 : 0 : return -ENODEV;
386 : : }
387 : :
388 : 0 : rc = cnxk_sso_xaq_allocate(dev);
389 [ # # ]: 0 : if (rc < 0)
390 : 0 : goto cnxk_rsrc_fini;
391 : :
392 [ # # # ]: 0 : dev->gw_mode = cnxk_sso_hws_preschedule_get(event_dev->data->dev_conf.preschedule_type);
393 : :
394 : 0 : rc = cnxk_setup_event_ports(event_dev, cn20k_sso_init_hws_mem, cn20k_sso_hws_setup);
395 [ # # ]: 0 : if (rc < 0)
396 : 0 : goto cnxk_rsrc_fini;
397 : :
398 : : /* Restore any prior port-queue mapping. */
399 : 0 : cnxk_sso_restore_links(event_dev, cn20k_sso_hws_link);
400 : :
401 : 0 : dev->configured = 1;
402 : : rte_mb();
403 : :
404 : 0 : return 0;
405 : 0 : cnxk_rsrc_fini:
406 : 0 : roc_sso_rsrc_fini(&dev->sso);
407 : 0 : dev->nb_event_ports = 0;
408 : 0 : return rc;
409 : : }
410 : :
411 : : static int
412 : 0 : cn20k_sso_port_setup(struct rte_eventdev *event_dev, uint8_t port_id,
413 : : const struct rte_event_port_conf *port_conf)
414 : : {
415 : :
416 : : RTE_SET_USED(port_conf);
417 : 0 : return cnxk_sso_port_setup(event_dev, port_id, cn20k_sso_hws_setup);
418 : : }
419 : :
420 : : static void
421 [ # # ]: 0 : cn20k_sso_port_release(void *port)
422 : : {
423 : : struct cnxk_sso_hws_cookie *gws_cookie = cnxk_sso_hws_get_cookie(port);
424 : : struct cnxk_sso_evdev *dev;
425 : :
426 [ # # ]: 0 : if (port == NULL)
427 : : return;
428 : :
429 [ # # ]: 0 : dev = cnxk_sso_pmd_priv(gws_cookie->event_dev);
430 [ # # ]: 0 : if (!gws_cookie->configured)
431 : 0 : goto free;
432 : :
433 : 0 : cn20k_sso_hws_release(dev, port);
434 : : memset(gws_cookie, 0, sizeof(*gws_cookie));
435 : 0 : free:
436 : 0 : rte_free(gws_cookie);
437 : : }
438 : :
439 : : static void
440 : 0 : cn20k_sso_port_quiesce(struct rte_eventdev *event_dev, void *port,
441 : : rte_eventdev_port_flush_t flush_cb, void *args)
442 : : {
443 : 0 : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
444 : : struct cn20k_sso_hws *ws = port;
445 : : struct rte_event ev;
446 : : uint64_t ptag;
447 : : bool is_pend;
448 : :
449 : : is_pend = false;
450 : : /* Work in WQE0 is always consumed, unless its a SWTAG. */
451 [ # # ]: 0 : ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
452 [ # # # # ]: 0 : if (ptag & (BIT_ULL(62) | BIT_ULL(54)) || ws->swtag_req)
453 : : is_pend = true;
454 : : do {
455 : : ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
456 [ # # ]: 0 : } while (ptag & (BIT_ULL(62) | BIT_ULL(58) | BIT_ULL(56) | BIT_ULL(54)));
457 : :
458 : : cn20k_sso_hws_get_work_empty(ws, &ev,
459 : : (NIX_RX_OFFLOAD_MAX - 1) | NIX_RX_REAS_F | NIX_RX_MULTI_SEG_F);
460 [ # # # # ]: 0 : if (is_pend && ev.u64)
461 [ # # ]: 0 : if (flush_cb)
462 : 0 : flush_cb(event_dev->data->dev_id, ev, args);
463 [ # # ]: 0 : ptag = (plt_read64(ws->base + SSOW_LF_GWS_TAG) >> 32) & SSO_TT_EMPTY;
464 [ # # ]: 0 : if (ptag != SSO_TT_EMPTY)
465 : : cnxk_sso_hws_swtag_flush(ws->base);
466 : :
467 : : do {
468 [ # # ]: 0 : ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
469 [ # # ]: 0 : } while (ptag & BIT_ULL(56));
470 : :
471 : : /* Check if we have work in PRF_WQE0, if so extract it. */
472 [ # # ]: 0 : switch (dev->gw_mode) {
473 : : case CNXK_GW_MODE_PREF:
474 : : case CNXK_GW_MODE_PREF_WFE:
475 [ # # ]: 0 : while (plt_read64(ws->base + SSOW_LF_GWS_PRF_WQE0) & BIT_ULL(63))
476 : : ;
477 : : break;
478 : : case CNXK_GW_MODE_NONE:
479 : : default:
480 : : break;
481 : : }
482 : :
483 [ # # ]: 0 : if (CNXK_TT_FROM_TAG(plt_read64(ws->base + SSOW_LF_GWS_PRF_WQE0)) != SSO_TT_EMPTY) {
484 : 0 : plt_write64(BIT_ULL(16) | 1, ws->base + SSOW_LF_GWS_OP_GET_WORK0);
485 : : cn20k_sso_hws_get_work_empty(
486 : : ws, &ev, (NIX_RX_OFFLOAD_MAX - 1) | NIX_RX_REAS_F | NIX_RX_MULTI_SEG_F);
487 [ # # ]: 0 : if (ev.u64) {
488 [ # # ]: 0 : if (flush_cb)
489 : 0 : flush_cb(event_dev->data->dev_id, ev, args);
490 : : }
491 : 0 : cnxk_sso_hws_swtag_flush(ws->base);
492 : : do {
493 [ # # ]: 0 : ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
494 [ # # ]: 0 : } while (ptag & BIT_ULL(56));
495 : : }
496 : 0 : ws->swtag_req = 0;
497 : 0 : plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
498 : 0 : }
499 : :
500 : : static int
501 : 0 : cn20k_sso_port_link_profile(struct rte_eventdev *event_dev, void *port, const uint8_t queues[],
502 : : const uint8_t priorities[], uint16_t nb_links, uint8_t profile)
503 : 0 : {
504 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
505 : 0 : uint16_t hwgrp_ids[nb_links];
506 : : uint16_t link;
507 : :
508 : : RTE_SET_USED(priorities);
509 [ # # ]: 0 : for (link = 0; link < nb_links; link++)
510 : 0 : hwgrp_ids[link] = queues[link];
511 : 0 : nb_links = cn20k_sso_hws_link(dev, port, hwgrp_ids, nb_links, profile);
512 : :
513 : 0 : return (int)nb_links;
514 : : }
515 : :
516 : : static int
517 : 0 : cn20k_sso_port_unlink_profile(struct rte_eventdev *event_dev, void *port, uint8_t queues[],
518 : : uint16_t nb_unlinks, uint8_t profile)
519 : 0 : {
520 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
521 : 0 : uint16_t hwgrp_ids[nb_unlinks];
522 : : uint16_t unlink;
523 : :
524 [ # # ]: 0 : for (unlink = 0; unlink < nb_unlinks; unlink++)
525 : 0 : hwgrp_ids[unlink] = queues[unlink];
526 : 0 : nb_unlinks = cn20k_sso_hws_unlink(dev, port, hwgrp_ids, nb_unlinks, profile);
527 : :
528 : 0 : return (int)nb_unlinks;
529 : : }
530 : :
531 : : static int
532 : 0 : cn20k_sso_port_link(struct rte_eventdev *event_dev, void *port, const uint8_t queues[],
533 : : const uint8_t priorities[], uint16_t nb_links)
534 : : {
535 : 0 : return cn20k_sso_port_link_profile(event_dev, port, queues, priorities, nb_links, 0);
536 : : }
537 : :
538 : : static int
539 : 0 : cn20k_sso_port_unlink(struct rte_eventdev *event_dev, void *port, uint8_t queues[],
540 : : uint16_t nb_unlinks)
541 : : {
542 : 0 : return cn20k_sso_port_unlink_profile(event_dev, port, queues, nb_unlinks, 0);
543 : : }
544 : :
545 : : static int
546 : 0 : cn20k_sso_start(struct rte_eventdev *event_dev)
547 : : {
548 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
549 : : uint8_t hws[RTE_EVENT_MAX_PORTS_PER_DEV];
550 : : int rc, i;
551 : :
552 : 0 : cnxk_sso_configure_queue_stash(event_dev);
553 : 0 : rc = cnxk_sso_start(event_dev, cnxk_sso_hws_reset, cn20k_sso_hws_flush_events);
554 [ # # ]: 0 : if (rc < 0)
555 : : return rc;
556 : : cn20k_sso_fp_fns_set(event_dev);
557 [ # # ]: 0 : for (i = 0; i < event_dev->data->nb_ports; i++)
558 : 0 : hws[i] = i;
559 : 0 : roc_sso_hws_gwc_invalidate(&dev->sso, hws, event_dev->data->nb_ports);
560 : :
561 : 0 : return rc;
562 : : }
563 : :
564 : : static void
565 : 0 : cn20k_sso_stop(struct rte_eventdev *event_dev)
566 : : {
567 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
568 : : uint8_t hws[RTE_EVENT_MAX_PORTS_PER_DEV];
569 : : int i;
570 : :
571 [ # # ]: 0 : for (i = 0; i < event_dev->data->nb_ports; i++)
572 : 0 : hws[i] = i;
573 : 0 : roc_sso_hws_gwc_invalidate(&dev->sso, hws, event_dev->data->nb_ports);
574 : 0 : cnxk_sso_stop(event_dev, cnxk_sso_hws_reset, cn20k_sso_hws_flush_events);
575 : 0 : }
576 : :
577 : : static int
578 : 0 : cn20k_sso_close(struct rte_eventdev *event_dev)
579 : : {
580 : 0 : return cnxk_sso_close(event_dev, cn20k_sso_hws_unlink);
581 : : }
582 : :
583 : : static int
584 : 0 : cn20k_sso_selftest(void)
585 : : {
586 : 0 : return cnxk_sso_selftest(RTE_STR(event_cn20k));
587 : : }
588 : :
589 : : static int
590 : 0 : cn20k_sso_rx_adapter_caps_get(const struct rte_eventdev *event_dev,
591 : : const struct rte_eth_dev *eth_dev, uint32_t *caps)
592 : : {
593 : : int rc;
594 : :
595 : : RTE_SET_USED(event_dev);
596 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn20k", 9);
597 [ # # ]: 0 : if (rc)
598 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP;
599 : : else
600 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT |
601 : : RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ |
602 : : RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID |
603 : : RTE_EVENT_ETH_RX_ADAPTER_CAP_EVENT_VECTOR;
604 : :
605 : 0 : return 0;
606 : : }
607 : :
608 : : static void
609 : 0 : cn20k_sso_set_priv_mem(const struct rte_eventdev *event_dev, void *lookup_mem)
610 : : {
611 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
612 : : int i;
613 : :
614 [ # # # # : 0 : for (i = 0; i < dev->nb_event_ports; i++) {
# # # # ]
615 : 0 : struct cn20k_sso_hws *ws = event_dev->data->ports[i];
616 : 0 : ws->xaq_lmt = dev->xaq_lmt;
617 : 0 : ws->fc_mem = (int64_t __rte_atomic *)dev->fc_iova;
618 : 0 : ws->tstamp = dev->tstamp;
619 [ # # # # : 0 : if (lookup_mem)
# # ]
620 : 0 : ws->lookup_mem = lookup_mem;
621 : : }
622 : 0 : }
623 : :
624 : : static void
625 : : eventdev_fops_tstamp_update(struct rte_eventdev *event_dev)
626 : : {
627 : 0 : struct rte_event_fp_ops *fp_op = rte_event_fp_ops + event_dev->data->dev_id;
628 : :
629 : 0 : fp_op->dequeue_burst = event_dev->dequeue_burst;
630 : : }
631 : :
632 : : static void
633 : 0 : cn20k_sso_tstamp_hdl_update(uint16_t port_id, uint16_t flags, bool ptp_en)
634 : : {
635 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
636 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = dev->data->dev_private;
637 [ # # ]: 0 : struct rte_eventdev *event_dev = cnxk_eth_dev->evdev_priv;
638 : : struct cnxk_sso_evdev *evdev = cnxk_sso_pmd_priv(event_dev);
639 : :
640 : 0 : evdev->rx_offloads |= flags;
641 [ # # ]: 0 : if (ptp_en)
642 : 0 : evdev->tstamp[port_id] = &cnxk_eth_dev->tstamp;
643 : : else
644 : 0 : evdev->tstamp[port_id] = NULL;
645 : : cn20k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
646 : : eventdev_fops_tstamp_update(event_dev);
647 : 0 : }
648 : :
649 : : static int
650 : 0 : cn20k_sso_rxq_enable(struct cnxk_eth_dev *cnxk_eth_dev, uint16_t rq_id, uint16_t port_id,
651 : : const struct rte_event_eth_rx_adapter_queue_conf *queue_conf, int agq)
652 : : {
653 : : struct roc_nix_rq *rq;
654 : : uint32_t tag_mask;
655 : : uint16_t wqe_skip;
656 : : uint8_t tt;
657 : : int rc;
658 : :
659 : 0 : rq = &cnxk_eth_dev->rqs[rq_id];
660 [ # # ]: 0 : if (queue_conf->rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR) {
661 : 0 : tag_mask = agq;
662 : : tt = SSO_TT_AGG;
663 : 0 : rq->flow_tag_width = 0;
664 : : } else {
665 : 0 : tag_mask = (port_id & 0xFF) << 20;
666 : : tag_mask |= (RTE_EVENT_TYPE_ETHDEV << 28);
667 : 0 : tt = queue_conf->ev.sched_type;
668 : 0 : rq->flow_tag_width = 20;
669 [ # # ]: 0 : if (queue_conf->rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID) {
670 : 0 : rq->flow_tag_width = 0;
671 : 0 : tag_mask |= queue_conf->ev.flow_id;
672 : : }
673 : : }
674 : :
675 : 0 : rq->tag_mask = tag_mask;
676 : 0 : rq->sso_ena = 1;
677 : 0 : rq->tt = tt;
678 : 0 : rq->hwgrp = queue_conf->ev.queue_id;
679 : : wqe_skip = RTE_ALIGN_CEIL(sizeof(struct rte_mbuf), ROC_CACHE_LINE_SZ);
680 : : wqe_skip = wqe_skip / ROC_CACHE_LINE_SZ;
681 : 0 : rq->wqe_skip = wqe_skip;
682 : :
683 : 0 : rc = roc_nix_rq_modify(&cnxk_eth_dev->nix, rq, 0);
684 : 0 : return rc;
685 : : }
686 : :
687 : : static int
688 : 0 : cn20k_sso_rx_adapter_vwqe_enable(struct cnxk_sso_evdev *dev, uint16_t port_id, uint16_t rq_id,
689 : : const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
690 : : {
691 : : uint32_t agq, tag_mask, stag_mask;
692 : : struct roc_sso_agq_data data;
693 : : int rc;
694 : :
695 : 0 : tag_mask = (port_id & 0xff) << 20;
696 [ # # ]: 0 : if (queue_conf->rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID)
697 : 0 : tag_mask |= queue_conf->ev.flow_id;
698 : : else
699 : 0 : tag_mask |= rq_id;
700 : :
701 : : stag_mask = tag_mask;
702 [ # # ]: 0 : tag_mask |= RTE_EVENT_TYPE_ETHDEV_VECTOR << 28;
703 : : stag_mask |= RTE_EVENT_TYPE_ETHDEV << 28;
704 : :
705 : : memset(&data, 0, sizeof(struct roc_sso_agq_data));
706 : 0 : data.tag = tag_mask;
707 : 0 : data.tt = queue_conf->ev.sched_type;
708 : 0 : data.stag = stag_mask;
709 [ # # ]: 0 : data.vwqe_aura = roc_npa_aura_handle_to_aura(queue_conf->vector_mp->pool_id);
710 [ # # ]: 0 : data.vwqe_max_sz_exp = rte_log2_u32(queue_conf->vector_sz);
711 : 0 : data.vwqe_wait_tmo = queue_conf->vector_timeout_ns / ((SSO_AGGR_DEF_TMO + 1) * 100);
712 : : data.xqe_type = 0;
713 : :
714 : 0 : agq = UINT32_MAX;
715 : 0 : rc = roc_sso_hwgrp_agq_alloc(&dev->sso, queue_conf->ev.queue_id, &data, &agq);
716 [ # # ]: 0 : if (rc < 0)
717 : : return rc;
718 : :
719 : 0 : return agq;
720 : : }
721 : :
722 : : static int
723 : 0 : cn20k_rx_adapter_queue_del(const struct rte_eventdev *event_dev, const struct rte_eth_dev *eth_dev,
724 : : int32_t rx_queue_id)
725 : : {
726 [ # # ]: 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
727 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
728 : : struct roc_nix_rq *rxq;
729 : : int i, rc = 0;
730 : :
731 : : RTE_SET_USED(event_dev);
732 [ # # ]: 0 : if (rx_queue_id < 0) {
733 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
734 : 0 : cn20k_rx_adapter_queue_del(event_dev, eth_dev, i);
735 : : } else {
736 : 0 : rxq = &cnxk_eth_dev->rqs[rx_queue_id];
737 [ # # ]: 0 : if (rxq->tt == SSO_TT_AGG)
738 : 0 : roc_sso_hwgrp_agq_free(&dev->sso, rxq->hwgrp, rxq->tag_mask);
739 : 0 : rc = cnxk_sso_rxq_disable(eth_dev, (uint16_t)rx_queue_id);
740 : 0 : cnxk_eth_dev->nb_rxq_sso--;
741 : : }
742 : :
743 [ # # ]: 0 : if (rc < 0)
744 : 0 : plt_err("Failed to clear Rx adapter config port=%d, q=%d", eth_dev->data->port_id,
745 : : rx_queue_id);
746 : 0 : return rc;
747 : : }
748 : :
749 : : static int
750 : 0 : cn20k_rx_adapter_queues_add(const struct rte_eventdev *event_dev, const struct rte_eth_dev *eth_dev,
751 : : int32_t rx_queue_id[],
752 : : const struct rte_event_eth_rx_adapter_queue_conf queue_conf[],
753 : : uint16_t nb_rx_queues)
754 : : {
755 [ # # ]: 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
756 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
757 : : const struct rte_event_eth_rx_adapter_queue_conf *conf;
758 : 0 : uint64_t old_xae_cnt = dev->adptr_xae_cnt;
759 : 0 : uint16_t port = eth_dev->data->port_id;
760 : : struct cnxk_eth_rxq_sp *rxq_sp;
761 : : uint16_t max_rx_queues;
762 : : int i, rc = 0, agq = 0;
763 : : int32_t queue_id;
764 : :
765 [ # # ]: 0 : max_rx_queues = nb_rx_queues ? nb_rx_queues : eth_dev->data->nb_rx_queues;
766 [ # # ]: 0 : for (i = 0; i < max_rx_queues; i++) {
767 [ # # ]: 0 : conf = nb_rx_queues ? &queue_conf[i] : &queue_conf[0];
768 [ # # ]: 0 : queue_id = nb_rx_queues ? rx_queue_id[i] : i;
769 : 0 : rxq_sp = cnxk_eth_rxq_to_sp(eth_dev->data->rx_queues[queue_id]);
770 : 0 : cnxk_sso_updt_xae_cnt(dev, rxq_sp, RTE_EVENT_TYPE_ETHDEV);
771 : :
772 [ # # ]: 0 : if (conf->rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR)
773 : 0 : cnxk_sso_updt_xae_cnt(dev, conf->vector_mp, RTE_EVENT_TYPE_ETHDEV_VECTOR);
774 : : }
775 : :
776 [ # # ]: 0 : if (dev->adptr_xae_cnt != old_xae_cnt) {
777 : 0 : rc = cnxk_sso_xae_reconfigure((struct rte_eventdev *)(uintptr_t)event_dev);
778 [ # # ]: 0 : if (rc < 0)
779 : : return rc;
780 : : }
781 : :
782 [ # # ]: 0 : for (i = 0; i < max_rx_queues; i++) {
783 [ # # ]: 0 : conf = nb_rx_queues ? &queue_conf[i] : &queue_conf[0];
784 [ # # ]: 0 : queue_id = nb_rx_queues ? rx_queue_id[i] : i;
785 [ # # ]: 0 : if (conf->rx_queue_flags & RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR) {
786 : 0 : rc = cn20k_sso_rx_adapter_vwqe_enable(dev, port, queue_id, conf);
787 [ # # ]: 0 : if (rc < 0) {
788 : 0 : plt_err("Failed to enable VWQE, port=%d, rxq=%d", port, queue_id);
789 : 0 : goto fail;
790 : : }
791 : :
792 : : agq = rc;
793 : : }
794 : :
795 : 0 : rc = cn20k_sso_rxq_enable(cnxk_eth_dev, (uint16_t)queue_id, port, conf, agq);
796 [ # # ]: 0 : if (rc < 0) {
797 : 0 : plt_err("Failed to enable Rx queue, port=%d, rxq=%d", port, queue_id);
798 : 0 : goto fail;
799 : : }
800 : :
801 : 0 : cnxk_eth_dev->nb_rxq_sso++;
802 : : }
803 : :
804 : : /* Propagate force bp devarg */
805 : 0 : cnxk_eth_dev->nix.force_rx_aura_bp = dev->force_ena_bp;
806 : 0 : cnxk_sso_tstamp_cfg(port, eth_dev, dev);
807 : 0 : dev->rx_offloads |= cnxk_eth_dev->rx_offload_flags;
808 : 0 : return 0;
809 : :
810 : 0 : fail:
811 [ # # ]: 0 : for (i = cnxk_eth_dev->nb_rxq_sso - 1; i >= 0; i--) {
812 [ # # ]: 0 : queue_id = nb_rx_queues ? rx_queue_id[i] : i;
813 : 0 : cn20k_rx_adapter_queue_del(event_dev, eth_dev, queue_id);
814 : : }
815 : :
816 : : return rc;
817 : : }
818 : :
819 : : static int
820 : 0 : cn20k_sso_configure_queue_stash_default(struct cnxk_sso_evdev *dev, uint16_t hwgrp)
821 : : {
822 : : struct roc_sso_hwgrp_stash stash;
823 : : int rc;
824 : :
825 : 0 : stash.hwgrp = hwgrp;
826 : 0 : stash.stash_offset = CN20K_SSO_DEFAULT_STASH_OFFSET;
827 : 0 : stash.stash_count = CN20K_SSO_DEFAULT_STASH_LENGTH;
828 : 0 : rc = roc_sso_hwgrp_stash_config(&dev->sso, &stash, 1);
829 [ # # ]: 0 : if (rc < 0)
830 : 0 : plt_warn("failed to configure HWGRP WQE stashing rc = %d", rc);
831 : :
832 : 0 : return rc;
833 : : }
834 : :
835 : : static int
836 : 0 : cn20k_sso_rx_adapter_queue_add(const struct rte_eventdev *event_dev,
837 : : const struct rte_eth_dev *eth_dev, int32_t rx_queue_id,
838 : : const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
839 : : {
840 [ # # ]: 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
841 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
842 : : struct cn20k_eth_rxq *rxq;
843 : : uint16_t nb_rx_queues;
844 : : void *lookup_mem;
845 : : int rc;
846 : :
847 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn20k", 8);
848 [ # # ]: 0 : if (rc)
849 : : return -EINVAL;
850 : :
851 : 0 : nb_rx_queues = rx_queue_id == -1 ? 0 : 1;
852 : 0 : rc = cn20k_rx_adapter_queues_add(event_dev, eth_dev, &rx_queue_id, queue_conf,
853 : : nb_rx_queues);
854 [ # # ]: 0 : if (rc)
855 : : return -EINVAL;
856 : :
857 : 0 : cnxk_eth_dev->cnxk_sso_ptp_tstamp_cb = cn20k_sso_tstamp_hdl_update;
858 : 0 : cnxk_eth_dev->evdev_priv = (struct rte_eventdev *)(uintptr_t)event_dev;
859 : :
860 : 0 : rxq = eth_dev->data->rx_queues[0];
861 : 0 : lookup_mem = rxq->lookup_mem;
862 : : cn20k_sso_set_priv_mem(event_dev, lookup_mem);
863 : : cn20k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
864 [ # # # # ]: 0 : if (roc_feature_sso_has_stash() && dev->nb_event_ports > 1)
865 : 0 : rc = cn20k_sso_configure_queue_stash_default(dev, queue_conf->ev.queue_id);
866 : :
867 : : return rc;
868 : : }
869 : :
870 : : static int
871 : 0 : cn20k_sso_rx_adapter_queues_add(const struct rte_eventdev *event_dev,
872 : : const struct rte_eth_dev *eth_dev, int32_t rx_queue_id[],
873 : : const struct rte_event_eth_rx_adapter_queue_conf queue_conf[],
874 : : uint16_t nb_rx_queues)
875 : : {
876 [ # # ]: 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
877 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
878 : : struct cn20k_eth_rxq *rxq;
879 : : void *lookup_mem;
880 : : int rc, i;
881 : :
882 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn20k", 8);
883 [ # # ]: 0 : if (rc)
884 : : return -EINVAL;
885 : :
886 : 0 : rc = cn20k_rx_adapter_queues_add(event_dev, eth_dev, rx_queue_id, queue_conf, nb_rx_queues);
887 [ # # ]: 0 : if (rc)
888 : : return -EINVAL;
889 : :
890 : 0 : cnxk_eth_dev->cnxk_sso_ptp_tstamp_cb = cn20k_sso_tstamp_hdl_update;
891 : 0 : cnxk_eth_dev->evdev_priv = (struct rte_eventdev *)(uintptr_t)event_dev;
892 : :
893 : 0 : rxq = eth_dev->data->rx_queues[0];
894 : 0 : lookup_mem = rxq->lookup_mem;
895 : : cn20k_sso_set_priv_mem(event_dev, lookup_mem);
896 : : cn20k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
897 [ # # # # ]: 0 : if (roc_feature_sso_has_stash() && dev->nb_event_ports > 1) {
898 : 0 : uint16_t hwgrp = dev->sso.max_hwgrp;
899 : :
900 [ # # ]: 0 : if (nb_rx_queues == 0)
901 : 0 : rc = cn20k_sso_configure_queue_stash_default(dev,
902 : 0 : queue_conf[0].ev.queue_id);
903 : :
904 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++) {
905 [ # # ]: 0 : if (hwgrp == queue_conf[i].ev.queue_id)
906 : 0 : continue;
907 : :
908 : : hwgrp = queue_conf[i].ev.queue_id;
909 : 0 : rc = cn20k_sso_configure_queue_stash_default(dev, hwgrp);
910 [ # # ]: 0 : if (rc < 0)
911 : : break;
912 : : }
913 : : }
914 : :
915 : : return rc;
916 : : }
917 : :
918 : : static int
919 : 0 : cn20k_sso_rx_adapter_queue_del(const struct rte_eventdev *event_dev,
920 : : const struct rte_eth_dev *eth_dev, int32_t rx_queue_id)
921 : : {
922 : : int rc;
923 : :
924 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn20k", 8);
925 [ # # ]: 0 : if (rc)
926 : : return -EINVAL;
927 : :
928 : 0 : return cn20k_rx_adapter_queue_del(event_dev, eth_dev, rx_queue_id);
929 : : }
930 : :
931 : : static int
932 : 0 : cn20k_sso_rx_adapter_vector_limits(const struct rte_eventdev *dev,
933 : : const struct rte_eth_dev *eth_dev,
934 : : struct rte_event_eth_rx_adapter_vector_limits *limits)
935 : : {
936 : : int ret;
937 : :
938 : : RTE_SET_USED(dev);
939 : : RTE_SET_USED(eth_dev);
940 : 0 : ret = strncmp(eth_dev->device->driver->name, "net_cn20k", 8);
941 [ # # ]: 0 : if (ret)
942 : : return -ENOTSUP;
943 : :
944 : 0 : limits->log2_sz = true;
945 : 0 : limits->min_sz = 1 << ROC_NIX_VWQE_MIN_SIZE_LOG2;
946 : 0 : limits->max_sz = 1 << ROC_NIX_VWQE_MAX_SIZE_LOG2;
947 : 0 : limits->min_timeout_ns = (SSO_AGGR_DEF_TMO + 1) * 100;
948 : 0 : limits->max_timeout_ns = (BITMASK_ULL(11, 0) + 1) * limits->min_timeout_ns;
949 : :
950 : 0 : return 0;
951 : : }
952 : :
953 : : static int
954 : 0 : cn20k_sso_tx_adapter_caps_get(const struct rte_eventdev *dev, const struct rte_eth_dev *eth_dev,
955 : : uint32_t *caps)
956 : : {
957 : : int ret;
958 : :
959 : : RTE_SET_USED(dev);
960 : 0 : ret = strncmp(eth_dev->device->driver->name, "net_cn20k", 8);
961 [ # # ]: 0 : if (ret)
962 : 0 : *caps = 0;
963 : : else
964 : 0 : *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT |
965 : : RTE_EVENT_ETH_TX_ADAPTER_CAP_EVENT_VECTOR;
966 : :
967 : 0 : return 0;
968 : : }
969 : :
970 : : static void
971 : 0 : cn20k_sso_txq_fc_update(const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
972 : : {
973 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
974 : : struct cn20k_eth_txq *txq;
975 : : struct roc_nix_sq *sq;
976 : : int i;
977 : :
978 [ # # ]: 0 : if (tx_queue_id < 0) {
979 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
980 : 0 : cn20k_sso_txq_fc_update(eth_dev, i);
981 : : } else {
982 : : uint16_t sqes_per_sqb;
983 : :
984 : 0 : sq = &cnxk_eth_dev->sqs[tx_queue_id];
985 : 0 : txq = eth_dev->data->tx_queues[tx_queue_id];
986 : 0 : sqes_per_sqb = 1U << txq->sqes_per_sqb_log2;
987 [ # # ]: 0 : if (cnxk_eth_dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY)
988 : 0 : sq->nb_sqb_bufs_adj -= (cnxk_eth_dev->outb.nb_desc / sqes_per_sqb);
989 : 0 : txq->nb_sqb_bufs_adj = sq->nb_sqb_bufs_adj;
990 : : }
991 : 0 : }
992 : :
993 : : static int
994 : 0 : cn20k_sso_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *event_dev,
995 : : const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
996 : : {
997 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
998 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
999 : : uint64_t tx_offloads;
1000 : : int rc;
1001 : :
1002 : : RTE_SET_USED(id);
1003 : 0 : rc = cnxk_sso_tx_adapter_queue_add(event_dev, eth_dev, tx_queue_id);
1004 [ # # ]: 0 : if (rc < 0)
1005 : : return rc;
1006 : :
1007 : : /* Can't enable tstamp if all the ports don't have it enabled. */
1008 : 0 : tx_offloads = cnxk_eth_dev->tx_offload_flags;
1009 [ # # ]: 0 : if (dev->tx_adptr_configured) {
1010 : 0 : uint8_t tstmp_req = !!(tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F);
1011 : 0 : uint8_t tstmp_ena = !!(dev->tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F);
1012 : :
1013 [ # # ]: 0 : if (tstmp_ena && !tstmp_req)
1014 : 0 : dev->tx_offloads &= ~(NIX_TX_OFFLOAD_TSTAMP_F);
1015 [ # # ]: 0 : else if (!tstmp_ena && tstmp_req)
1016 : 0 : tx_offloads &= ~(NIX_TX_OFFLOAD_TSTAMP_F);
1017 : : }
1018 : :
1019 : 0 : dev->tx_offloads |= tx_offloads;
1020 : 0 : cn20k_sso_txq_fc_update(eth_dev, tx_queue_id);
1021 : 0 : rc = cn20k_sso_updt_tx_adptr_data(event_dev);
1022 [ # # ]: 0 : if (rc < 0)
1023 : : return rc;
1024 : : cn20k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
1025 : 0 : dev->tx_adptr_configured = 1;
1026 : :
1027 : 0 : return 0;
1028 : : }
1029 : :
1030 : : static int
1031 : 0 : cn20k_sso_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *event_dev,
1032 : : const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
1033 : : {
1034 : : int rc;
1035 : :
1036 : : RTE_SET_USED(id);
1037 : 0 : rc = cnxk_sso_tx_adapter_queue_del(event_dev, eth_dev, tx_queue_id);
1038 [ # # ]: 0 : if (rc < 0)
1039 : : return rc;
1040 : 0 : return cn20k_sso_updt_tx_adptr_data(event_dev);
1041 : : }
1042 : :
1043 : : static int
1044 : 0 : cn20k_crypto_adapter_caps_get(const struct rte_eventdev *event_dev,
1045 : : const struct rte_cryptodev *cdev, uint32_t *caps)
1046 : : {
1047 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn20k", ENOTSUP);
1048 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn20k", ENOTSUP);
1049 : :
1050 : 0 : *caps = RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD |
1051 : : RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA |
1052 : : RTE_EVENT_CRYPTO_ADAPTER_CAP_EVENT_VECTOR;
1053 : :
1054 : 0 : return 0;
1055 : : }
1056 : :
1057 : : static int
1058 : 0 : cn20k_crypto_adapter_qp_add(const struct rte_eventdev *event_dev, const struct rte_cryptodev *cdev,
1059 : : int32_t queue_pair_id,
1060 : : const struct rte_event_crypto_adapter_queue_conf *conf)
1061 : : {
1062 : : int ret;
1063 : :
1064 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn20k", EINVAL);
1065 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn20k", EINVAL);
1066 : :
1067 : : cn20k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
1068 : :
1069 : 0 : ret = cnxk_crypto_adapter_qp_add(event_dev, cdev, queue_pair_id, conf);
1070 : : cn20k_sso_set_priv_mem(event_dev, NULL);
1071 : :
1072 : : return ret;
1073 : : }
1074 : :
1075 : : static int
1076 : 0 : cn20k_crypto_adapter_qp_del(const struct rte_eventdev *event_dev, const struct rte_cryptodev *cdev,
1077 : : int32_t queue_pair_id)
1078 : : {
1079 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn20k", EINVAL);
1080 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn20k", EINVAL);
1081 : :
1082 : 0 : return cnxk_crypto_adapter_qp_del(cdev, queue_pair_id);
1083 : : }
1084 : :
1085 : : static int
1086 : 0 : cn20k_tim_caps_get(const struct rte_eventdev *evdev, uint64_t flags, uint32_t *caps,
1087 : : const struct event_timer_adapter_ops **ops)
1088 : : {
1089 : 0 : return cnxk_tim_caps_get(evdev, flags, caps, ops, cn20k_sso_set_priv_mem);
1090 : : }
1091 : :
1092 : : static int
1093 : 0 : cn20k_crypto_adapter_vec_limits(const struct rte_eventdev *event_dev,
1094 : : const struct rte_cryptodev *cdev,
1095 : : struct rte_event_crypto_adapter_vector_limits *limits)
1096 : : {
1097 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn20k", EINVAL);
1098 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn20k", EINVAL);
1099 : :
1100 : 0 : limits->log2_sz = false;
1101 : 0 : limits->min_sz = 0;
1102 : 0 : limits->max_sz = UINT16_MAX;
1103 : : /* Unused timeout, in software implementation we aggregate all crypto
1104 : : * operations passed to the enqueue function
1105 : : */
1106 : 0 : limits->min_timeout_ns = 0;
1107 : 0 : limits->max_timeout_ns = 0;
1108 : :
1109 : 0 : return 0;
1110 : : }
1111 : :
1112 : : static struct eventdev_ops cn20k_sso_dev_ops = {
1113 : : .dev_infos_get = cn20k_sso_info_get,
1114 : : .dev_configure = cn20k_sso_dev_configure,
1115 : :
1116 : : .queue_def_conf = cnxk_sso_queue_def_conf,
1117 : : .queue_setup = cnxk_sso_queue_setup,
1118 : : .queue_release = cnxk_sso_queue_release,
1119 : : .queue_attr_set = cnxk_sso_queue_attribute_set,
1120 : :
1121 : : .port_def_conf = cnxk_sso_port_def_conf,
1122 : : .port_setup = cn20k_sso_port_setup,
1123 : : .port_release = cn20k_sso_port_release,
1124 : : .port_quiesce = cn20k_sso_port_quiesce,
1125 : : .port_link = cn20k_sso_port_link,
1126 : : .port_unlink = cn20k_sso_port_unlink,
1127 : : .port_link_profile = cn20k_sso_port_link_profile,
1128 : : .port_unlink_profile = cn20k_sso_port_unlink_profile,
1129 : : .timeout_ticks = cnxk_sso_timeout_ticks,
1130 : :
1131 : : .eth_rx_adapter_caps_get = cn20k_sso_rx_adapter_caps_get,
1132 : : .eth_rx_adapter_queue_add = cn20k_sso_rx_adapter_queue_add,
1133 : : .eth_rx_adapter_queues_add = cn20k_sso_rx_adapter_queues_add,
1134 : : .eth_rx_adapter_queue_del = cn20k_sso_rx_adapter_queue_del,
1135 : : .eth_rx_adapter_start = cnxk_sso_rx_adapter_start,
1136 : : .eth_rx_adapter_stop = cnxk_sso_rx_adapter_stop,
1137 : :
1138 : : .eth_rx_adapter_vector_limits_get = cn20k_sso_rx_adapter_vector_limits,
1139 : :
1140 : : .eth_tx_adapter_caps_get = cn20k_sso_tx_adapter_caps_get,
1141 : : .eth_tx_adapter_queue_add = cn20k_sso_tx_adapter_queue_add,
1142 : : .eth_tx_adapter_queue_del = cn20k_sso_tx_adapter_queue_del,
1143 : : .eth_tx_adapter_start = cnxk_sso_tx_adapter_start,
1144 : : .eth_tx_adapter_stop = cnxk_sso_tx_adapter_stop,
1145 : : .eth_tx_adapter_free = cnxk_sso_tx_adapter_free,
1146 : :
1147 : : .timer_adapter_caps_get = cn20k_tim_caps_get,
1148 : :
1149 : : .crypto_adapter_caps_get = cn20k_crypto_adapter_caps_get,
1150 : : .crypto_adapter_queue_pair_add = cn20k_crypto_adapter_qp_add,
1151 : : .crypto_adapter_queue_pair_del = cn20k_crypto_adapter_qp_del,
1152 : : .crypto_adapter_vector_limits_get = cn20k_crypto_adapter_vec_limits,
1153 : :
1154 : : .vector_adapter_caps_get = cnxk_vector_caps_get,
1155 : : .vector_adapter_info_get = cnxk_vector_info_get,
1156 : :
1157 : : .xstats_get = cnxk_sso_xstats_get,
1158 : : .xstats_reset = cnxk_sso_xstats_reset,
1159 : : .xstats_get_names = cnxk_sso_xstats_get_names,
1160 : :
1161 : : .dump = cnxk_sso_dump,
1162 : : .dev_start = cn20k_sso_start,
1163 : : .dev_stop = cn20k_sso_stop,
1164 : : .dev_close = cn20k_sso_close,
1165 : : .dev_selftest = cn20k_sso_selftest,
1166 : : };
1167 : :
1168 : : static int
1169 : 0 : cn20k_sso_init(struct rte_eventdev *event_dev)
1170 : : {
1171 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
1172 : : int rc;
1173 : :
1174 : 0 : rc = roc_plt_init();
1175 [ # # ]: 0 : if (rc < 0) {
1176 : 0 : plt_err("Failed to initialize platform model");
1177 : 0 : return rc;
1178 : : }
1179 : :
1180 : 0 : event_dev->dev_ops = &cn20k_sso_dev_ops;
1181 : : /* For secondary processes, the primary has done all the work */
1182 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1183 : : cn20k_sso_fp_fns_set(event_dev);
1184 : : return 0;
1185 : : }
1186 : :
1187 : 0 : rc = cnxk_sso_init(event_dev);
1188 [ # # ]: 0 : if (rc < 0)
1189 : : return rc;
1190 : :
1191 : : cn20k_sso_set_rsrc(cnxk_sso_pmd_priv(event_dev));
1192 [ # # # # ]: 0 : if (!dev->max_event_ports || !dev->max_event_queues) {
1193 : 0 : plt_err("Not enough eventdev resource queues=%d ports=%d", dev->max_event_queues,
1194 : : dev->max_event_ports);
1195 : 0 : cnxk_sso_fini(event_dev);
1196 : 0 : return -ENODEV;
1197 : : }
1198 : :
1199 : 0 : plt_sso_dbg("Initializing %s max_queues=%d max_ports=%d", event_dev->data->name,
1200 : : dev->max_event_queues, dev->max_event_ports);
1201 : :
1202 : 0 : return 0;
1203 : : }
1204 : :
1205 : : static int
1206 : 0 : cn20k_sso_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
1207 : : {
1208 : 0 : return rte_event_pmd_pci_probe(pci_drv, pci_dev, sizeof(struct cnxk_sso_evdev),
1209 : : cn20k_sso_init);
1210 : : }
1211 : :
1212 : : static const struct rte_pci_id cn20k_pci_sso_map[] = {
1213 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN20KA, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1214 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN20KA, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1215 : : {
1216 : : .vendor_id = 0,
1217 : : },
1218 : : };
1219 : :
1220 : : static struct rte_pci_driver cn20k_pci_sso = {
1221 : : .id_table = cn20k_pci_sso_map,
1222 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
1223 : : .probe = cn20k_sso_probe,
1224 : : .remove = cnxk_sso_remove,
1225 : : };
1226 : :
1227 : 254 : RTE_PMD_REGISTER_PCI(event_cn20k, cn20k_pci_sso);
1228 : : RTE_PMD_REGISTER_PCI_TABLE(event_cn20k, cn20k_pci_sso_map);
1229 : : RTE_PMD_REGISTER_KMOD_DEP(event_cn20k, "vfio-pci");
1230 : : RTE_PMD_REGISTER_PARAM_STRING(event_cn20k,
1231 : : CNXK_SSO_XAE_CNT "=<int>"
1232 : : CNXK_SSO_GGRP_QOS "=<string>"
1233 : : CNXK_SSO_STASH "=<string>"
1234 : : CNXK_SSO_FORCE_BP "=1"
1235 : : CNXK_TIM_DISABLE_NPA "=1"
1236 : : CNXK_TIM_CHNK_SLOTS "=<int>"
1237 : : CNXK_TIM_RINGS_LMT "=<int>"
1238 : : CNXK_TIM_STATS_ENA "=1"
1239 : : CNXK_TIM_EXT_CLK "=<string>");
|