diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-08-28 23:20:46 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-29 02:01:47 +0300 |
commit | 640917dd81b622ac1c6e66b80be6a4174cbe3710 (patch) | |
tree | 1e8e0e44e3d526bcd1c2cfa8925a4825a997c047 /drivers/net/ethernet/netronome | |
parent | 1240989ccca95863ceebfbdff0f84993d84458f9 (diff) | |
download | linux-640917dd81b622ac1c6e66b80be6a4174cbe3710.tar.xz |
nfp: support access to absolute RTsyms
Add support in nfpcore for reading the absolute RTsyms.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Francois H. Theron <francois.theron@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c | 42 |
2 files changed, 46 insertions, 9 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h index 04700278d00d..8d2cbdf4d517 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h @@ -61,10 +61,12 @@ void nfp_mip_strtab(const struct nfp_mip *mip, u32 *addr, u32 *size); /* Implemented in nfp_rtsym.c */ -#define NFP_RTSYM_TYPE_NONE 0 -#define NFP_RTSYM_TYPE_OBJECT 1 -#define NFP_RTSYM_TYPE_FUNCTION 2 -#define NFP_RTSYM_TYPE_ABS 3 +enum nfp_rtsym_type { + NFP_RTSYM_TYPE_NONE = 0, + NFP_RTSYM_TYPE_OBJECT = 1, + NFP_RTSYM_TYPE_FUNCTION = 2, + NFP_RTSYM_TYPE_ABS = 3, +}; #define NFP_RTSYM_TARGET_NONE 0 #define NFP_RTSYM_TARGET_LMEM -1 @@ -83,7 +85,7 @@ struct nfp_rtsym { const char *name; u64 addr; u64 size; - int type; + enum nfp_rtsym_type type; int target; int domain; }; @@ -98,6 +100,7 @@ const struct nfp_rtsym *nfp_rtsym_get(struct nfp_rtsym_table *rtbl, int idx); const struct nfp_rtsym * nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, const char *name); +u64 nfp_rtsym_size(const struct nfp_rtsym *rtsym); int __nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u8 action, u8 token, u64 off, void *buf, size_t len); int nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off, diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c index 28e5ed0bb31d..108ce8c5e68e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c @@ -233,10 +233,32 @@ nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, const char *name) return NULL; } +u64 nfp_rtsym_size(const struct nfp_rtsym *sym) +{ + switch (sym->type) { + case NFP_RTSYM_TYPE_NONE: + pr_err("rtsym type NONE\n"); + return 0; + default: + pr_warn("Unknown rtsym type: %d\n", sym->type); + /* fall through */ + case NFP_RTSYM_TYPE_OBJECT: + case NFP_RTSYM_TYPE_FUNCTION: + return sym->size; + case NFP_RTSYM_TYPE_ABS: + return sizeof(u64); + } +} + static int nfp_rtsym_to_dest(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u8 action, u8 token, u64 off, u32 *cpp_id, u64 *addr) { + if (sym->type != NFP_RTSYM_TYPE_OBJECT) { + nfp_err(cpp, "Direct access attempt to non-object rtsym\n"); + return -EINVAL; + } + *addr = sym->addr + off; if (sym->target == NFP_RTSYM_TARGET_EMU_CACHE) { @@ -266,6 +288,15 @@ int __nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 addr; int err; + if (sym->type == NFP_RTSYM_TYPE_ABS) { + __le64 tmp = cpu_to_le64(sym->addr); + + len = min(len, sizeof(tmp)); + memcpy(buf, &tmp, len); + + return len; + } + err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr); if (err) return err; @@ -306,6 +337,9 @@ int __nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 addr; int err; + if (sym->type == NFP_RTSYM_TYPE_ABS) + return sym->addr; + err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr); if (err) return err; @@ -405,7 +439,7 @@ u64 nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, goto exit; } - switch (sym->size) { + switch (nfp_rtsym_size(sym)) { case 4: err = nfp_rtsym_readl(rtbl->cpp, sym, 0, &val32); val = val32; @@ -416,7 +450,7 @@ u64 nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, default: nfp_err(rtbl->cpp, "rtsym '%s' unsupported or non-scalar size: %lld\n", - name, sym->size); + name, nfp_rtsym_size(sym)); err = -EINVAL; break; } @@ -452,7 +486,7 @@ int nfp_rtsym_write_le(struct nfp_rtsym_table *rtbl, const char *name, if (!sym) return -ENOENT; - switch (sym->size) { + switch (nfp_rtsym_size(sym)) { case 4: err = nfp_rtsym_writel(rtbl->cpp, sym, 0, value); break; @@ -462,7 +496,7 @@ int nfp_rtsym_write_le(struct nfp_rtsym_table *rtbl, const char *name, default: nfp_err(rtbl->cpp, "rtsym '%s' unsupported or non-scalar size: %lld\n", - name, sym->size); + name, nfp_rtsym_size(sym)); err = -EINVAL; break; } |