1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Intel Corporation.
9 #include <rte_common.h>
10 #include <rte_lcore.h>
11 #include <rte_cycles.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>
21 #include "ntb_hw_intel.h"
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 */ },
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)
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)
47 ntb_queue_release(struct rte_rawdev *dev __rte_unused,
48 uint16_t queue_id __rte_unused)
54 ntb_queue_count(struct rte_rawdev *dev)
56 struct ntb_hw *hw = dev->dev_private;
57 return hw->queue_pairs;
61 ntb_enqueue_bufs(struct rte_rawdev *dev,
62 struct rte_rawdev_buf **buffers,
64 rte_rawdev_obj_t context)
67 RTE_SET_USED(buffers);
69 RTE_SET_USED(context);
75 ntb_dequeue_bufs(struct rte_rawdev *dev,
76 struct rte_rawdev_buf **buffers,
78 rte_rawdev_obj_t context)
81 RTE_SET_USED(buffers);
83 RTE_SET_USED(context);
89 ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
91 struct ntb_hw *hw = dev->dev_private;
92 struct ntb_attr *ntb_attrs = dev_info;
94 strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
96 case NTB_TOPO_B2B_DSD:
97 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
100 case NTB_TOPO_B2B_USD:
101 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
105 strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
109 strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
111 snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
112 "%d", hw->link_status);
114 strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
116 snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
117 "%d", hw->link_speed);
119 strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
121 snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
122 "%d", hw->link_width);
124 strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
126 snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
129 strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
131 snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
134 strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
136 snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
141 ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
142 rte_rawdev_obj_t config __rte_unused)
148 ntb_dev_start(struct rte_rawdev *dev)
150 /* TODO: init queues and start queues. */
157 ntb_dev_stop(struct rte_rawdev *dev)
159 /* TODO: stop rx/tx queues. */
164 ntb_dev_close(struct rte_rawdev *dev)
171 /* TODO: free queues. */
177 ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
183 ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
186 struct ntb_hw *hw = dev->dev_private;
189 if (dev == NULL || attr_name == NULL) {
190 NTB_LOG(ERR, "Invalid arguments for setting attributes");
194 if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
195 if (hw->ntb_ops->spad_write == NULL)
197 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
198 (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
200 NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
201 attr_name, attr_value);
205 /* Attribute not found. */
206 NTB_LOG(ERR, "Attribute not found.");
211 ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
212 uint64_t *attr_value)
214 struct ntb_hw *hw = dev->dev_private;
217 if (dev == NULL || attr_name == NULL || attr_value == NULL) {
218 NTB_LOG(ERR, "Invalid arguments for getting attributes");
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);
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);
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);
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);
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);
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);
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);
271 if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
272 if (hw->ntb_ops->spad_read == NULL)
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);
282 /* Attribute not found. */
283 NTB_LOG(ERR, "Attribute not found.");
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)
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)
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)
313 ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
314 const uint32_t ids[] __rte_unused,
315 uint32_t nb_ids __rte_unused)
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,
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,
333 .enqueue_bufs = ntb_enqueue_bufs,
334 .dequeue_bufs = ntb_dequeue_bufs,
336 .attr_get = ntb_attr_get,
337 .attr_set = ntb_attr_set,
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,
346 ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
348 struct ntb_hw *hw = dev->dev_private;
351 hw->pci_dev = pci_dev;
353 hw->link_status = NTB_LINK_DOWN;
354 hw->link_speed = NTB_SPEED_NONE;
355 hw->link_width = NTB_WIDTH_NONE;
357 switch (pci_dev->id.device_id) {
358 case NTB_INTEL_DEV_ID_B2B_SKX:
359 hw->ntb_ops = &intel_ntb_ops;
362 NTB_LOG(ERR, "Not supported device.");
366 if (hw->ntb_ops->ntb_dev_init == NULL)
368 ret = (*hw->ntb_ops->ntb_dev_init)(dev);
370 NTB_LOG(ERR, "Unable to init ntb dev.");
374 if (hw->ntb_ops->set_link == NULL)
376 ret = (*hw->ntb_ops->set_link)(dev, 1);
384 ntb_create(struct rte_pci_device *pci_dev, int socket_id)
386 char name[RTE_RAWDEV_NAME_MAX_LEN];
387 struct rte_rawdev *rawdev = NULL;
390 if (pci_dev == NULL) {
391 NTB_LOG(ERR, "Invalid pci_dev.");
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);
400 NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
402 /* Allocate device structure. */
403 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
405 if (rawdev == NULL) {
406 NTB_LOG(ERR, "Unable to allocate rawdev.");
410 rawdev->dev_ops = &ntb_ops;
411 rawdev->device = &pci_dev->device;
412 rawdev->driver_name = pci_dev->driver->driver.name;
414 ret = ntb_init_hw(rawdev, pci_dev);
416 NTB_LOG(ERR, "Unable to init ntb hw.");
424 rte_rawdev_pmd_release(rawdev);
430 ntb_destroy(struct rte_pci_device *pci_dev)
432 char name[RTE_RAWDEV_NAME_MAX_LEN];
433 struct rte_rawdev *rawdev;
436 if (pci_dev == NULL) {
437 NTB_LOG(ERR, "Invalid pci_dev.");
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);
447 NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
449 rawdev = rte_rawdev_pmd_get_named_dev(name);
450 if (rawdev == NULL) {
451 NTB_LOG(ERR, "Invalid device name (%s)", name);
456 ret = rte_rawdev_pmd_release(rawdev);
458 NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
464 ntb_probe(struct rte_pci_driver *pci_drv __rte_unused,
465 struct rte_pci_device *pci_dev)
467 return ntb_create(pci_dev, rte_socket_id());
471 ntb_remove(struct rte_pci_device *pci_dev)
473 return ntb_destroy(pci_dev);
477 static struct rte_pci_driver rte_ntb_pmd = {
478 .id_table = pci_id_ntb_map,
479 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
481 .remove = ntb_remove,
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");
488 RTE_INIT(ntb_init_log)
490 ntb_logtype = rte_log_register("pmd.raw.ntb");
491 if (ntb_logtype >= 0)
492 rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);