b8c74633b146088c7fea940ce78b28f702bc801d
[dpdk.git] / drivers / event / cnxk / cn9k_eventdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "cnxk_eventdev.h"
6
7 #define CN9K_DUAL_WS_NB_WS          2
8 #define CN9K_DUAL_WS_PAIR_ID(x, id) (((x)*CN9K_DUAL_WS_NB_WS) + id)
9
10 static void
11 cn9k_init_hws_ops(struct cn9k_sso_hws_state *ws, uintptr_t base)
12 {
13         ws->tag_op = base + SSOW_LF_GWS_TAG;
14         ws->wqp_op = base + SSOW_LF_GWS_WQP;
15         ws->getwrk_op = base + SSOW_LF_GWS_OP_GET_WORK0;
16         ws->swtag_flush_op = base + SSOW_LF_GWS_OP_SWTAG_FLUSH;
17         ws->swtag_norm_op = base + SSOW_LF_GWS_OP_SWTAG_NORM;
18         ws->swtag_desched_op = base + SSOW_LF_GWS_OP_SWTAG_DESCHED;
19 }
20
21 static void
22 cn9k_sso_hws_setup(void *arg, void *hws, uintptr_t *grps_base)
23 {
24         struct cnxk_sso_evdev *dev = arg;
25         struct cn9k_sso_hws_dual *dws;
26         struct cn9k_sso_hws *ws;
27         uint64_t val;
28
29         /* Set get_work tmo for HWS */
30         val = NSEC2USEC(dev->deq_tmo_ns) - 1;
31         if (dev->dual_ws) {
32                 dws = hws;
33                 rte_memcpy(dws->grps_base, grps_base,
34                            sizeof(uintptr_t) * CNXK_SSO_MAX_HWGRP);
35                 dws->fc_mem = dev->fc_mem;
36                 dws->xaq_lmt = dev->xaq_lmt;
37
38                 plt_write64(val, dws->base[0] + SSOW_LF_GWS_NW_TIM);
39                 plt_write64(val, dws->base[1] + SSOW_LF_GWS_NW_TIM);
40         } else {
41                 ws = hws;
42                 rte_memcpy(ws->grps_base, grps_base,
43                            sizeof(uintptr_t) * CNXK_SSO_MAX_HWGRP);
44                 ws->fc_mem = dev->fc_mem;
45                 ws->xaq_lmt = dev->xaq_lmt;
46
47                 plt_write64(val, ws->base + SSOW_LF_GWS_NW_TIM);
48         }
49 }
50
51 static void
52 cn9k_sso_hws_release(void *arg, void *hws)
53 {
54         struct cnxk_sso_evdev *dev = arg;
55         struct cn9k_sso_hws_dual *dws;
56         struct cn9k_sso_hws *ws;
57
58         if (dev->dual_ws) {
59                 dws = hws;
60                 memset(dws, 0, sizeof(*dws));
61         } else {
62                 ws = hws;
63                 memset(ws, 0, sizeof(*ws));
64         }
65 }
66
67 static void
68 cn9k_sso_set_rsrc(void *arg)
69 {
70         struct cnxk_sso_evdev *dev = arg;
71
72         if (dev->dual_ws)
73                 dev->max_event_ports = dev->sso.max_hws / CN9K_DUAL_WS_NB_WS;
74         else
75                 dev->max_event_ports = dev->sso.max_hws;
76         dev->max_event_queues =
77                 dev->sso.max_hwgrp > RTE_EVENT_MAX_QUEUES_PER_DEV ?
78                               RTE_EVENT_MAX_QUEUES_PER_DEV :
79                               dev->sso.max_hwgrp;
80 }
81
82 static int
83 cn9k_sso_rsrc_init(void *arg, uint8_t hws, uint8_t hwgrp)
84 {
85         struct cnxk_sso_evdev *dev = arg;
86
87         if (dev->dual_ws)
88                 hws = hws * CN9K_DUAL_WS_NB_WS;
89
90         return roc_sso_rsrc_init(&dev->sso, hws, hwgrp);
91 }
92
93 static void *
94 cn9k_sso_init_hws_mem(void *arg, uint8_t port_id)
95 {
96         struct cnxk_sso_evdev *dev = arg;
97         struct cn9k_sso_hws_dual *dws;
98         struct cn9k_sso_hws *ws;
99         void *data;
100
101         if (dev->dual_ws) {
102                 dws = rte_zmalloc("cn9k_dual_ws",
103                                   sizeof(struct cn9k_sso_hws_dual) +
104                                           RTE_CACHE_LINE_SIZE,
105                                   RTE_CACHE_LINE_SIZE);
106                 if (dws == NULL) {
107                         plt_err("Failed to alloc memory for port=%d", port_id);
108                         return NULL;
109                 }
110
111                 dws = RTE_PTR_ADD(dws, sizeof(struct cnxk_sso_hws_cookie));
112                 dws->base[0] = roc_sso_hws_base_get(
113                         &dev->sso, CN9K_DUAL_WS_PAIR_ID(port_id, 0));
114                 dws->base[1] = roc_sso_hws_base_get(
115                         &dev->sso, CN9K_DUAL_WS_PAIR_ID(port_id, 1));
116                 cn9k_init_hws_ops(&dws->ws_state[0], dws->base[0]);
117                 cn9k_init_hws_ops(&dws->ws_state[1], dws->base[1]);
118                 dws->hws_id = port_id;
119                 dws->swtag_req = 0;
120                 dws->vws = 0;
121
122                 data = dws;
123         } else {
124                 /* Allocate event port memory */
125                 ws = rte_zmalloc("cn9k_ws",
126                                  sizeof(struct cn9k_sso_hws) +
127                                          RTE_CACHE_LINE_SIZE,
128                                  RTE_CACHE_LINE_SIZE);
129                 if (ws == NULL) {
130                         plt_err("Failed to alloc memory for port=%d", port_id);
131                         return NULL;
132                 }
133
134                 /* First cache line is reserved for cookie */
135                 ws = RTE_PTR_ADD(ws, sizeof(struct cnxk_sso_hws_cookie));
136                 ws->base = roc_sso_hws_base_get(&dev->sso, port_id);
137                 cn9k_init_hws_ops((struct cn9k_sso_hws_state *)ws, ws->base);
138                 ws->hws_id = port_id;
139                 ws->swtag_req = 0;
140
141                 data = ws;
142         }
143
144         return data;
145 }
146
147 static void
148 cn9k_sso_info_get(struct rte_eventdev *event_dev,
149                   struct rte_event_dev_info *dev_info)
150 {
151         struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
152
153         dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN9K_PMD);
154         cnxk_sso_info_get(dev, dev_info);
155 }
156
157 static int
158 cn9k_sso_dev_configure(const struct rte_eventdev *event_dev)
159 {
160         struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
161         int rc;
162
163         rc = cnxk_sso_dev_validate(event_dev);
164         if (rc < 0) {
165                 plt_err("Invalid event device configuration");
166                 return -EINVAL;
167         }
168
169         roc_sso_rsrc_fini(&dev->sso);
170
171         rc = cn9k_sso_rsrc_init(dev, dev->nb_event_ports, dev->nb_event_queues);
172         if (rc < 0) {
173                 plt_err("Failed to initialize SSO resources");
174                 return -ENODEV;
175         }
176
177         rc = cnxk_sso_xaq_allocate(dev);
178         if (rc < 0)
179                 goto cnxk_rsrc_fini;
180
181         rc = cnxk_setup_event_ports(event_dev, cn9k_sso_init_hws_mem,
182                                     cn9k_sso_hws_setup);
183         if (rc < 0)
184                 goto cnxk_rsrc_fini;
185
186         return 0;
187 cnxk_rsrc_fini:
188         roc_sso_rsrc_fini(&dev->sso);
189         dev->nb_event_ports = 0;
190         return rc;
191 }
192
193 static int
194 cn9k_sso_port_setup(struct rte_eventdev *event_dev, uint8_t port_id,
195                     const struct rte_event_port_conf *port_conf)
196 {
197
198         RTE_SET_USED(port_conf);
199         return cnxk_sso_port_setup(event_dev, port_id, cn9k_sso_hws_setup);
200 }
201
202 static void
203 cn9k_sso_port_release(void *port)
204 {
205         struct cnxk_sso_hws_cookie *gws_cookie = cnxk_sso_hws_get_cookie(port);
206         struct cnxk_sso_evdev *dev;
207
208         if (port == NULL)
209                 return;
210
211         dev = cnxk_sso_pmd_priv(gws_cookie->event_dev);
212         if (!gws_cookie->configured)
213                 goto free;
214
215         cn9k_sso_hws_release(dev, port);
216         memset(gws_cookie, 0, sizeof(*gws_cookie));
217 free:
218         rte_free(gws_cookie);
219 }
220
221 static struct rte_eventdev_ops cn9k_sso_dev_ops = {
222         .dev_infos_get = cn9k_sso_info_get,
223         .dev_configure = cn9k_sso_dev_configure,
224         .queue_def_conf = cnxk_sso_queue_def_conf,
225         .queue_setup = cnxk_sso_queue_setup,
226         .queue_release = cnxk_sso_queue_release,
227         .port_def_conf = cnxk_sso_port_def_conf,
228         .port_setup = cn9k_sso_port_setup,
229         .port_release = cn9k_sso_port_release,
230 };
231
232 static int
233 cn9k_sso_init(struct rte_eventdev *event_dev)
234 {
235         struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
236         int rc;
237
238         if (RTE_CACHE_LINE_SIZE != 128) {
239                 plt_err("Driver not compiled for CN9K");
240                 return -EFAULT;
241         }
242
243         rc = roc_plt_init();
244         if (rc < 0) {
245                 plt_err("Failed to initialize platform model");
246                 return rc;
247         }
248
249         event_dev->dev_ops = &cn9k_sso_dev_ops;
250         /* For secondary processes, the primary has done all the work */
251         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
252                 return 0;
253
254         rc = cnxk_sso_init(event_dev);
255         if (rc < 0)
256                 return rc;
257
258         cn9k_sso_set_rsrc(cnxk_sso_pmd_priv(event_dev));
259         if (!dev->max_event_ports || !dev->max_event_queues) {
260                 plt_err("Not enough eventdev resource queues=%d ports=%d",
261                         dev->max_event_queues, dev->max_event_ports);
262                 cnxk_sso_fini(event_dev);
263                 return -ENODEV;
264         }
265
266         plt_sso_dbg("Initializing %s max_queues=%d max_ports=%d",
267                     event_dev->data->name, dev->max_event_queues,
268                     dev->max_event_ports);
269
270         return 0;
271 }
272
273 static int
274 cn9k_sso_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
275 {
276         return rte_event_pmd_pci_probe(
277                 pci_drv, pci_dev, sizeof(struct cnxk_sso_evdev), cn9k_sso_init);
278 }
279
280 static const struct rte_pci_id cn9k_pci_sso_map[] = {
281         {
282                 .vendor_id = 0,
283         },
284 };
285
286 static struct rte_pci_driver cn9k_pci_sso = {
287         .id_table = cn9k_pci_sso_map,
288         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
289         .probe = cn9k_sso_probe,
290         .remove = cnxk_sso_remove,
291 };
292
293 RTE_PMD_REGISTER_PCI(event_cn9k, cn9k_pci_sso);
294 RTE_PMD_REGISTER_PCI_TABLE(event_cn9k, cn9k_pci_sso_map);
295 RTE_PMD_REGISTER_KMOD_DEP(event_cn9k, "vfio-pci");
296 RTE_PMD_REGISTER_PARAM_STRING(event_cn9k, CNXK_SSO_XAE_CNT "=<int>"
297                               CNXK_SSO_GGRP_QOS "=<string>");