Commit a8c06337 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'nfp-preliminary-support-for-nfp-3800'

Simon Horman says:

====================
nfp: preliminary support for NFP-3800

This series is the first step to add support to the NFP driver for the
new NFP-3800 device. In this first series the goal is to clean
up small issues found while adding support for the new device, prepare
an abstraction of the differences between the already supported devices
and the new Kestrel device and add the new PCI ID.

* Patch 1/11 and 2/11 starts by removing some dead code and incorrect
  assumptions found while working Kestrel support. Patch 3/11, 4/11 and
  5/11 cleans up and prepares for adding the new PCI ID for Kestrel.
* Patches 6/11, 7/11, 8/11, 9/11, 10/11 adds, plumb and populates a device
   information structure to abstract the differences between the existed
   supported devices (NFP-4000, NFP-5000 and NFP-6000) and the
   new device (NFP3800).
* Finally patch 11/11 adds the new PCI ID for Kestrel.

More work is needed to drive the new NFP-3800 device after this first
batch of patches the foundation is prepared for the follow up work.

Thanks to the work of all those who contributed to this work.
====================

Link: https://lore.kernel.org/r/20220311104306.28357-1-simon.horman@corigine.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d59c85dd d3826a95
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ nfp-objs := \
	    nfpcore/nfp6000_pcie.o \
	    nfpcore/nfp_cppcore.o \
	    nfpcore/nfp_cpplib.o \
	    nfpcore/nfp_dev.o \
	    nfpcore/nfp_hwinfo.o \
	    nfpcore/nfp_mip.o \
	    nfpcore/nfp_mutex.o \
+16 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "nfpcore/nfp.h"
#include "nfpcore/nfp_cpp.h"
#include "nfpcore/nfp_dev.h"
#include "nfpcore/nfp_nffw.h"
#include "nfpcore/nfp_nsp.h"

@@ -32,17 +33,21 @@
static const char nfp_driver_name[] = "nfp";

