Commit 3184fb5b authored by Tomasz Duszynski's avatar Tomasz Duszynski Committed by David S. Miller
Browse files

octeontx2-vf: Virtual function driver support



On OcteonTx2 silicon there two two types VFs, VFs that share the
physical link with their parent SR-IOV PF and the VFs which work
in pairs using internal HW loopback channels (LBK). Except for the
underlying Rx/Tx channel mapping from netdev functionality perspective
they are almost identical. This patch adds netdev driver support
for these VFs.

Unlike it's parent PF a VF cannot directly communicate with admin
function (AF) and it has to go through PF for the same. The mailbox
communication with AF works like 'VF <=> PF <=> AF'.

Also functionality wise VF and PF are identical, hence to avoid code
duplication PF driver's APIs are resued here for HW initialization,
packet handling etc etc ie almost everything. For VF driver to compile
as module exported few of the existing PF driver APIs.

Signed-off-by: default avatarSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: default avatarGeetha sowjanya <gakula@marvell.com>
Signed-off-by: default avatarTomasz Duszynski <tduszynski@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 547d20f1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -33,3 +33,9 @@ config OCTEONTX2_PF
	depends on PCI
	help
	  This driver supports Marvell's OcteonTX2 NIC physical function.

config OCTEONTX2_VF
	tristate "Marvell OcteonTX2 NIC Virtual Function driver"
	depends on OCTEONTX2_PF
	help
	  This driver supports Marvell's OcteonTX2 NIC virtual function.
+2 −0
Original line number Diff line number Diff line
@@ -4,7 +4,9 @@
#

obj-$(CONFIG_OCTEONTX2_PF) += octeontx2_nicpf.o
obj-$(CONFIG_OCTEONTX2_VF) += octeontx2_nicvf.o

octeontx2_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o
octeontx2_nicvf-y := otx2_vf.o

ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
+14 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ void otx2_get_stats64(struct net_device *netdev,
	stats->tx_packets = dev_stats->tx_frames;
	stats->tx_dropped = dev_stats->tx_drops;
}
EXPORT_SYMBOL(otx2_get_stats64);

/* Sync MAC address with RVU AF */
static int otx2_hw_set_mac_addr(struct otx2_nic *pfvf, u8 *mac)
@@ -197,6 +198,7 @@ int otx2_set_mac_address(struct net_device *netdev, void *p)

	return 0;
}
EXPORT_SYMBOL(otx2_set_mac_address);

int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu)
{
@@ -225,6 +227,9 @@ int otx2_config_pause_frm(struct otx2_nic *pfvf)
	struct cgx_pause_frm_cfg *req;
	int err;

	if (is_otx2_lbkvf(pfvf->pdev))
		return 0;

	otx2_mbox_lock(&pfvf->mbox);
	req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox);
	if (!req) {
@@ -416,6 +421,7 @@ void otx2_tx_timeout(struct net_device *netdev, unsigned int txq)

	schedule_work(&pfvf->reset_task);
}
EXPORT_SYMBOL(otx2_tx_timeout);

void otx2_get_mac_from_af(struct net_device *netdev)
{
@@ -430,6 +436,7 @@ void otx2_get_mac_from_af(struct net_device *netdev)
	if (!is_valid_ether_addr(netdev->dev_addr))
		eth_hw_addr_random(netdev);
}
EXPORT_SYMBOL(otx2_get_mac_from_af);

static int otx2_get_link(struct otx2_nic *pfvf)
{
@@ -1263,6 +1270,7 @@ int otx2_detach_resources(struct mbox *mbox)
	otx2_mbox_unlock(mbox);
	return 0;
}
EXPORT_SYMBOL(otx2_detach_resources);

int otx2_attach_npa_nix(struct otx2_nic *pfvf)
{
@@ -1319,6 +1327,7 @@ int otx2_attach_npa_nix(struct otx2_nic *pfvf)

	return 0;
}
EXPORT_SYMBOL(otx2_attach_npa_nix);

void otx2_ctx_disable(struct mbox *mbox, int type, bool npa)
{
@@ -1387,6 +1396,7 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
			pf->hw.txschq_list[lvl][schq] =
				rsp->schq_list[lvl][schq];
}
EXPORT_SYMBOL(mbox_handler_nix_txsch_alloc);

void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf,
			       struct npa_lf_alloc_rsp *rsp)
