From 8b3d5a47ae6b93654e39b543e33ded07c06fa8a9 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Sun, 28 May 2017 17:52:57 -0700 Subject: nfp: support long reads and writes with the cpp helpers nfp_cpp_{read,write}() helpers perform device memory mapping (setting the PCIe -> NOC translation BARs) and accessing it. They, however, currently implicitly expect that the length of entire operation will fit in one BAR translation window. There is a number of 16MB windows available, and we don't really need to access such large areas today. If the user, however, manages to trick the driver into making a big mapping (e.g. by providing a huge fake FW file), the driver will print a warning saying "No suitable BAR found for request" and a stack trace - which most users find concerning. To be future-proof and not scare users with warnings, make the nfp_cpp_{read,write}() helpers do accesses chunk by chunk if the area size is large. Set the notion of "large" to 2MB, which is the size of the smallest BAR window. Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 87 +++++++++++++++++----- 1 file changed, 69 insertions(+), 18 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c') diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index e2abba4c3a3f..5672d309d07d 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -924,18 +924,9 @@ area_cache_put(struct nfp_cpp *cpp, struct nfp_cpp_area_cache *cache) mutex_unlock(&cpp->area_cache_mutex); } -/** - * nfp_cpp_read() - read from CPP target - * @cpp: CPP handle - * @destination: CPP id - * @address: offset into CPP target - * @kernel_vaddr: kernel buffer for result - * @length: number of bytes to read - * - * Return: length of io, or -ERRNO - */ -int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination, - unsigned long long address, void *kernel_vaddr, size_t length) +static int __nfp_cpp_read(struct nfp_cpp *cpp, u32 destination, + unsigned long long address, void *kernel_vaddr, + size_t length) { struct nfp_cpp_area_cache *cache; struct nfp_cpp_area *area; @@ -968,18 +959,43 @@ int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination, } /** - * nfp_cpp_write() - write to CPP target + * nfp_cpp_read() - read from CPP target * @cpp: CPP handle * @destination: CPP id * @address: offset into CPP target - * @kernel_vaddr: kernel buffer to read from - * @length: number of bytes to write + * @kernel_vaddr: kernel buffer for result + * @length: number of bytes to read * * Return: length of io, or -ERRNO */ -int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination, - unsigned long long address, - const void *kernel_vaddr, size_t length) +int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination, + unsigned long long address, void *kernel_vaddr, + size_t length) +{ + size_t n, offset; + int ret; + + for (offset = 0; offset < length; offset += n) { + unsigned long long r_addr = address + offset; + + /* make first read smaller to align to safe window */ + n = min_t(size_t, length - offset, + ALIGN(r_addr + 1, NFP_CPP_SAFE_AREA_SIZE) - r_addr); + + ret = __nfp_cpp_read(cpp, destination, address + offset, + kernel_vaddr + offset, n); + if (ret < 0) + return ret; + if (ret != n) + return offset + n; + } + + return length; +} + +static int __nfp_cpp_write(struct nfp_cpp *cpp, u32 destination, + unsigned long long address, + const void *kernel_vaddr, size_t length) { struct nfp_cpp_area_cache *cache; struct nfp_cpp_area *area; @@ -1011,6 +1027,41 @@ int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination, return err; } +/** + * nfp_cpp_write() - write to CPP target + * @cpp: CPP handle + * @destination: CPP id + * @address: offset into CPP target + * @kernel_vaddr: kernel buffer to read from + * @length: number of bytes to write + * + * Return: length of io, or -ERRNO + */ +int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination, + unsigned long long address, + const void *kernel_vaddr, size_t length) +{ + size_t n, offset; + int ret; + + for (offset = 0; offset < length; offset += n) { + unsigned long long w_addr = address + offset; + + /* make first write smaller to align to safe window */ + n = min_t(size_t, length - offset, + ALIGN(w_addr + 1, NFP_CPP_SAFE_AREA_SIZE) - w_addr); + + ret = __nfp_cpp_write(cpp, destination, address + offset, + kernel_vaddr + offset, n); + if (ret < 0) + return ret; + if (ret != n) + return offset + n; + } + + return length; +} + /* Return the correct CPP address, and fixup xpb_addr as needed. */ static u32 nfp_xpb_to_cpp(struct nfp_cpp *cpp, u32 *xpb_addr) { -- cgit v1.2.3-55-g7522 From af4fa7eac770720d5edb9337ab0bccb843936364 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2017 20:56:11 -0700 Subject: nfp: remove automatic caching of RTsym table The fact that RTsym table is cached inside nfp_cpp handle is a relic of old times when nfpcore was a library module. All the nfp_cpp "caches" are awkward to deal with because of concurrency and prone to keeping stale information. Make the run time symbol table be an object read out from the device and managed by whoever requested it. Since the driver loads FW at ->probe() and never reloads, we can hold onto the table for ever. Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_main.c | 6 +- drivers/net/ethernet/netronome/nfp/nfp_main.h | 3 + drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 4 +- .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h | 4 - .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 26 ----- .../net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h | 13 ++- .../net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 8 +- .../net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c | 111 ++++++++------------- 8 files changed, 63 insertions(+), 112 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index 0c2e64d217b5..51fe8de34b67 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -77,7 +77,7 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) { int err; - pf->limit_vfs = nfp_rtsym_read_le(pf->cpp, "nfd_vf_cfg_max_vfs", &err); + pf->limit_vfs = nfp_rtsym_read_le(pf->rtbl, "nfd_vf_cfg_max_vfs", &err); if (!err) return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); @@ -373,6 +373,8 @@ static int nfp_pci_probe(struct pci_dev *pdev, if (err) goto err_devlink_unreg; + pf->rtbl = nfp_rtsym_table_read(pf->cpp); + err = nfp_pcie_sriov_read_nfd_limit(pf); if (err) goto err_fw_unload; @@ -394,6 +396,7 @@ err_net_remove: err_sriov_unlimit: pci_sriov_set_totalvfs(pf->pdev, 0); err_fw_unload: + kfree(pf->rtbl); if (pf->fw_loaded) nfp_fw_unload(pf); kfree(pf->eth_tbl); @@ -430,6 +433,7 @@ static void nfp_pci_remove(struct pci_dev *pdev) devlink_unregister(devlink); + kfree(pf->rtbl); if (pf->fw_loaded) nfp_fw_unload(pf); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h index 37832853b0b3..907852f00423 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h @@ -56,6 +56,7 @@ struct nfp_cpp_area; struct nfp_eth_table; struct nfp_net; struct nfp_nsp_identify; +struct nfp_rtsym_table; /** * struct nfp_pf - NFP PF-specific device structure @@ -70,6 +71,7 @@ struct nfp_nsp_identify; * @num_vfs: Number of SR-IOV VFs enabled * @fw_loaded: Is the firmware loaded? * @ctrl_vnic: Pointer to the control vNIC if available + * @rtbl: RTsym table * @eth_tbl: NSP ETH table * @nspi: NSP identification info * @hwmon_dev: pointer to hwmon device @@ -101,6 +103,7 @@ struct nfp_pf { struct nfp_net *ctrl_vnic; + struct nfp_rtsym_table *rtbl; struct nfp_eth_table *eth_tbl; struct nfp_nsp_identify *nspi; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index cdd25dc5988d..c845049fcff2 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -201,7 +201,7 @@ nfp_net_pf_rtsym_read_optional(struct nfp_pf *pf, const char *format, snprintf(name, sizeof(name), format, nfp_cppcore_pcie_unit(pf->cpp)); - val = nfp_rtsym_read_le(pf->cpp, name, &err); + val = nfp_rtsym_read_le(pf->rtbl, name, &err); if (err) { if (err == -ENOENT) return default_val; @@ -234,7 +234,7 @@ nfp_net_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt, snprintf(pf_symbol, sizeof(pf_symbol), sym_fmt, nfp_cppcore_pcie_unit(pf->cpp)); - sym = nfp_rtsym_lookup(pf->cpp, pf_symbol); + sym = nfp_rtsym_lookup(pf->rtbl, pf_symbol); if (!sym) { nfp_err(pf->cpp, "Failed to find PF symbol %s\n", pf_symbol); return (u8 __iomem *)ERR_PTR(-ENOENT); diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h index 0a46c0984e68..e3a2201eb658 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h @@ -224,10 +224,6 @@ int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial); void *nfp_hwinfo_cache(struct nfp_cpp *cpp); void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val); -void *nfp_rtsym_cache(struct nfp_cpp *cpp); -void nfp_rtsym_cache_set(struct nfp_cpp *cpp, void *val); - -void nfp_nffw_cache_flush(struct nfp_cpp *cpp); struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, u32 cpp_id, diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index 5672d309d07d..f477186558bd 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -78,7 +78,6 @@ struct nfp_cpp_resource { * * Following fields can be used only in probe() or with rtnl held: * @hwinfo: HWInfo database fetched from the device - * @rtsym: firmware run time symbols * * Following fields use explicit locking: * @resource_list: NFP CPP resource list @@ -109,7 +108,6 @@ struct nfp_cpp { struct list_head area_cache_list; void *hwinfo; - void *rtsym; }; /* Element of the area_cache_list */ @@ -234,7 +232,6 @@ void nfp_cpp_free(struct nfp_cpp *cpp) cpp->op->free(cpp); kfree(cpp->hwinfo); - kfree(cpp->rtsym); device_unregister(&cpp->dev); @@ -286,29 +283,6 @@ void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val) cpp->hwinfo = val; } -void *nfp_rtsym_cache(struct nfp_cpp *cpp) -{ - return cpp->rtsym; -} - -void nfp_rtsym_cache_set(struct nfp_cpp *cpp, void *val) -{ - cpp->rtsym = val; -} - -/** - * nfp_nffw_cache_flush() - Flush cached firmware information - * @cpp: NFP CPP handle - * - * Flush cached firmware information. This function should be called - * every time firmware is loaded on unloaded. - */ -void nfp_nffw_cache_flush(struct nfp_cpp *cpp) -{ - kfree(nfp_rtsym_cache(cpp)); - nfp_rtsym_cache_set(cpp, NULL); -} - /** * nfp_cpp_area_alloc_with_name() - allocate a new CPP area * @cpp: CPP device handle diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h index 988badd230d1..f845cf5dd762 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h @@ -87,9 +87,14 @@ struct nfp_rtsym { int domain; }; -int nfp_rtsym_count(struct nfp_cpp *cpp); -const struct nfp_rtsym *nfp_rtsym_get(struct nfp_cpp *cpp, int idx); -const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name); -u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error); +struct nfp_rtsym_table; + +struct nfp_rtsym_table *nfp_rtsym_table_read(struct nfp_cpp *cpp); +int nfp_rtsym_count(struct nfp_rtsym_table *rtbl); +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_read_le(struct nfp_rtsym_table *rtbl, const char *name, + int *error); #endif /* NFP_NFFW_H */ diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c index eefdb756d74e..37364555c42b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c @@ -474,13 +474,7 @@ int nfp_nsp_wait(struct nfp_nsp *state) int nfp_nsp_device_soft_reset(struct nfp_nsp *state) { - int err; - - err = nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0); - - nfp_nffw_cache_flush(state->cpp); - - return err; + return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0); } int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw) diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c index 0e3870ecfb8c..ef3566163cb0 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c @@ -65,7 +65,8 @@ struct nfp_rtsym_entry { __le32 size_lo; }; -struct nfp_rtsym_cache { +struct nfp_rtsym_table { + struct nfp_cpp *cpp; int num; char *strtab; struct nfp_rtsym symtab[]; @@ -78,7 +79,7 @@ static int nfp_meid(u8 island_id, u8 menum) } static void -nfp_rtsym_sw_entry_init(struct nfp_rtsym_cache *cache, u32 strtab_size, +nfp_rtsym_sw_entry_init(struct nfp_rtsym_table *cache, u32 strtab_size, struct nfp_rtsym *sw, struct nfp_rtsym_entry *fw) { sw->type = fw->type; @@ -106,26 +107,26 @@ nfp_rtsym_sw_entry_init(struct nfp_rtsym_cache *cache, u32 strtab_size, sw->domain = -1; } -static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) +struct nfp_rtsym_table *nfp_rtsym_table_read(struct nfp_cpp *cpp) { const u32 dram = NFP_CPP_ID(NFP_CPP_TARGET_MU, NFP_CPP_ACTION_RW, 0) | NFP_ISL_EMEM0; u32 strtab_addr, symtab_addr, strtab_size, symtab_size; struct nfp_rtsym_entry *rtsymtab; - struct nfp_rtsym_cache *cache; + struct nfp_rtsym_table *cache; const struct nfp_mip *mip; int err, n, size; mip = nfp_mip_open(cpp); if (!mip) - return -EIO; + return NULL; nfp_mip_strtab(mip, &strtab_addr, &strtab_size); nfp_mip_symtab(mip, &symtab_addr, &symtab_size); nfp_mip_close(mip); if (!symtab_size || !strtab_size || symtab_size % sizeof(*rtsymtab)) - return -ENXIO; + return NULL; /* Align to 64 bits */ symtab_size = round_up(symtab_size, 8); @@ -133,27 +134,26 @@ static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) rtsymtab = kmalloc(symtab_size, GFP_KERNEL); if (!rtsymtab) - return -ENOMEM; + return NULL; size = sizeof(*cache); size += symtab_size / sizeof(*rtsymtab) * sizeof(struct nfp_rtsym); size += strtab_size + 1; cache = kmalloc(size, GFP_KERNEL); - if (!cache) { - err = -ENOMEM; - goto err_free_rtsym_raw; - } + if (!cache) + goto exit_free_rtsym_raw; + cache->cpp = cpp; cache->num = symtab_size / sizeof(*rtsymtab); cache->strtab = (void *)&cache->symtab[cache->num]; err = nfp_cpp_read(cpp, dram, symtab_addr, rtsymtab, symtab_size); if (err != symtab_size) - goto err_free_cache; + goto exit_free_cache; err = nfp_cpp_read(cpp, dram, strtab_addr, cache->strtab, strtab_size); if (err != strtab_size) - goto err_free_cache; + goto exit_free_cache; cache->strtab[strtab_size] = '\0'; for (n = 0; n < cache->num; n++) @@ -161,97 +161,71 @@ static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) &cache->symtab[n], &rtsymtab[n]); kfree(rtsymtab); - nfp_rtsym_cache_set(cpp, cache); - return 0; -err_free_cache: + return cache; + +exit_free_cache: kfree(cache); -err_free_rtsym_raw: +exit_free_rtsym_raw: kfree(rtsymtab); - return err; -} - -static struct nfp_rtsym_cache *nfp_rtsym(struct nfp_cpp *cpp) -{ - struct nfp_rtsym_cache *cache; - int err; - - cache = nfp_rtsym_cache(cpp); - if (cache) - return cache; - - err = nfp_rtsymtab_probe(cpp); - if (err < 0) - return ERR_PTR(err); - - return nfp_rtsym_cache(cpp); + return NULL; } /** * nfp_rtsym_count() - Get the number of RTSYM descriptors - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * - * Return: Number of RTSYM descriptors, or -ERRNO + * Return: Number of RTSYM descriptors */ -int nfp_rtsym_count(struct nfp_cpp *cpp) +int nfp_rtsym_count(struct nfp_rtsym_table *rtbl) { - struct nfp_rtsym_cache *cache; - - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) - return PTR_ERR(cache); - - return cache->num; + if (!rtbl) + return -EINVAL; + return rtbl->num; } /** * nfp_rtsym_get() - Get the Nth RTSYM descriptor - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @idx: Index (0-based) of the RTSYM descriptor * * Return: const pointer to a struct nfp_rtsym descriptor, or NULL */ -const struct nfp_rtsym *nfp_rtsym_get(struct nfp_cpp *cpp, int idx) +const struct nfp_rtsym *nfp_rtsym_get(struct nfp_rtsym_table *rtbl, int idx) { - struct nfp_rtsym_cache *cache; - - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) + if (!rtbl) return NULL; - - if (idx >= cache->num) + if (idx >= rtbl->num) return NULL; - return &cache->symtab[idx]; + return &rtbl->symtab[idx]; } /** * nfp_rtsym_lookup() - Return the RTSYM descriptor for a symbol name - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @name: Symbol name * * Return: const pointer to a struct nfp_rtsym descriptor, or NULL */ -const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name) +const struct nfp_rtsym * +nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, const char *name) { - struct nfp_rtsym_cache *cache; int n; - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) + if (!rtbl) return NULL; - for (n = 0; n < cache->num; n++) { - if (strcmp(name, cache->symtab[n].name) == 0) - return &cache->symtab[n]; - } + for (n = 0; n < rtbl->num; n++) + if (strcmp(name, rtbl->symtab[n].name) == 0) + return &rtbl->symtab[n]; return NULL; } /** * nfp_rtsym_read_le() - Read a simple unsigned scalar value from symbol - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @name: Symbol name * @error: Poniter to error code (optional) * @@ -261,14 +235,15 @@ const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name) * * 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) +u64 nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, + int *error) { const struct nfp_rtsym *sym; u32 val32, id; u64 val; int err; - sym = nfp_rtsym_lookup(cpp, name); + sym = nfp_rtsym_lookup(rtbl, name); if (!sym) { err = -ENOENT; goto exit; @@ -278,14 +253,14 @@ u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error) switch (sym->size) { case 4: - err = nfp_cpp_readl(cpp, id, sym->addr, &val32); + err = nfp_cpp_readl(rtbl->cpp, id, sym->addr, &val32); val = val32; break; case 8: - err = nfp_cpp_readq(cpp, id, sym->addr, &val); + err = nfp_cpp_readq(rtbl->cpp, id, sym->addr, &val); break; default: - nfp_err(cpp, + nfp_err(rtbl->cpp, "rtsym '%s' unsupported or non-scalar size: %lld\n", name, sym->size); err = -EINVAL; -- cgit v1.2.3-55-g7522 From 9baa48859bd31f06b9170e86afd92585ff0bbb1f Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2017 20:56:12 -0700 Subject: nfp: remove automatic caching of HWInfo Make callers take care of managing life time of HWInfo. Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_app_nic.c | 2 +- drivers/net/ethernet/netronome/nfp/nfp_main.c | 20 ++++--- drivers/net/ethernet/netronome/nfp/nfp_main.h | 5 +- drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 12 ++-- drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h | 4 +- .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h | 3 - .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 17 ------ .../ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c | 70 +++++++++------------- 8 files changed, 54 insertions(+), 79 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c index 1a33ad9f4170..83c65e6291ee 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c @@ -80,7 +80,7 @@ int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn, if (err) return err < 0 ? err : 0; - nfp_net_get_mac_addr(nn, app->cpp, id); + nfp_net_get_mac_addr(app->pf, nn, id); return 0; } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index 51fe8de34b67..94211e245257 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -170,7 +170,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf) return NULL; } - fw_model = nfp_hwinfo_lookup(pf->cpp, "assembly.partno"); + fw_model = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"); if (!fw_model) { dev_err(&pdev->dev, "Error: can't read part number\n"); return NULL; @@ -358,16 +358,18 @@ static int nfp_pci_probe(struct pci_dev *pdev, goto err_disable_msix; } + pf->hwinfo = nfp_hwinfo_read(pf->cpp); + dev_info(&pdev->dev, "Assembly: %s%s%s-%s CPLD: %s\n", - nfp_hwinfo_lookup(pf->cpp, "assembly.vendor"), - nfp_hwinfo_lookup(pf->cpp, "assembly.partno"), - nfp_hwinfo_lookup(pf->cpp, "assembly.serial"), - nfp_hwinfo_lookup(pf->cpp, "assembly.revision"), - nfp_hwinfo_lookup(pf->cpp, "cpld.version")); + nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"), + nfp_hwinfo_lookup(pf->hwinfo, "cpld.version")); err = devlink_register(devlink, &pdev->dev); if (err) - goto err_cpp_free; + goto err_hwinfo_free; err = nfp_nsp_init(pdev, pf); if (err) @@ -403,7 +405,8 @@ err_fw_unload: kfree(pf->nspi); err_devlink_unreg: devlink_unregister(devlink); -err_cpp_free: +err_hwinfo_free: + kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); err_disable_msix: pci_set_drvdata(pdev, NULL); @@ -438,6 +441,7 @@ static void nfp_pci_remove(struct pci_dev *pdev) nfp_fw_unload(pf); pci_set_drvdata(pdev, NULL); + kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); kfree(pf->eth_tbl); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h index 907852f00423..041643807f7e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h @@ -54,6 +54,7 @@ struct pci_dev; struct nfp_cpp; struct nfp_cpp_area; struct nfp_eth_table; +struct nfp_hwinfo; struct nfp_net; struct nfp_nsp_identify; struct nfp_rtsym_table; @@ -72,6 +73,7 @@ struct nfp_rtsym_table; * @fw_loaded: Is the firmware loaded? * @ctrl_vnic: Pointer to the control vNIC if available * @rtbl: RTsym table + * @hwinfo: HWInfo table * @eth_tbl: NSP ETH table * @nspi: NSP identification info * @hwmon_dev: pointer to hwmon device @@ -104,6 +106,7 @@ struct nfp_pf { struct nfp_net *ctrl_vnic; struct nfp_rtsym_table *rtbl; + struct nfp_hwinfo *hwinfo; struct nfp_eth_table *eth_tbl; struct nfp_nsp_identify *nspi; @@ -133,7 +136,7 @@ void nfp_hwmon_unregister(struct nfp_pf *pf); struct nfp_eth_table_port * nfp_net_find_port(struct nfp_eth_table *eth_tbl, unsigned int id); void -nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id); +nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id); bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index c845049fcff2..bc2bc0886176 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -63,13 +63,13 @@ #define NFP_PF_CSR_SLICE_SIZE (32 * 1024) -static int nfp_is_ready(struct nfp_cpp *cpp) +static int nfp_is_ready(struct nfp_pf *pf) { const char *cp; long state; int err; - cp = nfp_hwinfo_lookup(cpp, "board.state"); + cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state"); if (!cp) return 0; @@ -134,15 +134,15 @@ err_area: /** * nfp_net_get_mac_addr() - Get the MAC address. + * @pf: NFP PF handle * @nn: NFP Network structure - * @cpp: NFP CPP handle * @id: NFP port id * * First try to get the MAC address from NSP ETH table. If that * fails try HWInfo. As a last resort generate a random address. */ void -nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id) +nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id) { struct nfp_eth_table_port *eth_port; struct nfp_net_dp *dp = &nn->dp; @@ -159,7 +159,7 @@ nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id) snprintf(name, sizeof(name), "eth%d.mac", id); - mac_str = nfp_hwinfo_lookup(cpp, name); + mac_str = nfp_hwinfo_lookup(pf->hwinfo, name); if (!mac_str) { dev_warn(dp->dev, "Can't lookup MAC address. Generate\n"); eth_hw_addr_random(dp->netdev); @@ -713,7 +713,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf) INIT_WORK(&pf->port_refresh_work, nfp_net_refresh_vnics); /* Verify that the board has completed initialization */ - if (!nfp_is_ready(pf->cpp)) { + if (!nfp_is_ready(pf)) { nfp_err(pf->cpp, "NFP is not ready for NIC operation.\n"); return -EINVAL; } diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h index 94641b4c2c55..1a8d04a1e113 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h @@ -46,7 +46,9 @@ /* Implemented in nfp_hwinfo.c */ -const char *nfp_hwinfo_lookup(struct nfp_cpp *cpp, const char *lookup); +struct nfp_hwinfo; +struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp); +const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup); /* Implemented in nfp_nsp.c, low level functions */ diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h index e3a2201eb658..25a967158ce9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h @@ -222,9 +222,6 @@ u32 nfp_cpp_model(struct nfp_cpp *cpp); u16 nfp_cpp_interface(struct nfp_cpp *cpp); int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial); -void *nfp_hwinfo_cache(struct nfp_cpp *cpp); -void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val); - struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, u32 cpp_id, const char *name, diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index f477186558bd..9b69dcf87be9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -76,9 +76,6 @@ struct nfp_cpp_resource { * @serial: chip serial number * @imb_cat_table: CPP Mapping Table * - * Following fields can be used only in probe() or with rtnl held: - * @hwinfo: HWInfo database fetched from the device - * * Following fields use explicit locking: * @resource_list: NFP CPP resource list * @resource_lock: protects @resource_list @@ -106,8 +103,6 @@ struct nfp_cpp { struct mutex area_cache_mutex; struct list_head area_cache_list; - - void *hwinfo; }; /* Element of the area_cache_list */ @@ -231,8 +226,6 @@ void nfp_cpp_free(struct nfp_cpp *cpp) if (cpp->op->free) cpp->op->free(cpp); - kfree(cpp->hwinfo); - device_unregister(&cpp->dev); kfree(cpp); @@ -273,16 +266,6 @@ int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial) return sizeof(cpp->serial); } -void *nfp_hwinfo_cache(struct nfp_cpp *cpp) -{ - return cpp->hwinfo; -} - -void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val) -{ - cpp->hwinfo = val; -} - /** * nfp_cpp_area_alloc_with_name() - allocate a new CPP area * @cpp: CPP device handle diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c index 8d8f311ffa6e..4f24aff1e772 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c @@ -178,7 +178,8 @@ hwinfo_db_validate(struct nfp_cpp *cpp, struct nfp_hwinfo *db, u32 len) return hwinfo_db_walk(cpp, db, size); } -static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) +static struct nfp_hwinfo * +hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) { struct nfp_hwinfo *header; struct nfp_resource *res; @@ -196,7 +197,7 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) nfp_resource_release(res); if (*cpp_size < HWINFO_SIZE_MIN) - return -ENOENT; + return NULL; } else if (PTR_ERR(res) == -ENOENT) { /* Try getting the HWInfo table from the 'classic' location */ cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU, @@ -204,101 +205,86 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) cpp_addr = 0x30000; *cpp_size = 0x0e000; } else { - return PTR_ERR(res); + return NULL; } db = kmalloc(*cpp_size + 1, GFP_KERNEL); if (!db) - return -ENOMEM; + return NULL; err = nfp_cpp_read(cpp, cpp_id, cpp_addr, db, *cpp_size); - if (err != *cpp_size) { - kfree(db); - return err < 0 ? err : -EIO; - } + if (err != *cpp_size) + goto exit_free; header = (void *)db; - if (nfp_hwinfo_is_updating(header)) { - kfree(db); - return -EBUSY; - } + if (nfp_hwinfo_is_updating(header)) + goto exit_free; if (le32_to_cpu(header->version) != NFP_HWINFO_VERSION_2) { nfp_err(cpp, "Unknown HWInfo version: 0x%08x\n", le32_to_cpu(header->version)); - kfree(db); - return -EINVAL; + goto exit_free; } /* NULL-terminate for safety */ db[*cpp_size] = '\0'; - nfp_hwinfo_cache_set(cpp, db); - - return 0; + return (void *)db; +exit_free: + kfree(db); + return NULL; } -static int hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size) +static struct nfp_hwinfo *hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size) { const unsigned long wait_until = jiffies + HWINFO_WAIT * HZ; + struct nfp_hwinfo *db; int err; for (;;) { const unsigned long start_time = jiffies; - err = hwinfo_try_fetch(cpp, hwdb_size); - if (!err) - return 0; + db = hwinfo_try_fetch(cpp, hwdb_size); + if (db) + return db; err = msleep_interruptible(100); if (err || time_after(start_time, wait_until)) { nfp_err(cpp, "NFP access error\n"); - return -EIO; + return NULL; } } } -static int nfp_hwinfo_load(struct nfp_cpp *cpp) +struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp) { struct nfp_hwinfo *db; size_t hwdb_size = 0; int err; - err = hwinfo_fetch(cpp, &hwdb_size); - if (err) - return err; + db = hwinfo_fetch(cpp, &hwdb_size); + if (!db) + return NULL; - db = nfp_hwinfo_cache(cpp); err = hwinfo_db_validate(cpp, db, hwdb_size); if (err) { kfree(db); - nfp_hwinfo_cache_set(cpp, NULL); - return err; + return NULL; } - return 0; + return db; } /** * nfp_hwinfo_lookup() - Find a value in the HWInfo table by name - * @cpp: NFP CPP handle + * @hwinfo: NFP HWinfo table * @lookup: HWInfo name to search for * * Return: Value of the HWInfo name, or NULL */ -const char *nfp_hwinfo_lookup(struct nfp_cpp *cpp, const char *lookup) +const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup) { const char *key, *val, *end; - struct nfp_hwinfo *hwinfo; - int err; - - hwinfo = nfp_hwinfo_cache(cpp); - if (!hwinfo) { - err = nfp_hwinfo_load(cpp); - if (err) - return NULL; - hwinfo = nfp_hwinfo_cache(cpp); - } if (!hwinfo || !lookup) return NULL; -- cgit v1.2.3-55-g7522 From 064dc3196ebd2587ad9a4ca2d26629a20f819352 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 27 Jun 2017 00:50:16 -0700 Subject: nfp: move area mapping helper into nfpcore nfp_net_map_area() is a helper for mapping areas of NFP memory defined in nfp_net_main.c. Move it to nfpcore to allow reuse and rename accordingly. Create an additional helper - nfp_cpp_area_alloc_acquire() the opposite of already existing nfp_cpp_area_release_free(). Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 56 +--------------------- .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h | 7 +++ .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 35 ++++++++++++++ .../ethernet/netronome/nfp/nfpcore/nfp_cpplib.c | 40 ++++++++++++++++ 4 files changed, 84 insertions(+), 54 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index 3169400dd474..16ee904db0cd 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -80,58 +80,6 @@ static int nfp_is_ready(struct nfp_pf *pf) return state == 15; } -/** - * nfp_net_map_area() - Help function to map an area - * @cpp: NFP CPP handler - * @name: Name for the area - * @target: CPP target - * @addr: CPP address - * @size: Size of the area - * @area: Area handle (returned). - * - * This function is primarily to simplify the code in the main probe - * function. To undo the effect of this functions call - * @nfp_cpp_area_release_free(*area); - * - * Return: Pointer to memory mapped area or ERR_PTR - */ -static u8 __iomem *nfp_net_map_area(struct nfp_cpp *cpp, - const char *name, int isl, int target, - unsigned long long addr, unsigned long size, - struct nfp_cpp_area **area) -{ - u8 __iomem *res; - u32 dest; - int err; - - dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, isl); - - *area = nfp_cpp_area_alloc_with_name(cpp, dest, name, addr, size); - if (!*area) { - err = -EIO; - goto err_area; - } - - err = nfp_cpp_area_acquire(*area); - if (err < 0) - goto err_acquire; - - res = nfp_cpp_area_iomem(*area); - if (!res) { - err = -EIO; - goto err_map; - } - - return res; - -err_map: - nfp_cpp_area_release(*area); -err_acquire: - nfp_cpp_area_free(*area); -err_area: - return (u8 __iomem *)ERR_PTR(err); -} - /** * nfp_net_get_mac_addr() - Get the MAC address. * @pf: NFP PF handle @@ -242,7 +190,7 @@ nfp_net_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt, return (u8 __iomem *)ERR_PTR(-EINVAL); } - mem = nfp_net_map_area(pf->cpp, name, sym->domain, sym->target, + mem = nfp_cpp_map_area(pf->cpp, name, sym->domain, sym->target, sym->addr, sym->size, area); if (IS_ERR(mem)) { nfp_err(pf->cpp, "Failed to map PF symbol %s: %ld\n", @@ -617,7 +565,7 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf) pf->vf_cfg_mem = NULL; } - mem = nfp_net_map_area(pf->cpp, "net.qc", 0, 0, + mem = nfp_cpp_map_area(pf->cpp, "net.qc", 0, 0, NFP_PCIE_QUEUE(0), NFP_QCP_QUEUE_AREA_SZ, &pf->qc_area); if (IS_ERR(mem)) { diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h index 25a967158ce9..235dd023d9b9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h @@ -230,6 +230,9 @@ struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, struct nfp_cpp_area *nfp_cpp_area_alloc(struct nfp_cpp *cpp, u32 cpp_id, unsigned long long address, unsigned long size); +struct nfp_cpp_area * +nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, const char *name, u32 cpp_id, + unsigned long long address, unsigned long size); void nfp_cpp_area_free(struct nfp_cpp_area *area); int nfp_cpp_area_acquire(struct nfp_cpp_area *area); int nfp_cpp_area_acquire_nonblocking(struct nfp_cpp_area *area); @@ -278,6 +281,10 @@ int nfp_cpp_readq(struct nfp_cpp *cpp, u32 cpp_id, int nfp_cpp_writeq(struct nfp_cpp *cpp, u32 cpp_id, unsigned long long address, u64 value); +u8 __iomem * +nfp_cpp_map_area(struct nfp_cpp *cpp, const char *name, int domain, int target, + u64 addr, unsigned long size, struct nfp_cpp_area **area); + struct nfp_cpp_mutex; int nfp_cpp_mutex_init(struct nfp_cpp *cpp, int target, diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index 9b69dcf87be9..7d5d7293efed 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -360,6 +360,41 @@ nfp_cpp_area_alloc(struct nfp_cpp *cpp, u32 dest, return nfp_cpp_area_alloc_with_name(cpp, dest, NULL, address, size); } +/** + * nfp_cpp_area_alloc_acquire() - allocate a new CPP area and lock it down + * @cpp: CPP handle + * @name: Name of region + * @dest: CPP id + * @address: Start address on CPP target + * @size: Size of area + * + * Allocate and initialize a CPP area structure, and lock it down so + * that it can be accessed directly. + * + * NOTE: @address and @size must be 32-bit aligned values. + * + * NOTE: The area must also be 'released' when the structure is freed. + * + * Return: NFP CPP Area handle, or NULL + */ +struct nfp_cpp_area * +nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, const char *name, u32 dest, + unsigned long long address, unsigned long size) +{ + struct nfp_cpp_area *area; + + area = nfp_cpp_area_alloc_with_name(cpp, dest, name, address, size); + if (!area) + return NULL; + + if (nfp_cpp_area_acquire(area)) { + nfp_cpp_area_free(area); + return NULL; + } + + return area; +} + /** * nfp_cpp_area_free() - free up the CPP area * @area: CPP area handle diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c index 0ba0379b8f75..ab86bceb93f2 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c @@ -279,3 +279,43 @@ exit_release: return err; } + +/** + * nfp_cpp_map_area() - Helper function to map an area + * @cpp: NFP CPP handler + * @name: Name for the area + * @domain: CPP domain + * @target: CPP target + * @addr: CPP address + * @size: Size of the area + * @area: Area handle (output) + * + * 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 + */ +u8 __iomem * +nfp_cpp_map_area(struct nfp_cpp *cpp, const char *name, int domain, int target, + u64 addr, unsigned long size, struct nfp_cpp_area **area) +{ + u8 __iomem *res; + u32 dest; + + dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, domain); + + *area = nfp_cpp_area_alloc_acquire(cpp, name, dest, addr, size); + if (!*area) + goto err_eio; + + res = nfp_cpp_area_iomem(*area); + if (!res) + goto err_release_free; + + return res; + +err_release_free: + nfp_cpp_area_release_free(*area); +err_eio: + return (u8 __iomem *)ERR_PTR(-EIO); +} -- cgit v1.2.3-55-g7522 From 8a119cef9a84c396c7de49da2fb4b8af09e96d2b Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 27 Jun 2017 00:50:18 -0700 Subject: nfp: remove unused nfp_cpp_area_check_range() Remove unused nfp_cpp_area_check_range() function. Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- .../net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h | 2 -- .../ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 21 --------------------- 2 files changed, 23 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c') diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h index 235dd023d9b9..5798adc57cbc 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h @@ -242,8 +242,6 @@ int nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset, void *buffer, size_t length); int nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset, const void *buffer, size_t length); -int nfp_cpp_area_check_range(struct nfp_cpp_area *area, - unsigned long long offset, unsigned long size); const char *nfp_cpp_area_name(struct nfp_cpp_area *cpp_area); void *nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area); struct nfp_cpp *nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area); diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index 7d5d7293efed..04dd5758ecf5 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -570,27 +570,6 @@ int nfp_cpp_area_write(struct nfp_cpp_area *area, return area->cpp->op->area_write(area, kernel_vaddr, offset, length); } -/** - * nfp_cpp_area_check_range() - check if address range fits in CPP area - * @area: CPP area handle - * @offset: offset into CPP target - * @length: size of address range in bytes - * - * Check if address range fits within CPP area. Return 0 if area - * fits or -EFAULT on error. - * - * Return: 0, or -ERRNO - */ -int nfp_cpp_area_check_range(struct nfp_cpp_area *area, - unsigned long long offset, unsigned long length) -{ - if (offset < area->offset || - offset + length > area->offset + area->size) - return -EFAULT; - - return 0; -} - /** * nfp_cpp_area_name() - return name of a CPP area * @cpp_area: CPP area handle -- cgit v1.2.3-55-g7522