From: Alfredo Cardigliano <cardigliano@ntop.org>
To: Alfredo Cardigliano <cardigliano@ntop.org>,
John McNamara <john.mcnamara@intel.com>,
Marko Kovacevic <marko.kovacevic@intel.com>,
Anatoly Burakov <anatoly.burakov@intel.com>
Cc: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 04/17] net/ionic: register and initialize the adapter
Date: Tue, 15 Oct 2019 10:22:22 +0200 [thread overview]
Message-ID: <20191015082235.28639-5-cardigliano@ntop.org> (raw)
In-Reply-To: <20191015082235.28639-1-cardigliano@ntop.org>
Register the Pensando ionic PMD (net_ionic) and define initial probe
and remove callbacks with adapter initialization.
Signed-off-by: Alfredo Cardigliano <cardigliano@ntop.org>
Reviewed-by: Shannon Nelson <snelson@pensando.io>
---
doc/guides/nics/features/ionic.ini | 2 +
drivers/net/ionic/Makefile | 3 +
drivers/net/ionic/ionic.h | 63 +++++++++++++
drivers/net/ionic/ionic_dev.c | 128 ++++++++++++++++++++++++++
drivers/net/ionic/ionic_dev.h | 138 ++++++++++++++++++++++++++++
drivers/net/ionic/ionic_ethdev.c | 138 ++++++++++++++++++++++++++++
drivers/net/ionic/ionic_mac_api.c | 61 +++++++++++++
drivers/net/ionic/ionic_mac_api.h | 13 +++
drivers/net/ionic/ionic_main.c | 133 +++++++++++++++++++++++++++
drivers/net/ionic/ionic_osdep.h | 79 ++++++++++++++++
drivers/net/ionic/ionic_regs.h | 142 +++++++++++++++++++++++++++++
drivers/net/ionic/meson.build | 4 +
12 files changed, 904 insertions(+)
create mode 100644 drivers/net/ionic/ionic.h
create mode 100644 drivers/net/ionic/ionic_dev.c
create mode 100644 drivers/net/ionic/ionic_dev.h
create mode 100644 drivers/net/ionic/ionic_mac_api.c
create mode 100644 drivers/net/ionic/ionic_mac_api.h
create mode 100644 drivers/net/ionic/ionic_main.c
create mode 100644 drivers/net/ionic/ionic_osdep.h
create mode 100644 drivers/net/ionic/ionic_regs.h
diff --git a/doc/guides/nics/features/ionic.ini b/doc/guides/nics/features/ionic.ini
index 3a92eedc7..6915d9c42 100644
--- a/doc/guides/nics/features/ionic.ini
+++ b/doc/guides/nics/features/ionic.ini
@@ -4,5 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Linux UIO = Y
+Linux VFIO = Y
x86-64 = Y
Usage doc = Y
diff --git a/drivers/net/ionic/Makefile b/drivers/net/ionic/Makefile
index f9b9a6af9..69fb7dcf1 100644
--- a/drivers/net/ionic/Makefile
+++ b/drivers/net/ionic/Makefile
@@ -53,6 +53,9 @@ LDLIBS += -lrte_bus_pci
#
# all source are stored in SRCS-y
#
+SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_mac_api.c
+SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_dev.c
SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_main.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ionic/ionic.h b/drivers/net/ionic/ionic.h
new file mode 100644
index 000000000..1f91e0a10
--- /dev/null
+++ b/drivers/net/ionic/ionic.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_H_
+#define _IONIC_H_
+
+#include <stdint.h>
+
+#include "ionic_dev.h"
+#include "ionic_if.h"
+#include "ionic_osdep.h"
+
+#define IONIC_DRV_NAME "ionic"
+#define IONIC_DRV_DESCRIPTION "Pensando Ethernet NIC Driver"
+#define IONIC_DRV_VERSION "0.11.0-49"
+
+/* Vendor ID */
+#define IONIC_PENSANDO_VENDOR_ID 0x1dd8
+
+/* Device IDs */
+#define IONIC_DEV_ID_ETH_PF 0x1002
+#define IONIC_DEV_ID_ETH_VF 0x1003
+#define IONIC_DEV_ID_ETH_MGMT 0x1004
+
+enum ionic_mac_type {
+ IONIC_MAC_UNKNOWN = 0,
+ IONIC_MAC_CAPRI,
+ IONIC_NUM_MACS
+};
+
+struct ionic_mac_info {
+ enum ionic_mac_type type;
+};
+
+struct ionic_hw {
+ struct ionic_mac_info mac;
+ uint16_t device_id;
+ uint16_t vendor_id;
+};
+
+/*
+ * Structure to store private data for each driver instance (for each adapter).
+ */
+struct ionic_adapter {
+ struct ionic_hw hw;
+ struct ionic_dev idev;
+ struct ionic_dev_bar bars[IONIC_BARS_MAX];
+ struct ionic_identity ident;
+ uint32_t num_bars;
+ bool is_mgmt_nic;
+ struct rte_pci_device *pci_dev;
+ LIST_ENTRY(ionic_adapter) pci_adapters;
+};
+
+int ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait);
+int ionic_setup(struct ionic_adapter *adapter);
+
+int ionic_identify(struct ionic_adapter *adapter);
+int ionic_init(struct ionic_adapter *adapter);
+int ionic_reset(struct ionic_adapter *adapter);
+
+#endif /* _IONIC_H_ */
diff --git a/drivers/net/ionic/ionic_dev.c b/drivers/net/ionic/ionic_dev.c
new file mode 100644
index 000000000..5cdcaa104
--- /dev/null
+++ b/drivers/net/ionic/ionic_dev.c
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#include <rte_malloc.h>
+
+#include "ionic_dev.h"
+#include "ionic.h"
+
+int
+ionic_dev_setup(struct ionic_adapter *adapter)
+{
+ struct ionic_dev_bar *bar = adapter->bars;
+ unsigned int num_bars = adapter->num_bars;
+ struct ionic_dev *idev = &adapter->idev;
+ uint32_t sig;
+
+ /* BAR0: dev_cmd and interrupts */
+ if (num_bars < 1) {
+ ionic_init_print(ERR, "No bars found, aborting\n");
+ return -EFAULT;
+ }
+
+ if (bar->len < IONIC_BAR0_SIZE) {
+ ionic_init_print(ERR,
+ "Resource bar size %lu too small, aborting\n",
+ bar->len);
+ return -EFAULT;
+ }
+
+ idev->dev_info = bar->vaddr + IONIC_BAR0_DEV_INFO_REGS_OFFSET;
+ idev->dev_cmd = bar->vaddr + IONIC_BAR0_DEV_CMD_REGS_OFFSET;
+ idev->intr_status = bar->vaddr + IONIC_BAR0_INTR_STATUS_OFFSET;
+ idev->intr_ctrl = bar->vaddr + IONIC_BAR0_INTR_CTRL_OFFSET;
+
+ sig = ioread32(&idev->dev_info->signature);
+ if (sig != IONIC_DEV_INFO_SIGNATURE) {
+ ionic_init_print(ERR, "Incompatible firmware signature %x",
+ sig);
+ return -EFAULT;
+ }
+
+ /* BAR1: doorbells */
+ bar++;
+ if (num_bars < 2) {
+ ionic_init_print(ERR, "Doorbell bar missing, aborting\n");
+ return -EFAULT;
+ }
+
+ idev->db_pages = bar->vaddr;
+ idev->phy_db_pages = bar->bus_addr;
+
+ return 0;
+}
+
+/* Devcmd Interface */
+
+uint8_t
+ionic_dev_cmd_status(struct ionic_dev *idev)
+{
+ return ioread8(&idev->dev_cmd->comp.comp.status);
+}
+
+bool
+ionic_dev_cmd_done(struct ionic_dev *idev)
+{
+ return ioread32(&idev->dev_cmd->done) & IONIC_DEV_CMD_DONE;
+}
+
+void
+ionic_dev_cmd_comp(struct ionic_dev *idev, void *mem)
+{
+ union ionic_dev_cmd_comp *comp = mem;
+ unsigned int i;
+ uint32_t comp_size = sizeof(comp->words) /
+ sizeof(comp->words[0]);
+
+ for (i = 0; i < comp_size; i++)
+ comp->words[i] = ioread32(&idev->dev_cmd->comp.words[i]);
+}
+
+void
+ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
+{
+ unsigned int i;
+ uint32_t cmd_size = sizeof(cmd->words) /
+ sizeof(cmd->words[0]);
+
+ for (i = 0; i < cmd_size; i++)
+ iowrite32(cmd->words[i], &idev->dev_cmd->cmd.words[i]);
+
+ iowrite32(0, &idev->dev_cmd->done);
+ iowrite32(1, &idev->dev_cmd->doorbell);
+}
+
+/* Device commands */
+
+void
+ionic_dev_cmd_identify(struct ionic_dev *idev, uint8_t ver)
+{
+ union ionic_dev_cmd cmd = {
+ .identify.opcode = IONIC_CMD_IDENTIFY,
+ .identify.ver = ver,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
+
+void
+ionic_dev_cmd_init(struct ionic_dev *idev)
+{
+ union ionic_dev_cmd cmd = {
+ .init.opcode = IONIC_CMD_INIT,
+ .init.type = 0,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
+
+void
+ionic_dev_cmd_reset(struct ionic_dev *idev)
+{
+ union ionic_dev_cmd cmd = {
+ .reset.opcode = IONIC_CMD_RESET,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
new file mode 100644
index 000000000..a157e4175
--- /dev/null
+++ b/drivers/net/ionic/ionic_dev.h
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_DEV_H_
+#define _IONIC_DEV_H_
+
+#include "ionic_osdep.h"
+#include "ionic_if.h"
+#include "ionic_regs.h"
+
+/** IONIC_API_VERSION - Version number of this interface.
+ *
+ * Any interface changes to this interface must also change the version.
+ *
+ * If drivers are compiled from different sources,
+ * they are compatible only if IONIC_API_VERSION is statically the same in both
+ * sources. Drivers must have matching values of IONIC_API_VERSION at compile
+ * time, to be considered compatible at run time.
+ */
+#define IONIC_API_VERSION "3"
+
+#define IONIC_DEVCMD_TIMEOUT 30 /* devcmd_timeout */
+
+struct ionic_adapter;
+
+struct ionic_dev_bar {
+ void __iomem *vaddr;
+ rte_iova_t bus_addr;
+ unsigned long len;
+};
+
+static inline void ionic_struct_size_checks(void)
+{
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_doorbell) != 8);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_intr) != 32);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_intr_status) != 8);
+
+ RTE_BUILD_BUG_ON(sizeof(union ionic_dev_regs) != 4096);
+ RTE_BUILD_BUG_ON(sizeof(union ionic_dev_info_regs) != 2048);
+ RTE_BUILD_BUG_ON(sizeof(union ionic_dev_cmd_regs) != 2048);
+
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_stats) != 1024);
+
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_admin_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_admin_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_nop_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_nop_comp) != 16);
+
+ /* Device commands */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_identify_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_identify_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_init_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_init_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_reset_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_reset_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_getattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_getattr_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_setattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_dev_setattr_comp) != 16);
+
+ /* Port commands */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_identify_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_identify_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_init_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_init_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_reset_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_reset_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_getattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_getattr_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_setattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_port_setattr_comp) != 16);
+
+ /* LIF commands */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_init_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_init_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_reset_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_getattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_getattr_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_setattr_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_lif_setattr_comp) != 16);
+
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_q_init_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_q_init_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_q_control_cmd) != 64);
+
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rx_mode_set_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rx_filter_add_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rx_filter_add_comp) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rx_filter_del_cmd) != 64);
+
+ /* RDMA commands */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rdma_reset_cmd) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rdma_queue_cmd) != 64);
+
+ /* Events */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_notifyq_cmd) != 4);
+ RTE_BUILD_BUG_ON(sizeof(union ionic_notifyq_comp) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_notifyq_event) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_link_change_event) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_reset_event) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_heartbeat_event) != 64);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_log_event) != 64);
+
+ /* I/O */
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_txq_desc) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_txq_sg_desc) != 128);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_txq_comp) != 16);
+
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rxq_desc) != 16);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rxq_sg_desc) != 128);
+ RTE_BUILD_BUG_ON(sizeof(struct ionic_rxq_comp) != 16);
+}
+
+struct ionic_dev {
+ union ionic_dev_info_regs __iomem *dev_info;
+ union ionic_dev_cmd_regs __iomem *dev_cmd;
+
+ struct ionic_doorbell __iomem *db_pages;
+ rte_iova_t phy_db_pages;
+
+ struct ionic_intr __iomem *intr_ctrl;
+
+ struct ionic_intr_status __iomem *intr_status;
+};
+
+int ionic_dev_setup(struct ionic_adapter *adapter);
+
+void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd);
+uint8_t ionic_dev_cmd_status(struct ionic_dev *idev);
+bool ionic_dev_cmd_done(struct ionic_dev *idev);
+void ionic_dev_cmd_comp(struct ionic_dev *idev, void *mem);
+
+void ionic_dev_cmd_identify(struct ionic_dev *idev, uint8_t ver);
+void ionic_dev_cmd_init(struct ionic_dev *idev);
+void ionic_dev_cmd_reset(struct ionic_dev *idev);
+
+#endif /* _IONIC_DEV_H_ */
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 863d20d19..148d6f236 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -2,11 +2,147 @@
* Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
*/
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
+#include <rte_malloc.h>
+
#include "ionic_logs.h"
+#include "ionic.h"
+#include "ionic_dev.h"
+#include "ionic_mac_api.h"
int ionic_logtype_init;
int ionic_logtype_driver;
+static const struct rte_pci_id pci_id_ionic_map[] = {
+ { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_PF) },
+ { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_VF) },
+ { RTE_PCI_DEVICE(IONIC_PENSANDO_VENDOR_ID, IONIC_DEV_ID_ETH_MGMT) },
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+/*
+ * There is no room in struct rte_pci_driver to keep a reference
+ * to the adapter, using a static list for the time being.
+ */
+static LIST_HEAD(ionic_pci_adapters_list, ionic_adapter) ionic_pci_adapters =
+ LIST_HEAD_INITIALIZER(ionic_pci_adapters);
+static rte_spinlock_t ionic_pci_adapters_lock = RTE_SPINLOCK_INITIALIZER;
+
+static int
+eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ struct rte_mem_resource *resource;
+ struct ionic_adapter *adapter;
+ struct ionic_hw *hw;
+ unsigned long i;
+ int err;
+
+ /* Multi-process not supported */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ ionic_init_print(DEBUG, "Initializing device %s %s",
+ pci_dev->device.name,
+ rte_eal_process_type() == RTE_PROC_SECONDARY ?
+ "[SECONDARY]" : "");
+
+ adapter = rte_zmalloc("ionic", sizeof(*adapter), 0);
+
+ if (!adapter) {
+ ionic_init_print(ERR, "OOM");
+ return -ENOMEM;
+ }
+
+ adapter->pci_dev = pci_dev;
+ hw = &adapter->hw;
+
+ hw->device_id = pci_dev->id.device_id;
+ hw->vendor_id = pci_dev->id.vendor_id;
+
+ err = ionic_init_mac(hw);
+ if (err != 0) {
+ ionic_init_print(ERR, "Mac init failed: %d", err);
+ return -EIO;
+ }
+
+ adapter->is_mgmt_nic = (pci_dev->id.device_id == IONIC_DEV_ID_ETH_MGMT);
+
+ adapter->num_bars = 0;
+ for (i = 0; i < PCI_MAX_RESOURCE && i < IONIC_BARS_MAX; i++) {
+ resource = &pci_dev->mem_resource[i];
+ if (resource->phys_addr == 0 || resource->len == 0)
+ continue;
+ adapter->bars[adapter->num_bars].vaddr = resource->addr;
+ adapter->bars[adapter->num_bars].bus_addr = resource->phys_addr;
+ adapter->bars[adapter->num_bars].len = resource->len;
+ adapter->num_bars++;
+ }
+
+ /* Discover ionic dev resources */
+
+ err = ionic_setup(adapter);
+ if (err) {
+ ionic_init_print(ERR, "Cannot setup device: %d, aborting", err);
+ return err;
+ }
+
+ err = ionic_identify(adapter);
+ if (err) {
+ ionic_init_print(ERR, "Cannot identify device: %d, aborting",
+ err);
+ return err;
+ }
+
+ err = ionic_init(adapter);
+ if (err) {
+ ionic_init_print(ERR, "Cannot init device: %d, aborting", err);
+ return err;
+ }
+
+ rte_spinlock_lock(&ionic_pci_adapters_lock);
+ LIST_INSERT_HEAD(&ionic_pci_adapters, adapter, pci_adapters);
+ rte_spinlock_unlock(&ionic_pci_adapters_lock);
+
+ return 0;
+}
+
+static int
+eth_ionic_pci_remove(struct rte_pci_device *pci_dev)
+{
+ struct ionic_adapter *adapter = NULL;
+
+ rte_spinlock_lock(&ionic_pci_adapters_lock);
+ LIST_FOREACH(adapter, &ionic_pci_adapters, pci_adapters) {
+ if (adapter->pci_dev == pci_dev)
+ break;
+
+ adapter = NULL;
+ }
+ if (adapter)
+ LIST_REMOVE(adapter, pci_adapters);
+ rte_spinlock_unlock(&ionic_pci_adapters_lock);
+
+ if (adapter)
+ rte_free(adapter);
+
+ return 0;
+}
+
+static struct rte_pci_driver rte_ionic_pmd = {
+ .id_table = pci_id_ionic_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+ .probe = eth_ionic_pci_probe,
+ .remove = eth_ionic_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_ionic, rte_ionic_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_ionic, pci_id_ionic_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_ionic, "* igb_uio | uio_pci_generic | vfio-pci");
+
RTE_INIT(ionic_init_log)
{
ionic_logtype_init = rte_log_register("pmd.net.ionic.init");
@@ -14,6 +150,8 @@ RTE_INIT(ionic_init_log)
if (ionic_logtype_init >= 0)
rte_log_set_level(ionic_logtype_init, RTE_LOG_NOTICE);
+ ionic_struct_size_checks();
+
ionic_logtype_driver = rte_log_register("pmd.net.ionic.driver");
if (ionic_logtype_driver >= 0)
diff --git a/drivers/net/ionic/ionic_mac_api.c b/drivers/net/ionic/ionic_mac_api.c
new file mode 100644
index 000000000..5413afa93
--- /dev/null
+++ b/drivers/net/ionic/ionic_mac_api.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#include "ionic_mac_api.h"
+
+int32_t
+ionic_init_mac(struct ionic_hw *hw)
+{
+ int err = 0;
+
+ ionic_drv_print_call();
+
+ /*
+ * Set the mac type
+ */
+ ionic_set_mac_type(hw);
+
+ switch (hw->mac.type) {
+ case IONIC_MAC_CAPRI:
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+int32_t
+ionic_set_mac_type(struct ionic_hw *hw)
+{
+ int err = 0;
+
+ ionic_drv_print_call();
+
+ if (hw->vendor_id != IONIC_PENSANDO_VENDOR_ID) {
+ ionic_drv_print(ERR, "Unsupported vendor id: %x",
+ hw->vendor_id);
+ return -EINVAL;
+ }
+
+ switch (hw->device_id) {
+ case IONIC_DEV_ID_ETH_PF:
+ case IONIC_DEV_ID_ETH_VF:
+ case IONIC_DEV_ID_ETH_MGMT:
+ hw->mac.type = IONIC_MAC_CAPRI;
+ break;
+ default:
+ err = -EINVAL;
+ ionic_drv_print(ERR, "Unsupported device id: %x",
+ hw->device_id);
+ break;
+ }
+
+ ionic_drv_print(INFO, "Mac: %d (%d)\n",
+ hw->mac.type, err);
+
+ return err;
+}
+
diff --git a/drivers/net/ionic/ionic_mac_api.h b/drivers/net/ionic/ionic_mac_api.h
new file mode 100644
index 000000000..41f9328f3
--- /dev/null
+++ b/drivers/net/ionic/ionic_mac_api.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_API_H_
+#define _IONIC_API_H_
+
+#include "ionic.h"
+
+int32_t ionic_init_mac(struct ionic_hw *hw);
+int32_t ionic_set_mac_type(struct ionic_hw *hw);
+
+#endif /* _IONIC_API_H_ */
diff --git a/drivers/net/ionic/ionic_main.c b/drivers/net/ionic/ionic_main.c
new file mode 100644
index 000000000..79a141140
--- /dev/null
+++ b/drivers/net/ionic/ionic_main.c
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#include "ionic.h"
+
+static int
+ionic_dev_cmd_wait(struct ionic_dev *idev, unsigned long max_wait)
+{
+ unsigned long step_msec = 100;
+ unsigned int max_wait_msec = max_wait * 1000;
+ unsigned long elapsed_msec = 0;
+ int done;
+
+ /* Wait for dev cmd to complete.. but no more than max_wait sec */
+
+ do {
+ done = ionic_dev_cmd_done(idev);
+
+ if (done) {
+ ionic_drv_print(DEBUG, "DEVCMD %d done took %ld msecs\n",
+ idev->dev_cmd->cmd.cmd.opcode,
+ elapsed_msec);
+ return 0;
+ }
+
+ msec_delay(step_msec);
+
+ elapsed_msec += step_msec;
+ } while (elapsed_msec < max_wait_msec);
+
+ ionic_drv_print(DEBUG, "DEVCMD %d timeout after %ld msecs\n",
+ idev->dev_cmd->cmd.cmd.opcode,
+ elapsed_msec);
+
+ return -ETIMEDOUT;
+}
+
+static int
+ionic_dev_cmd_check_error(struct ionic_dev *idev)
+{
+ uint8_t status;
+
+ status = ionic_dev_cmd_status(idev);
+
+ if (status == 0)
+ return 0;
+
+ return -EIO;
+}
+
+int
+ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait)
+{
+ int err;
+
+ err = ionic_dev_cmd_wait(idev, max_wait);
+
+ if (err)
+ return err;
+
+ return ionic_dev_cmd_check_error(idev);
+}
+
+int
+ionic_setup(struct ionic_adapter *adapter)
+{
+ return ionic_dev_setup(adapter);
+}
+
+int
+ionic_identify(struct ionic_adapter *adapter)
+{
+ struct ionic_dev *idev = &adapter->idev;
+ struct ionic_identity *ident = &adapter->ident;
+ int err = 0;
+ uint32_t i;
+ unsigned int nwords;
+ uint32_t drv_size = sizeof(ident->drv.words) /
+ sizeof(ident->drv.words[0]);
+ uint32_t cmd_size = sizeof(idev->dev_cmd->data) /
+ sizeof(idev->dev_cmd->data[0]);
+ uint32_t dev_size = sizeof(ident->dev.words) /
+ sizeof(ident->dev.words[0]);
+
+ memset(ident, 0, sizeof(*ident));
+
+ ident->drv.os_type = IONIC_OS_TYPE_LINUX;
+ ident->drv.os_dist = 0;
+ snprintf(ident->drv.os_dist_str,
+ sizeof(ident->drv.os_dist_str), "Unknown");
+ ident->drv.kernel_ver = 0;
+ snprintf(ident->drv.kernel_ver_str,
+ sizeof(ident->drv.kernel_ver_str), "DPDK");
+ strncpy(ident->drv.driver_ver_str, IONIC_DRV_VERSION,
+ sizeof(ident->drv.driver_ver_str) - 1);
+
+ nwords = RTE_MIN(drv_size, cmd_size);
+ for (i = 0; i < nwords; i++)
+ iowrite32(ident->drv.words[i], &idev->dev_cmd->data[i]);
+
+ ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1);
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (!err) {
+ nwords = RTE_MIN(dev_size, cmd_size);
+ for (i = 0; i < nwords; i++)
+ ident->dev.words[i] = ioread32(&idev->dev_cmd->data[i]);
+ }
+
+ return err;
+}
+
+int
+ionic_init(struct ionic_adapter *adapter)
+{
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ ionic_dev_cmd_init(idev);
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ return err;
+}
+
+int
+ionic_reset(struct ionic_adapter *adapter)
+{
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ ionic_dev_cmd_reset(idev);
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ return err;
+}
diff --git a/drivers/net/ionic/ionic_osdep.h b/drivers/net/ionic/ionic_osdep.h
new file mode 100644
index 000000000..5b8baa67b
--- /dev/null
+++ b/drivers/net/ionic/ionic_osdep.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_OSDEP_
+#define _IONIC_OSDEP_
+
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_log.h>
+#include <rte_byteorder.h>
+#include <rte_io.h>
+#include <rte_memory.h>
+
+#include "ionic_logs.h"
+
+#define DELAY(x) rte_delay_us(x)
+#define usec_delay(x) DELAY(x)
+#define msec_delay(x) DELAY(1000 * (x))
+
+#define BIT(nr) (1UL << (nr))
+#define BIT_ULL(nr) (1ULL << (nr))
+#define BITS_TO_LONGS(nr) div_round_up(nr, 8 * sizeof(long))
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#endif
+
+#define __iomem
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef uint16_t __le16;
+typedef uint32_t __le32;
+typedef uint64_t __le64;
+
+#ifndef __cplusplus
+typedef uint8_t bool;
+#define false 0
+#define true 1
+#endif
+
+static inline uint32_t div_round_up(uint32_t n, uint32_t d)
+{
+ return (n + d - 1) / d;
+}
+
+static inline uint16_t ilog2(uint32_t n)
+{
+ uint16_t logv = -1;
+
+ if (n == 0)
+ return 0;
+
+ while (n) {
+ logv++;
+ n >>= 1;
+ }
+
+ return logv;
+}
+
+#define ioread8(reg) rte_read8(reg)
+#define ioread32(reg) rte_read32(reg)
+#define iowrite8(value, reg) rte_write8(value, reg)
+#define iowrite32(value, reg) rte_write32(value, reg)
+#define writeq(value, reg) rte_write64(value, reg)
+
+#endif
diff --git a/drivers/net/ionic/ionic_regs.h b/drivers/net/ionic/ionic_regs.h
new file mode 100644
index 000000000..e213062c9
--- /dev/null
+++ b/drivers/net/ionic/ionic_regs.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_REGS_H_
+#define _IONIC_REGS_H_
+
+/** struct ionic_intr - interrupt control register set.
+ * @coal_init: coalesce timer initial value.
+ * @mask: interrupt mask value.
+ * @credits: interrupt credit count and return.
+ * @mask_assert: interrupt mask value on assert.
+ * @coal: coalesce timer time remaining.
+ */
+struct ionic_intr {
+ uint32_t coal_init;
+ uint32_t mask;
+ uint32_t credits;
+ uint32_t mask_assert;
+ uint32_t coal;
+ uint32_t rsvd[3];
+};
+
+#define IONIC_INTR_CTRL_REGS_MAX 2048
+#define IONIC_INTR_CTRL_COAL_MAX 0x3F
+
+/** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
+ * @IONIC_INTR_MASK_CLEAR: unmask interrupt.
+ * @IONIC_INTR_MASK_SET: mask interrupt.
+ */
+enum ionic_intr_mask_vals {
+ IONIC_INTR_MASK_CLEAR = 0,
+ IONIC_INTR_MASK_SET = 1,
+};
+
+/** enum ionic_intr_credits_bits - bitwise composition of credits values.
+ * @IONIC_INTR_CRED_COUNT: bit mask of credit count, no shift needed.
+ * @IONIC_INTR_CRED_COUNT_SIGNED: bit mask of credit count, including sign bit.
+ * @IONIC_INTR_CRED_UNMASK: unmask the interrupt.
+ * @IONIC_INTR_CRED_RESET_COALESCE: reset the coalesce timer.
+ * @IONIC_INTR_CRED_REARM: unmask the and reset the timer.
+ */
+enum ionic_intr_credits_bits {
+ IONIC_INTR_CRED_COUNT = 0x7fffu,
+ IONIC_INTR_CRED_COUNT_SIGNED = 0xffffu,
+ IONIC_INTR_CRED_UNMASK = 0x10000u,
+ IONIC_INTR_CRED_RESET_COALESCE = 0x20000u,
+ IONIC_INTR_CRED_REARM = (IONIC_INTR_CRED_UNMASK |
+ IONIC_INTR_CRED_RESET_COALESCE),
+};
+
+static inline void
+ionic_intr_coal_init(struct ionic_intr __iomem *intr_ctrl,
+ int intr_idx, uint32_t coal)
+{
+ iowrite32(coal, &intr_ctrl[intr_idx].coal_init);
+}
+
+static inline void
+ionic_intr_mask(struct ionic_intr __iomem *intr_ctrl,
+ int intr_idx, uint32_t mask)
+{
+ iowrite32(mask, &intr_ctrl[intr_idx].mask);
+}
+
+static inline void
+ionic_intr_credits(struct ionic_intr __iomem *intr_ctrl,
+ int intr_idx, uint32_t cred, uint32_t flags)
+{
+ if (cred > IONIC_INTR_CRED_COUNT) {
+ IONIC_WARN_ON(cred > IONIC_INTR_CRED_COUNT);
+ cred = ioread32(&intr_ctrl[intr_idx].credits);
+ cred &= IONIC_INTR_CRED_COUNT_SIGNED;
+ }
+
+ iowrite32(cred | flags, &intr_ctrl[intr_idx].credits);
+}
+
+static inline void
+ionic_intr_clean(struct ionic_intr __iomem *intr_ctrl,
+ int intr_idx)
+{
+ uint32_t cred;
+
+ cred = ioread32(&intr_ctrl[intr_idx].credits);
+ cred &= IONIC_INTR_CRED_COUNT_SIGNED;
+ cred |= IONIC_INTR_CRED_RESET_COALESCE;
+ iowrite32(cred, &intr_ctrl[intr_idx].credits);
+}
+
+static inline void
+ionic_intr_mask_assert(struct ionic_intr __iomem *intr_ctrl,
+ int intr_idx, uint32_t mask)
+{
+ iowrite32(mask, &intr_ctrl[intr_idx].mask_assert);
+}
+
+/** enum ionic_dbell_bits - bitwise composition of dbell values.
+ *
+ * @IONIC_DBELL_QID_MASK: unshifted mask of valid queue id bits.
+ * @IONIC_DBELL_QID_SHIFT: queue id shift amount in dbell value.
+ * @IONIC_DBELL_QID: macro to build QID component of dbell value.
+ *
+ * @IONIC_DBELL_RING_MASK: unshifted mask of valid ring bits.
+ * @IONIC_DBELL_RING_SHIFT: ring shift amount in dbell value.
+ * @IONIC_DBELL_RING: macro to build ring component of dbell value.
+ *
+ * @IONIC_DBELL_RING_0: ring zero dbell component value.
+ * @IONIC_DBELL_RING_1: ring one dbell component value.
+ * @IONIC_DBELL_RING_2: ring two dbell component value.
+ * @IONIC_DBELL_RING_3: ring three dbell component value.
+ *
+ * @IONIC_DBELL_INDEX_MASK: bit mask of valid index bits, no shift needed.
+ */
+enum ionic_dbell_bits {
+ IONIC_DBELL_QID_MASK = 0xffffff,
+ IONIC_DBELL_QID_SHIFT = 24,
+
+#define IONIC_DBELL_QID(n) \
+ (((u64)(n) & IONIC_DBELL_QID_MASK) << IONIC_DBELL_QID_SHIFT)
+
+ IONIC_DBELL_RING_MASK = 0x7,
+ IONIC_DBELL_RING_SHIFT = 16,
+
+#define IONIC_DBELL_RING(n) \
+ (((u64)(n) & IONIC_DBELL_RING_MASK) << IONIC_DBELL_RING_SHIFT)
+
+ IONIC_DBELL_RING_0 = 0,
+ IONIC_DBELL_RING_1 = IONIC_DBELL_RING(1),
+ IONIC_DBELL_RING_2 = IONIC_DBELL_RING(2),
+ IONIC_DBELL_RING_3 = IONIC_DBELL_RING(3),
+
+ IONIC_DBELL_INDEX_MASK = 0xffff,
+};
+
+static inline void
+ionic_dbell_ring(u64 __iomem *db_page, int qtype, u64 val)
+{
+ writeq(val, &db_page[qtype]);
+}
+
+#endif /* _IONIC_REGS_H_ */
diff --git a/drivers/net/ionic/meson.build b/drivers/net/ionic/meson.build
index 5534ad6c3..bd63e6136 100644
--- a/drivers/net/ionic/meson.build
+++ b/drivers/net/ionic/meson.build
@@ -4,6 +4,10 @@
version = 1
sources = files(
+ 'ionic_mac_api.c',
+ 'ionic_dev.c',
+ 'ionic_ethdev.c',
+ 'ionic_main.c',
'ionic_ethdev.c'
)
--
2.17.1
next prev parent reply other threads:[~2019-10-15 8:23 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-15 8:22 [dpdk-dev] [PATCH v2 00/17] Introduces net/ionic PMD Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 01/17] net/ionic: add skeleton Alfredo Cardigliano
2019-12-02 16:06 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 02/17] net/ionic: add hardware structures definitions Alfredo Cardigliano
2019-12-02 16:07 ` Ferruh Yigit
2019-12-02 16:33 ` Stephen Hemminger
2019-12-04 16:26 ` Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 03/17] net/ionic: add log Alfredo Cardigliano
2019-12-02 16:07 ` Ferruh Yigit
2019-10-15 8:22 ` Alfredo Cardigliano [this message]
2019-12-02 16:09 ` [dpdk-dev] [PATCH v2 04/17] net/ionic: register and initialize the adapter Ferruh Yigit
2019-12-08 19:25 ` Alfredo Cardigliano
2019-12-09 9:12 ` Ferruh Yigit
2019-12-02 16:35 ` Stephen Hemminger
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 05/17] net/ionic: add port management commands Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 06/17] net/ionic: add basic lif support Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 07/17] net/ionic: add doorbells Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 08/17] net/ionic: add adminq support Alfredo Cardigliano
2019-12-02 16:15 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 09/17] net/ionic: add notifyq support Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 10/17] net/ionic: add basic port operations Alfredo Cardigliano
2019-12-02 16:11 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 11/17] net/ionic: add RX filters support Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 12/17] net/ionic: add Flow Control support Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 13/17] net/ionic: add RX and TX handling Alfredo Cardigliano
2019-12-02 16:13 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 14/17] net/ionic: add RSS support Alfredo Cardigliano
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 15/17] net/ionic: add stats Alfredo Cardigliano
2019-12-02 16:14 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 16/17] net/ionic: add TX checksum support Alfredo Cardigliano
2019-12-02 16:15 ` Ferruh Yigit
2019-10-15 8:22 ` [dpdk-dev] [PATCH v2 17/17] net/ionic: read fw version Alfredo Cardigliano
2019-10-15 13:09 ` [dpdk-dev] [PATCH v2 00/17] Introduces net/ionic PMD Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191015082235.28639-5-cardigliano@ntop.org \
--to=cardigliano@ntop.org \
--cc=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=john.mcnamara@intel.com \
--cc=marko.kovacevic@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).