Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "cn9k_worker.h"
6 : : #include "cnxk_eventdev.h"
7 : : #include "cnxk_worker.h"
8 : :
9 : : #include <rte_dmadev_pmd.h>
10 : :
11 : : #define CN9K_DUAL_WS_PAIR_ID(x, id) (((x)*CN9K_DUAL_WS_NB_WS) + id)
12 : :
13 : : #define CN9K_SET_EVDEV_DEQ_OP(dev, deq_op, deq_ops) \
14 : : deq_op = deq_ops[dev->rx_offloads & (NIX_RX_OFFLOAD_MAX - 1)]
15 : :
16 : : #define CN9K_SET_EVDEV_ENQ_OP(dev, enq_op, enq_ops) \
17 : : enq_op = enq_ops[dev->tx_offloads & (NIX_TX_OFFLOAD_MAX - 1)]
18 : :
19 : : static int
20 : 0 : cn9k_sso_hws_link(void *arg, void *port, uint16_t *map, uint16_t nb_link, uint8_t profile)
21 : : {
22 : : struct cnxk_sso_evdev *dev = arg;
23 : : struct cn9k_sso_hws_dual *dws;
24 : : struct cn9k_sso_hws *ws;
25 : : int rc;
26 : :
27 [ # # ]: 0 : if (dev->dual_ws) {
28 : : dws = port;
29 : 0 : rc = roc_sso_hws_link(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 0), map, nb_link,
30 : : profile, 0);
31 : 0 : rc |= roc_sso_hws_link(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 1), map,
32 : : nb_link, profile, 0);
33 : : } else {
34 : : ws = port;
35 : 0 : rc = roc_sso_hws_link(&dev->sso, ws->hws_id, map, nb_link, profile, 0);
36 : : }
37 : :
38 : 0 : return rc;
39 : : }
40 : :
41 : : static int
42 : 0 : cn9k_sso_hws_unlink(void *arg, void *port, uint16_t *map, uint16_t nb_link, uint8_t profile)
43 : : {
44 : : struct cnxk_sso_evdev *dev = arg;
45 : : struct cn9k_sso_hws_dual *dws;
46 : : struct cn9k_sso_hws *ws;
47 : : int rc;
48 : :
49 [ # # ]: 0 : if (dev->dual_ws) {
50 : : dws = port;
51 : 0 : rc = roc_sso_hws_unlink(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 0), map,
52 : : nb_link, profile, 0);
53 : 0 : rc |= roc_sso_hws_unlink(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 1), map,
54 : : nb_link, profile, 0);
55 : : } else {
56 : : ws = port;
57 : 0 : rc = roc_sso_hws_unlink(&dev->sso, ws->hws_id, map, nb_link, profile, 0);
58 : : }
59 : :
60 : 0 : return rc;
61 : : }
62 : :
63 : : static void
64 : 0 : cn9k_sso_hws_setup(void *arg, void *hws, uintptr_t grp_base)
65 : : {
66 : : struct cnxk_sso_evdev *dev = arg;
67 : : struct cn9k_sso_hws_dual *dws;
68 : : struct cn9k_sso_hws *ws;
69 : : uint64_t val;
70 : :
71 : : /* Set get_work tmo for HWS */
72 : 0 : val = NSEC2USEC(dev->deq_tmo_ns);
73 [ # # ]: 0 : val = val ? val - 1 : 0;
74 [ # # ]: 0 : if (dev->dual_ws) {
75 : : dws = hws;
76 : 0 : dws->grp_base = grp_base;
77 : 0 : dws->fc_mem = (uint64_t __rte_atomic *)dev->fc_iova;
78 : 0 : dws->xaq_lmt = dev->xaq_lmt;
79 : :
80 : 0 : plt_write64(val, dws->base[0] + SSOW_LF_GWS_NW_TIM);
81 : 0 : plt_write64(val, dws->base[1] + SSOW_LF_GWS_NW_TIM);
82 : : } else {
83 : : ws = hws;
84 : 0 : ws->grp_base = grp_base;
85 : 0 : ws->fc_mem = (uint64_t __rte_atomic *)dev->fc_iova;
86 : 0 : ws->xaq_lmt = dev->xaq_lmt;
87 : :
88 : 0 : plt_write64(val, ws->base + SSOW_LF_GWS_NW_TIM);
89 : : }
90 : 0 : }
91 : :
92 : : static void
93 : 0 : cn9k_sso_hws_release(void *arg, void *hws)
94 : : {
95 : : struct cnxk_sso_evdev *dev = arg;
96 : : struct cn9k_sso_hws_dual *dws;
97 : : struct cn9k_sso_hws *ws;
98 : : uint16_t i, k;
99 : :
100 [ # # ]: 0 : if (dev->dual_ws) {
101 : : dws = hws;
102 [ # # ]: 0 : for (i = 0; i < dev->nb_event_queues; i++) {
103 [ # # ]: 0 : for (k = 0; k < CNXK_SSO_MAX_PROFILES; k++) {
104 : 0 : roc_sso_hws_unlink(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 0),
105 : : &i, 1, k, 0);
106 : 0 : roc_sso_hws_unlink(&dev->sso, CN9K_DUAL_WS_PAIR_ID(dws->hws_id, 1),
107 : : &i, 1, k, 0);
108 : : }
109 : : }
110 : : memset(dws, 0, sizeof(*dws));
111 : : } else {
112 : : ws = hws;
113 [ # # ]: 0 : for (i = 0; i < dev->nb_event_queues; i++)
114 [ # # ]: 0 : for (k = 0; k < CNXK_SSO_MAX_PROFILES; k++)
115 : 0 : roc_sso_hws_unlink(&dev->sso, ws->hws_id, &i, 1, k, 0);
116 : : memset(ws, 0, sizeof(*ws));
117 : : }
118 : 0 : }
119 : :
120 : : static int
121 [ # # ]: 0 : cn9k_sso_hws_flush_events(void *hws, uint8_t queue_id, uintptr_t base,
122 : : cnxk_handle_event_t fn, void *arg)
123 : : {
124 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(arg);
125 : : uint64_t retry = CNXK_SSO_FLUSH_RETRY_MAX;
126 : : struct cnxk_timesync_info **tstamp;
127 : : struct cn9k_sso_hws_dual *dws;
128 : : struct cn9k_sso_hws *ws;
129 : : uint64_t cq_ds_cnt = 1;
130 : : uint64_t aq_cnt = 1;
131 : : uint64_t ds_cnt = 1;
132 : : struct rte_event ev;
133 : : uintptr_t ws_base;
134 : : uint64_t val, req;
135 : : void *lookup_mem;
136 : :
137 [ # # ]: 0 : plt_write64(0, base + SSO_LF_GGRP_QCTL);
138 : :
139 : 0 : req = queue_id; /* GGRP ID */
140 : : req |= BIT_ULL(18); /* Grouped */
141 : 0 : req |= BIT_ULL(16); /* WAIT */
142 : :
143 [ # # ]: 0 : aq_cnt = plt_read64(base + SSO_LF_GGRP_AQ_CNT);
144 : 0 : ds_cnt = plt_read64(base + SSO_LF_GGRP_MISC_CNT);
145 : 0 : cq_ds_cnt = plt_read64(base + SSO_LF_GGRP_INT_CNT);
146 : 0 : cq_ds_cnt &= 0x3FFF3FFF0000;
147 : :
148 [ # # ]: 0 : if (dev->dual_ws) {
149 : : dws = hws;
150 : 0 : ws_base = dws->base[0];
151 : 0 : lookup_mem = dws->lookup_mem;
152 : 0 : tstamp = dws->tstamp;
153 : : } else {
154 : : ws = hws;
155 : 0 : ws_base = ws->base;
156 : 0 : lookup_mem = ws->lookup_mem;
157 : 0 : tstamp = ws->tstamp;
158 : : }
159 : :
160 [ # # ]: 0 : while (aq_cnt || cq_ds_cnt || ds_cnt) {
161 : 0 : plt_write64(req, ws_base + SSOW_LF_GWS_OP_GET_WORK0);
162 : 0 : cn9k_sso_hws_get_work_empty(ws_base, &ev, dev->rx_offloads,
163 : : lookup_mem, tstamp);
164 [ # # # # ]: 0 : if (fn != NULL && ev.u64 != 0)
165 : 0 : fn(arg, ev);
166 [ # # ]: 0 : if (ev.sched_type != SSO_TT_EMPTY)
167 : : cnxk_sso_hws_swtag_flush(ws_base);
168 [ # # ]: 0 : else if (retry-- == 0)
169 : : break;
170 : : do {
171 [ # # ]: 0 : val = plt_read64(ws_base + SSOW_LF_GWS_PENDSTATE);
172 [ # # ]: 0 : } while (val & BIT_ULL(56));
173 : : aq_cnt = plt_read64(base + SSO_LF_GGRP_AQ_CNT);
174 : : ds_cnt = plt_read64(base + SSO_LF_GGRP_MISC_CNT);
175 : : cq_ds_cnt = plt_read64(base + SSO_LF_GGRP_INT_CNT);
176 : : /* Extract cq and ds count */
177 : 0 : cq_ds_cnt &= 0x3FFF3FFF0000;
178 : : }
179 : :
180 [ # # ]: 0 : if (aq_cnt || cq_ds_cnt || ds_cnt)
181 : : return -EAGAIN;
182 : :
183 : 0 : plt_write64(0, ws_base + SSOW_LF_GWS_OP_GWC_INVAL);
184 : :
185 : 0 : return 0;
186 : : }
187 : :
188 : : static void
189 : 0 : cn9k_sso_hws_reset(void *arg, void *hws)
190 : : {
191 : : struct cnxk_sso_evdev *dev = arg;
192 : : struct cn9k_sso_hws_dual *dws;
193 : : struct cn9k_sso_hws *ws;
194 : : uint64_t pend_state;
195 : : uint8_t pend_tt;
196 : : uintptr_t base;
197 : : bool is_pend;
198 : : uint64_t tag;
199 : : uint8_t i;
200 : :
201 : : dws = hws;
202 : : ws = hws;
203 [ # # # # ]: 0 : for (i = 0; i < (dev->dual_ws ? CN9K_DUAL_WS_NB_WS : 1); i++) {
204 [ # # ]: 0 : base = dev->dual_ws ? dws->base[i] : ws->base;
205 : : is_pend = false;
206 : : /* Work in WQE0 is always consumed, unless its a SWTAG. */
207 [ # # ]: 0 : pend_state = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
208 [ # # # # : 0 : if (pend_state & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(54)) ||
# # ]
209 [ # # # # ]: 0 : (dev->dual_ws ? (dws->swtag_req && i == !dws->vws) :
210 [ # # ]: 0 : ws->swtag_req))
211 : : is_pend = true;
212 : : /* Wait till getwork/swtp/waitw/desched completes. */
213 : : do {
214 : : pend_state = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
215 [ # # ]: 0 : } while (pend_state & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(58) |
216 : : BIT_ULL(56)));
217 : :
218 [ # # ]: 0 : tag = plt_read64(base + SSOW_LF_GWS_TAG);
219 : 0 : pend_tt = (tag >> 32) & 0x3;
220 [ # # ]: 0 : if (is_pend && pend_tt != SSO_TT_EMPTY) { /* Work was pending */
221 [ # # ]: 0 : if (pend_tt == SSO_TT_ATOMIC ||
222 : : pend_tt == SSO_TT_ORDERED)
223 : : cnxk_sso_hws_swtag_untag(
224 : 0 : base + SSOW_LF_GWS_OP_SWTAG_UNTAG);
225 : 0 : plt_write64(0, base + SSOW_LF_GWS_OP_DESCHED);
226 [ # # ]: 0 : } else if (pend_tt != SSO_TT_EMPTY) {
227 : 0 : plt_write64(0, base + SSOW_LF_GWS_OP_SWTAG_FLUSH);
228 : : }
229 : :
230 : : /* Wait for desched to complete. */
231 : : do {
232 : : pend_state = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
233 [ # # ]: 0 : } while (pend_state & (BIT_ULL(58) | BIT_ULL(56)));
234 : 0 : plt_write64(0, base + SSOW_LF_GWS_OP_GWC_INVAL);
235 : : }
236 [ # # ]: 0 : if (dev->dual_ws)
237 : 0 : dws->swtag_req = 0;
238 : : else
239 : 0 : ws->swtag_req = 0;
240 : 0 : }
241 : :
242 : : static int
243 : 0 : cn9k_sso_rsrc_init(void *arg, uint8_t hws, uint8_t hwgrp)
244 : : {
245 : : struct cnxk_tim_evdev *tim_dev = cnxk_tim_priv_get();
246 : : struct cnxk_sso_evdev *dev = arg;
247 : : uint16_t nb_tim_lfs;
248 : :
249 [ # # ]: 0 : if (dev->dual_ws)
250 : 0 : hws = hws * CN9K_DUAL_WS_NB_WS;
251 : :
252 [ # # ]: 0 : nb_tim_lfs = tim_dev ? tim_dev->nb_rings : 0;
253 : 0 : return roc_sso_rsrc_init(&dev->sso, hws, hwgrp, nb_tim_lfs);
254 : : }
255 : :
256 : : static int
257 [ # # ]: 0 : cn9k_sso_updt_tx_adptr_data(const struct rte_eventdev *event_dev)
258 : : {
259 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
260 : : int i;
261 : :
262 [ # # ]: 0 : if (dev->tx_adptr_data == NULL)
263 : : return 0;
264 : :
265 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
266 [ # # ]: 0 : if (dev->dual_ws) {
267 : 0 : struct cn9k_sso_hws_dual *dws =
268 : 0 : event_dev->data->ports[i];
269 : : void *ws_cookie;
270 : :
271 : : ws_cookie = cnxk_sso_hws_get_cookie(dws);
272 : 0 : ws_cookie = rte_realloc_socket(
273 : : ws_cookie,
274 : : sizeof(struct cnxk_sso_hws_cookie) +
275 : : sizeof(struct cn9k_sso_hws_dual) +
276 : 0 : dev->tx_adptr_data_sz,
277 : : RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
278 [ # # ]: 0 : if (ws_cookie == NULL)
279 : : return -ENOMEM;
280 : 0 : dws = RTE_PTR_ADD(ws_cookie,
281 : : sizeof(struct cnxk_sso_hws_cookie));
282 : 0 : memcpy(&dws->tx_adptr_data, dev->tx_adptr_data,
283 : : dev->tx_adptr_data_sz);
284 : 0 : event_dev->data->ports[i] = dws;
285 : : } else {
286 : 0 : struct cn9k_sso_hws *ws = event_dev->data->ports[i];
287 : : void *ws_cookie;
288 : :
289 : : ws_cookie = cnxk_sso_hws_get_cookie(ws);
290 : 0 : ws_cookie = rte_realloc_socket(
291 : : ws_cookie,
292 : : sizeof(struct cnxk_sso_hws_cookie) +
293 : : sizeof(struct cn9k_sso_hws_dual) +
294 : 0 : dev->tx_adptr_data_sz,
295 : : RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
296 [ # # ]: 0 : if (ws_cookie == NULL)
297 : : return -ENOMEM;
298 : 0 : ws = RTE_PTR_ADD(ws_cookie,
299 : : sizeof(struct cnxk_sso_hws_cookie));
300 : 0 : memcpy(&ws->tx_adptr_data, dev->tx_adptr_data,
301 : : dev->tx_adptr_data_sz);
302 : 0 : event_dev->data->ports[i] = ws;
303 : : }
304 : : }
305 : : rte_mb();
306 : :
307 : 0 : return 0;
308 : : }
309 : :
310 : : #if defined(RTE_ARCH_ARM64)
311 : : static inline void
312 : : cn9k_sso_fp_tmplt_fns_set(struct rte_eventdev *event_dev)
313 : : {
314 : : #if !defined(CNXK_DIS_TMPLT_FUNC)
315 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
316 : : /* Single WS modes */
317 : : const event_dequeue_burst_t sso_hws_deq_burst[NIX_RX_OFFLOAD_MAX] = {
318 : : #define R(name, flags)[flags] = cn9k_sso_hws_deq_burst_##name,
319 : : NIX_RX_FASTPATH_MODES
320 : : #undef R
321 : : };
322 : :
323 : : const event_dequeue_burst_t sso_hws_deq_tmo_burst[NIX_RX_OFFLOAD_MAX] = {
324 : : #define R(name, flags)[flags] = cn9k_sso_hws_deq_tmo_burst_##name,
325 : : NIX_RX_FASTPATH_MODES
326 : : #undef R
327 : : };
328 : :
329 : : const event_dequeue_burst_t sso_hws_deq_seg_burst[NIX_RX_OFFLOAD_MAX] = {
330 : : #define R(name, flags)[flags] = cn9k_sso_hws_deq_seg_burst_##name,
331 : : NIX_RX_FASTPATH_MODES
332 : : #undef R
333 : : };
334 : :
335 : : const event_dequeue_burst_t sso_hws_deq_tmo_seg_burst[NIX_RX_OFFLOAD_MAX] = {
336 : : #define R(name, flags)[flags] = cn9k_sso_hws_deq_tmo_seg_burst_##name,
337 : : NIX_RX_FASTPATH_MODES
338 : : #undef R
339 : : };
340 : :
341 : : /* Dual WS modes */
342 : : const event_dequeue_burst_t sso_hws_dual_deq_burst[NIX_RX_OFFLOAD_MAX] = {
343 : : #define R(name, flags)[flags] = cn9k_sso_hws_dual_deq_burst_##name,
344 : : NIX_RX_FASTPATH_MODES
345 : : #undef R
346 : : };
347 : :
348 : : const event_dequeue_burst_t sso_hws_dual_deq_tmo_burst[NIX_RX_OFFLOAD_MAX] = {
349 : : #define R(name, flags)[flags] = cn9k_sso_hws_dual_deq_tmo_burst_##name,
350 : : NIX_RX_FASTPATH_MODES
351 : : #undef R
352 : : };
353 : :
354 : : const event_dequeue_burst_t sso_hws_dual_deq_seg_burst[NIX_RX_OFFLOAD_MAX] = {
355 : : #define R(name, flags)[flags] = cn9k_sso_hws_dual_deq_seg_burst_##name,
356 : : NIX_RX_FASTPATH_MODES
357 : : #undef R
358 : : };
359 : :
360 : : const event_dequeue_burst_t sso_hws_dual_deq_tmo_seg_burst[NIX_RX_OFFLOAD_MAX] = {
361 : : #define R(name, flags)[flags] = cn9k_sso_hws_dual_deq_tmo_seg_burst_##name,
362 : : NIX_RX_FASTPATH_MODES
363 : : #undef R
364 : : };
365 : :
366 : : /* Tx modes */
367 : : const event_tx_adapter_enqueue_t sso_hws_tx_adptr_enq[NIX_TX_OFFLOAD_MAX] = {
368 : : #define T(name, sz, flags)[flags] = cn9k_sso_hws_tx_adptr_enq_##name,
369 : : NIX_TX_FASTPATH_MODES
370 : : #undef T
371 : : };
372 : :
373 : : const event_tx_adapter_enqueue_t sso_hws_tx_adptr_enq_seg[NIX_TX_OFFLOAD_MAX] = {
374 : : #define T(name, sz, flags)[flags] = cn9k_sso_hws_tx_adptr_enq_seg_##name,
375 : : NIX_TX_FASTPATH_MODES
376 : : #undef T
377 : : };
378 : :
379 : : const event_tx_adapter_enqueue_t sso_hws_dual_tx_adptr_enq[NIX_TX_OFFLOAD_MAX] = {
380 : : #define T(name, sz, flags)[flags] = cn9k_sso_hws_dual_tx_adptr_enq_##name,
381 : : NIX_TX_FASTPATH_MODES
382 : : #undef T
383 : : };
384 : :
385 : : const event_tx_adapter_enqueue_t sso_hws_dual_tx_adptr_enq_seg[NIX_TX_OFFLOAD_MAX] = {
386 : : #define T(name, sz, flags)[flags] = cn9k_sso_hws_dual_tx_adptr_enq_seg_##name,
387 : : NIX_TX_FASTPATH_MODES
388 : : #undef T
389 : : };
390 : :
391 : : event_dev->enqueue_burst = cn9k_sso_hws_enq_burst;
392 : : event_dev->enqueue_new_burst = cn9k_sso_hws_enq_new_burst;
393 : : event_dev->enqueue_forward_burst = cn9k_sso_hws_enq_fwd_burst;
394 : : event_dev->profile_switch = cn9k_sso_hws_profile_switch;
395 : : if (dev->rx_offloads & NIX_RX_MULTI_SEG_F) {
396 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
397 : : sso_hws_deq_seg_burst);
398 : : if (dev->is_timeout_deq)
399 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
400 : : sso_hws_deq_tmo_seg_burst);
401 : : } else {
402 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
403 : : sso_hws_deq_burst);
404 : : if (dev->is_timeout_deq)
405 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
406 : : sso_hws_deq_tmo_burst);
407 : : }
408 : : event_dev->ca_enqueue = cn9k_sso_hws_ca_enq;
409 : : event_dev->dma_enqueue = cn9k_dma_adapter_enqueue;
410 : :
411 : : if (dev->tx_offloads & NIX_TX_MULTI_SEG_F)
412 : : CN9K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue,
413 : : sso_hws_tx_adptr_enq_seg);
414 : : else
415 : : CN9K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue,
416 : : sso_hws_tx_adptr_enq);
417 : :
418 : : if (dev->dual_ws) {
419 : : event_dev->enqueue_burst = cn9k_sso_hws_dual_enq_burst;
420 : : event_dev->enqueue_new_burst = cn9k_sso_hws_dual_enq_new_burst;
421 : : event_dev->enqueue_forward_burst =
422 : : cn9k_sso_hws_dual_enq_fwd_burst;
423 : : event_dev->ca_enqueue = cn9k_sso_hws_dual_ca_enq;
424 : : event_dev->dma_enqueue = cn9k_dma_adapter_dual_enqueue;
425 : : event_dev->profile_switch = cn9k_sso_hws_dual_profile_switch;
426 : :
427 : : if (dev->rx_offloads & NIX_RX_MULTI_SEG_F) {
428 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
429 : : sso_hws_dual_deq_seg_burst);
430 : : if (dev->is_timeout_deq) {
431 : : CN9K_SET_EVDEV_DEQ_OP(
432 : : dev, event_dev->dequeue_burst,
433 : : sso_hws_dual_deq_tmo_seg_burst);
434 : : }
435 : : } else {
436 : : CN9K_SET_EVDEV_DEQ_OP(dev, event_dev->dequeue_burst,
437 : : sso_hws_dual_deq_burst);
438 : : if (dev->is_timeout_deq) {
439 : : CN9K_SET_EVDEV_DEQ_OP(
440 : : dev, event_dev->dequeue_burst,
441 : : sso_hws_dual_deq_tmo_burst);
442 : : }
443 : : }
444 : :
445 : : if (dev->tx_offloads & NIX_TX_MULTI_SEG_F)
446 : : CN9K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue,
447 : : sso_hws_dual_tx_adptr_enq_seg);
448 : : else
449 : : CN9K_SET_EVDEV_ENQ_OP(dev, event_dev->txa_enqueue,
450 : : sso_hws_dual_tx_adptr_enq);
451 : : }
452 : :
453 : : event_dev->dma_enqueue = cn9k_dma_adapter_enqueue;
454 : :
455 : : event_dev->txa_enqueue_same_dest = event_dev->txa_enqueue;
456 : : rte_mb();
457 : : #else
458 : : RTE_SET_USED(event_dev);
459 : : #endif
460 : : }
461 : :
462 : : static inline void
463 : : cn9k_sso_fp_blk_fns_set(struct rte_eventdev *event_dev)
464 : : {
465 : : #if defined(CNXK_DIS_TMPLT_FUNC)
466 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
467 : :
468 : : event_dev->dequeue_burst = cn9k_sso_hws_deq_burst_all_offload;
469 : : if (dev->rx_offloads & NIX_RX_OFFLOAD_TSTAMP_F)
470 : : event_dev->dequeue_burst = cn9k_sso_hws_deq_burst_all_offload_tst;
471 : : event_dev->txa_enqueue = cn9k_sso_hws_tx_adptr_enq_seg_all_offload;
472 : : event_dev->txa_enqueue_same_dest = cn9k_sso_hws_tx_adptr_enq_seg_all_offload;
473 : : if (dev->tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F) {
474 : : event_dev->txa_enqueue = cn9k_sso_hws_tx_adptr_enq_seg_all_offload_tst;
475 : : event_dev->txa_enqueue_same_dest = cn9k_sso_hws_tx_adptr_enq_seg_all_offload_tst;
476 : : }
477 : : if (dev->dual_ws) {
478 : : event_dev->dequeue_burst = cn9k_sso_hws_deq_dual_burst_all_offload;
479 : : if (dev->rx_offloads & NIX_RX_OFFLOAD_TSTAMP_F)
480 : : event_dev->dequeue_burst = cn9k_sso_hws_deq_dual_burst_all_offload_tst;
481 : : event_dev->txa_enqueue = cn9k_sso_hws_tx_adptr_enq_dual_seg_all_offload;
482 : : event_dev->txa_enqueue_same_dest = cn9k_sso_hws_tx_adptr_enq_dual_seg_all_offload;
483 : : if (dev->tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F) {
484 : : event_dev->txa_enqueue = cn9k_sso_hws_tx_adptr_enq_dual_seg_all_offload_tst;
485 : : event_dev->txa_enqueue_same_dest =
486 : : cn9k_sso_hws_tx_adptr_enq_dual_seg_all_offload_tst;
487 : : }
488 : : }
489 : : #else
490 : : RTE_SET_USED(event_dev);
491 : : #endif
492 : : }
493 : : #endif
494 : :
495 : : static void
496 : : cn9k_sso_fp_fns_set(struct rte_eventdev *event_dev)
497 : : {
498 : : #if defined(RTE_ARCH_ARM64)
499 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
500 : :
501 : : cn9k_sso_fp_blk_fns_set(event_dev);
502 : : cn9k_sso_fp_tmplt_fns_set(event_dev);
503 : :
504 : : event_dev->enqueue_burst = cn9k_sso_hws_enq_burst;
505 : : event_dev->enqueue_new_burst = cn9k_sso_hws_enq_new_burst;
506 : : event_dev->enqueue_forward_burst = cn9k_sso_hws_enq_fwd_burst;
507 : : event_dev->ca_enqueue = cn9k_sso_hws_ca_enq;
508 : : event_dev->profile_switch = cn9k_sso_hws_profile_switch;
509 : :
510 : : if (dev->dual_ws) {
511 : : event_dev->enqueue_burst = cn9k_sso_hws_dual_enq_burst;
512 : : event_dev->enqueue_new_burst = cn9k_sso_hws_dual_enq_new_burst;
513 : : event_dev->enqueue_forward_burst = cn9k_sso_hws_dual_enq_fwd_burst;
514 : : event_dev->ca_enqueue = cn9k_sso_hws_dual_ca_enq;
515 : : event_dev->profile_switch = cn9k_sso_hws_dual_profile_switch;
516 : : }
517 : :
518 : : event_dev->dma_enqueue = cn9k_dma_adapter_enqueue;
519 : : #else
520 : : RTE_SET_USED(event_dev);
521 : : #endif
522 : : }
523 : :
524 : : static void *
525 : 0 : cn9k_sso_init_hws_mem(void *arg, uint8_t port_id)
526 : : {
527 : : struct cnxk_sso_evdev *dev = arg;
528 : : struct cn9k_sso_hws_dual *dws;
529 : : struct cn9k_sso_hws *ws;
530 : : void *data;
531 : :
532 [ # # ]: 0 : if (dev->dual_ws) {
533 : 0 : dws = rte_zmalloc("cn9k_dual_ws",
534 : : sizeof(struct cn9k_sso_hws_dual) +
535 : : RTE_CACHE_LINE_SIZE,
536 : : RTE_CACHE_LINE_SIZE);
537 [ # # ]: 0 : if (dws == NULL) {
538 : 0 : plt_err("Failed to alloc memory for port=%d", port_id);
539 : 0 : return NULL;
540 : : }
541 : :
542 : 0 : dws = RTE_PTR_ADD(dws, sizeof(struct cnxk_sso_hws_cookie));
543 : 0 : dws->base[0] = roc_sso_hws_base_get(
544 : : &dev->sso, CN9K_DUAL_WS_PAIR_ID(port_id, 0));
545 : 0 : dws->base[1] = roc_sso_hws_base_get(
546 : 0 : &dev->sso, CN9K_DUAL_WS_PAIR_ID(port_id, 1));
547 : 0 : dws->hws_id = port_id;
548 : 0 : dws->swtag_req = 0;
549 : 0 : dws->vws = 0;
550 [ # # ]: 0 : if (dev->deq_tmo_ns)
551 : 0 : dws->gw_wdata = BIT_ULL(16);
552 : 0 : dws->gw_wdata |= 1;
553 : :
554 : : data = dws;
555 : : } else {
556 : : /* Allocate event port memory */
557 : 0 : ws = rte_zmalloc("cn9k_ws",
558 : : sizeof(struct cn9k_sso_hws) +
559 : : RTE_CACHE_LINE_SIZE,
560 : : RTE_CACHE_LINE_SIZE);
561 [ # # ]: 0 : if (ws == NULL) {
562 : 0 : plt_err("Failed to alloc memory for port=%d", port_id);
563 : 0 : return NULL;
564 : : }
565 : :
566 : : /* First cache line is reserved for cookie */
567 : 0 : ws = RTE_PTR_ADD(ws, sizeof(struct cnxk_sso_hws_cookie));
568 : 0 : ws->base = roc_sso_hws_base_get(&dev->sso, port_id);
569 : 0 : ws->hws_id = port_id;
570 : 0 : ws->swtag_req = 0;
571 [ # # ]: 0 : if (dev->deq_tmo_ns)
572 : 0 : ws->gw_wdata = BIT_ULL(16);
573 : 0 : ws->gw_wdata |= 1;
574 : :
575 : : data = ws;
576 : : }
577 : :
578 : : return data;
579 : : }
580 : :
581 : : static void
582 : 0 : cn9k_sso_info_get(struct rte_eventdev *event_dev,
583 : : struct rte_event_dev_info *dev_info)
584 : : {
585 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
586 : :
587 : 0 : dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN9K_PMD);
588 : 0 : cnxk_sso_info_get(dev, dev_info);
589 : 0 : }
590 : :
591 : : static int
592 : 0 : cn9k_sso_dev_configure(const struct rte_eventdev *event_dev)
593 : : {
594 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
595 : : int rc;
596 : :
597 : 0 : rc = cnxk_sso_dev_validate(event_dev, 1, 1);
598 [ # # ]: 0 : if (rc < 0) {
599 : 0 : plt_err("Invalid event device configuration");
600 : 0 : return -EINVAL;
601 : : }
602 : :
603 : 0 : rc = cn9k_sso_rsrc_init(dev, dev->nb_event_ports, dev->nb_event_queues);
604 [ # # ]: 0 : if (rc < 0) {
605 : 0 : plt_err("Failed to initialize SSO resources");
606 : 0 : return -ENODEV;
607 : : }
608 : :
609 : 0 : rc = cnxk_sso_xaq_allocate(dev);
610 [ # # ]: 0 : if (rc < 0)
611 : 0 : goto cnxk_rsrc_fini;
612 : :
613 : 0 : rc = cnxk_setup_event_ports(event_dev, cn9k_sso_init_hws_mem,
614 : : cn9k_sso_hws_setup);
615 [ # # ]: 0 : if (rc < 0)
616 : 0 : goto cnxk_rsrc_fini;
617 : :
618 : : /* Restore any prior port-queue mapping. */
619 : 0 : cnxk_sso_restore_links(event_dev, cn9k_sso_hws_link);
620 : :
621 : 0 : dev->configured = 1;
622 : : rte_mb();
623 : :
624 : 0 : return 0;
625 : 0 : cnxk_rsrc_fini:
626 : 0 : roc_sso_rsrc_fini(&dev->sso);
627 : 0 : dev->nb_event_ports = 0;
628 : 0 : return rc;
629 : : }
630 : :
631 : : static int
632 : 0 : cn9k_sso_port_setup(struct rte_eventdev *event_dev, uint8_t port_id,
633 : : const struct rte_event_port_conf *port_conf)
634 : : {
635 : :
636 : : RTE_SET_USED(port_conf);
637 : 0 : return cnxk_sso_port_setup(event_dev, port_id, cn9k_sso_hws_setup);
638 : : }
639 : :
640 : : static void
641 [ # # ]: 0 : cn9k_sso_port_release(void *port)
642 : : {
643 : : struct cnxk_sso_hws_cookie *gws_cookie = cnxk_sso_hws_get_cookie(port);
644 : : struct cnxk_sso_evdev *dev;
645 : :
646 [ # # ]: 0 : if (port == NULL)
647 : : return;
648 : :
649 [ # # ]: 0 : dev = cnxk_sso_pmd_priv(gws_cookie->event_dev);
650 [ # # ]: 0 : if (!gws_cookie->configured)
651 : 0 : goto free;
652 : :
653 : 0 : cn9k_sso_hws_release(dev, port);
654 : : memset(gws_cookie, 0, sizeof(*gws_cookie));
655 : 0 : free:
656 : 0 : rte_free(gws_cookie);
657 : : }
658 : :
659 : : static void
660 : 0 : cn9k_sso_port_quiesce(struct rte_eventdev *event_dev, void *port,
661 : : rte_eventdev_port_flush_t flush_cb, void *args)
662 : : {
663 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
664 : : struct cn9k_sso_hws_dual *dws;
665 : : struct cn9k_sso_hws *ws;
666 : : struct rte_event ev;
667 : : uintptr_t base;
668 : : uint64_t ptag;
669 : : bool is_pend;
670 : : uint8_t i;
671 : :
672 : : dws = port;
673 : : ws = port;
674 [ # # # # ]: 0 : for (i = 0; i < (dev->dual_ws ? CN9K_DUAL_WS_NB_WS : 1); i++) {
675 [ # # ]: 0 : base = dev->dual_ws ? dws->base[i] : ws->base;
676 : : is_pend = false;
677 : : /* Work in WQE0 is always consumed, unless its a SWTAG. */
678 [ # # ]: 0 : ptag = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
679 [ # # # # : 0 : if (ptag & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(54)) ||
# # ]
680 [ # # # # ]: 0 : (dev->dual_ws ? (dws->swtag_req && i == !dws->vws) :
681 [ # # ]: 0 : ws->swtag_req))
682 : : is_pend = true;
683 : : /* Wait till getwork/swtp/waitw/desched completes. */
684 : : do {
685 : : ptag = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
686 [ # # ]: 0 : } while (ptag & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(58) |
687 : : BIT_ULL(56)));
688 : :
689 [ # # # # ]: 0 : cn9k_sso_hws_get_work_empty(
690 : 0 : base, &ev, dev->rx_offloads,
691 : : dev->dual_ws ? dws->lookup_mem : ws->lookup_mem,
692 : : dev->dual_ws ? dws->tstamp : ws->tstamp);
693 [ # # # # ]: 0 : if (is_pend && ev.u64)
694 [ # # ]: 0 : if (flush_cb)
695 : 0 : flush_cb(event_dev->data->dev_id, ev, args);
696 : :
697 : 0 : ptag = (plt_read64(base + SSOW_LF_GWS_TAG) >> 32) & SSO_TT_EMPTY;
698 [ # # ]: 0 : if (ptag != SSO_TT_EMPTY)
699 : : cnxk_sso_hws_swtag_flush(base);
700 : :
701 : : do {
702 : : ptag = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
703 [ # # ]: 0 : } while (ptag & BIT_ULL(56));
704 : :
705 : 0 : plt_write64(0, base + SSOW_LF_GWS_OP_GWC_INVAL);
706 : : }
707 : :
708 [ # # ]: 0 : if (dev->dual_ws)
709 : 0 : dws->swtag_req = 0;
710 : : else
711 : 0 : ws->swtag_req = 0;
712 : 0 : }
713 : :
714 : : static int
715 : 0 : cn9k_sso_port_link_profile(struct rte_eventdev *event_dev, void *port, const uint8_t queues[],
716 : : const uint8_t priorities[], uint16_t nb_links, uint8_t profile)
717 : 0 : {
718 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
719 : 0 : uint16_t hwgrp_ids[nb_links];
720 : : uint16_t link;
721 : :
722 : : RTE_SET_USED(priorities);
723 [ # # ]: 0 : for (link = 0; link < nb_links; link++)
724 : 0 : hwgrp_ids[link] = queues[link];
725 : 0 : nb_links = cn9k_sso_hws_link(dev, port, hwgrp_ids, nb_links, profile);
726 : :
727 : 0 : return (int)nb_links;
728 : : }
729 : :
730 : : static int
731 : 0 : cn9k_sso_port_unlink_profile(struct rte_eventdev *event_dev, void *port, uint8_t queues[],
732 : : uint16_t nb_unlinks, uint8_t profile)
733 : 0 : {
734 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
735 : 0 : uint16_t hwgrp_ids[nb_unlinks];
736 : : uint16_t unlink;
737 : :
738 [ # # ]: 0 : for (unlink = 0; unlink < nb_unlinks; unlink++)
739 : 0 : hwgrp_ids[unlink] = queues[unlink];
740 : 0 : nb_unlinks = cn9k_sso_hws_unlink(dev, port, hwgrp_ids, nb_unlinks, profile);
741 : :
742 : 0 : return (int)nb_unlinks;
743 : : }
744 : :
745 : : static int
746 : 0 : cn9k_sso_port_link(struct rte_eventdev *event_dev, void *port, const uint8_t queues[],
747 : : const uint8_t priorities[], uint16_t nb_links)
748 : : {
749 : 0 : return cn9k_sso_port_link_profile(event_dev, port, queues, priorities, nb_links, 0);
750 : : }
751 : :
752 : : static int
753 : 0 : cn9k_sso_port_unlink(struct rte_eventdev *event_dev, void *port, uint8_t queues[],
754 : : uint16_t nb_unlinks)
755 : : {
756 : 0 : return cn9k_sso_port_unlink_profile(event_dev, port, queues, nb_unlinks, 0);
757 : : }
758 : :
759 : : static int
760 : 0 : cn9k_sso_start(struct rte_eventdev *event_dev)
761 : : {
762 : : int rc;
763 : :
764 : 0 : rc = cn9k_sso_updt_tx_adptr_data(event_dev);
765 [ # # ]: 0 : if (rc < 0)
766 : : return rc;
767 : :
768 : 0 : rc = cnxk_sso_start(event_dev, cn9k_sso_hws_reset,
769 : : cn9k_sso_hws_flush_events);
770 : : if (rc < 0)
771 : : return rc;
772 : :
773 : : cn9k_sso_fp_fns_set(event_dev);
774 : :
775 : : return rc;
776 : : }
777 : :
778 : : static void
779 : 0 : cn9k_sso_stop(struct rte_eventdev *event_dev)
780 : : {
781 : 0 : cnxk_sso_stop(event_dev, cn9k_sso_hws_reset, cn9k_sso_hws_flush_events);
782 : 0 : }
783 : :
784 : : static int
785 : 0 : cn9k_sso_close(struct rte_eventdev *event_dev)
786 : : {
787 : 0 : return cnxk_sso_close(event_dev, cn9k_sso_hws_unlink);
788 : : }
789 : :
790 : : static int
791 : 0 : cn9k_sso_selftest(void)
792 : : {
793 : 0 : return cnxk_sso_selftest(RTE_STR(event_cn9k));
794 : : }
795 : :
796 : : static int
797 : 0 : cn9k_sso_rx_adapter_caps_get(const struct rte_eventdev *event_dev,
798 : : const struct rte_eth_dev *eth_dev, uint32_t *caps)
799 : : {
800 : : int rc;
801 : :
802 : : RTE_SET_USED(event_dev);
803 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn9k", 9);
804 [ # # ]: 0 : if (rc)
805 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP;
806 : : else
807 : 0 : *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT |
808 : : RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ |
809 : : RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID;
810 : :
811 : 0 : return 0;
812 : : }
813 : :
814 : : static void
815 : 0 : cn9k_sso_set_priv_mem(const struct rte_eventdev *event_dev, void *lookup_mem)
816 : : {
817 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
818 : : int i;
819 : :
820 [ # # ]: 0 : for (i = 0; i < dev->nb_event_ports; i++) {
821 [ # # ]: 0 : if (dev->dual_ws) {
822 : 0 : struct cn9k_sso_hws_dual *dws =
823 : : event_dev->data->ports[i];
824 : 0 : dws->xaq_lmt = dev->xaq_lmt;
825 : 0 : dws->fc_mem = (uint64_t __rte_atomic *)dev->fc_iova;
826 : 0 : dws->tstamp = dev->tstamp;
827 [ # # ]: 0 : if (lookup_mem)
828 : 0 : dws->lookup_mem = lookup_mem;
829 : : } else {
830 : 0 : struct cn9k_sso_hws *ws = event_dev->data->ports[i];
831 : 0 : ws->xaq_lmt = dev->xaq_lmt;
832 : 0 : ws->fc_mem = (uint64_t __rte_atomic *)dev->fc_iova;
833 : 0 : ws->tstamp = dev->tstamp;
834 [ # # ]: 0 : if (lookup_mem)
835 : 0 : ws->lookup_mem = lookup_mem;
836 : : }
837 : : }
838 : 0 : }
839 : :
840 : : static void
841 : : eventdev_fops_tstamp_update(struct rte_eventdev *event_dev)
842 : : {
843 : 0 : struct rte_event_fp_ops *fp_op =
844 : 0 : rte_event_fp_ops + event_dev->data->dev_id;
845 : :
846 : 0 : fp_op->dequeue_burst = event_dev->dequeue_burst;
847 : : }
848 : :
849 : : static void
850 : 0 : cn9k_sso_tstamp_hdl_update(uint16_t port_id, uint16_t flags, bool ptp_en)
851 : : {
852 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
853 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = dev->data->dev_private;
854 [ # # ]: 0 : struct rte_eventdev *event_dev = cnxk_eth_dev->evdev_priv;
855 : : struct cnxk_sso_evdev *evdev = cnxk_sso_pmd_priv(event_dev);
856 : :
857 : 0 : evdev->rx_offloads |= flags;
858 [ # # ]: 0 : if (ptp_en)
859 : 0 : evdev->tstamp[port_id] = &cnxk_eth_dev->tstamp;
860 : : else
861 : 0 : evdev->tstamp[port_id] = NULL;
862 : : cn9k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
863 : : eventdev_fops_tstamp_update(event_dev);
864 : 0 : }
865 : :
866 : : static int
867 : 0 : cn9k_sso_rx_adapter_queue_add(
868 : : const struct rte_eventdev *event_dev, const struct rte_eth_dev *eth_dev,
869 : : int32_t rx_queue_id,
870 : : const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
871 : : {
872 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
873 : : struct cn9k_eth_rxq *rxq;
874 : : void *lookup_mem;
875 : : int rc;
876 : :
877 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn9k", 8);
878 [ # # ]: 0 : if (rc)
879 : : return -EINVAL;
880 : :
881 : 0 : rc = cnxk_sso_rx_adapter_queue_add(event_dev, eth_dev, rx_queue_id,
882 : : queue_conf);
883 [ # # ]: 0 : if (rc)
884 : : return -EINVAL;
885 : :
886 : 0 : cnxk_eth_dev->cnxk_sso_ptp_tstamp_cb = cn9k_sso_tstamp_hdl_update;
887 : 0 : cnxk_eth_dev->evdev_priv = (struct rte_eventdev *)(uintptr_t)event_dev;
888 : :
889 : 0 : rxq = eth_dev->data->rx_queues[0];
890 : 0 : lookup_mem = rxq->lookup_mem;
891 : 0 : cn9k_sso_set_priv_mem(event_dev, lookup_mem);
892 : : cn9k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
893 : :
894 : 0 : return 0;
895 : : }
896 : :
897 : : static int
898 : 0 : cn9k_sso_rx_adapter_queue_del(const struct rte_eventdev *event_dev,
899 : : const struct rte_eth_dev *eth_dev,
900 : : int32_t rx_queue_id)
901 : : {
902 : : int rc;
903 : :
904 : 0 : rc = strncmp(eth_dev->device->driver->name, "net_cn9k", 8);
905 [ # # ]: 0 : if (rc)
906 : : return -EINVAL;
907 : :
908 : 0 : return cnxk_sso_rx_adapter_queue_del(event_dev, eth_dev, rx_queue_id);
909 : : }
910 : :
911 : : static int
912 : 0 : cn9k_sso_tx_adapter_caps_get(const struct rte_eventdev *dev,
913 : : const struct rte_eth_dev *eth_dev, uint32_t *caps)
914 : : {
915 : : int ret;
916 : :
917 : : RTE_SET_USED(dev);
918 : 0 : ret = strncmp(eth_dev->device->driver->name, "net_cn9k", 8);
919 [ # # ]: 0 : if (ret)
920 : 0 : *caps = 0;
921 : : else
922 : 0 : *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT;
923 : :
924 : 0 : return 0;
925 : : }
926 : :
927 : : static void
928 : 0 : cn9k_sso_txq_fc_update(const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
929 : : {
930 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
931 : : struct cn9k_eth_txq *txq;
932 : : struct roc_nix_sq *sq;
933 : : int i;
934 : :
935 [ # # ]: 0 : if (tx_queue_id < 0) {
936 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
937 : 0 : cn9k_sso_txq_fc_update(eth_dev, i);
938 : : } else {
939 : : uint16_t sqes_per_sqb;
940 : :
941 : 0 : sq = &cnxk_eth_dev->sqs[tx_queue_id];
942 : 0 : txq = eth_dev->data->tx_queues[tx_queue_id];
943 : 0 : sqes_per_sqb = 1U << txq->sqes_per_sqb_log2;
944 [ # # ]: 0 : if (cnxk_eth_dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY)
945 : 0 : sq->nb_sqb_bufs_adj -= (cnxk_eth_dev->outb.nb_desc / sqes_per_sqb);
946 : 0 : txq->nb_sqb_bufs_adj = sq->nb_sqb_bufs_adj;
947 : : }
948 : 0 : }
949 : :
950 : : static int
951 : 0 : cn9k_sso_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *event_dev,
952 : : const struct rte_eth_dev *eth_dev,
953 : : int32_t tx_queue_id)
954 : : {
955 : 0 : struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
956 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
957 : : uint64_t tx_offloads;
958 : : int rc;
959 : :
960 : : RTE_SET_USED(id);
961 : 0 : rc = cnxk_sso_tx_adapter_queue_add(event_dev, eth_dev, tx_queue_id);
962 [ # # ]: 0 : if (rc < 0)
963 : : return rc;
964 : :
965 : : /* Can't enable tstamp if all the ports don't have it enabled. */
966 : 0 : tx_offloads = cnxk_eth_dev->tx_offload_flags;
967 [ # # ]: 0 : if (dev->tx_adptr_configured) {
968 : 0 : uint8_t tstmp_req = !!(tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F);
969 : : uint8_t tstmp_ena =
970 : 0 : !!(dev->tx_offloads & NIX_TX_OFFLOAD_TSTAMP_F);
971 : :
972 [ # # ]: 0 : if (tstmp_ena && !tstmp_req)
973 : 0 : dev->tx_offloads &= ~(NIX_TX_OFFLOAD_TSTAMP_F);
974 [ # # ]: 0 : else if (!tstmp_ena && tstmp_req)
975 : 0 : tx_offloads &= ~(NIX_TX_OFFLOAD_TSTAMP_F);
976 : : }
977 : :
978 : 0 : dev->tx_offloads |= tx_offloads;
979 : 0 : cn9k_sso_txq_fc_update(eth_dev, tx_queue_id);
980 : 0 : rc = cn9k_sso_updt_tx_adptr_data(event_dev);
981 [ # # ]: 0 : if (rc < 0)
982 : : return rc;
983 : : cn9k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
984 : 0 : dev->tx_adptr_configured = 1;
985 : :
986 : 0 : return 0;
987 : : }
988 : :
989 : : static int
990 : 0 : cn9k_sso_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *event_dev,
991 : : const struct rte_eth_dev *eth_dev,
992 : : int32_t tx_queue_id)
993 : : {
994 : : int rc;
995 : :
996 : : RTE_SET_USED(id);
997 : 0 : rc = cnxk_sso_tx_adapter_queue_del(event_dev, eth_dev, tx_queue_id);
998 [ # # ]: 0 : if (rc < 0)
999 : : return rc;
1000 : 0 : cn9k_sso_txq_fc_update(eth_dev, tx_queue_id);
1001 : 0 : return cn9k_sso_updt_tx_adptr_data(event_dev);
1002 : : }
1003 : :
1004 : : static int
1005 : 0 : cn9k_crypto_adapter_caps_get(const struct rte_eventdev *event_dev, const struct rte_cryptodev *cdev,
1006 : : uint32_t *caps)
1007 : : {
1008 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn9k", ENOTSUP);
1009 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn9k", ENOTSUP);
1010 : :
1011 : 0 : *caps = RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD |
1012 : : RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA;
1013 : :
1014 : 0 : return 0;
1015 : : }
1016 : :
1017 : : static int
1018 : 0 : cn9k_crypto_adapter_qp_add(const struct rte_eventdev *event_dev,
1019 : : const struct rte_cryptodev *cdev,
1020 : : int32_t queue_pair_id,
1021 : : const struct rte_event_crypto_adapter_queue_conf *conf)
1022 : : {
1023 : : int ret;
1024 : :
1025 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn9k", EINVAL);
1026 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn9k", EINVAL);
1027 : :
1028 : : cn9k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
1029 : :
1030 : 0 : ret = cnxk_crypto_adapter_qp_add(event_dev, cdev, queue_pair_id, conf);
1031 : 0 : cn9k_sso_set_priv_mem(event_dev, NULL);
1032 : :
1033 : 0 : return ret;
1034 : : }
1035 : :
1036 : : static int
1037 : 0 : cn9k_crypto_adapter_qp_del(const struct rte_eventdev *event_dev, const struct rte_cryptodev *cdev,
1038 : : int32_t queue_pair_id)
1039 : : {
1040 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(event_dev->dev, "event_cn9k", EINVAL);
1041 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(cdev->device, "crypto_cn9k", EINVAL);
1042 : :
1043 : 0 : return cnxk_crypto_adapter_qp_del(cdev, queue_pair_id);
1044 : : }
1045 : :
1046 : : static int
1047 : 0 : cn9k_tim_caps_get(const struct rte_eventdev *evdev, uint64_t flags,
1048 : : uint32_t *caps, const struct event_timer_adapter_ops **ops)
1049 : : {
1050 : 0 : return cnxk_tim_caps_get(evdev, flags, caps, ops,
1051 : : cn9k_sso_set_priv_mem);
1052 : : }
1053 : :
1054 : : static int
1055 : 0 : cn9k_dma_adapter_caps_get(const struct rte_eventdev *event_dev,
1056 : : const int16_t dma_dev_id, uint32_t *caps)
1057 : : {
1058 : : struct rte_dma_dev *dma_dev;
1059 : : RTE_SET_USED(event_dev);
1060 : :
1061 : 0 : dma_dev = rte_dma_pmd_get_dev_by_id(dma_dev_id);
1062 [ # # ]: 0 : if (dma_dev == NULL)
1063 : : return -EINVAL;
1064 : :
1065 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(dma_dev->device, "cnxk_dmadev_pci_driver", EINVAL);
1066 : :
1067 : 0 : *caps = RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD;
1068 : :
1069 : 0 : return 0;
1070 : : }
1071 : :
1072 : : static int
1073 : 0 : cn9k_dma_adapter_vchan_add(const struct rte_eventdev *event_dev,
1074 : : const int16_t dma_dev_id, uint16_t vchan_id,
1075 : : const struct rte_event *event)
1076 : : {
1077 : : struct rte_dma_dev *dma_dev;
1078 : : int ret;
1079 : :
1080 : : RTE_SET_USED(event);
1081 : :
1082 : 0 : dma_dev = rte_dma_pmd_get_dev_by_id(dma_dev_id);
1083 [ # # ]: 0 : if (dma_dev == NULL)
1084 : : return -EINVAL;
1085 : :
1086 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(dma_dev->device, "cnxk_dmadev_pci_driver", EINVAL);
1087 : :
1088 : : cn9k_sso_fp_fns_set((struct rte_eventdev *)(uintptr_t)event_dev);
1089 : :
1090 : 0 : ret = cnxk_dma_adapter_vchan_add(event_dev, dma_dev_id, vchan_id);
1091 : 0 : cn9k_sso_set_priv_mem(event_dev, NULL);
1092 : :
1093 : 0 : return ret;
1094 : : }
1095 : :
1096 : : static int
1097 : 0 : cn9k_dma_adapter_vchan_del(const struct rte_eventdev *event_dev,
1098 : : const int16_t dma_dev_id, uint16_t vchan_id)
1099 : : {
1100 : : struct rte_dma_dev *dma_dev;
1101 : :
1102 : : RTE_SET_USED(event_dev);
1103 : :
1104 : 0 : dma_dev = rte_dma_pmd_get_dev_by_id(dma_dev_id);
1105 [ # # ]: 0 : if (dma_dev == NULL)
1106 : : return -EINVAL;
1107 : :
1108 [ # # ]: 0 : CNXK_VALID_DEV_OR_ERR_RET(dma_dev->device, "cnxk_dmadev_pci_driver", EINVAL);
1109 : :
1110 : 0 : return cnxk_dma_adapter_vchan_del(dma_dev_id, vchan_id);
1111 : : }
1112 : :
1113 : : static struct eventdev_ops cn9k_sso_dev_ops = {
1114 : : .dev_infos_get = cn9k_sso_info_get,
1115 : : .dev_configure = cn9k_sso_dev_configure,
1116 : :
1117 : : .queue_def_conf = cnxk_sso_queue_def_conf,
1118 : : .queue_setup = cnxk_sso_queue_setup,
1119 : : .queue_release = cnxk_sso_queue_release,
1120 : : .queue_attr_set = cnxk_sso_queue_attribute_set,
1121 : :
1122 : : .port_def_conf = cnxk_sso_port_def_conf,
1123 : : .port_setup = cn9k_sso_port_setup,
1124 : : .port_release = cn9k_sso_port_release,
1125 : : .port_quiesce = cn9k_sso_port_quiesce,
1126 : : .port_link = cn9k_sso_port_link,
1127 : : .port_unlink = cn9k_sso_port_unlink,
1128 : : .port_link_profile = cn9k_sso_port_link_profile,
1129 : : .port_unlink_profile = cn9k_sso_port_unlink_profile,
1130 : : .timeout_ticks = cnxk_sso_timeout_ticks,
1131 : :
1132 : : .eth_rx_adapter_caps_get = cn9k_sso_rx_adapter_caps_get,
1133 : : .eth_rx_adapter_queue_add = cn9k_sso_rx_adapter_queue_add,
1134 : : .eth_rx_adapter_queue_del = cn9k_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_tx_adapter_caps_get = cn9k_sso_tx_adapter_caps_get,
1139 : : .eth_tx_adapter_queue_add = cn9k_sso_tx_adapter_queue_add,
1140 : : .eth_tx_adapter_queue_del = cn9k_sso_tx_adapter_queue_del,
1141 : : .eth_tx_adapter_start = cnxk_sso_tx_adapter_start,
1142 : : .eth_tx_adapter_stop = cnxk_sso_tx_adapter_stop,
1143 : : .eth_tx_adapter_free = cnxk_sso_tx_adapter_free,
1144 : :
1145 : : .timer_adapter_caps_get = cn9k_tim_caps_get,
1146 : :
1147 : : .crypto_adapter_caps_get = cn9k_crypto_adapter_caps_get,
1148 : : .crypto_adapter_queue_pair_add = cn9k_crypto_adapter_qp_add,
1149 : : .crypto_adapter_queue_pair_del = cn9k_crypto_adapter_qp_del,
1150 : :
1151 : : .dma_adapter_caps_get = cn9k_dma_adapter_caps_get,
1152 : : .dma_adapter_vchan_add = cn9k_dma_adapter_vchan_add,
1153 : : .dma_adapter_vchan_del = cn9k_dma_adapter_vchan_del,
1154 : :
1155 : : .xstats_get = cnxk_sso_xstats_get,
1156 : : .xstats_reset = cnxk_sso_xstats_reset,
1157 : : .xstats_get_names = cnxk_sso_xstats_get_names,
1158 : :
1159 : : .dump = cnxk_sso_dump,
1160 : : .dev_start = cn9k_sso_start,
1161 : : .dev_stop = cn9k_sso_stop,
1162 : : .dev_close = cn9k_sso_close,
1163 : : .dev_selftest = cn9k_sso_selftest,
1164 : : };
1165 : :
1166 : : static int
1167 : 0 : cn9k_sso_init(struct rte_eventdev *event_dev)
1168 : : {
1169 : : struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
1170 : : int rc;
1171 : :
1172 : 0 : rc = roc_plt_init();
1173 [ # # ]: 0 : if (rc < 0) {
1174 : 0 : plt_err("Failed to initialize platform model");
1175 : 0 : return rc;
1176 : : }
1177 : :
1178 : 0 : event_dev->dev_ops = &cn9k_sso_dev_ops;
1179 : : /* For secondary processes, the primary has done all the work */
1180 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1181 : : cn9k_sso_fp_fns_set(event_dev);
1182 : : return 0;
1183 : : }
1184 : :
1185 : 0 : rc = cnxk_sso_init(event_dev);
1186 [ # # ]: 0 : if (rc < 0)
1187 : : return rc;
1188 : :
1189 : 0 : cn9k_sso_set_rsrc(cnxk_sso_pmd_priv(event_dev));
1190 [ # # # # ]: 0 : if (!dev->max_event_ports || !dev->max_event_queues) {
1191 : 0 : plt_err("Not enough eventdev resource queues=%d ports=%d",
1192 : : dev->max_event_queues, dev->max_event_ports);
1193 : 0 : cnxk_sso_fini(event_dev);
1194 : 0 : return -ENODEV;
1195 : : }
1196 : :
1197 : 0 : plt_sso_dbg("Initializing %s max_queues=%d max_ports=%d",
1198 : : event_dev->data->name, dev->max_event_queues,
1199 : : dev->max_event_ports);
1200 : :
1201 : 0 : return 0;
1202 : : }
1203 : :
1204 : : static int
1205 : 0 : cn9k_sso_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
1206 : : {
1207 : 0 : return rte_event_pmd_pci_probe(
1208 : : pci_drv, pci_dev, sizeof(struct cnxk_sso_evdev), cn9k_sso_init);
1209 : : }
1210 : :
1211 : : static const struct rte_pci_id cn9k_pci_sso_map[] = {
1212 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KA, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1213 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KB, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1214 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KC, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1215 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KD, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1216 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KE, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1217 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF9KA, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
1218 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KA, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1219 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KB, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1220 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KC, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1221 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KD, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1222 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN9KE, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1223 : : CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF9KA, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
1224 : : {
1225 : : .vendor_id = 0,
1226 : : },
1227 : : };
1228 : :
1229 : : static struct rte_pci_driver cn9k_pci_sso = {
1230 : : .id_table = cn9k_pci_sso_map,
1231 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
1232 : : .probe = cn9k_sso_probe,
1233 : : .remove = cnxk_sso_remove,
1234 : : };
1235 : :
1236 : 252 : RTE_PMD_REGISTER_PCI(event_cn9k, cn9k_pci_sso);
1237 : : RTE_PMD_REGISTER_PCI_TABLE(event_cn9k, cn9k_pci_sso_map);
1238 : : RTE_PMD_REGISTER_KMOD_DEP(event_cn9k, "vfio-pci");
1239 : : RTE_PMD_REGISTER_PARAM_STRING(event_cn9k, CNXK_SSO_XAE_CNT "=<int>"
1240 : : CNXK_SSO_GGRP_QOS "=<string>"
1241 : : CNXK_SSO_FORCE_BP "=1"
1242 : : CN9K_SSO_SINGLE_WS "=1"
1243 : : CNXK_TIM_DISABLE_NPA "=1"
1244 : : CNXK_TIM_CHNK_SLOTS "=<int>"
1245 : : CNXK_TIM_RINGS_LMT "=<int>"
1246 : : CNXK_TIM_STATS_ENA "=1");
|