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