static int bpe_lookup(struct nfp_device *nfp, int nbi, u32 *bpe, int bpe_max) { int err, i; const struct nfp_rtsym *sym; u32 id, tmp; u32 __iomem *ptr; struct nfp_cpp_area *area; char buff[] = "nbi0_dma_bpe_credits"; buff[3] += nbi; sym = nfp_rtsym_lookup(nfp, buff); if (!sym) { nfp_info(nfp, "%s: Symbol not present\n", buff); return 0; } id = NFP_CPP_ISLAND_ID(sym->target, NFP_CPP_ACTION_RW, 0, sym->domain); area = nfp_cpp_area_alloc_acquire(nfp_device_cpp(nfp), id, sym->addr, sym->size); if (IS_ERR_OR_NULL(area)) { nfp_err(nfp, "%s: Can't acquire area\n", buff); return area ? PTR_ERR(area) : -ENOMEM; } ptr = nfp_cpp_area_iomem(area); if (IS_ERR_OR_NULL(ptr)) { nfp_err(nfp, "%s: Can't map area\n", buff); err = ptr ? PTR_ERR(ptr) : -ENOMEM; goto exit; } tmp = readl(ptr++); if (!BPECFG_MAGIC_CHECK(tmp)) { nfp_err(nfp, "%s: Magic value (0x%08x) unrecognized\n", buff, tmp); err = -EINVAL; goto exit; } if (BPECFG_MAGIC_COUNT(tmp) > bpe_max) { nfp_err(nfp, "%s: Magic count (%d) too large (> %d)\n", buff, BPECFG_MAGIC_COUNT(tmp), bpe_max); err = -EINVAL; goto exit; } for (i = 0; i < bpe_max; i++) bpe[i] = readl(ptr++); err = BPECFG_MAGIC_COUNT(tmp); exit: nfp_cpp_area_release_free(area); return err; }
/** * nfp_rtsym_read_le() - Read a simple unsigned scalar value from symbol * @cpp: NFP CPP handle * @name: Symbol name * @error: Poniter to error code (optional) * * Lookup a symbol, map, read it and return it's value. Value of the symbol * will be interpreted as a simple little-endian unsigned value. Symbol can * be 4 or 8 bytes in size. * * Return: value read, on error sets the error and returns ~0ULL. */ u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error) { const struct nfp_rtsym *sym; u32 val32, id; u64 val; int err; sym = nfp_rtsym_lookup(cpp, name); if (!sym) { err = -ENOENT; goto exit; } id = NFP_CPP_ISLAND_ID(sym->target, NFP_CPP_ACTION_RW, 0, sym->domain); switch (sym->size) { case 4: err = nfp_cpp_readl(cpp, id, sym->addr, &val32); val = val32; break; case 8: err = nfp_cpp_readq(cpp, id, sym->addr, &val); break; default: nfp_err(cpp, "rtsym '%s' unsupported or non-scalar size: %lld\n", name, sym->size); err = -EINVAL; break; } if (err == sym->size) err = 0; else if (err >= 0) err = -EIO; exit: if (error) *error = err; if (err) return ~0ULL; return val; }