static const struct pci_device_id nfp_pci_device_ids[] = {
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000,
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP3800,
	  PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
	  PCI_ANY_ID, 0, NFP_DEV_NFP3800,
	},
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP4000,
	  PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
	  PCI_ANY_ID, 0,
	  PCI_ANY_ID, 0, NFP_DEV_NFP6000,
	},
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP5000,
	  PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
	  PCI_ANY_ID, 0,
	  PCI_ANY_ID, 0, NFP_DEV_NFP6000,
	},
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP4000,
	{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000,
	  PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
	  PCI_ANY_ID, 0,
	  PCI_ANY_ID, 0, NFP_DEV_NFP6000,
	},
	{ 0, } /* Required last entry. */
};
@@ -667,6 +672,7 @@ static int nfp_pf_find_rtsyms(struct nfp_pf *pf)
static int nfp_pci_probe(struct pci_dev *pdev,
			 const struct pci_device_id *pci_id)
{
	const struct nfp_dev_info *dev_info;
	struct devlink *devlink;
	struct nfp_pf *pf;
	int err;
@@ -675,14 +681,15 @@ static int nfp_pci_probe(struct pci_dev *pdev,
	    pdev->device == PCI_DEVICE_ID_NETRONOME_NFP6000_VF)
		dev_warn(&pdev->dev, "Binding NFP VF device to the NFP PF driver, the VF driver is called 'nfp_netvf'\n");

	dev_info = &nfp_dev_info[pci_id->driver_data];

	err = pci_enable_device(pdev);
	if (err < 0)
		return err;

	pci_set_master(pdev);

	err = dma_set_mask_and_coherent(&pdev->dev,
					DMA_BIT_MASK(NFP_NET_MAX_DMA_BITS));
	err = dma_set_mask_and_coherent(&pdev->dev, dev_info->dma_mask);
	if (err)
		goto err_pci_disable;

@@ -703,6 +710,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
	mutex_init(&pf->lock);
	pci_set_drvdata(pdev, pf);
	pf->pdev = pdev;
	pf->dev_info = dev_info;

	pf->wq = alloc_workqueue("nfp-%s", 0, 2, pci_name(pdev));
	if (!pf->wq) {
@@ -710,7 +718,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
		goto err_pci_priv_unset;
	}

	pf->cpp = nfp_cpp_from_nfp6000_pcie(pdev);
	pf->cpp = nfp_cpp_from_nfp6000_pcie(pdev, dev_info);
	if (IS_ERR(pf->cpp)) {
		err = PTR_ERR(pf->cpp);
		goto err_disable_msix;
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct nfp_dumpspec {
/**
 * struct nfp_pf - NFP PF-specific device structure
 * @pdev:		Backpointer to PCI device
 * @dev_info:		NFP ASIC params
 * @cpp:		Pointer to the CPP handle
 * @app:		Pointer to the APP handle
 * @data_vnic_bar:	Pointer to the CPP area for the data vNICs' BARs
@@ -88,6 +89,7 @@ struct nfp_dumpspec {
 */
struct nfp_pf {
	struct pci_dev *pdev;
	const struct nfp_dev_info *dev_info;

	struct nfp_cpp *cpp;

+9 −43
Original line number Diff line number Diff line
@@ -63,9 +63,6 @@
#define NFP_NET_Q0_BAR		2
#define NFP_NET_Q1_BAR		4	/* OBSOLETE */

/* Max bits in DMA address */
#define NFP_NET_MAX_DMA_BITS	40

/* Default size for MTU and freelist buffer sizes */
#define NFP_NET_DEFAULT_MTU		1500U

@@ -85,11 +82,6 @@
				 NFP_NET_MAX_TX_RINGS : NFP_NET_MAX_RX_RINGS)
#define NFP_NET_MAX_IRQS	(NFP_NET_NON_Q_VECTORS + NFP_NET_MAX_R_VECS)

#define NFP_NET_MIN_TX_DESCS	256	/* Min. # of Tx descs per ring */
#define NFP_NET_MIN_RX_DESCS	256	/* Min. # of Rx descs per ring */
#define NFP_NET_MAX_TX_DESCS	(256 * 1024) /* Max. # of Tx descs per ring */
#define NFP_NET_MAX_RX_DESCS	(256 * 1024) /* Max. # of Rx descs per ring */

#define NFP_NET_TX_DESCS_DEFAULT 4096	/* Default # of Tx descs per ring */
#define NFP_NET_RX_DESCS_DEFAULT 4096	/* Default # of Rx descs per ring */

@@ -105,6 +97,7 @@

/* Forward declarations */
struct nfp_cpp;
struct nfp_dev_info;
struct nfp_eth_table_port;
struct nfp_net;
struct nfp_net_r_vector;
@@ -571,6 +564,7 @@ struct nfp_net_dp {
/**
 * struct nfp_net - NFP network device structure
 * @dp:			Datapath structure
 * @dev_info:		NFP ASIC params
 * @id:			vNIC id within the PF (0 for VFs)
 * @fw_ver:		Firmware version
 * @cap:                Capabilities advertised by the Firmware
@@ -644,6 +638,7 @@ struct nfp_net_dp {
struct nfp_net {
	struct nfp_net_dp dp;

	const struct nfp_dev_info *dev_info;
	struct nfp_net_fw_version fw_ver;

	u32 id;
@@ -796,7 +791,6 @@ static inline void nn_pci_flush(struct nfp_net *nn)
 * either add to a pointer or to read the pointer value.
 */
#define NFP_QCP_QUEUE_ADDR_SZ			0x800
#define NFP_QCP_QUEUE_AREA_SZ			0x80000
#define NFP_QCP_QUEUE_OFF(_x)			((_x) * NFP_QCP_QUEUE_ADDR_SZ)
#define NFP_QCP_QUEUE_ADD_RPTR			0x0000
#define NFP_QCP_QUEUE_ADD_WPTR			0x0004
@@ -805,50 +799,21 @@ static inline void nn_pci_flush(struct nfp_net *nn)
#define NFP_QCP_QUEUE_STS_HI			0x000c
#define NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask	0x3ffff

/* The offset of a QCP queues in the PCIe Target */
#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff)))

/* nfp_qcp_ptr - Read or Write Pointer of a queue */
enum nfp_qcp_ptr {
	NFP_QCP_READ_PTR = 0,
	NFP_QCP_WRITE_PTR
};

/* There appear to be an *undocumented* upper limit on the value which
 * one can add to a queue and that value is either 0x3f or 0x7f.  We
 * go with 0x3f as a conservative measure.
 */
#define NFP_QCP_MAX_ADD				0x3f

static inline void _nfp_qcp_ptr_add(u8 __iomem *q,
				    enum nfp_qcp_ptr ptr, u32 val)
{
	u32 off;

	if (ptr == NFP_QCP_READ_PTR)
		off = NFP_QCP_QUEUE_ADD_RPTR;
	else
		off = NFP_QCP_QUEUE_ADD_WPTR;

	while (val > NFP_QCP_MAX_ADD) {
		writel(NFP_QCP_MAX_ADD, q + off);
		val -= NFP_QCP_MAX_ADD;
	}

	writel(val, q + off);
}

/**
 * nfp_qcp_rd_ptr_add() - Add the value to the read pointer of a queue
 *
 * @q:   Base address for queue structure
 * @val: Value to add to the queue pointer
 *
 * If @val is greater than @NFP_QCP_MAX_ADD multiple writes are performed.
 */
static inline void nfp_qcp_rd_ptr_add(u8 __iomem *q, u32 val)
{
	_nfp_qcp_ptr_add(q, NFP_QCP_READ_PTR, val);
	writel(val, q + NFP_QCP_QUEUE_ADD_RPTR);
}

/**
@@ -856,12 +821,10 @@ static inline void nfp_qcp_rd_ptr_add(u8 __iomem *q, u32 val)
 *
 * @q:   Base address for queue structure
 * @val: Value to add to the queue pointer
 *
 * If @val is greater than @NFP_QCP_MAX_ADD multiple writes are performed.
 */
static inline void nfp_qcp_wr_ptr_add(u8 __iomem *q, u32 val)
{
	_nfp_qcp_ptr_add(q, NFP_QCP_WRITE_PTR, val);
	writel(val, q + NFP_QCP_QUEUE_ADD_WPTR);
}

static inline u32 _nfp_qcp_read(u8 __iomem *q, enum nfp_qcp_ptr ptr)
@@ -904,6 +867,8 @@ static inline u32 nfp_qcp_wr_ptr_read(u8 __iomem *q)
	return _nfp_qcp_read(q, NFP_QCP_WRITE_PTR);
}

u32 nfp_qcp_queue_offset(const struct nfp_dev_info *dev_info, u16 queue);

static inline bool nfp_net_is_data_vnic(struct nfp_net *nn)
{
	WARN_ON_ONCE(!nn->dp.netdev && nn->port);
@@ -970,7 +935,8 @@ void nfp_net_get_fw_version(struct nfp_net_fw_version *fw_ver,
			    void __iomem *ctrl_bar);

struct nfp_net *
nfp_net_alloc(struct pci_dev *pdev, void __iomem *ctrl_bar, bool needs_netdev,
nfp_net_alloc(struct pci_dev *pdev, const struct nfp_dev_info *dev_info,
	      void __iomem *ctrl_bar, bool needs_netdev,
	      unsigned int max_tx_rings, unsigned int max_rx_rings);
void nfp_net_free(struct nfp_net *nn);

+11 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <net/vxlan.h>
#include <net/xdp_sock_drv.h>

#include "nfpcore/nfp_dev.h"
#include "nfpcore/nfp_nsp.h"
#include "ccm.h"
#include "nfp_app.h"
@@ -65,6 +66,12 @@ void nfp_net_get_fw_version(struct nfp_net_fw_version *fw_ver,
	put_unaligned_le32(reg, fw_ver);
}

u32 nfp_qcp_queue_offset(const struct nfp_dev_info *dev_info, u16 queue)
{
	queue &= dev_info->qc_idx_mask;
	return dev_info->qc_addr_offset + NFP_QCP_QUEUE_ADDR_SZ * queue;
}

static dma_addr_t nfp_net_dma_map_rx(struct nfp_net_dp *dp, void *frag)
{
	return dma_map_single_attrs(dp->dev, frag + NFP_NET_RX_BUF_HEADROOM,
@@ -3962,6 +3969,7 @@ void nfp_net_info(struct nfp_net *nn)
/**
 * nfp_net_alloc() - Allocate netdev and related structure
 * @pdev:         PCI device
 * @dev_info:     NFP ASIC params
 * @ctrl_bar:     PCI IOMEM with vNIC config memory
 * @needs_netdev: Whether to allocate a netdev for this vNIC
 * @max_tx_rings: Maximum number of TX rings supported by device
@@ -3974,7 +3982,8 @@ void nfp_net_info(struct nfp_net *nn)
 * Return: NFP Net device structure, or ERR_PTR on error.
 */
struct nfp_net *
nfp_net_alloc(struct pci_dev *pdev, void __iomem *ctrl_bar, bool needs_netdev,
nfp_net_alloc(struct pci_dev *pdev, const struct nfp_dev_info *dev_info,
	      void __iomem *ctrl_bar, bool needs_netdev,
	      unsigned int max_tx_rings, unsigned int max_rx_rings)
{
	struct nfp_net *nn;
@@ -3999,6 +4008,7 @@ nfp_net_alloc(struct pci_dev *pdev, void __iomem *ctrl_bar, bool needs_netdev,

	nn->dp.dev = &pdev->dev;
	nn->dp.ctrl_bar = ctrl_bar;
	nn->dev_info = dev_info;
	nn->pdev = pdev;

	nn->max_tx_rings = max_tx_rings;
Loading