Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016-2020 Intel Corporation
3 : : */
4 : :
5 : : #include <stdint.h>
6 : : #include <stdbool.h>
7 : : #include <stdio.h>
8 : : #include <sys/mman.h>
9 : : #include <fcntl.h>
10 : : #include <sys/time.h>
11 : : #include <errno.h>
12 : : #include <assert.h>
13 : : #include <unistd.h>
14 : : #include <string.h>
15 : :
16 : : #include <rte_debug.h>
17 : : #include <rte_log.h>
18 : : #include <dev_driver.h>
19 : : #include <rte_devargs.h>
20 : : #include <rte_mbuf.h>
21 : : #include <rte_ring.h>
22 : : #include <rte_errno.h>
23 : : #include <rte_kvargs.h>
24 : : #include <rte_malloc.h>
25 : : #include <rte_cycles.h>
26 : : #include <rte_io.h>
27 : : #include <rte_pci.h>
28 : : #include <bus_pci_driver.h>
29 : : #include <rte_eventdev.h>
30 : : #include <eventdev_pmd.h>
31 : : #include <eventdev_pmd_pci.h>
32 : : #include <rte_memory.h>
33 : : #include <rte_string_fns.h>
34 : :
35 : : #include "../dlb2_priv.h"
36 : : #include "../dlb2_iface.h"
37 : : #include "../dlb2_inline_fns.h"
38 : : #include "dlb2_main.h"
39 : : #include "base/dlb2_hw_types.h"
40 : : #include "base/dlb2_osdep.h"
41 : : #include "base/dlb2_resource.h"
42 : :
43 : : static const char *event_dlb2_pf_name = RTE_STR(EVDEV_DLB2_NAME_PMD);
44 : : static unsigned int dlb2_qe_sa_pct = 1;
45 : : static unsigned int dlb2_qid_sa_pct;
46 : :
47 : : static void
48 : 0 : dlb2_pf_low_level_io_init(struct dlb2_hw_dev *handle)
49 : : {
50 : : int i;
51 : :
52 [ # # ]: 0 : if (handle == NULL) {
53 : : /* Addresses will be initialized at port create in primary process*/
54 [ # # ]: 0 : for (i = 0; i < DLB2_MAX_NUM_PORTS(DLB2_HW_V2_5); i++) {
55 : : /* First directed ports */
56 : 0 : dlb2_port[i][DLB2_DIR_PORT].pp_addr = NULL;
57 : 0 : dlb2_port[i][DLB2_DIR_PORT].cq_base = NULL;
58 : 0 : dlb2_port[i][DLB2_DIR_PORT].mmaped = false;
59 : :
60 : : /* Now load balanced ports */
61 : 0 : dlb2_port[i][DLB2_LDB_PORT].pp_addr = NULL;
62 : 0 : dlb2_port[i][DLB2_LDB_PORT].cq_base = NULL;
63 : 0 : dlb2_port[i][DLB2_LDB_PORT].mmaped = false;
64 : : }
65 : : } else {
66 : : /* Retrieve stored addresses in secondary processes */
67 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
68 : 0 : struct dlb2_ldb_port *ldb_ports = dlb2_dev->hw.rsrcs.ldb_ports;
69 : 0 : struct dlb2_dir_pq_pair *dir_ports = dlb2_dev->hw.rsrcs.dir_pq_pairs;
70 : :
71 [ # # ]: 0 : for (i = 0; i < DLB2_MAX_NUM_LDB_PORTS; i++) {
72 : 0 : dlb2_port[i][DLB2_LDB_PORT].cq_base = ldb_ports[i].port_data.cq_base;
73 : 0 : dlb2_port[i][DLB2_LDB_PORT].pp_addr = ldb_ports[i].port_data.pp_addr;
74 : 0 : dlb2_port[i][DLB2_LDB_PORT].mmaped = true;
75 : : }
76 [ # # ]: 0 : for (i = 0; i < DLB2_MAX_NUM_DIR_PORTS_V2_5; i++) {
77 : 0 : dlb2_port[i][DLB2_DIR_PORT].cq_base = dir_ports[i].port_data.cq_base;
78 : 0 : dlb2_port[i][DLB2_DIR_PORT].pp_addr = dir_ports[i].port_data.pp_addr;
79 : 0 : dlb2_port[i][DLB2_DIR_PORT].mmaped = true;
80 : : }
81 : : }
82 : 0 : }
83 : :
84 : : static int
85 : 0 : dlb2_pf_open(struct dlb2_hw_dev *handle, const char *name)
86 : : {
87 : : RTE_SET_USED(handle);
88 : : RTE_SET_USED(name);
89 : :
90 : 0 : return 0;
91 : : }
92 : :
93 : : static int
94 : 0 : dlb2_pf_get_device_version(struct dlb2_hw_dev *handle,
95 : : uint8_t *revision)
96 : : {
97 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
98 : :
99 : 0 : *revision = dlb2_dev->revision;
100 : :
101 : 0 : return 0;
102 : : }
103 : :
104 : : static void dlb2_pf_calc_arbiter_weights(u8 *weight,
105 : : unsigned int pct)
106 : : {
107 : : int val, i;
108 : :
109 : : /* Largest possible weight (100% SA case): 32 */
110 : : val = (DLB2_MAX_WEIGHT + 1) / DLB2_NUM_ARB_WEIGHTS;
111 : :
112 : : /* Scale val according to the starvation avoidance percentage */
113 : 0 : val = (val * pct) / 100;
114 [ # # # # ]: 0 : if (val == 0 && pct != 0)
115 : : val = 1;
116 : :
117 : : /* Prio 7 always has weight 0xff */
118 : 0 : weight[DLB2_NUM_ARB_WEIGHTS - 1] = DLB2_MAX_WEIGHT;
119 : :
120 [ # # # # ]: 0 : for (i = DLB2_NUM_ARB_WEIGHTS - 2; i >= 0; i--)
121 : 0 : weight[i] = weight[i + 1] - val;
122 : : }
123 : :
124 : :
125 : : static void
126 : 0 : dlb2_pf_hardware_init(struct dlb2_hw_dev *handle)
127 : : {
128 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
129 : :
130 : 0 : dlb2_hw_enable_sparse_ldb_cq_mode(&dlb2_dev->hw);
131 : 0 : dlb2_hw_enable_sparse_dir_cq_mode(&dlb2_dev->hw);
132 : :
133 : : /* Configure arbitration weights for QE selection */
134 [ # # ]: 0 : if (dlb2_qe_sa_pct <= 100) {
135 : : u8 weight[DLB2_NUM_ARB_WEIGHTS];
136 : :
137 : : dlb2_pf_calc_arbiter_weights(weight,
138 : : dlb2_qe_sa_pct);
139 : :
140 : 0 : dlb2_hw_set_qe_arbiter_weights(&dlb2_dev->hw, weight);
141 : : }
142 : :
143 : : /* Configure arbitration weights for QID selection */
144 [ # # ]: 0 : if (dlb2_qid_sa_pct <= 100) {
145 : : u8 weight[DLB2_NUM_ARB_WEIGHTS];
146 : :
147 : : dlb2_pf_calc_arbiter_weights(weight,
148 : : dlb2_qid_sa_pct);
149 : :
150 : 0 : dlb2_hw_set_qid_arbiter_weights(&dlb2_dev->hw, weight);
151 : : }
152 : :
153 : 0 : }
154 : :
155 : : static int
156 : 0 : dlb2_pf_get_num_resources(struct dlb2_hw_dev *handle,
157 : : struct dlb2_get_num_resources_args *rsrcs)
158 : : {
159 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
160 : :
161 : 0 : return dlb2_hw_get_num_resources(&dlb2_dev->hw, rsrcs, false, 0);
162 : : }
163 : :
164 : : static int
165 : 0 : dlb2_pf_get_cq_poll_mode(struct dlb2_hw_dev *handle,
166 : : enum dlb2_cq_poll_modes *mode)
167 : : {
168 : : RTE_SET_USED(handle);
169 : :
170 : 0 : *mode = DLB2_CQ_POLL_MODE_SPARSE;
171 : :
172 : 0 : return 0;
173 : : }
174 : :
175 : : static int
176 : 0 : dlb2_pf_sched_domain_create(struct dlb2_hw_dev *handle,
177 : : struct dlb2_create_sched_domain_args *arg)
178 : : {
179 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
180 : 0 : struct dlb2_cmd_response response = {0};
181 : : int ret;
182 : :
183 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
184 : :
185 [ # # ]: 0 : if (dlb2_dev->domain_reset_failed) {
186 : 0 : response.status = DLB2_ST_DOMAIN_RESET_FAILED;
187 : : ret = -EINVAL;
188 : 0 : goto done;
189 : : }
190 : :
191 : 0 : ret = dlb2_pf_create_sched_domain(&dlb2_dev->hw, arg, &response);
192 [ # # ]: 0 : if (ret)
193 : 0 : goto done;
194 : :
195 : 0 : done:
196 : :
197 : 0 : arg->response = response;
198 : :
199 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
200 : : __func__, ret);
201 : :
202 : 0 : return ret;
203 : : }
204 : :
205 : : static void
206 : 0 : dlb2_pf_domain_reset(struct dlb2_eventdev *dlb2)
207 : : {
208 : : struct dlb2_dev *dlb2_dev;
209 : : int ret;
210 : :
211 : 0 : dlb2_dev = (struct dlb2_dev *)dlb2->qm_instance.pf_dev;
212 : 0 : ret = dlb2_pf_reset_domain(&dlb2_dev->hw, dlb2->qm_instance.domain_id);
213 [ # # ]: 0 : if (ret)
214 : 0 : DLB2_LOG_ERR("dlb2_pf_reset_domain err %d", ret);
215 : 0 : }
216 : :
217 : : static int
218 : 0 : dlb2_pf_ldb_queue_create(struct dlb2_hw_dev *handle,
219 : : struct dlb2_create_ldb_queue_args *cfg)
220 : : {
221 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
222 : 0 : struct dlb2_cmd_response response = {0};
223 : : int ret;
224 : :
225 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
226 : :
227 : 0 : ret = dlb2_pf_create_ldb_queue(&dlb2_dev->hw,
228 : : handle->domain_id,
229 : : cfg,
230 : : &response);
231 : :
232 : 0 : cfg->response = response;
233 : :
234 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
235 : : __func__, ret);
236 : :
237 : 0 : return ret;
238 : : }
239 : :
240 : : static int
241 : 0 : dlb2_pf_get_sn_occupancy(struct dlb2_hw_dev *handle,
242 : : struct dlb2_get_sn_occupancy_args *args)
243 : : {
244 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
245 : : struct dlb2_cmd_response response = {0};
246 : : int ret;
247 : :
248 : 0 : ret = dlb2_get_group_sequence_number_occupancy(&dlb2_dev->hw,
249 : : args->group);
250 : :
251 : 0 : response.id = ret;
252 : : response.status = 0;
253 : :
254 : 0 : args->response = response;
255 : :
256 : 0 : return ret;
257 : : }
258 : :
259 : : static int
260 : 0 : dlb2_pf_get_sn_allocation(struct dlb2_hw_dev *handle,
261 : : struct dlb2_get_sn_allocation_args *args)
262 : : {
263 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
264 : : struct dlb2_cmd_response response = {0};
265 : : int ret;
266 : :
267 : 0 : ret = dlb2_get_group_sequence_numbers(&dlb2_dev->hw, args->group);
268 : :
269 : 0 : response.id = ret;
270 : : response.status = 0;
271 : :
272 : 0 : args->response = response;
273 : :
274 : 0 : return ret;
275 : : }
276 : :
277 : : static int
278 : 0 : dlb2_pf_set_sn_allocation(struct dlb2_hw_dev *handle,
279 : : struct dlb2_set_sn_allocation_args *args)
280 : : {
281 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
282 : : struct dlb2_cmd_response response = {0};
283 : : int ret;
284 : :
285 : 0 : ret = dlb2_set_group_sequence_numbers(&dlb2_dev->hw, args->group,
286 : : args->num);
287 : :
288 : : response.status = 0;
289 : :
290 : 0 : args->response = response;
291 : :
292 : 0 : return ret;
293 : : }
294 : :
295 : : static void *
296 : 0 : dlb2_alloc_coherent_aligned(const struct rte_memzone **mz, uintptr_t *phys,
297 : : size_t size, int align)
298 : : {
299 : : char mz_name[RTE_MEMZONE_NAMESIZE];
300 : : uint32_t core_id = rte_lcore_id();
301 : : unsigned int socket_id;
302 : :
303 : : snprintf(mz_name, sizeof(mz_name) - 1, "event_dlb2_pf_%lx",
304 : : (unsigned long)rte_get_timer_cycles());
305 [ # # ]: 0 : if (core_id == (unsigned int)LCORE_ID_ANY)
306 : 0 : core_id = rte_get_main_lcore();
307 : 0 : socket_id = rte_lcore_to_socket_id(core_id);
308 : 0 : *mz = rte_memzone_reserve_aligned(mz_name, size, socket_id,
309 : : RTE_MEMZONE_IOVA_CONTIG, align);
310 [ # # ]: 0 : if (*mz == NULL) {
311 : : DLB2_LOG_LINE_DBG("Unable to allocate DMA memory of size %zu bytes - %s",
312 : : size, rte_strerror(rte_errno));
313 : 0 : *phys = 0;
314 : 0 : return NULL;
315 : : }
316 : 0 : *phys = (*mz)->iova;
317 : 0 : return (*mz)->addr;
318 : : }
319 : :
320 : : static int
321 : 0 : dlb2_pf_ldb_port_create(struct dlb2_hw_dev *handle,
322 : : struct dlb2_create_ldb_port_args *cfg,
323 : : enum dlb2_cq_poll_modes poll_mode)
324 : : {
325 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
326 : : struct process_local_port_data *port_data;
327 : 0 : struct dlb2_cmd_response response = {0};
328 : : struct dlb2_port_memory port_memory;
329 : : int ret, cq_alloc_depth;
330 : : uint8_t *port_base;
331 : : const struct rte_memzone *mz;
332 : : int alloc_sz, qe_sz;
333 : : phys_addr_t cq_base;
334 : : phys_addr_t pp_base;
335 : : int is_dir = false;
336 : :
337 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
338 : :
339 [ # # ]: 0 : if (poll_mode == DLB2_CQ_POLL_MODE_STD)
340 : : qe_sz = sizeof(struct dlb2_dequeue_qe);
341 : : else
342 : : qe_sz = RTE_CACHE_LINE_SIZE;
343 : :
344 : : /* Calculate the port memory required, and round up to the nearest
345 : : * cache line.
346 : : */
347 : 0 : cq_alloc_depth = RTE_MAX(cfg->cq_depth, DLB2_MIN_HARDWARE_CQ_DEPTH);
348 : 0 : alloc_sz = cq_alloc_depth * qe_sz;
349 : 0 : alloc_sz = RTE_CACHE_LINE_ROUNDUP(alloc_sz);
350 : :
351 : 0 : port_base = dlb2_alloc_coherent_aligned(&mz, &cq_base, alloc_sz,
352 : 0 : rte_mem_page_size());
353 [ # # ]: 0 : if (port_base == NULL)
354 : : return -ENOMEM;
355 : :
356 : : /* Lock the page in memory */
357 : 0 : ret = rte_mem_lock_page(port_base);
358 [ # # ]: 0 : if (ret < 0) {
359 : 0 : DLB2_LOG_ERR("dlb2 pf pmd could not lock page for device i/o");
360 : 0 : goto create_port_err;
361 : : }
362 : :
363 : : memset(port_base, 0, alloc_sz);
364 : :
365 : 0 : ret = dlb2_pf_create_ldb_port(&dlb2_dev->hw,
366 : : handle->domain_id,
367 : : cfg,
368 : : cq_base,
369 : : &response);
370 : 0 : cfg->response = response;
371 [ # # ]: 0 : if (ret)
372 : 0 : goto create_port_err;
373 : :
374 : 0 : pp_base = (uintptr_t)dlb2_dev->hw.func_kva + PP_BASE(is_dir);
375 : 0 : dlb2_port[response.id][DLB2_LDB_PORT].pp_addr =
376 : 0 : (void *)(pp_base + (rte_mem_page_size() * response.id));
377 : :
378 : 0 : dlb2_port[response.id][DLB2_LDB_PORT].cq_base = (void *)(port_base);
379 : 0 : dlb2_port[response.id][DLB2_LDB_PORT].mmaped = true;
380 : : memset(&port_memory, 0, sizeof(port_memory));
381 : :
382 : 0 : dlb2_port[response.id][DLB2_LDB_PORT].mz = mz;
383 : :
384 : : dlb2_list_init_head(&port_memory.list);
385 : :
386 : 0 : cfg->response = response;
387 : :
388 : : /* Store cq_base and pp_addr for secondary processes*/
389 : : port_data = &dlb2_dev->hw.rsrcs.ldb_ports[response.id].port_data;
390 : 0 : port_data->pp_addr = dlb2_port[response.id][DLB2_LDB_PORT].pp_addr;
391 : 0 : port_data->cq_base = (struct dlb2_dequeue_qe *)cq_base;
392 : :
393 : 0 : return 0;
394 : :
395 : 0 : create_port_err:
396 : :
397 : 0 : rte_memzone_free(mz);
398 : :
399 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
400 : : __func__, ret);
401 : 0 : return ret;
402 : : }
403 : :
404 : : static int
405 : 0 : dlb2_pf_dir_port_create(struct dlb2_hw_dev *handle,
406 : : struct dlb2_create_dir_port_args *cfg,
407 : : enum dlb2_cq_poll_modes poll_mode)
408 : : {
409 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
410 : : struct process_local_port_data *port_data;
411 : 0 : struct dlb2_cmd_response response = {0};
412 : : struct dlb2_port_memory port_memory;
413 : : int ret;
414 : : uint8_t *port_base;
415 : : const struct rte_memzone *mz;
416 : : int alloc_sz, qe_sz;
417 : : phys_addr_t cq_base;
418 : : phys_addr_t pp_base;
419 : : int is_dir = true;
420 : :
421 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
422 : :
423 [ # # ]: 0 : if (poll_mode == DLB2_CQ_POLL_MODE_STD)
424 : : qe_sz = sizeof(struct dlb2_dequeue_qe);
425 : : else
426 : : qe_sz = RTE_CACHE_LINE_SIZE;
427 : :
428 : : /* Calculate the port memory required, and round up to the nearest
429 : : * cache line.
430 : : */
431 : 0 : alloc_sz = RTE_MAX(cfg->cq_depth, DLB2_MIN_HARDWARE_CQ_DEPTH) * qe_sz;
432 : 0 : alloc_sz = RTE_CACHE_LINE_ROUNDUP(alloc_sz);
433 : :
434 : 0 : port_base = dlb2_alloc_coherent_aligned(&mz, &cq_base, alloc_sz,
435 : 0 : rte_mem_page_size());
436 [ # # ]: 0 : if (port_base == NULL)
437 : : return -ENOMEM;
438 : :
439 : : /* Lock the page in memory */
440 : 0 : ret = rte_mem_lock_page(port_base);
441 [ # # ]: 0 : if (ret < 0) {
442 : 0 : DLB2_LOG_ERR("dlb2 pf pmd could not lock page for device i/o");
443 : 0 : goto create_port_err;
444 : : }
445 : :
446 : : memset(port_base, 0, alloc_sz);
447 : :
448 : 0 : ret = dlb2_pf_create_dir_port(&dlb2_dev->hw,
449 : : handle->domain_id,
450 : : cfg,
451 : : cq_base,
452 : : &response);
453 : :
454 : 0 : cfg->response = response;
455 : :
456 [ # # ]: 0 : if (ret)
457 : 0 : goto create_port_err;
458 : :
459 : 0 : pp_base = (uintptr_t)dlb2_dev->hw.func_kva + PP_BASE(is_dir);
460 : 0 : dlb2_port[response.id][DLB2_DIR_PORT].pp_addr =
461 : 0 : (void *)(pp_base + (rte_mem_page_size() * response.id));
462 : :
463 : 0 : dlb2_port[response.id][DLB2_DIR_PORT].cq_base =
464 : : (void *)(port_base);
465 : 0 : dlb2_port[response.id][DLB2_DIR_PORT].mmaped = true;
466 : : memset(&port_memory, 0, sizeof(port_memory));
467 : :
468 : 0 : dlb2_port[response.id][DLB2_DIR_PORT].mz = mz;
469 : :
470 : : dlb2_list_init_head(&port_memory.list);
471 : :
472 : 0 : cfg->response = response;
473 : :
474 : : /* Store cq_base and pp_addr for secondary processes*/
475 : : port_data = &dlb2_dev->hw.rsrcs.dir_pq_pairs[response.id].port_data;
476 : 0 : port_data->pp_addr = dlb2_port[response.id][DLB2_DIR_PORT].pp_addr;
477 : 0 : port_data->cq_base = (struct dlb2_dequeue_qe *)cq_base;
478 : :
479 : 0 : return 0;
480 : :
481 : 0 : create_port_err:
482 : :
483 : 0 : rte_memzone_free(mz);
484 : :
485 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
486 : : __func__, ret);
487 : :
488 : 0 : return ret;
489 : : }
490 : :
491 : : static int
492 : 0 : dlb2_pf_dir_queue_create(struct dlb2_hw_dev *handle,
493 : : struct dlb2_create_dir_queue_args *cfg)
494 : : {
495 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
496 : 0 : struct dlb2_cmd_response response = {0};
497 : : int ret;
498 : :
499 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
500 : :
501 : 0 : ret = dlb2_pf_create_dir_queue(&dlb2_dev->hw,
502 : : handle->domain_id,
503 : : cfg,
504 : : &response);
505 : :
506 : 0 : cfg->response = response;
507 : :
508 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
509 : : __func__, ret);
510 : :
511 : 0 : return ret;
512 : : }
513 : :
514 : : static int
515 : 0 : dlb2_pf_map_qid(struct dlb2_hw_dev *handle,
516 : : struct dlb2_map_qid_args *cfg)
517 : : {
518 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
519 : 0 : struct dlb2_cmd_response response = {0};
520 : : int ret;
521 : :
522 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
523 : :
524 : 0 : ret = dlb2_hw_map_qid(&dlb2_dev->hw,
525 : : handle->domain_id,
526 : : cfg,
527 : : &response,
528 : : false,
529 : : 0);
530 : :
531 : 0 : cfg->response = response;
532 : :
533 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
534 : : __func__, ret);
535 : :
536 : 0 : return ret;
537 : : }
538 : :
539 : : static int
540 : 0 : dlb2_pf_unmap_qid(struct dlb2_hw_dev *handle,
541 : : struct dlb2_unmap_qid_args *cfg)
542 : : {
543 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
544 : 0 : struct dlb2_cmd_response response = {0};
545 : : int ret;
546 : :
547 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
548 : :
549 : 0 : ret = dlb2_hw_unmap_qid(&dlb2_dev->hw,
550 : : handle->domain_id,
551 : : cfg,
552 : : &response,
553 : : false,
554 : : 0);
555 : :
556 : 0 : cfg->response = response;
557 : :
558 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
559 : : __func__, ret);
560 : :
561 : 0 : return ret;
562 : : }
563 : :
564 : : static int
565 : 0 : dlb2_pf_pending_port_unmaps(struct dlb2_hw_dev *handle,
566 : : struct dlb2_pending_port_unmaps_args *args)
567 : : {
568 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
569 : 0 : struct dlb2_cmd_response response = {0};
570 : : int ret;
571 : :
572 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
573 : :
574 : 0 : ret = dlb2_hw_pending_port_unmaps(&dlb2_dev->hw,
575 : : handle->domain_id,
576 : : args,
577 : : &response,
578 : : false,
579 : : 0);
580 : :
581 : 0 : args->response = response;
582 : :
583 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
584 : : __func__, ret);
585 : :
586 : 0 : return ret;
587 : : }
588 : :
589 : : static int
590 : 0 : dlb2_pf_sched_domain_start(struct dlb2_hw_dev *handle,
591 : : struct dlb2_start_domain_args *cfg)
592 : : {
593 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
594 : 0 : struct dlb2_cmd_response response = {0};
595 : : int ret;
596 : :
597 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
598 : :
599 : 0 : ret = dlb2_pf_start_domain(&dlb2_dev->hw,
600 : : handle->domain_id,
601 : : cfg,
602 : : &response);
603 : :
604 : 0 : cfg->response = response;
605 : :
606 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
607 : : __func__, ret);
608 : :
609 : 0 : return ret;
610 : : }
611 : :
612 : : static int
613 : 0 : dlb2_pf_get_ldb_queue_depth(struct dlb2_hw_dev *handle,
614 : : struct dlb2_get_ldb_queue_depth_args *args)
615 : : {
616 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
617 : 0 : struct dlb2_cmd_response response = {0};
618 : : int ret;
619 : :
620 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
621 : :
622 : 0 : ret = dlb2_hw_get_ldb_queue_depth(&dlb2_dev->hw,
623 : : handle->domain_id,
624 : : args,
625 : : &response,
626 : : false,
627 : : 0);
628 : :
629 : 0 : args->response = response;
630 : :
631 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
632 : : __func__, ret);
633 : :
634 : 0 : return ret;
635 : : }
636 : :
637 : : static int
638 : 0 : dlb2_pf_get_dir_queue_depth(struct dlb2_hw_dev *handle,
639 : : struct dlb2_get_dir_queue_depth_args *args)
640 : : {
641 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
642 : 0 : struct dlb2_cmd_response response = {0};
643 : : int ret = 0;
644 : :
645 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
646 : :
647 : 0 : ret = dlb2_hw_get_dir_queue_depth(&dlb2_dev->hw,
648 : : handle->domain_id,
649 : : args,
650 : : &response,
651 : : false,
652 : : 0);
653 : :
654 : 0 : args->response = response;
655 : :
656 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
657 : : __func__, ret);
658 : :
659 : 0 : return ret;
660 : : }
661 : :
662 : : static int
663 : 0 : dlb2_pf_enable_cq_weight(struct dlb2_hw_dev *handle,
664 : : struct dlb2_enable_cq_weight_args *args)
665 : : {
666 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
667 : 0 : struct dlb2_cmd_response response = {0};
668 : : int ret = 0;
669 : :
670 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
671 : :
672 : 0 : ret = dlb2_hw_enable_cq_weight(&dlb2_dev->hw,
673 : : handle->domain_id,
674 : : args,
675 : : &response,
676 : : false,
677 : : 0);
678 : 0 : args->response = response;
679 : :
680 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
681 : : __func__, ret);
682 : :
683 : 0 : return ret;
684 : : }
685 : :
686 : : static int
687 : 0 : dlb2_pf_set_cq_inflight_ctrl(struct dlb2_hw_dev *handle,
688 : : struct dlb2_cq_inflight_ctrl_args *args)
689 : : {
690 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
691 : 0 : struct dlb2_cmd_response response = {0};
692 : : int ret = 0;
693 : :
694 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
695 : :
696 : 0 : ret = dlb2_hw_set_cq_inflight_ctrl(&dlb2_dev->hw, handle->domain_id,
697 : : args, &response, false, 0);
698 : 0 : args->response = response;
699 : :
700 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d",
701 : : __func__, ret);
702 : :
703 : 0 : return ret;
704 : : }
705 : :
706 : : static int
707 : 0 : dlb2_pf_set_cos_bandwidth(struct dlb2_hw_dev *handle,
708 : : struct dlb2_set_cos_bw_args *args)
709 : : {
710 : 0 : struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
711 : : int ret = 0;
712 : :
713 : 0 : DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
714 : :
715 : 0 : ret = dlb2_hw_set_cos_bandwidth(&dlb2_dev->hw,
716 : : args->cos_id,
717 : 0 : args->bandwidth);
718 : :
719 : 0 : DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
720 : : __func__, ret);
721 : :
722 : 0 : return ret;
723 : : }
724 : :
725 : : static void
726 : 0 : dlb2_pf_iface_fn_ptrs_init(void)
727 : : {
728 : 0 : dlb2_iface_low_level_io_init = dlb2_pf_low_level_io_init;
729 : 0 : dlb2_iface_open = dlb2_pf_open;
730 : 0 : dlb2_iface_domain_reset = dlb2_pf_domain_reset;
731 : 0 : dlb2_iface_get_device_version = dlb2_pf_get_device_version;
732 : 0 : dlb2_iface_hardware_init = dlb2_pf_hardware_init;
733 : 0 : dlb2_iface_get_num_resources = dlb2_pf_get_num_resources;
734 : 0 : dlb2_iface_get_cq_poll_mode = dlb2_pf_get_cq_poll_mode;
735 : 0 : dlb2_iface_sched_domain_create = dlb2_pf_sched_domain_create;
736 : 0 : dlb2_iface_ldb_queue_create = dlb2_pf_ldb_queue_create;
737 : 0 : dlb2_iface_ldb_port_create = dlb2_pf_ldb_port_create;
738 : 0 : dlb2_iface_dir_queue_create = dlb2_pf_dir_queue_create;
739 : 0 : dlb2_iface_dir_port_create = dlb2_pf_dir_port_create;
740 : 0 : dlb2_iface_map_qid = dlb2_pf_map_qid;
741 : 0 : dlb2_iface_unmap_qid = dlb2_pf_unmap_qid;
742 : 0 : dlb2_iface_get_ldb_queue_depth = dlb2_pf_get_ldb_queue_depth;
743 : 0 : dlb2_iface_get_dir_queue_depth = dlb2_pf_get_dir_queue_depth;
744 : 0 : dlb2_iface_sched_domain_start = dlb2_pf_sched_domain_start;
745 : 0 : dlb2_iface_pending_port_unmaps = dlb2_pf_pending_port_unmaps;
746 : 0 : dlb2_iface_get_sn_allocation = dlb2_pf_get_sn_allocation;
747 : 0 : dlb2_iface_set_sn_allocation = dlb2_pf_set_sn_allocation;
748 : 0 : dlb2_iface_get_sn_occupancy = dlb2_pf_get_sn_occupancy;
749 : 0 : dlb2_iface_enable_cq_weight = dlb2_pf_enable_cq_weight;
750 : 0 : dlb2_iface_set_cos_bw = dlb2_pf_set_cos_bandwidth;
751 : 0 : dlb2_iface_set_cq_inflight_ctrl = dlb2_pf_set_cq_inflight_ctrl;
752 : 0 : }
753 : :
754 : : /* PCI DEV HOOKS */
755 : : static int
756 : 0 : dlb2_eventdev_pci_init(struct rte_eventdev *eventdev)
757 : : {
758 : : int ret = 0;
759 : : struct rte_pci_device *pci_dev;
760 : 0 : struct dlb2_devargs dlb2_args = {
761 : 0 : .socket_id = rte_socket_id(),
762 : : .max_num_events = DLB2_MAX_NUM_LDB_CREDITS,
763 : : .producer_coremask = NULL,
764 : : .num_dir_credits_override = -1,
765 : : .qid_depth_thresholds = { {0} },
766 : : .poll_interval = DLB2_POLL_INTERVAL_DEFAULT,
767 : : .sw_credit_quanta = DLB2_SW_CREDIT_QUANTA_DEFAULT,
768 : : .hw_credit_quanta = DLB2_SW_CREDIT_BATCH_SZ,
769 : : .default_depth_thresh = DLB2_DEPTH_THRESH_DEFAULT,
770 : : .max_cq_depth = DLB2_DEFAULT_CQ_DEPTH,
771 : : .max_enq_depth = DLB2_MAX_ENQUEUE_DEPTH,
772 : : .use_default_hl = true,
773 : : .alloc_hl_entries = 0
774 : : };
775 : : struct dlb2_eventdev *dlb2;
776 : : int q;
777 : : const void *probe_args = NULL;
778 : :
779 : : DLB2_LOG_LINE_DBG("Enter with dev_id=%d socket_id=%d",
780 : : eventdev->data->dev_id, eventdev->data->socket_id);
781 : :
782 [ # # ]: 0 : for (q = 0; q < DLB2_MAX_NUM_PORTS_ALL; q++)
783 : 0 : dlb2_args.port_cos.cos_id[q] = DLB2_COS_DEFAULT;
784 : :
785 : 0 : dlb2_pf_iface_fn_ptrs_init();
786 : :
787 : 0 : pci_dev = RTE_DEV_TO_PCI(eventdev->dev);
788 : :
789 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
790 : : dlb2 = dlb2_pmd_priv(eventdev); /* rte_zmalloc_socket mem */
791 : 0 : dlb2->version = DLB2_HW_DEVICE_FROM_PCI_ID(pci_dev);
792 [ # # ]: 0 : if (dlb2->version == DLB2_HW_V2_5)
793 : 0 : dlb2_args.max_num_events = DLB2_MAX_NUM_CREDITS(DLB2_HW_V2_5);
794 : :
795 : : /* Were we invoked with runtime parameters? */
796 [ # # ]: 0 : if (pci_dev->device.devargs) {
797 : 0 : ret = dlb2_parse_params(pci_dev->device.devargs->args,
798 : 0 : pci_dev->device.devargs->name,
799 : : &dlb2_args,
800 : : dlb2->version);
801 [ # # ]: 0 : if (ret) {
802 : 0 : DLB2_LOG_ERR("PFPMD failed to parse args ret=%d, errno=%d",
803 : : ret, rte_errno);
804 : 0 : goto dlb2_probe_failed;
805 : : }
806 : : probe_args = &dlb2_args;
807 : : }
808 : :
809 : : /* Probe the DLB2 PF layer */
810 : 0 : dlb2->qm_instance.pf_dev = dlb2_probe(pci_dev, probe_args);
811 : :
812 [ # # ]: 0 : if (dlb2->qm_instance.pf_dev == NULL) {
813 : 0 : DLB2_LOG_ERR("DLB2 PF Probe failed with error %d",
814 : : rte_errno);
815 : 0 : ret = -rte_errno;
816 : 0 : goto dlb2_probe_failed;
817 : : }
818 : :
819 : 0 : ret = dlb2_primary_eventdev_probe(eventdev,
820 : : event_dlb2_pf_name,
821 : : &dlb2_args);
822 : : } else {
823 : : dlb2 = dlb2_pmd_priv(eventdev);
824 : 0 : dlb2->version = DLB2_HW_DEVICE_FROM_PCI_ID(pci_dev);
825 : 0 : ret = dlb2_secondary_eventdev_probe(eventdev,
826 : : event_dlb2_pf_name);
827 : : }
828 [ # # ]: 0 : if (ret)
829 : 0 : goto dlb2_probe_failed;
830 : :
831 : 0 : DLB2_LOG_INFO("DLB2 PF Probe success");
832 : :
833 : 0 : return 0;
834 : :
835 : 0 : dlb2_probe_failed:
836 : :
837 : 0 : DLB2_LOG_INFO("DLB2 PF Probe failed, ret=%d", ret);
838 : :
839 : 0 : return ret;
840 : : }
841 : :
842 : : #define EVENTDEV_INTEL_VENDOR_ID 0x8086
843 : :
844 : : static const struct rte_pci_id pci_id_dlb2_map[] = {
845 : : {
846 : : RTE_PCI_DEVICE(EVENTDEV_INTEL_VENDOR_ID,
847 : : PCI_DEVICE_ID_INTEL_DLB2_PF)
848 : : },
849 : : {
850 : : .vendor_id = 0,
851 : : },
852 : : };
853 : :
854 : : static const struct rte_pci_id pci_id_dlb2_5_map[] = {
855 : : {
856 : : RTE_PCI_DEVICE(EVENTDEV_INTEL_VENDOR_ID,
857 : : PCI_DEVICE_ID_INTEL_DLB2_5_PF)
858 : : },
859 : : {
860 : : .vendor_id = 0,
861 : : },
862 : : };
863 : :
864 : : static int
865 : 0 : event_dlb2_pci_probe(struct rte_pci_driver *pci_drv,
866 : : struct rte_pci_device *pci_dev)
867 : : {
868 : : int ret;
869 : :
870 : 0 : ret = rte_event_pmd_pci_probe_named(pci_drv, pci_dev,
871 : : sizeof(struct dlb2_eventdev),
872 : : dlb2_eventdev_pci_init,
873 : : event_dlb2_pf_name);
874 [ # # ]: 0 : if (ret) {
875 : 0 : DLB2_LOG_INFO("rte_event_pmd_pci_probe_named() failed, "
876 : : "ret=%d", ret);
877 : : }
878 : :
879 : 0 : return ret;
880 : : }
881 : :
882 : : static int
883 : 0 : event_dlb2_pci_remove(struct rte_pci_device *pci_dev)
884 : : {
885 : : int ret;
886 : :
887 : 0 : ret = rte_event_pmd_pci_remove(pci_dev, NULL);
888 : :
889 [ # # ]: 0 : if (ret) {
890 : 0 : DLB2_LOG_INFO("rte_event_pmd_pci_remove() failed, "
891 : : "ret=%d", ret);
892 : : }
893 : :
894 : 0 : return ret;
895 : :
896 : : }
897 : :
898 : : static int
899 : 0 : event_dlb2_5_pci_probe(struct rte_pci_driver *pci_drv,
900 : : struct rte_pci_device *pci_dev)
901 : : {
902 : : int ret;
903 : :
904 : 0 : ret = rte_event_pmd_pci_probe_named(pci_drv, pci_dev,
905 : : sizeof(struct dlb2_eventdev),
906 : : dlb2_eventdev_pci_init,
907 : : event_dlb2_pf_name);
908 [ # # ]: 0 : if (ret) {
909 : 0 : DLB2_LOG_INFO("rte_event_pmd_pci_probe_named() failed, "
910 : : "ret=%d", ret);
911 : : }
912 : :
913 : 0 : return ret;
914 : : }
915 : :
916 : : static int
917 : 0 : event_dlb2_5_pci_remove(struct rte_pci_device *pci_dev)
918 : : {
919 : : int ret;
920 : :
921 : 0 : ret = rte_event_pmd_pci_remove(pci_dev, NULL);
922 : :
923 [ # # ]: 0 : if (ret) {
924 : 0 : DLB2_LOG_INFO("rte_event_pmd_pci_remove() failed, "
925 : : "ret=%d", ret);
926 : : }
927 : :
928 : 0 : return ret;
929 : :
930 : : }
931 : :
932 : : static struct rte_pci_driver pci_eventdev_dlb2_pmd = {
933 : : .id_table = pci_id_dlb2_map,
934 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
935 : : .probe = event_dlb2_pci_probe,
936 : : .remove = event_dlb2_pci_remove,
937 : : };
938 : :
939 : : static struct rte_pci_driver pci_eventdev_dlb2_5_pmd = {
940 : : .id_table = pci_id_dlb2_5_map,
941 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
942 : : .probe = event_dlb2_5_pci_probe,
943 : : .remove = event_dlb2_5_pci_remove,
944 : : };
945 : :
946 : 253 : RTE_PMD_REGISTER_PCI(event_dlb2_pf, pci_eventdev_dlb2_pmd);
947 : : RTE_PMD_REGISTER_PCI_TABLE(event_dlb2_pf, pci_id_dlb2_map);
948 : :
949 : 253 : RTE_PMD_REGISTER_PCI(event_dlb2_5_pf, pci_eventdev_dlb2_5_pmd);
950 : : RTE_PMD_REGISTER_PCI_TABLE(event_dlb2_5_pf, pci_id_dlb2_5_map);
|