[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