@@ -24,5 +24,6 @@ LDLIBS += -lrte_cryptodev
# library source files
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NITROX) += nitrox_device.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NITROX) += nitrox_hal.c
include $(RTE_SDK)/mk/rte.lib.mk
@@ -10,4 +10,5 @@ deps += ['bus_pci']
allow_experimental_apis = true
sources = files(
'nitrox_device.c',
+ 'nitrox_hal.c',
)
new file mode 100644
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef _NITROX_CSR_H_
+#define _NITROX_CSR_H_
+
+#include <rte_common.h>
+#include <rte_io.h>
+
+#define CSR_DELAY 30
+
+/* AQM Virtual Function Registers */
+#define AQMQ_QSZX(_i) (0x20008 + ((_i)*0x40000))
+
+static inline uint64_t
+nitrox_read_csr(uint8_t *bar_addr, uint64_t offset)
+{
+ return rte_read64(bar_addr + offset);
+}
+
+static inline void
+nitrox_write_csr(uint8_t *bar_addr, uint64_t offset, uint64_t value)
+{
+ rte_write64(value, (bar_addr + offset));
+}
+
+#endif /* _NITROX_CSR_H_ */
@@ -1,3 +1,108 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2019 Marvell International Ltd.
*/
+
+#include <rte_malloc.h>
+
+#include "nitrox_device.h"
+#include "nitrox_hal.h"
+
+TAILQ_HEAD(ndev_list, nitrox_device);
+static struct ndev_list ndev_list = TAILQ_HEAD_INITIALIZER(ndev_list);
+
+static struct nitrox_device *
+ndev_allocate(struct rte_pci_device *pdev)
+{
+ struct nitrox_device *ndev;
+
+ ndev = rte_zmalloc_socket("nitrox device", sizeof(*ndev),
+ RTE_CACHE_LINE_SIZE,
+ pdev->device.numa_node);
+ if (!ndev)
+ return NULL;
+
+ TAILQ_INSERT_TAIL(&ndev_list, ndev, next);
+ return ndev;
+}
+
+static void
+ndev_init(struct nitrox_device *ndev, struct rte_pci_device *pdev)
+{
+ enum nitrox_vf_mode vf_mode;
+
+ ndev->pdev = pdev;
+ ndev->bar_addr = pdev->mem_resource[0].addr;
+ vf_mode = vf_get_vf_config_mode(ndev->bar_addr);
+ ndev->nr_queues = vf_config_mode_to_nr_queues(vf_mode);
+}
+
+static struct nitrox_device *
+find_ndev(struct rte_pci_device *pdev)
+{
+ struct nitrox_device *ndev;
+
+ TAILQ_FOREACH(ndev, &ndev_list, next)
+ if (ndev->pdev == pdev)
+ return ndev;
+
+ return NULL;
+}
+
+static void
+ndev_release(struct nitrox_device *ndev)
+{
+ if (!ndev)
+ return;
+
+ TAILQ_REMOVE(&ndev_list, ndev, next);
+ rte_free(ndev);
+}
+
+static int
+nitrox_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pdev)
+{
+ struct nitrox_device *ndev;
+
+ /* Nitrox CSR space */
+ if (!pdev->mem_resource[0].addr)
+ return -EINVAL;
+
+ ndev = ndev_allocate(pdev);
+ if (!ndev)
+ return -ENOMEM;
+
+ ndev_init(ndev, pdev);
+ return 0;
+}
+
+static int
+nitrox_pci_remove(struct rte_pci_device *pdev)
+{
+ struct nitrox_device *ndev;
+
+ ndev = find_ndev(pdev);
+ if (!ndev)
+ return -ENODEV;
+
+ ndev_release(ndev);
+ return 0;
+}
+
+static struct rte_pci_id pci_id_nitrox_map[] = {
+ {
+ /* Nitrox 5 VF */
+ RTE_PCI_DEVICE(0x177d, 0x13)
+ },
+ {.device_id = 0},
+};
+
+static struct rte_pci_driver nitrox_pmd = {
+ .id_table = pci_id_nitrox_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = nitrox_pci_probe,
+ .remove = nitrox_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(nitrox, nitrox_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(nitrox, pci_id_nitrox_map);
new file mode 100644
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef _NITROX_DEVICE_H_
+#define _NITROX_DEVICE_H_
+
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+
+struct nitrox_device {
+ TAILQ_ENTRY(nitrox_device) next;
+ struct rte_pci_device *pdev;
+ uint8_t *bar_addr;
+ uint16_t nr_queues;
+};
+
+#endif /* _NITROX_DEVICE_H_ */
new file mode 100644
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_byteorder.h>
+
+#include "nitrox_hal.h"
+#include "nitrox_csr.h"
+
+#define MAX_VF_QUEUES 8
+#define MAX_PF_QUEUES 64
+
+int
+vf_get_vf_config_mode(uint8_t *bar_addr)
+{
+ union aqmq_qsz aqmq_qsz;
+ uint64_t reg_addr;
+ int q, vf_mode;
+
+ aqmq_qsz.u64 = 0;
+ aqmq_qsz.s.host_queue_size = 0xDEADBEEF;
+
+ reg_addr = AQMQ_QSZX(0);
+ nitrox_write_csr(bar_addr, reg_addr, aqmq_qsz.u64);
+ rte_delay_us_block(CSR_DELAY);
+
+ aqmq_qsz.u64 = 0;
+ for (q = 1; q < MAX_VF_QUEUES; q++) {
+ reg_addr = AQMQ_QSZX(q);
+ aqmq_qsz.u64 = nitrox_read_csr(bar_addr, reg_addr);
+ if (aqmq_qsz.s.host_queue_size == 0xDEADBEEF)
+ break;
+ }
+
+ switch (q) {
+ case 1:
+ vf_mode = NITROX_MODE_VF128;
+ break;
+ case 2:
+ vf_mode = NITROX_MODE_VF64;
+ break;
+ case 4:
+ vf_mode = NITROX_MODE_VF32;
+ break;
+ case 8:
+ vf_mode = NITROX_MODE_VF16;
+ break;
+ default:
+ vf_mode = 0;
+ break;
+ }
+
+ return vf_mode;
+}
+
+int
+vf_config_mode_to_nr_queues(enum nitrox_vf_mode vf_mode)
+{
+ int nr_queues;
+
+ switch (vf_mode) {
+ case NITROX_MODE_PF:
+ nr_queues = MAX_PF_QUEUES;
+ break;
+ case NITROX_MODE_VF16:
+ nr_queues = 8;
+ break;
+ case NITROX_MODE_VF32:
+ nr_queues = 4;
+ break;
+ case NITROX_MODE_VF64:
+ nr_queues = 2;
+ break;
+ case NITROX_MODE_VF128:
+ nr_queues = 1;
+ break;
+ default:
+ nr_queues = 0;
+ break;
+ }
+
+ return nr_queues;
+}
new file mode 100644
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef _NITROX_HAL_H_
+#define _NITROX_HAL_H_
+
+#include <rte_cycles.h>
+#include <rte_byteorder.h>
+
+#include "nitrox_csr.h"
+
+union aqmq_qsz {
+ uint64_t u64;
+ struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+ uint64_t raz : 32;
+ uint64_t host_queue_size : 32;
+#else
+ uint64_t host_queue_size : 32;
+ uint64_t raz : 32;
+#endif
+ } s;
+};
+
+enum nitrox_vf_mode {
+ NITROX_MODE_PF = 0x0,
+ NITROX_MODE_VF16 = 0x1,
+ NITROX_MODE_VF32 = 0x2,
+ NITROX_MODE_VF64 = 0x3,
+ NITROX_MODE_VF128 = 0x4,
+};
+
+int vf_get_vf_config_mode(uint8_t *bar_addr);
+int vf_config_mode_to_nr_queues(enum nitrox_vf_mode vf_mode);
+
+#endif /* _NITROX_HAL_H_ */