[PATCH v2 net-next 04/19] ionic: Add basic lif support
From: Shannon Nelson <hidden>
Date: 2019-06-28 21:39:51
Subsystem:
networking drivers, pensando ethernet drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Brett Creeley, Linus Torvalds
The LIF is the Logical Interface, which represents the external connections. The NIC can multiplex many LIFs to a single port, but in most setups, LIF0 is the primary control for the port. Signed-off-by: Shannon Nelson <redacted> --- drivers/net/ethernet/pensando/ionic/Makefile | 3 +- drivers/net/ethernet/pensando/ionic/ionic.h | 8 +- .../net/ethernet/pensando/ionic/ionic_bus.h | 2 + .../ethernet/pensando/ionic/ionic_bus_pci.c | 48 +++ .../ethernet/pensando/ionic/ionic_debugfs.c | 47 +++ .../ethernet/pensando/ionic/ionic_debugfs.h | 6 + .../net/ethernet/pensando/ionic/ionic_dev.c | 34 ++ .../net/ethernet/pensando/ionic/ionic_dev.h | 7 + .../net/ethernet/pensando/ionic/ionic_lif.c | 296 ++++++++++++++++++ .../net/ethernet/pensando/ionic/ionic_lif.h | 70 +++++ .../net/ethernet/pensando/ionic/ionic_main.c | 1 + 11 files changed, 520 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_lif.c create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_lif.h
diff --git a/drivers/net/ethernet/pensando/ionic/Makefile b/drivers/net/ethernet/pensando/ionic/Makefile
index 49a8e28a5c84..04d519d00be6 100644
--- a/drivers/net/ethernet/pensando/ionic/Makefile
+++ b/drivers/net/ethernet/pensando/ionic/Makefile@@ -3,4 +3,5 @@ obj-$(CONFIG_IONIC) := ionic.o -ionic-y := ionic_main.o ionic_bus_pci.o ionic_dev.o ionic_debugfs.o +ionic-y := ionic_main.o ionic_bus_pci.o ionic_dev.o ionic_debugfs.o \ + ionic_lif.o
diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h b/drivers/net/ethernet/pensando/ionic/ionic.h
index f77712feef5c..afff2e074f1a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h@@ -6,7 +6,6 @@ #include "ionic_if.h" #include "ionic_dev.h" -#include "ionic_debugfs.h" #define DRV_NAME "ionic" #define DRV_DESCRIPTION "Pensando Ethernet NIC Driver"
@@ -32,6 +31,13 @@ struct ionic { struct ionic_dev_bar bars[IONIC_BARS_MAX]; unsigned int num_bars; struct identity ident; + struct list_head lifs; + unsigned int nnqs_per_lif; + unsigned int neqs_per_lif; + unsigned int ntxqs_per_lif; + unsigned int nrxqs_per_lif; + DECLARE_BITMAP(lifbits, IONIC_LIFS_MAX); + unsigned int nintrs; }; int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus.h b/drivers/net/ethernet/pensando/ionic/ionic_bus.h
index 24b4c01ec03f..3b1e2d0ebf8f 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_bus.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_bus.h@@ -5,6 +5,8 @@ #define _IONIC_BUS_H_ const char *ionic_bus_info(struct ionic *ionic); +int ionic_bus_alloc_irq_vectors(struct ionic *ionic, unsigned int nintrs); +void ionic_bus_free_irq_vectors(struct ionic *ionic); int ionic_bus_register_driver(void); void ionic_bus_unregister_driver(void);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
index 7a41f8995c35..0ed724efe117 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c@@ -8,6 +8,8 @@ #include "ionic.h" #include "ionic_bus.h" +#include "ionic_lif.h" +#include "ionic_debugfs.h" /* Supported devices */ static const struct pci_device_id ionic_id_table[] = {
@@ -22,6 +24,17 @@ const char *ionic_bus_info(struct ionic *ionic) return pci_name(ionic->pdev); } +int ionic_bus_alloc_irq_vectors(struct ionic *ionic, unsigned int nintrs) +{ + return pci_alloc_irq_vectors(ionic->pdev, nintrs, nintrs, + PCI_IRQ_MSIX); +} + +void ionic_bus_free_irq_vectors(struct ionic *ionic) +{ + pci_free_irq_vectors(ionic->pdev); +} + static int ionic_map_bars(struct ionic *ionic) { struct pci_dev *pdev = ionic->pdev;
@@ -150,8 +163,40 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_reset; } + /* Configure LIFs */ + err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC, + &ionic->ident.lif); + if (err) { + dev_err(dev, "Cannot identify LIFs: %d, aborting\n", err); + goto err_out_port_reset; + } + + err = ionic_lifs_size(ionic); + if (err) { + dev_err(dev, "Cannot size LIFs: %d, aborting\n", err); + goto err_out_port_reset; + } + + err = ionic_lifs_alloc(ionic); + if (err) { + dev_err(dev, "Cannot allocate LIFs: %d, aborting\n", err); + goto err_out_free_irqs; + } + + err = ionic_lifs_init(ionic); + if (err) { + dev_err(dev, "Cannot init LIFs: %d, aborting\n", err); + goto err_out_free_lifs; + } + return 0; +err_out_free_lifs: + ionic_lifs_free(ionic); +err_out_free_irqs: + ionic_bus_free_irq_vectors(ionic); +err_out_port_reset: + ionic_port_reset(ionic); err_out_reset: ionic_reset(ionic); err_out_teardown:
@@ -177,6 +222,9 @@ static void ionic_remove(struct pci_dev *pdev) struct ionic *ionic = pci_get_drvdata(pdev); if (ionic) { + ionic_lifs_deinit(ionic); + ionic_lifs_free(ionic); + ionic_bus_free_irq_vectors(ionic); ionic_port_reset(ionic); ionic_reset(ionic); ionic_dev_teardown(ionic);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_debugfs.c b/drivers/net/ethernet/pensando/ionic/ionic_debugfs.c
index c33a8bfcbcd4..a2a566695f63 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_debugfs.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_debugfs.c@@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ +#include <linux/pci.h> #include <linux/netdevice.h> #include "ionic.h" #include "ionic_bus.h" +#include "ionic_lif.h" #include "ionic_debugfs.h" #ifdef CONFIG_DEBUG_FS
@@ -64,4 +66,49 @@ int ionic_debugfs_add_ident(struct ionic *ionic) ionic, &identity_fops) ? 0 : -ENOTSUPP; } +int ionic_debugfs_add_sizes(struct ionic *ionic) +{ + debugfs_create_u32("nlifs", 0400, ionic->dentry, + (u32 *)&ionic->ident.dev.nlifs); + debugfs_create_u32("nintrs", 0400, ionic->dentry, &ionic->nintrs); + + debugfs_create_u32("ntxqs_per_lif", 0400, ionic->dentry, + (u32 *)&ionic->ident.lif.eth.config.queue_count[IONIC_QTYPE_TXQ]); + debugfs_create_u32("nrxqs_per_lif", 0400, ionic->dentry, + (u32 *)&ionic->ident.lif.eth.config.queue_count[IONIC_QTYPE_RXQ]); + + return 0; +} + +static int netdev_show(struct seq_file *seq, void *v) +{ + struct net_device *netdev = seq->private; + + seq_printf(seq, "%s\n", netdev->name); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(netdev); + +int ionic_debugfs_add_lif(struct lif *lif) +{ + struct dentry *netdev_dentry; + + lif->dentry = debugfs_create_dir(lif->name, lif->ionic->dentry); + if (IS_ERR_OR_NULL(lif->dentry)) + return PTR_ERR(lif->dentry); + + netdev_dentry = debugfs_create_file("netdev", 0400, lif->dentry, + lif->netdev, &netdev_fops); + if (IS_ERR_OR_NULL(netdev_dentry)) + return PTR_ERR(netdev_dentry); + + return 0; +} + +void ionic_debugfs_del_lif(struct lif *lif) +{ + debugfs_remove_recursive(lif->dentry); + lif->dentry = NULL; +} #endif
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_debugfs.h b/drivers/net/ethernet/pensando/ionic/ionic_debugfs.h
index c3958b0c15b1..cb00166e7c30 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_debugfs.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_debugfs.h@@ -15,6 +15,9 @@ void ionic_debugfs_del_dev(struct ionic *ionic); int ionic_debugfs_add_bars(struct ionic *ionic); int ionic_debugfs_add_dev_cmd(struct ionic *ionic); int ionic_debugfs_add_ident(struct ionic *ionic); +int ionic_debugfs_add_sizes(struct ionic *ionic); +int ionic_debugfs_add_lif(struct lif *lif); +void ionic_debugfs_del_lif(struct lif *lif); #else static inline void ionic_debugfs_create(void) { } static inline void ionic_debugfs_destroy(void) { }
@@ -23,6 +26,9 @@ static inline void ionic_debugfs_del_dev(struct ionic *ionic) { } static inline int ionic_debugfs_add_bars(struct ionic *ionic) { return 0; } static inline int ionic_debugfs_add_dev_cmd(struct ionic *ionic) { return 0; } static inline int ionic_debugfs_add_ident(struct ionic *ionic) { return 0; } +static inline int ionic_debugfs_add_sizes(struct ionic *ionic) { return 0; } +static inline int ionic_debugfs_add_lif(struct lif *lif) { return 0; } +static inline void ionic_debugfs_del_lif(struct lif *lif) { return 0; } #endif #endif /* _IONIC_DEBUGFS_H_ */
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index e2eda2bedac6..59d863e45072 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c@@ -246,3 +246,37 @@ void ionic_dev_cmd_port_loopback(struct ionic_dev *idev, u8 loopback_mode) ionic_dev_cmd_go(idev, &cmd); } + +/* LIF commands */ +void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver) +{ + union dev_cmd cmd = { + .lif_identify.opcode = CMD_OPCODE_LIF_IDENTIFY, + .lif_identify.type = type, + .lif_identify.ver = ver, + }; + + ionic_dev_cmd_go(idev, &cmd); +} + +void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index, + dma_addr_t info_pa) +{ + union dev_cmd cmd = { + .lif_init.opcode = CMD_OPCODE_LIF_INIT, + .lif_init.index = cpu_to_le16(lif_index), + .lif_init.info_pa = cpu_to_le64(info_pa), + }; + + ionic_dev_cmd_go(idev, &cmd); +} + +void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index) +{ + union dev_cmd cmd = { + .lif_init.opcode = CMD_OPCODE_LIF_RESET, + .lif_init.index = cpu_to_le16(lif_index), + }; + + ionic_dev_cmd_go(idev, &cmd); +}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index fe5e1b0e8d55..a8a84734b433 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h@@ -10,6 +10,8 @@ #include "ionic_if.h" #include "ionic_regs.h" +#define IONIC_LIFS_MAX 1024 + struct ionic_dev_bar { void __iomem *vaddr; phys_addr_t bus_addr;
@@ -156,4 +158,9 @@ void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type); void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type); void ionic_dev_cmd_port_loopback(struct ionic_dev *idev, u8 loopback_mode); +void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver); +void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index, + dma_addr_t addr); +void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index); + #endif /* _IONIC_DEV_H_ */
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
new file mode 100644
index 000000000000..da0cee316719
--- /dev/null
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c@@ -0,0 +1,296 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/cpumask.h> + +#include "ionic.h" +#include "ionic_bus.h" +#include "ionic_lif.h" +#include "ionic_debugfs.h" + +static struct lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index) +{ + struct device *dev = ionic->dev; + struct net_device *netdev; + struct lif *lif; + int err; + + netdev = alloc_etherdev_mqs(sizeof(*lif), + ionic->ntxqs_per_lif, ionic->ntxqs_per_lif); + if (!netdev) { + dev_err(dev, "Cannot allocate netdev, aborting\n"); + return ERR_PTR(-ENOMEM); + } + netif_set_real_num_tx_queues(netdev, ionic->ntxqs_per_lif); + netif_set_real_num_rx_queues(netdev, ionic->nrxqs_per_lif); + + SET_NETDEV_DEV(netdev, dev); + + lif = netdev_priv(netdev); + lif->netdev = netdev; + + lif->neqs = ionic->neqs_per_lif; + lif->nxqs = ionic->ntxqs_per_lif; + + lif->ionic = ionic; + lif->index = index; + + snprintf(lif->name, sizeof(lif->name), "lif%u", index); + + /* allocate lif info */ + lif->info_sz = ALIGN(sizeof(*lif->info), PAGE_SIZE); + lif->info = dma_alloc_coherent(dev, lif->info_sz, + &lif->info_pa, GFP_KERNEL); + if (!lif->info) { + dev_err(dev, "Failed to allocate lif info, aborting\n"); + err = -ENOMEM; + goto err_out_free_netdev; + } + + list_add_tail(&lif->list, &ionic->lifs); + + return lif; + +err_out_free_netdev: + free_netdev(lif->netdev); + lif = NULL; + + return ERR_PTR(err); +} + +int ionic_lifs_alloc(struct ionic *ionic) +{ + struct lif *lif; + + INIT_LIST_HEAD(&ionic->lifs); + + /* only build the first lif, others are for later features */ + set_bit(0, ionic->lifbits); + lif = ionic_lif_alloc(ionic, 0); + + return PTR_ERR_OR_ZERO(lif); +} + +static void ionic_lif_reset(struct lif *lif) +{ + struct ionic_dev *idev = &lif->ionic->idev; + + mutex_lock(&lif->ionic->dev_cmd_lock); + ionic_dev_cmd_lif_reset(idev, lif->index); + ionic_dev_cmd_wait(lif->ionic, devcmd_timeout); + mutex_unlock(&lif->ionic->dev_cmd_lock); +} + +static void ionic_lif_free(struct lif *lif) +{ + struct device *dev = lif->ionic->dev; + + ionic_lif_reset(lif); + + /* free lif info */ + if (lif->info) { + dma_free_coherent(dev, lif->info_sz, lif->info, lif->info_pa); + lif->info = NULL; + lif->info_pa = 0; + } + + /* free netdev & lif */ + ionic_debugfs_del_lif(lif); + list_del(&lif->list); + free_netdev(lif->netdev); +} + +void ionic_lifs_free(struct ionic *ionic) +{ + struct list_head *cur, *tmp; + struct lif *lif; + + list_for_each_safe(cur, tmp, &ionic->lifs) { + lif = list_entry(cur, struct lif, list); + + ionic_lif_free(lif); + } +} + +static void ionic_lif_deinit(struct lif *lif) +{ + if (!test_bit(LIF_INITED, lif->state)) + return; + + clear_bit(LIF_INITED, lif->state); + + ionic_lif_reset(lif); +} + +void ionic_lifs_deinit(struct ionic *ionic) +{ + struct list_head *cur, *tmp; + struct lif *lif; + + list_for_each_safe(cur, tmp, &ionic->lifs) { + lif = list_entry(cur, struct lif, list); + ionic_lif_deinit(lif); + } +} + +static int ionic_lif_init(struct lif *lif) +{ + struct ionic_dev *idev = &lif->ionic->idev; + struct lif_init_comp comp; + int err; + + ionic_debugfs_add_lif(lif); + + mutex_lock(&lif->ionic->dev_cmd_lock); + ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa); + err = ionic_dev_cmd_wait(lif->ionic, devcmd_timeout); + ionic_dev_cmd_comp(idev, (union dev_cmd_comp *)&comp); + mutex_unlock(&lif->ionic->dev_cmd_lock); + if (err) + return err; + + lif->hw_index = le16_to_cpu(comp.hw_index); + + set_bit(LIF_INITED, lif->state); + + return 0; +} + +int ionic_lifs_init(struct ionic *ionic) +{ + struct list_head *cur, *tmp; + struct lif *lif; + int err; + + list_for_each_safe(cur, tmp, &ionic->lifs) { + lif = list_entry(cur, struct lif, list); + err = ionic_lif_init(lif); + if (err) + return err; + } + + return 0; +} + +int ionic_lif_identify(struct ionic *ionic, u8 lif_type, + union lif_identity *lid) +{ + struct ionic_dev *idev = &ionic->idev; + size_t sz; + int err; + + sz = min(sizeof(*lid), sizeof(idev->dev_cmd_regs->data)); + + mutex_lock(&ionic->dev_cmd_lock); + ionic_dev_cmd_lif_identify(idev, lif_type, IONIC_IDENTITY_VERSION_1); + err = ionic_dev_cmd_wait(ionic, devcmd_timeout); + memcpy_fromio(lid, &idev->dev_cmd_regs->data, sz); + mutex_unlock(&ionic->dev_cmd_lock); + if (err) + return (err); + + dev_dbg(ionic->dev, "capabilities 0x%llx\n", + le64_to_cpu(lid->capabilities)); + + dev_dbg(ionic->dev, "eth.max_ucast_filters %d\n", + le32_to_cpu(lid->eth.max_ucast_filters)); + dev_dbg(ionic->dev, "eth.max_mcast_filters %d\n", + le32_to_cpu(lid->eth.max_mcast_filters)); + dev_dbg(ionic->dev, "eth.features 0x%llx\n", + le64_to_cpu(lid->eth.config.features)); + dev_dbg(ionic->dev, "eth.queue_count[IONIC_QTYPE_ADMINQ] %d\n", + le32_to_cpu(lid->eth.config.queue_count[IONIC_QTYPE_ADMINQ])); + dev_dbg(ionic->dev, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] %d\n", + le32_to_cpu(lid->eth.config.queue_count[IONIC_QTYPE_NOTIFYQ])); + dev_dbg(ionic->dev, "eth.queue_count[IONIC_QTYPE_RXQ] %d\n", + le32_to_cpu(lid->eth.config.queue_count[IONIC_QTYPE_RXQ])); + dev_dbg(ionic->dev, "eth.queue_count[IONIC_QTYPE_TXQ] %d\n", + le32_to_cpu(lid->eth.config.queue_count[IONIC_QTYPE_TXQ])); + dev_dbg(ionic->dev, "eth.config.name %s\n", lid->eth.config.name); + dev_dbg(ionic->dev, "eth.config.mac %pM\n", lid->eth.config.mac); + dev_dbg(ionic->dev, "eth.config.mtu %d\n", + le32_to_cpu(lid->eth.config.mtu)); + + return 0; +} + +int ionic_lifs_size(struct ionic *ionic) +{ + struct identity *ident = &ionic->ident; + union lif_config *lc = &ident->lif.eth.config; + unsigned int nintrs, dev_nintrs; + unsigned int ntxqs_per_lif; + unsigned int nrxqs_per_lif; + unsigned int neqs_per_lif; + unsigned int nnqs_per_lif; + unsigned int nxqs, neqs; + unsigned int min_intrs; + unsigned int nlifs; + int err; + + nlifs = le32_to_cpu(ident->dev.nlifs); + dev_nintrs = le32_to_cpu(ident->dev.nintrs); + neqs_per_lif = le32_to_cpu(ident->lif.rdma.eq_qtype.qid_count); + nnqs_per_lif = le32_to_cpu(lc->queue_count[IONIC_QTYPE_NOTIFYQ]); + ntxqs_per_lif = le32_to_cpu(lc->queue_count[IONIC_QTYPE_TXQ]); + nrxqs_per_lif = le32_to_cpu(lc->queue_count[IONIC_QTYPE_RXQ]); + + nxqs = min(ntxqs_per_lif, nrxqs_per_lif); + nxqs = min(nxqs, num_online_cpus()); + neqs = min(neqs_per_lif, num_online_cpus()); + +try_again: + /* interrupt usage: + * 1 for master lif adminq/notifyq + * 1 for each CPU for master lif TxRx queue pairs + * whatever's left is for RDMA queues + */ + nintrs = 1 + nxqs + neqs; + min_intrs = 2; /* adminq + 1 TxRx queue pair */ + + if (nintrs > dev_nintrs) + goto try_fewer; + + err = ionic_bus_alloc_irq_vectors(ionic, nintrs); + if (err < 0 && err != -ENOSPC) { + dev_err(ionic->dev, "Can't get intrs from OS: %d\n", err); + return err; + } + if (err == -ENOSPC) + goto try_fewer; + + if (err != nintrs) { + ionic_bus_free_irq_vectors(ionic); + goto try_fewer; + } + + ionic->nnqs_per_lif = nnqs_per_lif; + ionic->neqs_per_lif = neqs; + ionic->ntxqs_per_lif = nxqs; + ionic->nrxqs_per_lif = nxqs; + ionic->nintrs = nintrs; + + ionic_debugfs_add_sizes(ionic); + + return 0; + +try_fewer: + if (nnqs_per_lif > 1) { + nnqs_per_lif >>= 1; + goto try_again; + } + if (neqs > 1) { + neqs >>= 1; + goto try_again; + } + if (nxqs > 1) { + nxqs >>= 1; + goto try_again; + } + dev_err(ionic->dev, "Can't get minimum %d intrs from OS\n", min_intrs); + return -ENOSPC; +}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
new file mode 100644
index 000000000000..37f79d36744a
--- /dev/null
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h@@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ + +#ifndef _IONIC_LIF_H_ +#define _IONIC_LIF_H_ + +#include <linux/pci.h> + +enum lif_state_flags { + LIF_INITED, + + /* leave this as last */ + LIF_STATE_SIZE +}; + +#define LIF_NAME_MAX_SZ (32) +struct lif { + char name[LIF_NAME_MAX_SZ]; + struct list_head list; + struct net_device *netdev; + DECLARE_BITMAP(state, LIF_STATE_SIZE); + struct ionic *ionic; + bool registered; + unsigned int index; + unsigned int hw_index; + unsigned int neqs; + unsigned int nxqs; + + struct lif_info *info; + dma_addr_t info_pa; + u32 info_sz; + + struct dentry *dentry; + u32 flags; +}; + +static inline bool ionic_is_pf(struct ionic *ionic) +{ + return ionic->pdev && + ionic->pdev->device == PCI_DEVICE_ID_PENSANDO_IONIC_ETH_PF; +} + +static inline bool ionic_is_vf(struct ionic *ionic) +{ + return ionic->pdev && + ionic->pdev->device == PCI_DEVICE_ID_PENSANDO_IONIC_ETH_VF; +} + +static inline bool ionic_is_25g(struct ionic *ionic) +{ + return ionic_is_pf(ionic) && + ionic->pdev->subsystem_device == IONIC_SUBDEV_ID_NAPLES_25; +} + +static inline bool ionic_is_100g(struct ionic *ionic) +{ + return ionic_is_pf(ionic) && + (ionic->pdev->subsystem_device == IONIC_SUBDEV_ID_NAPLES_100_4 || + ionic->pdev->subsystem_device == IONIC_SUBDEV_ID_NAPLES_100_8); +} + +int ionic_lifs_alloc(struct ionic *ionic); +void ionic_lifs_free(struct ionic *ionic); +void ionic_lifs_deinit(struct ionic *ionic); +int ionic_lifs_init(struct ionic *ionic); +int ionic_lif_identify(struct ionic *ionic, u8 lif_type, + union lif_identity *lif_ident); +int ionic_lifs_size(struct ionic *ionic); + +#endif /* _IONIC_LIF_H_ */
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index 78eab326b067..b732e7345550 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c@@ -8,6 +8,7 @@ #include "ionic.h" #include "ionic_bus.h" +#include "ionic_lif.h" #include "ionic_debugfs.h" MODULE_DESCRIPTION(DRV_DESCRIPTION);
--
2.17.1