Skip to content

Commit 8b3d5a4

Browse files
Jakub Kicinskidavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 321b5e9 commit 8b3d5a4

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include <linux/ctype.h>
4444
#include <linux/types.h>
45+
#include <linux/sizes.h>
4546

4647
#ifndef NFP_SUBSYS
4748
#define NFP_SUBSYS "nfp"
@@ -59,6 +60,8 @@
5960
#define PCI_64BIT_BAR_COUNT 3
6061

6162
#define NFP_CPP_NUM_TARGETS 16
63+
/* Max size of area it should be safe to request */
64+
#define NFP_CPP_SAFE_AREA_SIZE SZ_2M
6265

6366
struct device;
6467

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -924,18 +924,9 @@ area_cache_put(struct nfp_cpp *cpp, struct nfp_cpp_area_cache *cache)
924924
mutex_unlock(&cpp->area_cache_mutex);
925925
}
926926

927-
/**
928-
* nfp_cpp_read() - read from CPP target
929-
* @cpp: CPP handle
930-
* @destination: CPP id
931-
* @address: offset into CPP target
932-
* @kernel_vaddr: kernel buffer for result
933-
* @length: number of bytes to read
934-
*
935-
* Return: length of io, or -ERRNO
936-
*/
937-
int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
938-
unsigned long long address, void *kernel_vaddr, size_t length)
927+
static int __nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
928+
unsigned long long address, void *kernel_vaddr,
929+
size_t length)
939930
{
940931
struct nfp_cpp_area_cache *cache;
941932
struct nfp_cpp_area *area;
@@ -968,18 +959,43 @@ int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
968959
}
969960

970961
/**
971-
* nfp_cpp_write() - write to CPP target
962+
* nfp_cpp_read() - read from CPP target
972963
* @cpp: CPP handle
973964
* @destination: CPP id
974965
* @address: offset into CPP target
975-
* @kernel_vaddr: kernel buffer to read from
976-
* @length: number of bytes to write
966+
* @kernel_vaddr: kernel buffer for result
967+
* @length: number of bytes to read
977968
*
978969
* Return: length of io, or -ERRNO
979970
*/
980-
int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
981-
unsigned long long address,
982-
const void *kernel_vaddr, size_t length)
971+
int nfp_cpp_read(struct nfp_cpp *cpp, u32 destination,
972+
unsigned long long address, void *kernel_vaddr,
973+
size_t length)
974+
{
975+
size_t n, offset;
976+
int ret;
977+
978+
for (offset = 0; offset < length; offset += n) {
979+
unsigned long long r_addr = address + offset;
980+
981+
/* make first read smaller to align to safe window */
982+
n = min_t(size_t, length - offset,
983+
ALIGN(r_addr + 1, NFP_CPP_SAFE_AREA_SIZE) - r_addr);
984+
985+
ret = __nfp_cpp_read(cpp, destination, address + offset,
986+
kernel_vaddr + offset, n);
987+
if (ret < 0)
988+
return ret;
989+
if (ret != n)
990+
return offset + n;
991+
}
992+
993+
return length;
994+
}
995+
996+
static int __nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
997+
unsigned long long address,
998+
const void *kernel_vaddr, size_t length)
983999
{
9841000
struct nfp_cpp_area_cache *cache;
9851001
struct nfp_cpp_area *area;
@@ -1011,6 +1027,41 @@ int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
10111027
return err;
10121028
}
10131029

1030+
/**
1031+
* nfp_cpp_write() - write to CPP target
1032+
* @cpp: CPP handle
1033+
* @destination: CPP id
1034+
* @address: offset into CPP target
1035+
* @kernel_vaddr: kernel buffer to read from
1036+
* @length: number of bytes to write
1037+
*
1038+
* Return: length of io, or -ERRNO
1039+
*/
1040+
int nfp_cpp_write(struct nfp_cpp *cpp, u32 destination,
1041+
unsigned long long address,
1042+
const void *kernel_vaddr, size_t length)
1043+
{
1044+
size_t n, offset;
1045+
int ret;
1046+
1047+
for (offset = 0; offset < length; offset += n) {
1048+
unsigned long long w_addr = address + offset;
1049+
1050+
/* make first write smaller to align to safe window */
1051+
n = min_t(size_t, length - offset,
1052+
ALIGN(w_addr + 1, NFP_CPP_SAFE_AREA_SIZE) - w_addr);
1053+
1054+
ret = __nfp_cpp_write(cpp, destination, address + offset,
1055+
kernel_vaddr + offset, n);
1056+
if (ret < 0)
1057+
return ret;
1058+
if (ret != n)
1059+
return offset + n;
1060+
}
1061+
1062+
return length;
1063+
}
1064+
10141065
/* Return the correct CPP address, and fixup xpb_addr as needed. */
10151066
static u32 nfp_xpb_to_cpp(struct nfp_cpp *cpp, u32 *xpb_addr)
10161067
{

0 commit comments

Comments
 (0)