net/ionic: register and initialize adapter
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>
This commit is contained in:
parent
7c12539358
commit
5ef518098e
@ -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
|
||||
|
@ -20,6 +20,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
|
||||
|
64
drivers/net/ionic/ionic.h
Normal file
64
drivers/net/ionic/ionic.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
|
||||
* Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _IONIC_H_
|
||||
#define _IONIC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.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_ */
|
134
drivers/net/ionic/ionic_dev.c
Normal file
134
drivers/net/ionic/ionic_dev.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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;
|
||||
u_char *bar0_base;
|
||||
|
||||
/* BAR0: dev_cmd and interrupts */
|
||||
if (num_bars < 1) {
|
||||
IONIC_PRINT(ERR, "No bars found, aborting");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (bar->len < IONIC_BAR0_SIZE) {
|
||||
IONIC_PRINT(ERR,
|
||||
"Resource bar size %lu too small, aborting",
|
||||
bar->len);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
bar0_base = bar->vaddr;
|
||||
idev->dev_info = (union ionic_dev_info_regs *)
|
||||
&bar0_base[IONIC_BAR0_DEV_INFO_REGS_OFFSET];
|
||||
idev->dev_cmd = (union ionic_dev_cmd_regs *)
|
||||
&bar0_base[IONIC_BAR0_DEV_CMD_REGS_OFFSET];
|
||||
idev->intr_status = (struct ionic_intr_status *)
|
||||
&bar0_base[IONIC_BAR0_INTR_STATUS_OFFSET];
|
||||
idev->intr_ctrl = (struct ionic_intr *)
|
||||
&bar0_base[IONIC_BAR0_INTR_CTRL_OFFSET];
|
||||
|
||||
sig = ioread32(&idev->dev_info->signature);
|
||||
if (sig != IONIC_DEV_INFO_SIGNATURE) {
|
||||
IONIC_PRINT(ERR, "Incompatible firmware signature %" PRIx32 "",
|
||||
sig);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* BAR1: doorbells */
|
||||
bar++;
|
||||
if (num_bars < 2) {
|
||||
IONIC_PRINT(ERR, "Doorbell bar missing, aborting");
|
||||
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);
|
||||
}
|
127
drivers/net/ionic/ionic_dev.h
Normal file
127
drivers/net/ionic/ionic_dev.h
Normal file
@ -0,0 +1,127 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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"
|
||||
|
||||
#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_ */
|
@ -2,10 +2,127 @@
|
||||
* 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;
|
||||
|
||||
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 */ },
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
/* Check structs (trigger error at compilation time) */
|
||||
ionic_struct_size_checks();
|
||||
|
||||
/* Multi-process not supported */
|
||||
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
||||
err = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
IONIC_PRINT(DEBUG, "Initializing device %s",
|
||||
pci_dev->device.name);
|
||||
|
||||
adapter = rte_zmalloc("ionic", sizeof(*adapter), 0);
|
||||
if (!adapter) {
|
||||
IONIC_PRINT(ERR, "OOM");
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
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_PRINT(ERR, "Mac init failed: %d", err);
|
||||
err = -EIO;
|
||||
goto err_free_adapter;
|
||||
}
|
||||
|
||||
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_PRINT(ERR, "Cannot setup device: %d, aborting", err);
|
||||
goto err_free_adapter;
|
||||
}
|
||||
|
||||
err = ionic_identify(adapter);
|
||||
if (err) {
|
||||
IONIC_PRINT(ERR, "Cannot identify device: %d, aborting",
|
||||
err);
|
||||
goto err_free_adapter;
|
||||
}
|
||||
|
||||
err = ionic_init(adapter);
|
||||
if (err) {
|
||||
IONIC_PRINT(ERR, "Cannot init device: %d, aborting", err);
|
||||
goto err_free_adapter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_adapter:
|
||||
rte_free(adapter);
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
|
||||
{
|
||||
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 = rte_log_register("pmd.net.ionic");
|
||||
|
61
drivers/net/ionic/ionic_mac_api.c
Normal file
61
drivers/net/ionic/ionic_mac_api.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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_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_PRINT_CALL();
|
||||
|
||||
if (hw->vendor_id != IONIC_PENSANDO_VENDOR_ID) {
|
||||
IONIC_PRINT(ERR, "Unsupported vendor id: %" PRIx32 "",
|
||||
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_PRINT(ERR, "Unsupported device id: %" PRIx32 "",
|
||||
hw->device_id);
|
||||
break;
|
||||
}
|
||||
|
||||
IONIC_PRINT(INFO, "Mac: %d (%d)",
|
||||
hw->mac.type, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
13
drivers/net/ionic/ionic_mac_api.h
Normal file
13
drivers/net/ionic/ionic_mac_api.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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_ */
|
130
drivers/net/ionic/ionic_main.c
Normal file
130
drivers/net/ionic/ionic_main.c
Normal file
@ -0,0 +1,130 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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_PRINT(DEBUG, "DEVCMD %d done took %ld msecs",
|
||||
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_PRINT(DEBUG, "DEVCMD %d timeout after %ld msecs",
|
||||
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;
|
||||
}
|
64
drivers/net/ionic/ionic_osdep.h
Normal file
64
drivers/net/ionic/ionic_osdep.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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;
|
||||
}
|
||||
|
||||
#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
|
142
drivers/net/ionic/ionic_regs.h
Normal file
142
drivers/net/ionic/ionic_regs.h
Normal file
@ -0,0 +1,142 @@
|
||||
/* SPDX-License-Identifier: (BSD-3-Clause OR 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_ */
|
@ -2,6 +2,9 @@
|
||||
# Copyright(c) 2019 Pensando
|
||||
|
||||
sources = files(
|
||||
'ionic_ethdev.c'
|
||||
'ionic_mac_api.c',
|
||||
'ionic_dev.c',
|
||||
'ionic_ethdev.c',
|
||||
'ionic_main.c'
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user