提交 f787d848 编写于 作者: A Alex Elder 提交者: Paolo Abeni

net: ipa: determine filter table size from memory region

Currently we assume that any filter table contains a fixed number
of entries.  Like routing tables, the number of entries in a filter
table is limited only by the size of the IPA-local memory region
used to hold the table.

Stop assuming that a filter table has exactly 14 entries.  Instead,
determine the number of entries in a routing table by dividing its
memory region size by the size of an entry.  (Note that the first
"entry" in a filter table contains an endpoint bitmap.)
Signed-off-by: NAlex Elder <elder@linaro.org>
Signed-off-by: NPaolo Abeni <pabeni@redhat.com>
上级 8defab8b
...@@ -41,6 +41,7 @@ struct ipa_interrupt; ...@@ -41,6 +41,7 @@ struct ipa_interrupt;
* @table_virt: Virtual address of filter/route table content * @table_virt: Virtual address of filter/route table content
* @route_count: Total number of entries in a routing table * @route_count: Total number of entries in a routing table
* @modem_route_count: Number of modem entries in a routing table * @modem_route_count: Number of modem entries in a routing table
* @filter_count: Maximum number of entries in a filter table
* @interrupt: IPA Interrupt information * @interrupt: IPA Interrupt information
* @uc_powered: true if power is active by proxy for microcontroller * @uc_powered: true if power is active by proxy for microcontroller
* @uc_loaded: true after microcontroller has reported it's ready * @uc_loaded: true after microcontroller has reported it's ready
...@@ -88,6 +89,7 @@ struct ipa { ...@@ -88,6 +89,7 @@ struct ipa {
__le64 *table_virt; __le64 *table_virt;
u32 route_count; u32 route_count;
u32 modem_route_count; u32 modem_route_count;
u32 filter_count;
struct ipa_interrupt *interrupt; struct ipa_interrupt *interrupt;
bool uc_powered; bool uc_powered;
......
...@@ -151,11 +151,6 @@ static void ipa_cmd_validate_build(void) ...@@ -151,11 +151,6 @@ static void ipa_cmd_validate_build(void)
* maximum size. IPv4 and IPv6 filter tables have the same number * maximum size. IPv4 and IPv6 filter tables have the same number
* of entries. * of entries.
*/ */
#define TABLE_SIZE (IPA_FILTER_COUNT_MAX * sizeof(__le64))
BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK));
BUILD_BUG_ON(TABLE_SIZE > field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK));
#undef TABLE_SIZE
/* Hashed and non-hashed fields are assumed to be the same size */ /* Hashed and non-hashed fields are assumed to be the same size */
BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK) != BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK) !=
field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK)); field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK));
...@@ -177,7 +172,8 @@ bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem, ...@@ -177,7 +172,8 @@ bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem,
struct device *dev = &ipa->pdev->dev; struct device *dev = &ipa->pdev->dev;
u32 size; u32 size;
size = route ? ipa->route_count * sizeof(__le64) : mem->size; size = route ? ipa->route_count : ipa->filter_count + 1;
size *= sizeof(__le64);
/* Size must fit in the immediate command field that holds it */ /* Size must fit in the immediate command field that holds it */
if (size > size_max) { if (size > size_max) {
......
...@@ -160,9 +160,9 @@ bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_map) ...@@ -160,9 +160,9 @@ bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_map)
} }
count = hweight32(filter_map); count = hweight32(filter_map);
if (count > IPA_FILTER_COUNT_MAX) { if (count > ipa->filter_count) {
dev_err(dev, "too many filtering endpoints (%u, max %u)\n", dev_err(dev, "too many filtering endpoints (%u, max %u)\n",
count, IPA_FILTER_COUNT_MAX); count, ipa->filter_count);
return false; return false;
} }
...@@ -178,7 +178,7 @@ static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count) ...@@ -178,7 +178,7 @@ static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count)
if (!count) if (!count)
return 0; return 0;
WARN_ON(count > max_t(u32, IPA_FILTER_COUNT_MAX, ipa->route_count)); WARN_ON(count > max_t(u32, ipa->filter_count, ipa->route_count));
/* Skip over the zero rule and possibly the filter mask */ /* Skip over the zero rule and possibly the filter mask */
skip = filter_mask ? 1 : 2; skip = filter_mask ? 1 : 2;
...@@ -586,11 +586,13 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter) ...@@ -586,11 +586,13 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
if (mem_ipv4->size != mem_ipv6->size) if (mem_ipv4->size != mem_ipv6->size)
return false; return false;
/* Compute the number of entries, and for routing tables, record it */ /* Compute and record the number of entries for each table type */
count = mem_ipv4->size / sizeof(__le64); count = mem_ipv4->size / sizeof(__le64);
if (count < 2) if (count < 2)
return false; return false;
if (!filter) if (filter)
ipa->filter_count = count - 1; /* Filter map in first entry */
else
ipa->route_count = count; ipa->route_count = count;
/* Table offset and size must fit in TABLE_INIT command fields */ /* Table offset and size must fit in TABLE_INIT command fields */
...@@ -645,7 +647,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter) ...@@ -645,7 +647,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
* *
* The first entry in a filter table contains a bitmap indicating which * The first entry in a filter table contains a bitmap indicating which
* endpoints contain entries in the table. In addition to that first entry, * endpoints contain entries in the table. In addition to that first entry,
* there are at most IPA_FILTER_COUNT_MAX entries that follow. Filter table * there is a fixed maximum number of entries that follow. Filter table
* entries are 64 bits wide, and (other than the bitmap) contain the DMA * entries are 64 bits wide, and (other than the bitmap) contain the DMA
* address of a filter rule. A "zero rule" indicates no filtering, and * address of a filter rule. A "zero rule" indicates no filtering, and
* consists of 64 bits of zeroes. When a filter table is initialized (or * consists of 64 bits of zeroes. When a filter table is initialized (or
...@@ -669,7 +671,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter) ...@@ -669,7 +671,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
* |\ |-------------------| * |\ |-------------------|
* | ---- zero rule address | \ * | ---- zero rule address | \
* |\ |-------------------| | * |\ |-------------------| |
* | ---- zero rule address | | IPA_FILTER_COUNT_MAX * | ---- zero rule address | | Max IPA filter count
* | |-------------------| > or IPA route count, * | |-------------------| > or IPA route count,
* | ... | whichever is greater * | ... | whichever is greater
* \ |-------------------| | * \ |-------------------| |
...@@ -687,7 +689,7 @@ int ipa_table_init(struct ipa *ipa) ...@@ -687,7 +689,7 @@ int ipa_table_init(struct ipa *ipa)
ipa_table_validate_build(); ipa_table_validate_build();
count = max_t(u32, IPA_FILTER_COUNT_MAX, ipa->route_count); count = max_t(u32, ipa->filter_count, ipa->route_count);
/* The IPA hardware requires route and filter table rules to be /* The IPA hardware requires route and filter table rules to be
* aligned on a 128-byte boundary. We put the "zero rule" at the * aligned on a 128-byte boundary. We put the "zero rule" at the
...@@ -723,7 +725,7 @@ int ipa_table_init(struct ipa *ipa) ...@@ -723,7 +725,7 @@ int ipa_table_init(struct ipa *ipa)
void ipa_table_exit(struct ipa *ipa) void ipa_table_exit(struct ipa *ipa)
{ {
u32 count = max_t(u32, 1 + IPA_FILTER_COUNT_MAX, ipa->route_count); u32 count = max_t(u32, 1 + ipa->filter_count, ipa->route_count);
struct device *dev = &ipa->pdev->dev; struct device *dev = &ipa->pdev->dev;
size_t size; size_t size;
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
struct ipa; struct ipa;
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
#define IPA_FILTER_COUNT_MAX 14
/** /**
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap * ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer * @ipa: IPA pointer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册