Skip to content

Commit

Permalink
ionic: Add basic lif support
Browse files Browse the repository at this point in the history
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 <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shannon Nelson authored and David S. Miller committed Sep 5, 2019
1 parent 0443659 commit 1a58e19
Show file tree
Hide file tree
Showing 11 changed files with 477 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/pensando/ionic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
obj-$(CONFIG_IONIC) := ionic.o

ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o ionic_dev.o \
ionic_debugfs.o
ionic_debugfs.o ionic_lif.o
7 changes: 7 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ struct ionic {
struct ionic_dev_bar bars[IONIC_BARS_MAX];
unsigned int num_bars;
struct ionic_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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
47 changes: 47 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "ionic.h"
#include "ionic_bus.h"
#include "ionic_lif.h"
#include "ionic_debugfs.h"

/* Supported devices */
Expand All @@ -23,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;
Expand Down Expand Up @@ -151,12 +163,44 @@ 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;
}

err = ionic_devlink_register(ionic);
if (err)
dev_err(dev, "Cannot register devlink: %d\n", err);

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:
Expand Down Expand Up @@ -185,6 +229,9 @@ static void ionic_remove(struct pci_dev *pdev)
return;

ionic_devlink_unregister(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);
Expand Down
36 changes: 36 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_debugfs.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -58,4 +60,38 @@ void ionic_debugfs_add_ident(struct ionic *ionic)
ionic, &identity_fops) ? 0 : -EOPNOTSUPP;
}

void 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]);
}

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);

void ionic_debugfs_add_lif(struct ionic_lif *lif)
{
lif->dentry = debugfs_create_dir(lif->name, lif->ionic->dentry);
debugfs_create_file("netdev", 0400, lif->dentry,
lif->netdev, &netdev_fops);
}

void ionic_debugfs_del_lif(struct ionic_lif *lif)
{
debugfs_remove_recursive(lif->dentry);
lif->dentry = NULL;
}
#endif
6 changes: 6 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ void ionic_debugfs_destroy(void);
void ionic_debugfs_add_dev(struct ionic *ionic);
void ionic_debugfs_del_dev(struct ionic *ionic);
void ionic_debugfs_add_ident(struct ionic *ionic);
void ionic_debugfs_add_sizes(struct ionic *ionic);
void ionic_debugfs_add_lif(struct ionic_lif *lif);
void ionic_debugfs_del_lif(struct ionic_lif *lif);
#else
static inline void ionic_debugfs_create(void) { }
static inline void ionic_debugfs_destroy(void) { }
static inline void ionic_debugfs_add_dev(struct ionic *ionic) { }
static inline void ionic_debugfs_del_dev(struct ionic *ionic) { }
static inline void ionic_debugfs_add_ident(struct ionic *ionic) { }
static inline void ionic_debugfs_add_sizes(struct ionic *ionic) { }
static inline void ionic_debugfs_add_lif(struct ionic_lif *lif) { }
static inline void ionic_debugfs_del_lif(struct ionic_lif *lif) { }
#endif

#endif /* _IONIC_DEBUGFS_H_ */
34 changes: 34 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,37 @@ void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type)

ionic_dev_cmd_go(idev, &cmd);
}

/* LIF commands */
void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver)
{
union ionic_dev_cmd cmd = {
.lif_identify.opcode = IONIC_CMD_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 ionic_dev_cmd cmd = {
.lif_init.opcode = IONIC_CMD_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 ionic_dev_cmd cmd = {
.lif_init.opcode = IONIC_CMD_LIF_RESET,
.lif_init.index = cpu_to_le16(lif_index),
};

ionic_dev_cmd_go(idev, &cmd);
}
7 changes: 7 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -148,4 +150,9 @@ void ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, u8 an_enable);
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_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_ */
Loading

0 comments on commit 1a58e19

Please sign in to comment.