diff options
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index e2abba4c3a3f..9b69dcf87be9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -76,10 +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 - * @rtsym: firmware run time symbols - * * Following fields use explicit locking: * @resource_list: NFP CPP resource list * @resource_lock: protects @resource_list @@ -107,9 +103,6 @@ struct nfp_cpp { struct mutex area_cache_mutex; struct list_head area_cache_list; - - void *hwinfo; - void *rtsym; }; /* Element of the area_cache_list */ @@ -233,9 +226,6 @@ void nfp_cpp_free(struct nfp_cpp *cpp) if (cpp->op->free) cpp->op->free(cpp); - kfree(cpp->hwinfo); - kfree(cpp->rtsym); - device_unregister(&cpp->dev); kfree(cpp); @@ -276,39 +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; -} - -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 @@ -924,18 +881,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 +916,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 +984,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) { |