new file mode 100644
@@ -0,0 +1,145 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include <rte_thread.h>
+
+#include "ntlog.h"
+#include "nt_util.h"
+#include "ntnic_mod_reg.h"
+
+static int nt4ga_adapter_show_info(struct adapter_info_s *p_adapter_info, FILE *pfh)
+{
+ const char *const p_dev_name = p_adapter_info->p_dev_name;
+ const char *const p_adapter_id_str = p_adapter_info->mp_adapter_id_str;
+ fpga_info_t *p_fpga_info = &p_adapter_info->fpga_info;
+ hw_info_t *p_hw_info = &p_adapter_info->hw_info;
+ char a_pci_ident_str[32];
+
+ snprintf(a_pci_ident_str, sizeof(a_pci_ident_str), PCIIDENT_PRINT_STR,
+ PCIIDENT_TO_DOMAIN(p_fpga_info->pciident),
+ PCIIDENT_TO_BUSNR(p_fpga_info->pciident),
+ PCIIDENT_TO_DEVNR(p_fpga_info->pciident),
+ PCIIDENT_TO_FUNCNR(p_fpga_info->pciident));
+
+ fprintf(pfh, "%s: DeviceName: %s\n", p_adapter_id_str, (p_dev_name ? p_dev_name : "NA"));
+ fprintf(pfh, "%s: PCI Details:\n", p_adapter_id_str);
+ fprintf(pfh, "%s: %s: %08X: %04X:%04X %04X:%04X\n", p_adapter_id_str, a_pci_ident_str,
+ p_fpga_info->pciident, p_hw_info->pci_vendor_id, p_hw_info->pci_device_id,
+ p_hw_info->pci_sub_vendor_id, p_hw_info->pci_sub_device_id);
+ fprintf(pfh, "%s: FPGA Details:\n", p_adapter_id_str);
+ fprintf(pfh, "%s: %03d-%04d-%02d-%02d [%016" PRIX64 "] (%08X)\n", p_adapter_id_str,
+ p_fpga_info->n_fpga_type_id, p_fpga_info->n_fpga_prod_id,
+ p_fpga_info->n_fpga_ver_id, p_fpga_info->n_fpga_rev_id, p_fpga_info->n_fpga_ident,
+ p_fpga_info->n_fpga_build_time);
+ fprintf(pfh, "%s: FpgaDebugMode=0x%x\n", p_adapter_id_str, p_fpga_info->n_fpga_debug_mode);
+ fprintf(pfh, "%s: Hw=0x%02X_rev%d: %s\n", p_adapter_id_str, p_hw_info->hw_platform_id,
+ p_fpga_info->nthw_hw_info.hw_id, p_fpga_info->nthw_hw_info.hw_plat_id_str);
+ fprintf(pfh, "%s: MCU Details:\n", p_adapter_id_str);
+
+ return 0;
+}
+
+static int nt4ga_adapter_init(struct adapter_info_s *p_adapter_info)
+{
+ char *const p_dev_name = malloc(24);
+ char *const p_adapter_id_str = malloc(24);
+ fpga_info_t *fpga_info = &p_adapter_info->fpga_info;
+ hw_info_t *p_hw_info = &p_adapter_info->hw_info;
+
+
+ p_hw_info->n_nthw_adapter_id = nthw_platform_get_nthw_adapter_id(p_hw_info->pci_device_id);
+
+ fpga_info->n_nthw_adapter_id = p_hw_info->n_nthw_adapter_id;
+ /* ref: DN-0060 section 9 */
+ p_hw_info->hw_product_type = p_hw_info->pci_device_id & 0x000f;
+ /* ref: DN-0060 section 9 */
+ p_hw_info->hw_platform_id = (p_hw_info->pci_device_id >> 4) & 0x00ff;
+ /* ref: DN-0060 section 9 */
+ p_hw_info->hw_reserved1 = (p_hw_info->pci_device_id >> 12) & 0x000f;
+
+ p_adapter_info->p_dev_name = p_dev_name;
+
+ if (p_dev_name) {
+ snprintf(p_dev_name, 24, PCIIDENT_PRINT_STR,
+ PCIIDENT_TO_DOMAIN(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_BUSNR(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_DEVNR(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_FUNCNR(p_adapter_info->fpga_info.pciident));
+ NT_LOG(DBG, NTNIC, "%s: (0x%08X)\n", p_dev_name,
+ p_adapter_info->fpga_info.pciident);
+ }
+
+ p_adapter_info->mp_adapter_id_str = p_adapter_id_str;
+
+ p_adapter_info->fpga_info.mp_adapter_id_str = p_adapter_id_str;
+
+ if (p_adapter_id_str) {
+ snprintf(p_adapter_id_str, 24, "PCI:" PCIIDENT_PRINT_STR,
+ PCIIDENT_TO_DOMAIN(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_BUSNR(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_DEVNR(p_adapter_info->fpga_info.pciident),
+ PCIIDENT_TO_FUNCNR(p_adapter_info->fpga_info.pciident));
+ NT_LOG(DBG, NTNIC, "%s: %s\n", p_adapter_id_str, p_dev_name);
+ }
+
+ {
+ int i;
+
+ for (i = 0; i < (int)ARRAY_SIZE(p_adapter_info->mp_port_id_str); i++) {
+ char *p = malloc(32);
+
+ if (p) {
+ snprintf(p, 32, "%s:intf_%d",
+ (p_adapter_id_str ? p_adapter_id_str : "NA"), i);
+ }
+
+ p_adapter_info->mp_port_id_str[i] = p;
+ }
+ }
+
+ return 0;
+}
+
+static int nt4ga_adapter_deinit(struct adapter_info_s *p_adapter_info)
+{
+ fpga_info_t *fpga_info = &p_adapter_info->fpga_info;
+ int i;
+ int res = -1;
+
+
+ /* Free adapter port ident strings */
+ for (i = 0; i < fpga_info->n_phy_ports; i++) {
+ if (p_adapter_info->mp_port_id_str[i]) {
+ free(p_adapter_info->mp_port_id_str[i]);
+ p_adapter_info->mp_port_id_str[i] = NULL;
+ }
+ }
+
+ /* Free adapter ident string */
+ if (p_adapter_info->mp_adapter_id_str) {
+ free(p_adapter_info->mp_adapter_id_str);
+ p_adapter_info->mp_adapter_id_str = NULL;
+ }
+
+ /* Free devname ident string */
+ if (p_adapter_info->p_dev_name) {
+ free(p_adapter_info->p_dev_name);
+ p_adapter_info->p_dev_name = NULL;
+ }
+
+ return res;
+}
+
+static const struct adapter_ops ops = {
+ .init = nt4ga_adapter_init,
+ .deinit = nt4ga_adapter_deinit,
+
+ .show_info = nt4ga_adapter_show_info,
+};
+
+void adapter_init(void)
+{
+ register_adapter_ops(&ops);
+}
new file mode 100644
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef _NT4GA_ADAPTER_H_
+#define _NT4GA_ADAPTER_H_
+
+#include "ntos_drv.h"
+typedef struct hw_info_s {
+ /* pciids */
+ uint16_t pci_vendor_id;
+ uint16_t pci_device_id;
+ uint16_t pci_sub_vendor_id;
+ uint16_t pci_sub_device_id;
+ uint16_t pci_class_id;
+
+ /* Derived from pciid */
+ nthw_adapter_id_t n_nthw_adapter_id;
+ int hw_platform_id;
+ int hw_product_type;
+ int hw_reserved1;
+} hw_info_t;
+
+typedef struct adapter_info_s {
+ struct hw_info_s hw_info;
+ struct fpga_info_s fpga_info;
+
+ char *mp_port_id_str[NUM_ADAPTER_PORTS_MAX];
+ char *mp_adapter_id_str;
+ char *p_dev_name;
+ volatile bool *pb_shutdown;
+
+ int adapter_no;
+ int n_rx_host_buffers;
+ int n_tx_host_buffers;
+} adapter_info_t;
+
+
+#endif /* _NT4GA_ADAPTER_H_ */
@@ -6,9 +6,11 @@
#ifndef __NTDRV_4GA_H__
#define __NTDRV_4GA_H__
+#include "nt4ga_adapter.h"
typedef struct ntdrv_4ga_s {
uint32_t pciident;
+ struct adapter_info_s adapter_info;
char *p_drv_name;
volatile bool b_shutdown;
@@ -18,9 +18,11 @@ includes = [
# all sources
sources = files(
+ 'adapter/nt4ga_adapter.c',
'nthw/nthw_platform.c',
'ntlog/ntlog.c',
'ntutil/nt_util.c',
+ 'ntnic_mod_reg.c',
'ntnic_vfio.c',
'ntnic_ethdev.c',
)
@@ -18,6 +18,7 @@
#include "ntos_drv.h"
#include "ntos_system.h"
#include "ntnic_vfio.h"
+#include "ntnic_mod_reg.h"
#include "nt_util.h"
#define EXCEPTION_PATH_HID 0
@@ -130,9 +131,21 @@ eth_dev_stop(struct rte_eth_dev *eth_dev)
static void
drv_deinit(struct drv_s *p_drv)
{
+ const struct adapter_ops *adapter_ops = get_adapter_ops();
+
+ if (adapter_ops == NULL) {
+ NT_LOG(ERR, NTNIC, "Adapter module uninitialized\n");
+ return;
+ }
+
if (p_drv == NULL)
return;
+ ntdrv_4ga_t *p_nt_drv = &p_drv->ntdrv;
+
+ /* stop adapter */
+ adapter_ops->deinit(&p_nt_drv->adapter_info);
+
/* clean memory */
rte_free(p_drv);
p_drv = NULL;
@@ -174,6 +187,13 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
{
nt_vfio_init();
+ const struct adapter_ops *adapter_ops = get_adapter_ops();
+
+ if (adapter_ops == NULL) {
+ NT_LOG(ERR, NTNIC, "Adapter module uninitialized\n");
+ return -1;
+ }
+
struct drv_s *p_drv;
ntdrv_4ga_t *p_nt_drv;
uint32_t n_port_mask = -1; /* All ports enabled by default */
@@ -213,23 +233,71 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
/* Set context for NtDrv */
p_nt_drv->pciident = BDF_TO_PCIIDENT(pci_dev->addr.domain, pci_dev->addr.bus,
pci_dev->addr.devid, pci_dev->addr.function);
+ p_nt_drv->adapter_info.n_rx_host_buffers = nb_rx_queues;
+ p_nt_drv->adapter_info.n_tx_host_buffers = nb_tx_queues;
+
+
+ p_nt_drv->adapter_info.hw_info.pci_class_id = pci_dev->id.class_id;
+ p_nt_drv->adapter_info.hw_info.pci_vendor_id = pci_dev->id.vendor_id;
+ p_nt_drv->adapter_info.hw_info.pci_device_id = pci_dev->id.device_id;
+ p_nt_drv->adapter_info.hw_info.pci_sub_vendor_id = pci_dev->id.subsystem_vendor_id;
+ p_nt_drv->adapter_info.hw_info.pci_sub_device_id = pci_dev->id.subsystem_device_id;
+
+ NT_LOG(DBG, NTNIC, "%s: " PCIIDENT_PRINT_STR " %04X:%04X: %04X:%04X:\n",
+ p_nt_drv->adapter_info.mp_adapter_id_str, PCIIDENT_TO_DOMAIN(p_nt_drv->pciident),
+ PCIIDENT_TO_BUSNR(p_nt_drv->pciident), PCIIDENT_TO_DEVNR(p_nt_drv->pciident),
+ PCIIDENT_TO_FUNCNR(p_nt_drv->pciident),
+ p_nt_drv->adapter_info.hw_info.pci_vendor_id,
+ p_nt_drv->adapter_info.hw_info.pci_device_id,
+ p_nt_drv->adapter_info.hw_info.pci_sub_vendor_id,
+ p_nt_drv->adapter_info.hw_info.pci_sub_device_id);
p_nt_drv->b_shutdown = false;
+ p_nt_drv->adapter_info.pb_shutdown = &p_nt_drv->b_shutdown;
/* store context */
store_pdrv(p_drv);
+ /* initialize nt4ga nthw fpga module instance in drv */
+ int err = adapter_ops->init(&p_nt_drv->adapter_info);
+
+ if (err != 0) {
+ NT_LOG(ERR, NTNIC, "%s: Cannot initialize the adapter instance\n",
+ p_nt_drv->adapter_info.mp_adapter_id_str);
+ return -1;
+ }
+
+ /* Start ctrl, monitor, stat thread only for primary process. */
+ if (err == 0) {
+ /* mp_adapter_id_str is initialized after nt4ga_adapter_init(p_nt_drv) */
+ const char *const p_adapter_id_str = p_nt_drv->adapter_info.mp_adapter_id_str;
+ (void)p_adapter_id_str;
+
+ } else {
+ NT_LOG_DBGX(ERR, NTNIC, "%s: error=%d\n",
+ (pci_dev->name[0] ? pci_dev->name : "NA"), err);
+ return -1;
+ }
+
n_phy_ports = 0;
for (int n_intf_no = 0; n_intf_no < n_phy_ports; n_intf_no++) {
+ const char *const p_port_id_str = p_nt_drv->adapter_info.mp_port_id_str[n_intf_no];
+ (void)p_port_id_str;
struct pmd_internals *internals = NULL;
struct rte_eth_dev *eth_dev = NULL;
char name[32];
- if ((1 << n_intf_no) & ~n_port_mask)
+ if ((1 << n_intf_no) & ~n_port_mask) {
+ NT_LOG_DBGX(DEBUG, NTNIC,
+ "%s: interface #%d: skipping due to portmask 0x%02X\n",
+ p_port_id_str, n_intf_no, n_port_mask);
continue;
+ }
snprintf(name, sizeof(name), "ntnic%d", n_intf_no);
+ NT_LOG_DBGX(DEBUG, NTNIC, "%s: interface #%d: %s: '%s'\n", p_port_id_str,
+ n_intf_no, (pci_dev->name[0] ? pci_dev->name : "NA"), name);
internals = rte_zmalloc_socket(name, sizeof(struct pmd_internals),
RTE_CACHE_LINE_SIZE, pci_dev->device.numa_node);
@@ -289,6 +357,21 @@ nthw_pci_dev_deinit(struct rte_eth_dev *eth_dev __rte_unused)
{
NT_LOG_DBGX(DEBUG, NTNIC, "PCI device deinitialization\n");
+ int i;
+ char name[32];
+
+ struct pmd_internals *internals = eth_dev->data->dev_private;
+ ntdrv_4ga_t *p_ntdrv = &internals->p_drv->ntdrv;
+ fpga_info_t *fpga_info = &p_ntdrv->adapter_info.fpga_info;
+ const int n_phy_ports = fpga_info->n_phy_ports;
+ for (i = 0; i < n_phy_ports; i++) {
+ sprintf(name, "ntnic%d", i);
+ eth_dev = rte_eth_dev_allocated(name);
+ if (eth_dev == NULL)
+ continue; /* port already released */
+ rte_eth_dev_release_port(eth_dev);
+ }
+
nt_vfio_remove(EXCEPTION_PATH_HID);
return 0;
}
new file mode 100644
@@ -0,0 +1,20 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntnic_mod_reg.h"
+
+static const struct adapter_ops *adapter_ops;
+
+void register_adapter_ops(const struct adapter_ops *ops)
+{
+ adapter_ops = ops;
+}
+
+const struct adapter_ops *get_adapter_ops(void)
+{
+ if (adapter_ops == NULL)
+ adapter_init();
+ return adapter_ops;
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTNIC_MOD_REG_H__
+#define __NTNIC_MOD_REG_H__
+
+#include <stdint.h>
+#include "nthw_platform_drv.h"
+#include "nthw_drv.h"
+#include "nt4ga_adapter.h"
+#include "ntos_drv.h"
+
+struct adapter_ops {
+ int (*init)(struct adapter_info_s *p_adapter_info);
+ int (*deinit)(struct adapter_info_s *p_adapter_info);
+
+ int (*show_info)(struct adapter_info_s *p_adapter_info, FILE *pfh);
+};
+
+void register_adapter_ops(const struct adapter_ops *ops);
+const struct adapter_ops *get_adapter_ops(void);
+void adapter_init(void);
+
+
+#endif /* __NTNIC_MOD_REG_H__ */