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>
25 static const struct rte_pci_id pci_id_ntb_map[] = {
26 { .vendor_id = 0, /* sentinel */ },
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)
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)
45 ntb_queue_release(struct rte_rawdev *dev __rte_unused,
46 uint16_t queue_id __rte_unused)
52 ntb_queue_count(struct rte_rawdev *dev)
54 struct ntb_hw *hw = dev->dev_private;
55 return hw->queue_pairs;
59 ntb_enqueue_bufs(struct rte_rawdev *dev,
60 struct rte_rawdev_buf **buffers,
62 rte_rawdev_obj_t context)
65 RTE_SET_USED(buffers);
67 RTE_SET_USED(context);
73 ntb_dequeue_bufs(struct rte_rawdev *dev,
74 struct rte_rawdev_buf **buffers,
76 rte_rawdev_obj_t context)
79 RTE_SET_USED(buffers);
81 RTE_SET_USED(context);
87 ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
89 struct ntb_hw *hw = dev->dev_private;
90 struct ntb_attr *ntb_attrs = dev_info;
92 strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
94 case NTB_TOPO_B2B_DSD:
95 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
98 case NTB_TOPO_B2B_USD:
99 strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
103 strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
107 strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
109 snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
110 "%d", hw->link_status);
112 strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
114 snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
115 "%d", hw->link_speed);
117 strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
119 snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
120 "%d", hw->link_width);
122 strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
124 snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
127 strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
129 snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
132 strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
134 snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
139 ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
140 rte_rawdev_obj_t config __rte_unused)
146 ntb_dev_start(struct rte_rawdev *dev)
148 /* TODO: init queues and start queues. */
155 ntb_dev_stop(struct rte_rawdev *dev)
157 /* TODO: stop rx/tx queues. */
162 ntb_dev_close(struct rte_rawdev *dev)
169 /* TODO: free queues. */
175 ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
181 ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
184 struct ntb_hw *hw = dev->dev_private;
187 if (dev == NULL || attr_name == NULL) {
188 NTB_LOG(ERR, "Invalid arguments for setting attributes");
192 if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
193 if (hw->ntb_ops->spad_write == NULL)
195 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
196 (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
198 NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
199 attr_name, attr_value);
203 /* Attribute not found. */
204 NTB_LOG(ERR, "Attribute not found.");
209 ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
210 uint64_t *attr_value)
212 struct ntb_hw *hw = dev->dev_private;
215 if (dev == NULL || attr_name == NULL || attr_value == NULL) {
216 NTB_LOG(ERR, "Invalid arguments for getting attributes");
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);
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);
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);
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);
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);
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);
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);
269 if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
270 if (hw->ntb_ops->spad_read == NULL)
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);
280 /* Attribute not found. */
281 NTB_LOG(ERR, "Attribute not found.");
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)
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)
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)
311 ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
312 const uint32_t ids[] __rte_unused,
313 uint32_t nb_ids __rte_unused)
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,
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,
331 .enqueue_bufs = ntb_enqueue_bufs,
332 .dequeue_bufs = ntb_dequeue_bufs,
334 .attr_get = ntb_attr_get,
335 .attr_set = ntb_attr_set,
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,
344 ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
346 struct ntb_hw *hw = dev->dev_private;
349 hw->pci_dev = pci_dev;
351 hw->link_status = NTB_LINK_DOWN;
352 hw->link_speed = NTB_SPEED_NONE;
353 hw->link_width = NTB_WIDTH_NONE;
355 switch (pci_dev->id.device_id) {
357 NTB_LOG(ERR, "Not supported device.");
361 if (hw->ntb_ops->ntb_dev_init == NULL)
363 ret = (*hw->ntb_ops->ntb_dev_init)(dev);
365 NTB_LOG(ERR, "Unable to init ntb dev.");
369 if (hw->ntb_ops->set_link == NULL)
371 ret = (*hw->ntb_ops->set_link)(dev, 1);
379 ntb_create(struct rte_pci_device *pci_dev, int socket_id)
381 char name[RTE_RAWDEV_NAME_MAX_LEN];
382 struct rte_rawdev *rawdev = NULL;
385 if (pci_dev == NULL) {
386 NTB_LOG(ERR, "Invalid pci_dev.");
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);
395 NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
397 /* Allocate device structure. */
398 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
400 if (rawdev == NULL) {
401 NTB_LOG(ERR, "Unable to allocate rawdev.");
405 rawdev->dev_ops = &ntb_ops;
406 rawdev->device = &pci_dev->device;
407 rawdev->driver_name = pci_dev->driver->driver.name;
409 ret = ntb_init_hw(rawdev, pci_dev);
411 NTB_LOG(ERR, "Unable to init ntb hw.");
419 rte_rawdev_pmd_release(rawdev);
425 ntb_destroy(struct rte_pci_device *pci_dev)
427 char name[RTE_RAWDEV_NAME_MAX_LEN];
428 struct rte_rawdev *rawdev;
431 if (pci_dev == NULL) {
432 NTB_LOG(ERR, "Invalid pci_dev.");
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);
442 NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
444 rawdev = rte_rawdev_pmd_get_named_dev(name);
445 if (rawdev == NULL) {
446 NTB_LOG(ERR, "Invalid device name (%s)", name);
451 ret = rte_rawdev_pmd_release(rawdev);
453 NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
459 ntb_probe(struct rte_pci_driver *pci_drv __rte_unused,
460 struct rte_pci_device *pci_dev)
462 return ntb_create(pci_dev, rte_socket_id());
466 ntb_remove(struct rte_pci_device *pci_dev)
468 return ntb_destroy(pci_dev);
472 static struct rte_pci_driver rte_ntb_pmd = {
473 .id_table = pci_id_ntb_map,
474 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
476 .remove = ntb_remove,
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");
483 RTE_INIT(ntb_init_log)
485 ntb_logtype = rte_log_register("pmd.raw.ntb");
486 if (ntb_logtype >= 0)
487 rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);