[PATCH 22.11 2/2] net/nfp: fix offloading flows

Xueming(Steven) Li xuemingl at nvidia.com
Wed Aug 9 14:50:47 CEST 2023


Hi Chaoyong,

Thanks for the backport.
Patches queued to 22.11 stable release.

> -----Original Message-----
> From: Chaoyong He <chaoyong.he at corigine.com>
> Sent: 6/20/2023 10:50
> To: stable at dpdk.org
> Cc: oss-drivers at corigine.com; niklas.soderlund at corigine.com; Chaoyong He
> <chaoyong.he at corigine.com>
> Subject: [PATCH 22.11 2/2] net/nfp: fix offloading flows
> 
> [ upstream commit 925c27ec8de92efe69f4cb56e3fc0e413354c739 ]
> 
> The symbol '_abi_flower_extra_features' is in IMEM for NFP4000, but in
> EMU_CACHE for NFP3800 because which does not have IMEM.
> 
> The original logic can't read symbol from EMU_CACHE, so the probe process
> will fail when we try to offload flows use NFP3800.
> 
> Modify the related data structure and logics to support read symbol from
> EMU_CACHE.
> 
> Fixes: c7e9729da6b5 ("net/nfp: support CPP")
> 
> Signed-off-by: Chaoyong He <chaoyong.he at corigine.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund at corigine.com>
> ---
>  drivers/net/nfp/nfp_ethdev.c          |   4 +-
>  drivers/net/nfp/nfpcore/nfp_cpp.h     |   7 +-
>  drivers/net/nfp/nfpcore/nfp_cppcore.c |  54 ++++++++---
>  drivers/net/nfp/nfpcore/nfp_rtsym.c   | 135 +++++++++++++++++++++++---
>  4 files changed, 174 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index
> dc63b05bd6..29491f6e6d 100644
> --- a/drivers/net/nfp/nfp_ethdev.c
> +++ b/drivers/net/nfp/nfp_ethdev.c
> @@ -929,6 +929,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
>  	int ret;
>  	int err = 0;
>  	uint64_t addr;
> +	uint32_t cpp_id;
>  	struct nfp_cpp *cpp;
>  	enum nfp_app_fw_id app_fw_id;
>  	struct nfp_pf_dev *pf_dev;
> @@ -1028,7 +1029,8 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
>  		goto pf_cleanup;
>  	}
> 
> -	pf_dev->hw_queues = nfp_cpp_map_area(pf_dev->cpp, 0, 0,
> +	cpp_id = NFP_CPP_ISLAND_ID(0, NFP_CPP_ACTION_RW, 0, 0);
> +	pf_dev->hw_queues = nfp_cpp_map_area(pf_dev->cpp, cpp_id,
>  			addr, NFP_QCP_QUEUE_AREA_SZ,
>  			&pf_dev->hwqueues_area);
>  	if (pf_dev->hw_queues == NULL) {
> diff --git a/drivers/net/nfp/nfpcore/nfp_cpp.h
> b/drivers/net/nfp/nfpcore/nfp_cpp.h
> index a04a68f546..68851b22e4 100644
> --- a/drivers/net/nfp/nfpcore/nfp_cpp.h
> +++ b/drivers/net/nfp/nfpcore/nfp_cpp.h
> @@ -34,6 +34,9 @@ struct nfp_cpp {
>  	 */
>  	uint32_t imb_cat_table[16];
> 
> +	/* MU access type bit offset */
> +	uint32_t mu_locality_lsb;
> +
>  	int driver_lock_needed;
>  };
> 
> @@ -363,7 +366,7 @@ struct nfp_cpp_area
> *nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp,
>   */
>  void nfp_cpp_area_release_free(struct nfp_cpp_area *area);
> 
> -uint8_t *nfp_cpp_map_area(struct nfp_cpp *cpp, int domain, int target,
> +uint8_t *nfp_cpp_map_area(struct nfp_cpp *cpp, uint32_t cpp_id,
>  			   uint64_t addr, unsigned long size,
>  			   struct nfp_cpp_area **area);
>  /*
> @@ -778,4 +781,6 @@ int nfp_cpp_mutex_unlock(struct nfp_cpp_mutex
> *mutex);
>   */
>  int nfp_cpp_mutex_trylock(struct nfp_cpp_mutex *mutex);
> 
> +uint32_t nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp);
> +
>  #endif /* !__NFP_CPP_H__ */
> diff --git a/drivers/net/nfp/nfpcore/nfp_cppcore.c
> b/drivers/net/nfp/nfpcore/nfp_cppcore.c
> index 37799af558..014f6c9df8 100644
> --- a/drivers/net/nfp/nfpcore/nfp_cppcore.c
> +++ b/drivers/net/nfp/nfpcore/nfp_cppcore.c
> @@ -19,6 +19,7 @@
>  #include "nfp6000/nfp6000.h"
>  #include "nfp6000/nfp_xpb.h"
>  #include "nfp_nffw.h"
> +#include "../nfp_logs.h"
> 
>  #define NFP_PL_DEVICE_ID                        0x00000004
>  #define NFP_PL_DEVICE_ID_MASK                   0xff
> @@ -118,6 +119,36 @@ nfp_cpp_area_name(struct nfp_cpp_area *cpp_area)
>  	return cpp_area->name;
>  }
> 
> +#define NFP_IMB_TGTADDRESSMODECFG_MODE_of(_x)       (((_x) >> 13) &
> 0x7)
> +#define NFP_IMB_TGTADDRESSMODECFG_ADDRMODE          RTE_BIT32(12)
> +
> +static int
> +nfp_cpp_set_mu_locality_lsb(struct nfp_cpp *cpp) {
> +	int ret;
> +	int mode;
> +	int addr40;
> +	uint32_t imbcppat;
> +
> +	imbcppat = cpp->imb_cat_table[NFP_CPP_TARGET_MU];
> +	mode = NFP_IMB_TGTADDRESSMODECFG_MODE_of(imbcppat);
> +	addr40 = imbcppat & NFP_IMB_TGTADDRESSMODECFG_ADDRMODE;
> +
> +	ret = nfp_cppat_mu_locality_lsb(mode, addr40);
> +	if (ret < 0)
> +		return ret;
> +
> +	cpp->mu_locality_lsb = ret;
> +
> +	return 0;
> +}
> +
> +uint32_t
> +nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp) {
> +	return cpp->mu_locality_lsb;
> +}
> +
>  /*
>   * nfp_cpp_area_alloc - allocate a new CPP area
>   * @cpp:    CPP handle
> @@ -142,10 +173,6 @@ nfp_cpp_area_alloc_with_name(struct nfp_cpp
> *cpp, uint32_t dest,
>  	if (!cpp)
>  		return NULL;
> 
> -	/* CPP bus uses only a 40-bit address */
> -	if ((address + size) > (1ULL << 40))
> -		return NFP_ERRPTR(EFAULT);
> -
>  	/* Remap from cpp_island to cpp_target */
>  	err = nfp_target_cpp(dest, tmp64, &dest, &tmp64, cpp-
> >imb_cat_table);
>  	if (err < 0)
> @@ -588,6 +615,13 @@ nfp_cpp_alloc(struct rte_pci_device *dev, int
> driver_lock_needed)
>  		}
>  	}
> 
> +	err = nfp_cpp_set_mu_locality_lsb(cpp);
> +	if (err < 0) {
> +		PMD_DRV_LOG(ERR, "Can't calculate MU locality bit offset");
> +		free(cpp);
> +		return NULL;
> +	}
> +
>  	return cpp;
>  }
> 
> @@ -819,8 +853,7 @@ __nfp_cpp_model_autodetect(struct nfp_cpp *cpp,
> uint32_t *model)
>  /*
>   * nfp_cpp_map_area() - Helper function to map an area
>   * @cpp:    NFP CPP handler
> - * @domain: CPP domain
> - * @target: CPP target
> + * @cpp_id: CPP ID
>   * @addr:   CPP address
>   * @size:   Size of the area
>   * @area:   Area handle (output)
> @@ -828,18 +861,15 @@ __nfp_cpp_model_autodetect(struct nfp_cpp *cpp,
> uint32_t *model)
>   * Map an area of IOMEM access.  To undo the effect of this function call
>   * @nfp_cpp_area_release_free(*area).
>   *
> - * Return: Pointer to memory mapped area or ERR_PTR
> + * Return: Pointer to memory mapped area or NULL
>   */
>  uint8_t *
> -nfp_cpp_map_area(struct nfp_cpp *cpp, int domain, int target, uint64_t addr,
> +nfp_cpp_map_area(struct nfp_cpp *cpp, uint32_t cpp_id, uint64_t addr,
>  		 unsigned long size, struct nfp_cpp_area **area)  {
>  	uint8_t *res;
> -	uint32_t dest;
> -
> -	dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, domain);
> 
> -	*area = nfp_cpp_area_alloc_acquire(cpp, dest, addr, size);
> +	*area = nfp_cpp_area_alloc_acquire(cpp, cpp_id, addr, size);
>  	if (!*area)
>  		goto err_eio;
> 
> diff --git a/drivers/net/nfp/nfpcore/nfp_rtsym.c
> b/drivers/net/nfp/nfpcore/nfp_rtsym.c
> index 56bbf05cd8..21879f7eb6 100644
> --- a/drivers/net/nfp/nfpcore/nfp_rtsym.c
> +++ b/drivers/net/nfp/nfpcore/nfp_rtsym.c
> @@ -14,6 +14,7 @@
>  #include "nfp_mip.h"
>  #include "nfp_rtsym.h"
>  #include "nfp6000/nfp6000.h"
> +#include "../nfp_logs.h"
> 
>  /* These need to match the linker */
>  #define SYM_TGT_LMEM		0
> @@ -213,6 +214,113 @@ nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl,
> const char *name)
>  	return NULL;
>  }
> 
> +static uint64_t
> +nfp_rtsym_size(const struct nfp_rtsym *sym) {
> +	switch (sym->type) {
> +	case NFP_RTSYM_TYPE_NONE:
> +		PMD_DRV_LOG(ERR, "rtsym '%s': type NONE", sym->name);
> +		return 0;
> +	case NFP_RTSYM_TYPE_OBJECT:    /* Fall through */
> +	case NFP_RTSYM_TYPE_FUNCTION:
> +		return sym->size;
> +	case NFP_RTSYM_TYPE_ABS:
> +		return sizeof(uint64_t);
> +	default:
> +		PMD_DRV_LOG(ERR, "rtsym '%s': unknown type: %d", sym-
> >name, sym->type);
> +		return 0;
> +	}
> +}
> +
> +static int
> +nfp_rtsym_to_dest(struct nfp_cpp *cpp,
> +		const struct nfp_rtsym *sym,
> +		uint8_t action,
> +		uint8_t token,
> +		uint64_t offset,
> +		uint32_t *cpp_id,
> +		uint64_t *addr)
> +{
> +	if (sym->type != NFP_RTSYM_TYPE_OBJECT) {
> +		PMD_DRV_LOG(ERR, "rtsym '%s': direct access to non-object
> rtsym",
> +				sym->name);
> +		return -EINVAL;
> +	}
> +
> +	*addr = sym->addr + offset;
> +
> +	if (sym->target >= 0) {
> +		*cpp_id = NFP_CPP_ISLAND_ID(sym->target, action, token,
> sym->domain);
> +	} else if (sym->target == NFP_RTSYM_TARGET_EMU_CACHE) {
> +		int locality_off = nfp_cpp_mu_locality_lsb(cpp);
> +
> +		*addr &= ~(NFP_MU_ADDR_ACCESS_TYPE_MASK <<
> locality_off);
> +		*addr |= NFP_MU_ADDR_ACCESS_TYPE_DIRECT <<
> locality_off;
> +
> +		*cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU,
> action, token,
> +				sym->domain);
> +	} else {
> +		PMD_DRV_LOG(ERR, "rtsym '%s': unhandled target
> encoding: %d",
> +				sym->name, sym->target);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +nfp_rtsym_readl(struct nfp_cpp *cpp,
> +		const struct nfp_rtsym *sym,
> +		uint8_t action,
> +		uint8_t token,
> +		uint64_t offset,
> +		uint32_t *value)
> +{
> +	int ret;
> +	uint64_t addr;
> +	uint32_t cpp_id;
> +
> +	if (offset + 4 > nfp_rtsym_size(sym)) {
> +		PMD_DRV_LOG(ERR, "rtsym '%s': readl out of bounds", sym-
> >name);
> +		return -ENXIO;
> +	}
> +
> +	ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id,
> &addr);
> +	if (ret != 0)
> +		return ret;
> +
> +	return nfp_cpp_readl(cpp, cpp_id, addr, value); }
> +
> +static int
> +nfp_rtsym_readq(struct nfp_cpp *cpp,
> +		const struct nfp_rtsym *sym,
> +		uint8_t action,
> +		uint8_t token,
> +		uint64_t offset,
> +		uint64_t *value)
> +{
> +	int ret;
> +	uint64_t addr;
> +	uint32_t cpp_id;
> +
> +	if (offset + 8 > nfp_rtsym_size(sym)) {
> +		PMD_DRV_LOG(ERR, "rtsym '%s': readq out of bounds", sym-
> >name);
> +		return -ENXIO;
> +	}
> +
> +	if (sym->type == NFP_RTSYM_TYPE_ABS) {
> +		*value = sym->addr;
> +		return 0;
> +	}
> +
> +	ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id,
> &addr);
> +	if (ret != 0)
> +		return ret;
> +
> +	return nfp_cpp_readq(cpp, cpp_id, addr, value); }
> +
>  /*
>   * nfp_rtsym_read_le() - Read a simple unsigned scalar value from symbol
>   * @rtbl:	NFP RTsym table
> @@ -229,7 +337,7 @@ uint64_t
>  nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, int *error)
> {
>  	const struct nfp_rtsym *sym;
> -	uint32_t val32, id;
> +	uint32_t val32;
>  	uint64_t val;
>  	int err;
> 
> @@ -239,19 +347,13 @@ nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl,
> const char *name, int *error)
>  		goto exit;
>  	}
> 
> -	id = NFP_CPP_ISLAND_ID(sym->target, NFP_CPP_ACTION_RW, 0, sym-
> >domain);
> -
> -#ifdef DEBUG
> -	printf("Reading symbol %s with size %" PRIu64 " at %" PRIx64 "\n",
> -		name, sym->size, sym->addr);
> -#endif
>  	switch (sym->size) {
>  	case 4:
> -		err = nfp_cpp_readl(rtbl->cpp, id, sym->addr, &val32);
> +		err = nfp_rtsym_readl(rtbl->cpp, sym, NFP_CPP_ACTION_RW,
> 0, 0,
> +&val32);
>  		val = val32;
>  		break;
>  	case 8:
> -		err = nfp_cpp_readq(rtbl->cpp, id, sym->addr, &val);
> +		err = nfp_rtsym_readq(rtbl->cpp, sym, NFP_CPP_ACTION_RW,
> 0, 0, &val);
>  		break;
>  	default:
>  		printf("rtsym '%s' unsupported size: %" PRId64 "\n", @@ -
> 276,8 +378,11 @@ uint8_t *  nfp_rtsym_map(struct nfp_rtsym_table *rtbl,
> const char *name,
>  	      unsigned int min_size, struct nfp_cpp_area **area)  {
> -	const struct nfp_rtsym *sym;
> +	int ret;
>  	uint8_t *mem;
> +	uint64_t addr;
> +	uint32_t cpp_id;
> +	const struct nfp_rtsym *sym;
> 
>  #ifdef DEBUG
>  	printf("mapping symbol %s\n", name);
> @@ -288,14 +393,20 @@ nfp_rtsym_map(struct nfp_rtsym_table *rtbl, const
> char *name,
>  		return NULL;
>  	}
> 
> +	ret = nfp_rtsym_to_dest(rtbl->cpp, sym, NFP_CPP_ACTION_RW, 0, 0,
> +			&cpp_id, &addr);
> +	if (ret != 0) {
> +		PMD_DRV_LOG(ERR, "rtsym '%s': mapping failed", name);
> +		return NULL;
> +	}
> +
>  	if (sym->size < min_size) {
>  		printf("Symbol %s too small (%" PRIu64 " < %u)\n", name,
>  			sym->size, min_size);
>  		return NULL;
>  	}
> 
> -	mem = nfp_cpp_map_area(rtbl->cpp, sym->domain, sym->target, sym-
> >addr,
> -			       sym->size, area);
> +	mem = nfp_cpp_map_area(rtbl->cpp, cpp_id, addr, sym->size, area);
>  	if (!mem) {
>  		printf("Failed to map symbol %s\n", name);
>  		return NULL;
> --
> 2.39.1



More information about the stable mailing list