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