@@ -1394,6 +1404,7 @@ void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf,
	pfvf->hw.stack_pg_ptrs = rsp->stack_pg_ptrs;
	pfvf->hw.stack_pg_bytes = rsp->stack_pg_bytes;
}
EXPORT_SYMBOL(mbox_handler_npa_lf_alloc);

void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
			       struct nix_lf_alloc_rsp *rsp)
@@ -1404,6 +1415,7 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
	pfvf->hw.lso_tsov4_idx = rsp->lso_tsov4_idx;
	pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx;
}
EXPORT_SYMBOL(mbox_handler_nix_lf_alloc);

void mbox_handler_msix_offset(struct otx2_nic *pfvf,
			      struct msix_offset_rsp *rsp)
@@ -1411,6 +1423,7 @@ void mbox_handler_msix_offset(struct otx2_nic *pfvf,
	pfvf->hw.npa_msixoff = rsp->npa_msixoff;
	pfvf->hw.nix_msixoff = rsp->nix_msixoff;
}
EXPORT_SYMBOL(mbox_handler_msix_offset);

void mbox_handler_nix_bp_enable(struct otx2_nic *pfvf,
				struct nix_bp_cfg_rsp *rsp)
@@ -1422,6 +1435,7 @@ void mbox_handler_nix_bp_enable(struct otx2_nic *pfvf,
		pfvf->bpid[chan_id] = rsp->chan_bpid[chan] & 0x3FF;
	}
}
EXPORT_SYMBOL(mbox_handler_nix_bp_enable);

void otx2_free_cints(struct otx2_nic *pfvf, int n)
{
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

/* PCI device IDs */
#define PCI_DEVID_OCTEONTX2_RVU_PF              0xA063
#define PCI_DEVID_OCTEONTX2_RVU_VF		0xA064
#define PCI_DEVID_OCTEONTX2_RVU_AFVF		0xA0F8

#define PCI_SUBSYS_DEVID_96XX_RVU_PFVF		0xB200

@@ -242,6 +244,11 @@ struct otx2_nic {
	int			nix_blkaddr;
};

static inline bool is_otx2_lbkvf(struct pci_dev *pdev)
{
	return pdev->device == PCI_DEVID_OCTEONTX2_RVU_AFVF;
}

static inline bool is_96xx_A0(struct pci_dev *pdev)
{
	return (pdev->revision == 0x00) &&
+10 −1
Original line number Diff line number Diff line
@@ -1085,6 +1085,7 @@ int otx2_set_real_num_queues(struct net_device *netdev,
			   "Failed to set no of Rx queues: %d\n", rx_queues);
	return err;
}
EXPORT_SYMBOL(otx2_set_real_num_queues);

static irqreturn_t otx2_q_intr_handler(int irq, void *data)
{
@@ -1520,6 +1521,9 @@ int otx2_open(struct net_device *netdev)
	if (pf->linfo.link_up && !(pf->pcifunc & RVU_PFVF_FUNC_MASK))
		otx2_handle_link_event(pf);

	/* Restore pause frame settings */
	otx2_config_pause_frm(pf);

	err = otx2_rxtx_enable(pf, true);
	if (err)
		goto err_free_cints;
@@ -1543,6 +1547,7 @@ err_free_mem:
	kfree(qset->napi);
	return err;
}
EXPORT_SYMBOL(otx2_open);

int otx2_stop(struct net_device *netdev)
{
@@ -1603,6 +1608,7 @@ int otx2_stop(struct net_device *netdev)
	       sizeof(*qset) - offsetof(struct otx2_qset, sqe_cnt));
	return 0;
}
EXPORT_SYMBOL(otx2_stop);

static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
{
@@ -1731,7 +1737,6 @@ static int otx2_realloc_msix_vectors(struct otx2_nic *pf)

	otx2_disable_mbox_intr(pf);
	pci_free_irq_vectors(hw->pdev);
	pci_free_irq_vectors(hw->pdev);
	err = pci_alloc_irq_vectors(hw->pdev, num_vec, num_vec, PCI_IRQ_MSIX);
	if (err < 0) {
		dev_err(pf->dev, "%s: Failed to realloc %d IRQ vectors\n",
@@ -1898,6 +1903,10 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	/* Enable link notifications */
	otx2_cgx_config_linkevents(pf, true);

	/* Enable pause frames by default */
	pf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED;
	pf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED;

	return 0;

err_detach_rsrc:
Loading