Skip to content

Commit

Permalink
net/nfp: fix offloading flows
Browse files Browse the repository at this point in the history
[ 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: c7e9729 ("net/nfp: support CPP")

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
  • Loading branch information
hechaoyong authored and bluca committed Jun 15, 2023
1 parent 56685a6 commit 0b8a7a7
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 25 deletions.
4 changes: 3 additions & 1 deletion drivers/net/nfp/nfp_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -2797,6 +2797,7 @@ nfp_net_init(struct rte_eth_dev *eth_dev)

uint64_t tx_bar_off = 0, rx_bar_off = 0;
uint32_t start_q;
uint32_t cpp_id;
int stride = 4;
int port = 0;
int err;
Expand Down Expand Up @@ -2908,7 +2909,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)

if (hw->is_pf && port == 0) {
/* configure access to tx/rx vNIC BARs */
hwport0->hw_queues = nfp_cpp_map_area(hw->cpp, 0, 0,
cpp_id = NFP_CPP_ISLAND_ID(0, NFP_CPP_ACTION_RW, 0, 0);
hwport0->hw_queues = nfp_cpp_map_area(hw->cpp, cpp_id,
NFP_PCIE_QUEUE(0),
NFP_QCP_QUEUE_AREA_SZ,
&hw->hwqueues_area);
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/nfp/nfpcore/nfp_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down Expand Up @@ -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);
/*
Expand Down Expand Up @@ -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__ */
52 changes: 41 additions & 11 deletions drivers/net/nfp/nfpcore/nfp_cppcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <errno.h>
#include <sys/types.h>

#include <rte_bitops.h>
#include <rte_byteorder.h>
#include <rte_ethdev_pci.h>

Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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) {
printf("Can't calculate MU locality bit offset");
free(cpp);
return NULL;
}

return cpp;
}

Expand Down Expand Up @@ -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)
Expand All @@ -831,15 +864,12 @@ __nfp_cpp_model_autodetect(struct nfp_cpp *cpp, uint32_t *model)
* Return: Pointer to memory mapped area or ERR_PTR
*/
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;

Expand Down
134 changes: 122 additions & 12 deletions drivers/net/nfp/nfpcore/nfp_rtsym.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,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:
printf("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:
printf("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) {
printf("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 {
printf("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)) {
printf("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)) {
printf("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
Expand All @@ -248,7 +355,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;

Expand All @@ -258,19 +365,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",
Expand All @@ -295,8 +396,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);
Expand All @@ -307,14 +411,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) {
printf("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;
Expand Down

0 comments on commit 0b8a7a7

Please sign in to comment.