raw/ntb: introduce NTB raw device driver
[dpdk.git] / drivers / raw / ntb / ntb.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation.
3  */
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <errno.h>
8
9 #include <rte_common.h>
10 #include <rte_lcore.h>
11 #include <rte_cycles.h>
12 #include <rte_eal.h>
13 #include <rte_log.h>
14 #include <rte_pci.h>
15 #include <rte_bus_pci.h>
16 #include <rte_memzone.h>
17 #include <rte_memcpy.h>
18 #include <rte_rawdev.h>
19 #include <rte_rawdev_pmd.h>
20
21 #include "ntb.h"
22
23 int ntb_logtype;
24
25 static const struct rte_pci_id pci_id_ntb_map[] = {
26         { .vendor_id = 0, /* sentinel */ },
27 };
28
29 static void
30 ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
31                    uint16_t queue_id __rte_unused,
32                    rte_rawdev_obj_t queue_conf __rte_unused)
33 {
34 }
35
36 static int
37 ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
38                 uint16_t queue_id __rte_unused,
39                 rte_rawdev_obj_t queue_conf __rte_unused)
40 {
41         return 0;
42 }
43
44 static int
45 ntb_queue_release(struct rte_rawdev *dev __rte_unused,
46                   uint16_t queue_id __rte_unused)
47 {
48         return 0;
49 }
50
51 static uint16_t
52 ntb_queue_count(struct rte_rawdev *dev)
53 {
54         struct ntb_hw *hw = dev->dev_private;
55         return hw->queue_pairs;
56 }
57
58 static int
59 ntb_enqueue_bufs(struct rte_rawdev *dev,
60                  struct rte_rawdev_buf **buffers,
61                  unsigned int count,
62                  rte_rawdev_obj_t context)
63 {
64         RTE_SET_USED(dev);
65         RTE_SET_USED(buffers);
66         RTE_SET_USED(count);
67         RTE_SET_USED(context);
68
69         return 0;
70 }
71
72 static int
73 ntb_dequeue_bufs(struct rte_rawdev *dev,
74                  struct rte_rawdev_buf **buffers,
75                  unsigned int count,
76                  rte_rawdev_obj_t context)
77 {
78         RTE_SET_USED(dev);
79         RTE_SET_USED(buffers);
80         RTE_SET_USED(count);
81         RTE_SET_USED(context);
82
83         return 0;
84 }
85
86 static void
87 ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
88 {
89         struct ntb_hw *hw = dev->dev_private;
90         struct ntb_attr *ntb_attrs = dev_info;
91
92         strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
93         switch (hw->topo) {
94         case NTB_TOPO_B2B_DSD:
95                 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
96                         NTB_ATTR_VAL_LEN);
97                 break;
98         case NTB_TOPO_B2B_USD:
99                 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
100                         NTB_ATTR_VAL_LEN);
101                 break;
102         default:
103                 strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
104                         NTB_ATTR_VAL_LEN);
105         }
106
107         strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
108                 NTB_ATTR_NAME_LEN);
109         snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
110                  "%d", hw->link_status);
111
112         strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
113                 NTB_ATTR_NAME_LEN);
114         snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
115                  "%d", hw->link_speed);
116
117         strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
118                 NTB_ATTR_NAME_LEN);
119         snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
120                  "%d", hw->link_width);
121
122         strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
123                 NTB_ATTR_NAME_LEN);
124         snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
125                  "%d", hw->mw_cnt);
126
127         strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
128                 NTB_ATTR_NAME_LEN);
129         snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
130                  "%d", hw->db_cnt);
131
132         strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
133                 NTB_ATTR_NAME_LEN);
134         snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
135                  "%d", hw->spad_cnt);
136 }
137
138 static int
139 ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
140                   rte_rawdev_obj_t config __rte_unused)
141 {
142         return 0;
143 }
144
145 static int
146 ntb_dev_start(struct rte_rawdev *dev)
147 {
148         /* TODO: init queues and start queues. */
149         dev->started = 1;
150
151         return 0;
152 }
153
154 static void
155 ntb_dev_stop(struct rte_rawdev *dev)
156 {
157         /* TODO: stop rx/tx queues. */
158         dev->started = 0;
159 }
160
161 static int
162 ntb_dev_close(struct rte_rawdev *dev)
163 {
164         int ret = 0;
165
166         if (dev->started)
167                 ntb_dev_stop(dev);
168
169         /* TODO: free queues. */
170
171         return ret;
172 }
173
174 static int
175 ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
176 {
177         return 0;
178 }
179
180 static int
181 ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
182                                  uint64_t attr_value)
183 {
184         struct ntb_hw *hw = dev->dev_private;
185         int index = 0;
186
187         if (dev == NULL || attr_name == NULL) {
188                 NTB_LOG(ERR, "Invalid arguments for setting attributes");
189                 return -EINVAL;
190         }
191
192         if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
193                 if (hw->ntb_ops->spad_write == NULL)
194                         return -ENOTSUP;
195                 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
196                 (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
197                                            1, attr_value);
198                 NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
199                         attr_name, attr_value);
200                 return 0;
201         }
202
203         /* Attribute not found. */
204         NTB_LOG(ERR, "Attribute not found.");
205         return -EINVAL;
206 }
207
208 static int
209 ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
210                                  uint64_t *attr_value)
211 {
212         struct ntb_hw *hw = dev->dev_private;
213         int index = 0;
214
215         if (dev == NULL || attr_name == NULL || attr_value == NULL) {
216                 NTB_LOG(ERR, "Invalid arguments for getting attributes");
217                 return -EINVAL;
218         }
219
220         if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
221                 *attr_value = hw->topo;
222                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
223                         attr_name, *attr_value);
224                 return 0;
225         }
226
227         if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
228                 *attr_value = hw->link_status;
229                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
230                         attr_name, *attr_value);
231                 return 0;
232         }
233
234         if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
235                 *attr_value = hw->link_speed;
236                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
237                         attr_name, *attr_value);
238                 return 0;
239         }
240
241         if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
242                 *attr_value = hw->link_width;
243                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
244                         attr_name, *attr_value);
245                 return 0;
246         }
247
248         if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
249                 *attr_value = hw->mw_cnt;
250                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
251                         attr_name, *attr_value);
252                 return 0;
253         }
254
255         if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
256                 *attr_value = hw->db_cnt;
257                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
258                         attr_name, *attr_value);
259                 return 0;
260         }
261
262         if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
263                 *attr_value = hw->spad_cnt;
264                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
265                         attr_name, *attr_value);
266                 return 0;
267         }
268
269         if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
270                 if (hw->ntb_ops->spad_read == NULL)
271                         return -ENOTSUP;
272                 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
273                 *attr_value = (*hw->ntb_ops->spad_read)(dev,
274                                 hw->spad_user_list[index], 0);
275                 NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
276                         attr_name, *attr_value);
277                 return 0;
278         }
279
280         /* Attribute not found. */
281         NTB_LOG(ERR, "Attribute not found.");
282         return -EINVAL;
283 }
284
285 static int
286 ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
287                const unsigned int ids[] __rte_unused,
288                uint64_t values[] __rte_unused,
289                unsigned int n __rte_unused)
290 {
291         return 0;
292 }
293
294 static int
295 ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
296                      struct rte_rawdev_xstats_name *xstats_names __rte_unused,
297                      unsigned int size __rte_unused)
298 {
299         return 0;
300 }
301
302 static uint64_t
303 ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
304                        const char *name __rte_unused,
305                        unsigned int *id __rte_unused)
306 {
307         return 0;
308 }
309
310 static int
311 ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
312                  const uint32_t ids[] __rte_unused,
313                  uint32_t nb_ids __rte_unused)
314 {
315         return 0;
316 }
317
318 static const struct rte_rawdev_ops ntb_ops = {
319         .dev_info_get         = ntb_dev_info_get,
320         .dev_configure        = ntb_dev_configure,
321         .dev_start            = ntb_dev_start,
322         .dev_stop             = ntb_dev_stop,
323         .dev_close            = ntb_dev_close,
324         .dev_reset            = ntb_dev_reset,
325
326         .queue_def_conf       = ntb_queue_conf_get,
327         .queue_setup          = ntb_queue_setup,
328         .queue_release        = ntb_queue_release,
329         .queue_count          = ntb_queue_count,
330
331         .enqueue_bufs         = ntb_enqueue_bufs,
332         .dequeue_bufs         = ntb_dequeue_bufs,
333
334         .attr_get             = ntb_attr_get,
335         .attr_set             = ntb_attr_set,
336
337         .xstats_get           = ntb_xstats_get,
338         .xstats_get_names     = ntb_xstats_get_names,
339         .xstats_get_by_name   = ntb_xstats_get_by_name,
340         .xstats_reset         = ntb_xstats_reset,
341 };
342
343 static int
344 ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
345 {
346         struct ntb_hw *hw = dev->dev_private;
347         int ret;
348
349         hw->pci_dev = pci_dev;
350         hw->peer_dev_up = 0;
351         hw->link_status = NTB_LINK_DOWN;
352         hw->link_speed = NTB_SPEED_NONE;
353         hw->link_width = NTB_WIDTH_NONE;
354
355         switch (pci_dev->id.device_id) {
356         default:
357                 NTB_LOG(ERR, "Not supported device.");
358                 return -EINVAL;
359         }
360
361         if (hw->ntb_ops->ntb_dev_init == NULL)
362                 return -ENOTSUP;
363         ret = (*hw->ntb_ops->ntb_dev_init)(dev);
364         if (ret) {
365                 NTB_LOG(ERR, "Unable to init ntb dev.");
366                 return ret;
367         }
368
369         if (hw->ntb_ops->set_link == NULL)
370                 return -ENOTSUP;
371         ret = (*hw->ntb_ops->set_link)(dev, 1);
372         if (ret)
373                 return ret;
374
375         return ret;
376 }
377
378 static int
379 ntb_create(struct rte_pci_device *pci_dev, int socket_id)
380 {
381         char name[RTE_RAWDEV_NAME_MAX_LEN];
382         struct rte_rawdev *rawdev = NULL;
383         int ret;
384
385         if (pci_dev == NULL) {
386                 NTB_LOG(ERR, "Invalid pci_dev.");
387                 ret = -EINVAL;
388         }
389
390         memset(name, 0, sizeof(name));
391         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
392                  pci_dev->addr.bus, pci_dev->addr.devid,
393                  pci_dev->addr.function);
394
395         NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
396
397         /* Allocate device structure. */
398         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
399                                          socket_id);
400         if (rawdev == NULL) {
401                 NTB_LOG(ERR, "Unable to allocate rawdev.");
402                 ret = -EINVAL;
403         }
404
405         rawdev->dev_ops = &ntb_ops;
406         rawdev->device = &pci_dev->device;
407         rawdev->driver_name = pci_dev->driver->driver.name;
408
409         ret = ntb_init_hw(rawdev, pci_dev);
410         if (ret < 0) {
411                 NTB_LOG(ERR, "Unable to init ntb hw.");
412                 goto fail;
413         }
414
415         return ret;
416
417 fail:
418         if (rawdev)
419                 rte_rawdev_pmd_release(rawdev);
420
421         return ret;
422 }
423
424 static int
425 ntb_destroy(struct rte_pci_device *pci_dev)
426 {
427         char name[RTE_RAWDEV_NAME_MAX_LEN];
428         struct rte_rawdev *rawdev;
429         int ret;
430
431         if (pci_dev == NULL) {
432                 NTB_LOG(ERR, "Invalid pci_dev.");
433                 ret = -EINVAL;
434                 return ret;
435         }
436
437         memset(name, 0, sizeof(name));
438         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
439                  pci_dev->addr.bus, pci_dev->addr.devid,
440                  pci_dev->addr.function);
441
442         NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
443
444         rawdev = rte_rawdev_pmd_get_named_dev(name);
445         if (rawdev == NULL) {
446                 NTB_LOG(ERR, "Invalid device name (%s)", name);
447                 ret = -EINVAL;
448                 return ret;
449         }
450
451         ret = rte_rawdev_pmd_release(rawdev);
452         if (ret)
453                 NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
454
455         return ret;
456 }
457
458 static int
459 ntb_probe(struct rte_pci_driver *pci_drv __rte_unused,
460         struct rte_pci_device *pci_dev)
461 {
462         return ntb_create(pci_dev, rte_socket_id());
463 }
464
465 static int
466 ntb_remove(struct rte_pci_device *pci_dev)
467 {
468         return ntb_destroy(pci_dev);
469 }
470
471
472 static struct rte_pci_driver rte_ntb_pmd = {
473         .id_table = pci_id_ntb_map,
474         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
475         .probe = ntb_probe,
476         .remove = ntb_remove,
477 };
478
479 RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
480 RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
481 RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
482
483 RTE_INIT(ntb_init_log)
484 {
485         ntb_logtype = rte_log_register("pmd.raw.ntb");
486         if (ntb_logtype >= 0)
487                 rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
488 }