event/dlb: add infos get and configure
[dpdk.git] / drivers / event / dlb / pf / dlb_pf.c
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 <sys/fcntl.h>
10 #include <sys/time.h>
11 #include <errno.h>
12 #include <assert.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include <rte_debug.h>
16 #include <rte_log.h>
17 #include <rte_dev.h>
18 #include <rte_devargs.h>
19 #include <rte_mbuf.h>
20 #include <rte_ring.h>
21 #include <rte_errno.h>
22 #include <rte_kvargs.h>
23 #include <rte_malloc.h>
24 #include <rte_cycles.h>
25 #include <rte_io.h>
26 #include <rte_memory.h>
27 #include <rte_string_fns.h>
28
29 #include "../dlb_priv.h"
30 #include "../dlb_iface.h"
31 #include "../dlb_inline_fns.h"
32 #include "dlb_main.h"
33 #include "base/dlb_hw_types.h"
34 #include "base/dlb_osdep.h"
35 #include "base/dlb_resource.h"
36
37 static void
38 dlb_pf_low_level_io_init(struct dlb_eventdev *dlb __rte_unused)
39 {
40         int i;
41
42         /* Addresses will be initialized at port create */
43         for (i = 0; i < DLB_MAX_NUM_PORTS; i++) {
44                 /* First directed ports */
45
46                 /* producer port */
47                 dlb_port[i][DLB_DIR].pp_addr = NULL;
48
49                 /* popcount */
50                 dlb_port[i][DLB_DIR].ldb_popcount = NULL;
51                 dlb_port[i][DLB_DIR].dir_popcount = NULL;
52
53                 /* consumer queue */
54                 dlb_port[i][DLB_DIR].cq_base = NULL;
55                 dlb_port[i][DLB_DIR].mmaped = true;
56
57                 /* Now load balanced ports */
58
59                 /* producer port */
60                 dlb_port[i][DLB_LDB].pp_addr = NULL;
61
62                 /* popcount */
63                 dlb_port[i][DLB_LDB].ldb_popcount = NULL;
64                 dlb_port[i][DLB_LDB].dir_popcount = NULL;
65
66                 /* consumer queue */
67                 dlb_port[i][DLB_LDB].cq_base = NULL;
68                 dlb_port[i][DLB_LDB].mmaped = true;
69         }
70 }
71
72 static int
73 dlb_pf_open(struct dlb_hw_dev *handle, const char *name)
74 {
75         RTE_SET_USED(handle);
76         RTE_SET_USED(name);
77
78         return 0;
79 }
80
81 static void
82 dlb_pf_domain_close(struct dlb_eventdev *dlb)
83 {
84         struct dlb_dev *dlb_dev = (struct dlb_dev *)dlb->qm_instance.pf_dev;
85         int ret;
86
87         ret = dlb_reset_domain(&dlb_dev->hw, dlb->qm_instance.domain_id);
88         if (ret)
89                 DLB_LOG_ERR("dlb_pf_reset_domain err %d", ret);
90 }
91
92 static int
93 dlb_pf_get_device_version(struct dlb_hw_dev *handle,
94                           uint8_t *revision)
95 {
96         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
97
98         *revision = dlb_dev->revision;
99
100         return 0;
101 }
102
103 static int
104 dlb_pf_get_num_resources(struct dlb_hw_dev *handle,
105                          struct dlb_get_num_resources_args *rsrcs)
106 {
107         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
108
109         dlb_hw_get_num_resources(&dlb_dev->hw, rsrcs);
110
111         return 0;
112 }
113
114 static int
115 dlb_pf_sched_domain_create(struct dlb_hw_dev *handle,
116                            struct dlb_create_sched_domain_args *arg)
117 {
118         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
119         struct dlb_cmd_response response = {0};
120         int ret;
121
122         DLB_INFO(dev->dlb_device, "Entering %s()\n", __func__);
123
124         if (dlb_dev->domain_reset_failed) {
125                 response.status = DLB_ST_DOMAIN_RESET_FAILED;
126                 ret = -EINVAL;
127                 goto done;
128         }
129
130         ret = dlb_hw_create_sched_domain(&dlb_dev->hw, arg, &response);
131         if (ret)
132                 goto done;
133
134 done:
135
136         *(struct dlb_cmd_response *)arg->response = response;
137
138         DLB_INFO(dev->dlb_device, "Exiting %s() with ret=%d\n", __func__, ret);
139
140         return ret;
141 }
142
143 static int
144 dlb_pf_ldb_credit_pool_create(struct dlb_hw_dev *handle,
145                               struct dlb_create_ldb_pool_args *cfg)
146 {
147         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
148         struct dlb_cmd_response response = {0};
149         int ret;
150
151         DLB_INFO(dev->dlb_device, "Entering %s()\n", __func__);
152
153         ret = dlb_hw_create_ldb_pool(&dlb_dev->hw,
154                                      handle->domain_id,
155                                      cfg,
156                                      &response);
157
158         *(struct dlb_cmd_response *)cfg->response = response;
159
160         DLB_INFO(dev->dlb_device, "Exiting %s() with ret=%d\n", __func__, ret);
161
162         return ret;
163 }
164
165 static int
166 dlb_pf_dir_credit_pool_create(struct dlb_hw_dev *handle,
167                               struct dlb_create_dir_pool_args *cfg)
168 {
169         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
170         struct dlb_cmd_response response = {0};
171         int ret;
172
173         DLB_INFO(dev->dlb_device, "Entering %s()\n", __func__);
174
175         ret = dlb_hw_create_dir_pool(&dlb_dev->hw,
176                                      handle->domain_id,
177                                      cfg,
178                                      &response);
179
180         *(struct dlb_cmd_response *)cfg->response = response;
181
182         DLB_INFO(dev->dlb_device, "Exiting %s() with ret=%d\n", __func__, ret);
183
184         return ret;
185 }
186
187 static int
188 dlb_pf_get_cq_poll_mode(struct dlb_hw_dev *handle,
189                         enum dlb_cq_poll_modes *mode)
190 {
191         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
192
193         if (dlb_dev->revision >= DLB_REV_B0)
194                 *mode = DLB_CQ_POLL_MODE_SPARSE;
195         else
196                 *mode = DLB_CQ_POLL_MODE_STD;
197
198         return 0;
199 }
200
201 static void
202 dlb_pf_iface_fn_ptrs_init(void)
203 {
204         dlb_iface_low_level_io_init = dlb_pf_low_level_io_init;
205         dlb_iface_open = dlb_pf_open;
206         dlb_iface_domain_close = dlb_pf_domain_close;
207         dlb_iface_get_device_version = dlb_pf_get_device_version;
208         dlb_iface_get_num_resources = dlb_pf_get_num_resources;
209         dlb_iface_sched_domain_create = dlb_pf_sched_domain_create;
210         dlb_iface_ldb_credit_pool_create = dlb_pf_ldb_credit_pool_create;
211         dlb_iface_dir_credit_pool_create = dlb_pf_dir_credit_pool_create;
212         dlb_iface_get_cq_poll_mode = dlb_pf_get_cq_poll_mode;
213 }
214
215 /* PCI DEV HOOKS */
216 static int
217 dlb_eventdev_pci_init(struct rte_eventdev *eventdev)
218 {
219         int ret = 0;
220         struct rte_pci_device *pci_dev;
221         struct dlb_devargs dlb_args = {
222                 .socket_id = rte_socket_id(),
223                 .max_num_events = DLB_MAX_NUM_LDB_CREDITS,
224                 .num_dir_credits_override = -1,
225                 .defer_sched = 0,
226                 .num_atm_inflights = DLB_NUM_ATOMIC_INFLIGHTS_PER_QUEUE,
227         };
228         struct dlb_eventdev *dlb;
229
230         DLB_LOG_DBG("Enter with dev_id=%d socket_id=%d",
231                     eventdev->data->dev_id, eventdev->data->socket_id);
232
233         dlb_entry_points_init(eventdev);
234
235         dlb_pf_iface_fn_ptrs_init();
236
237         pci_dev = RTE_DEV_TO_PCI(eventdev->dev);
238
239         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
240                 dlb = dlb_pmd_priv(eventdev); /* rte_zmalloc_socket mem */
241
242                 /* Probe the DLB PF layer */
243                 dlb->qm_instance.pf_dev = dlb_probe(pci_dev);
244
245                 if (dlb->qm_instance.pf_dev == NULL) {
246                         DLB_LOG_ERR("DLB PF Probe failed with error %d\n",
247                                     rte_errno);
248                         ret = -rte_errno;
249                         goto dlb_probe_failed;
250                 }
251
252                 /* Were we invoked with runtime parameters? */
253                 if (pci_dev->device.devargs) {
254                         ret = dlb_parse_params(pci_dev->device.devargs->args,
255                                                pci_dev->device.devargs->name,
256                                                &dlb_args);
257                         if (ret) {
258                                 DLB_LOG_ERR("PFPMD failed to parse args ret=%d, errno=%d\n",
259                                             ret, rte_errno);
260                                 goto dlb_probe_failed;
261                         }
262                 }
263
264                 ret = dlb_primary_eventdev_probe(eventdev,
265                                                  EVDEV_DLB_NAME_PMD_STR,
266                                                  &dlb_args);
267         } else {
268                 ret = dlb_secondary_eventdev_probe(eventdev,
269                                                    EVDEV_DLB_NAME_PMD_STR);
270         }
271         if (ret)
272                 goto dlb_probe_failed;
273
274         DLB_LOG_INFO("DLB PF Probe success\n");
275
276         return 0;
277
278 dlb_probe_failed:
279
280         DLB_LOG_INFO("DLB PF Probe failed, ret=%d\n", ret);
281
282         return ret;
283 }
284
285 #define EVENTDEV_INTEL_VENDOR_ID 0x8086
286
287 static const struct rte_pci_id pci_id_dlb_map[] = {
288         {
289                 RTE_PCI_DEVICE(EVENTDEV_INTEL_VENDOR_ID,
290                                DLB_PF_DEV_ID)
291         },
292         {
293                 .vendor_id = 0,
294         },
295 };
296
297 static int
298 event_dlb_pci_probe(struct rte_pci_driver *pci_drv,
299                     struct rte_pci_device *pci_dev)
300 {
301         return rte_event_pmd_pci_probe_named(pci_drv, pci_dev,
302                 sizeof(struct dlb_eventdev), dlb_eventdev_pci_init,
303                 EVDEV_DLB_NAME_PMD_STR);
304 }
305
306 static int
307 event_dlb_pci_remove(struct rte_pci_device *pci_dev)
308 {
309         return rte_event_pmd_pci_remove(pci_dev, NULL);
310 }
311
312 static struct rte_pci_driver pci_eventdev_dlb_pmd = {
313         .id_table = pci_id_dlb_map,
314         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
315         .probe = event_dlb_pci_probe,
316         .remove = event_dlb_pci_remove,
317 };
318
319 RTE_PMD_REGISTER_PCI(event_dlb_pf, pci_eventdev_dlb_pmd);
320 RTE_PMD_REGISTER_PCI_TABLE(event_dlb_pf, pci_id_dlb_map);