event/dlb: add probe-time hardware init
[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 int
82 dlb_pf_get_device_version(struct dlb_hw_dev *handle,
83                           uint8_t *revision)
84 {
85         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
86
87         *revision = dlb_dev->revision;
88
89         return 0;
90 }
91
92 static int
93 dlb_pf_get_num_resources(struct dlb_hw_dev *handle,
94                          struct dlb_get_num_resources_args *rsrcs)
95 {
96         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
97
98         dlb_hw_get_num_resources(&dlb_dev->hw, rsrcs);
99
100         return 0;
101 }
102
103 static int
104 dlb_pf_get_cq_poll_mode(struct dlb_hw_dev *handle,
105                         enum dlb_cq_poll_modes *mode)
106 {
107         struct dlb_dev *dlb_dev = (struct dlb_dev *)handle->pf_dev;
108
109         if (dlb_dev->revision >= DLB_REV_B0)
110                 *mode = DLB_CQ_POLL_MODE_SPARSE;
111         else
112                 *mode = DLB_CQ_POLL_MODE_STD;
113
114         return 0;
115 }
116
117 static void
118 dlb_pf_iface_fn_ptrs_init(void)
119 {
120         dlb_iface_low_level_io_init = dlb_pf_low_level_io_init;
121         dlb_iface_open = dlb_pf_open;
122         dlb_iface_get_device_version = dlb_pf_get_device_version;
123         dlb_iface_get_num_resources = dlb_pf_get_num_resources;
124         dlb_iface_get_cq_poll_mode = dlb_pf_get_cq_poll_mode;
125 }
126
127 /* PCI DEV HOOKS */
128 static int
129 dlb_eventdev_pci_init(struct rte_eventdev *eventdev)
130 {
131         int ret = 0;
132         struct rte_pci_device *pci_dev;
133         struct dlb_devargs dlb_args = {
134                 .socket_id = rte_socket_id(),
135                 .max_num_events = DLB_MAX_NUM_LDB_CREDITS,
136                 .num_dir_credits_override = -1,
137                 .defer_sched = 0,
138                 .num_atm_inflights = DLB_NUM_ATOMIC_INFLIGHTS_PER_QUEUE,
139         };
140         struct dlb_eventdev *dlb;
141
142         DLB_LOG_DBG("Enter with dev_id=%d socket_id=%d",
143                     eventdev->data->dev_id, eventdev->data->socket_id);
144
145         dlb_entry_points_init(eventdev);
146
147         dlb_pf_iface_fn_ptrs_init();
148
149         pci_dev = RTE_DEV_TO_PCI(eventdev->dev);
150
151         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
152                 dlb = dlb_pmd_priv(eventdev); /* rte_zmalloc_socket mem */
153
154                 /* Probe the DLB PF layer */
155                 dlb->qm_instance.pf_dev = dlb_probe(pci_dev);
156
157                 if (dlb->qm_instance.pf_dev == NULL) {
158                         DLB_LOG_ERR("DLB PF Probe failed with error %d\n",
159                                     rte_errno);
160                         ret = -rte_errno;
161                         goto dlb_probe_failed;
162                 }
163
164                 /* Were we invoked with runtime parameters? */
165                 if (pci_dev->device.devargs) {
166                         ret = dlb_parse_params(pci_dev->device.devargs->args,
167                                                pci_dev->device.devargs->name,
168                                                &dlb_args);
169                         if (ret) {
170                                 DLB_LOG_ERR("PFPMD failed to parse args ret=%d, errno=%d\n",
171                                             ret, rte_errno);
172                                 goto dlb_probe_failed;
173                         }
174                 }
175
176                 ret = dlb_primary_eventdev_probe(eventdev,
177                                                  EVDEV_DLB_NAME_PMD_STR,
178                                                  &dlb_args);
179         } else {
180                 ret = dlb_secondary_eventdev_probe(eventdev,
181                                                    EVDEV_DLB_NAME_PMD_STR);
182         }
183         if (ret)
184                 goto dlb_probe_failed;
185
186         DLB_LOG_INFO("DLB PF Probe success\n");
187
188         return 0;
189
190 dlb_probe_failed:
191
192         DLB_LOG_INFO("DLB PF Probe failed, ret=%d\n", ret);
193
194         return ret;
195 }
196
197 #define EVENTDEV_INTEL_VENDOR_ID 0x8086
198
199 static const struct rte_pci_id pci_id_dlb_map[] = {
200         {
201                 RTE_PCI_DEVICE(EVENTDEV_INTEL_VENDOR_ID,
202                                DLB_PF_DEV_ID)
203         },
204         {
205                 .vendor_id = 0,
206         },
207 };
208
209 static int
210 event_dlb_pci_probe(struct rte_pci_driver *pci_drv,
211                     struct rte_pci_device *pci_dev)
212 {
213         return rte_event_pmd_pci_probe_named(pci_drv, pci_dev,
214                 sizeof(struct dlb_eventdev), dlb_eventdev_pci_init,
215                 EVDEV_DLB_NAME_PMD_STR);
216 }
217
218 static int
219 event_dlb_pci_remove(struct rte_pci_device *pci_dev)
220 {
221         return rte_event_pmd_pci_remove(pci_dev, NULL);
222 }
223
224 static struct rte_pci_driver pci_eventdev_dlb_pmd = {
225         .id_table = pci_id_dlb_map,
226         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
227         .probe = event_dlb_pci_probe,
228         .remove = event_dlb_pci_remove,
229 };
230
231 RTE_PMD_REGISTER_PCI(event_dlb_pf, pci_eventdev_dlb_pmd);
232 RTE_PMD_REGISTER_PCI_TABLE(event_dlb_pf, pci_id_dlb_map);