You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
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: Subbaraya Sundeep <sbhatta@marvell.com> Signed-off-by: Geetha sowjanya <gakula@marvell.com> Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com> Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
547d20f10d
commit
3184fb5ba9
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -45,6 +45,19 @@
|
||||
#define RVU_PF_MSIX_VECX_CTL(a) (0x008 | (a) << 4)
|
||||
#define RVU_PF_MSIX_PBAX(a) (0xF0000 | (a) << 3)
|
||||
|
||||
/* RVU VF registers */
|
||||
#define RVU_VF_VFPF_MBOX0 (0x00000)
|
||||
#define RVU_VF_VFPF_MBOX1 (0x00008)
|
||||
#define RVU_VF_VFPF_MBOXX(a) (0x00 | (a) << 3)
|
||||
#define RVU_VF_INT (0x20)
|
||||
#define RVU_VF_INT_W1S (0x28)
|
||||
#define RVU_VF_INT_ENA_W1S (0x30)
|
||||
#define RVU_VF_INT_ENA_W1C (0x38)
|
||||
#define RVU_VF_BLOCK_ADDRX_DISC(a) (0x200 | (a) << 3)
|
||||
#define RVU_VF_MSIX_VECX_ADDR(a) (0x000 | (a) << 4)
|
||||
#define RVU_VF_MSIX_VECX_CTL(a) (0x008 | (a) << 4)
|
||||
#define RVU_VF_MSIX_PBAX(a) (0xF0000 | (a) << 3)
|
||||
|
||||
#define RVU_FUNC_BLKADDR_SHIFT 20
|
||||
#define RVU_FUNC_BLKADDR_MASK 0x1FULL
|
||||
|
||||
|
||||
@@ -778,6 +778,7 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq,
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_sq_append_skb);
|
||||
|
||||
void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq)
|
||||
{
|
||||
|
||||
646
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Normal file
646
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user