9310f7265ae126b416a9f711c4d15162e070ea1f
[dpdk.git] / drivers / event / dlb2 / pf / dlb2_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_pci.h>
27 #include <rte_bus_pci.h>
28 #include <rte_eventdev.h>
29 #include <rte_eventdev_pmd.h>
30 #include <rte_eventdev_pmd_pci.h>
31 #include <rte_memory.h>
32 #include <rte_string_fns.h>
33
34 #include "../dlb2_priv.h"
35 #include "../dlb2_iface.h"
36 #include "../dlb2_inline_fns.h"
37 #include "dlb2_main.h"
38 #include "base/dlb2_hw_types.h"
39 #include "base/dlb2_osdep.h"
40 #include "base/dlb2_resource.h"
41
42 static const char *event_dlb2_pf_name = RTE_STR(EVDEV_DLB2_NAME_PMD);
43
44 static void
45 dlb2_pf_low_level_io_init(void)
46 {
47         int i;
48         /* Addresses will be initialized at port create */
49         for (i = 0; i < DLB2_MAX_NUM_PORTS; i++) {
50                 /* First directed ports */
51                 dlb2_port[i][DLB2_DIR_PORT].pp_addr = NULL;
52                 dlb2_port[i][DLB2_DIR_PORT].cq_base = NULL;
53                 dlb2_port[i][DLB2_DIR_PORT].mmaped = true;
54
55                 /* Now load balanced ports */
56                 dlb2_port[i][DLB2_LDB_PORT].pp_addr = NULL;
57                 dlb2_port[i][DLB2_LDB_PORT].cq_base = NULL;
58                 dlb2_port[i][DLB2_LDB_PORT].mmaped = true;
59         }
60 }
61
62 static int
63 dlb2_pf_open(struct dlb2_hw_dev *handle, const char *name)
64 {
65         RTE_SET_USED(handle);
66         RTE_SET_USED(name);
67
68         return 0;
69 }
70
71 static int
72 dlb2_pf_get_device_version(struct dlb2_hw_dev *handle,
73                            uint8_t *revision)
74 {
75         struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
76
77         *revision = dlb2_dev->revision;
78
79         return 0;
80 }
81
82 static void
83 dlb2_pf_hardware_init(struct dlb2_hw_dev *handle)
84 {
85         struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
86
87         dlb2_hw_enable_sparse_ldb_cq_mode(&dlb2_dev->hw);
88         dlb2_hw_enable_sparse_dir_cq_mode(&dlb2_dev->hw);
89 }
90
91 static int
92 dlb2_pf_get_num_resources(struct dlb2_hw_dev *handle,
93                           struct dlb2_get_num_resources_args *rsrcs)
94 {
95         struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
96
97         return dlb2_hw_get_num_resources(&dlb2_dev->hw, rsrcs, false, 0);
98 }
99
100 static int
101 dlb2_pf_get_cq_poll_mode(struct dlb2_hw_dev *handle,
102                          enum dlb2_cq_poll_modes *mode)
103 {
104         RTE_SET_USED(handle);
105
106         *mode = DLB2_CQ_POLL_MODE_SPARSE;
107
108         return 0;
109 }
110
111 static int
112 dlb2_pf_sched_domain_create(struct dlb2_hw_dev *handle,
113                             struct dlb2_create_sched_domain_args *arg)
114 {
115         struct dlb2_dev *dlb2_dev = (struct dlb2_dev *)handle->pf_dev;
116         struct dlb2_cmd_response response = {0};
117         int ret;
118
119         DLB2_INFO(dev->dlb2_device, "Entering %s()\n", __func__);
120
121         if (dlb2_dev->domain_reset_failed) {
122                 response.status = DLB2_ST_DOMAIN_RESET_FAILED;
123                 ret = -EINVAL;
124                 goto done;
125         }
126
127         ret = dlb2_pf_create_sched_domain(&dlb2_dev->hw, arg, &response);
128         if (ret)
129                 goto done;
130
131 done:
132
133         arg->response = response;
134
135         DLB2_INFO(dev->dlb2_device, "Exiting %s() with ret=%d\n",
136                   __func__, ret);
137
138         return ret;
139 }
140
141 static void
142 dlb2_pf_domain_reset(struct dlb2_eventdev *dlb2)
143 {
144         struct dlb2_dev *dlb2_dev;
145         int ret;
146
147         dlb2_dev = (struct dlb2_dev *)dlb2->qm_instance.pf_dev;
148         ret = dlb2_pf_reset_domain(&dlb2_dev->hw, dlb2->qm_instance.domain_id);
149         if (ret)
150                 DLB2_LOG_ERR("dlb2_pf_reset_domain err %d", ret);
151 }
152
153 static void
154 dlb2_pf_iface_fn_ptrs_init(void)
155 {
156         dlb2_iface_low_level_io_init = dlb2_pf_low_level_io_init;
157         dlb2_iface_open = dlb2_pf_open;
158         dlb2_iface_domain_reset = dlb2_pf_domain_reset;
159         dlb2_iface_get_device_version = dlb2_pf_get_device_version;
160         dlb2_iface_hardware_init = dlb2_pf_hardware_init;
161         dlb2_iface_get_num_resources = dlb2_pf_get_num_resources;
162         dlb2_iface_get_cq_poll_mode = dlb2_pf_get_cq_poll_mode;
163         dlb2_iface_sched_domain_create = dlb2_pf_sched_domain_create;
164 }
165
166 /* PCI DEV HOOKS */
167 static int
168 dlb2_eventdev_pci_init(struct rte_eventdev *eventdev)
169 {
170         int ret = 0;
171         struct rte_pci_device *pci_dev;
172         struct dlb2_devargs dlb2_args = {
173                 .socket_id = rte_socket_id(),
174                 .max_num_events = DLB2_MAX_NUM_LDB_CREDITS,
175                 .num_dir_credits_override = -1,
176                 .qid_depth_thresholds = { {0} },
177                 .cos_id = DLB2_COS_DEFAULT
178         };
179         struct dlb2_eventdev *dlb2;
180
181         DLB2_LOG_DBG("Enter with dev_id=%d socket_id=%d",
182                      eventdev->data->dev_id, eventdev->data->socket_id);
183
184         dlb2_pf_iface_fn_ptrs_init();
185
186         pci_dev = RTE_DEV_TO_PCI(eventdev->dev);
187
188         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
189                 dlb2 = dlb2_pmd_priv(eventdev); /* rte_zmalloc_socket mem */
190
191                 /* Probe the DLB2 PF layer */
192                 dlb2->qm_instance.pf_dev = dlb2_probe(pci_dev);
193
194                 if (dlb2->qm_instance.pf_dev == NULL) {
195                         DLB2_LOG_ERR("DLB2 PF Probe failed with error %d\n",
196                                      rte_errno);
197                         ret = -rte_errno;
198                         goto dlb2_probe_failed;
199                 }
200
201                 /* Were we invoked with runtime parameters? */
202                 if (pci_dev->device.devargs) {
203                         ret = dlb2_parse_params(pci_dev->device.devargs->args,
204                                                 pci_dev->device.devargs->name,
205                                                 &dlb2_args);
206                         if (ret) {
207                                 DLB2_LOG_ERR("PFPMD failed to parse args ret=%d, errno=%d\n",
208                                              ret, rte_errno);
209                                 goto dlb2_probe_failed;
210                         }
211                 }
212
213                 ret = dlb2_primary_eventdev_probe(eventdev,
214                                                   event_dlb2_pf_name,
215                                                   &dlb2_args);
216         } else {
217                 ret = dlb2_secondary_eventdev_probe(eventdev,
218                                                     event_dlb2_pf_name);
219         }
220         if (ret)
221                 goto dlb2_probe_failed;
222
223         DLB2_LOG_INFO("DLB2 PF Probe success\n");
224
225         return 0;
226
227 dlb2_probe_failed:
228
229         DLB2_LOG_INFO("DLB2 PF Probe failed, ret=%d\n", ret);
230
231         return ret;
232 }
233
234 #define EVENTDEV_INTEL_VENDOR_ID 0x8086
235
236 static const struct rte_pci_id pci_id_dlb2_map[] = {
237         {
238                 RTE_PCI_DEVICE(EVENTDEV_INTEL_VENDOR_ID,
239                                PCI_DEVICE_ID_INTEL_DLB2_PF)
240         },
241         {
242                 .vendor_id = 0,
243         },
244 };
245
246 static int
247 event_dlb2_pci_probe(struct rte_pci_driver *pci_drv,
248                      struct rte_pci_device *pci_dev)
249 {
250         int ret;
251
252         ret = rte_event_pmd_pci_probe_named(pci_drv, pci_dev,
253                                              sizeof(struct dlb2_eventdev),
254                                              dlb2_eventdev_pci_init,
255                                              event_dlb2_pf_name);
256         if (ret) {
257                 DLB2_LOG_INFO("rte_event_pmd_pci_probe_named() failed, "
258                                 "ret=%d\n", ret);
259         }
260
261         return ret;
262 }
263
264 static int
265 event_dlb2_pci_remove(struct rte_pci_device *pci_dev)
266 {
267         int ret;
268
269         ret = rte_event_pmd_pci_remove(pci_dev, NULL);
270
271         if (ret) {
272                 DLB2_LOG_INFO("rte_event_pmd_pci_remove() failed, "
273                                 "ret=%d\n", ret);
274         }
275
276         return ret;
277
278 }
279
280 static struct rte_pci_driver pci_eventdev_dlb2_pmd = {
281         .id_table = pci_id_dlb2_map,
282         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
283         .probe = event_dlb2_pci_probe,
284         .remove = event_dlb2_pci_remove,
285 };
286
287 RTE_PMD_REGISTER_PCI(event_dlb2_pf, pci_eventdev_dlb2_pmd);
288 RTE_PMD_REGISTER_PCI_TABLE(event_dlb2_pf, pci_id_dlb2_map);