Commit f787d848 authored by Alex Elder's avatar Alex Elder Committed by Paolo Abeni
Browse files

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: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 8defab8b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct ipa_interrupt;
 * @table_virt:		Virtual address of filter/route table content
 * @route_count:	Total number of 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
 * @uc_powered:		true if power is active by proxy for microcontroller
 * @uc_loaded:		true after microcontroller has reported it's ready
@@ -88,6 +89,7 @@ struct ipa {
	__le64 *table_virt;
	u32 route_count;
	u32 modem_route_count;
	u32 filter_count;

	struct ipa_interrupt *interrupt;
	bool uc_powered;
+2 −6
Original line number Diff line number Diff line
@@ -151,11 +151,6 @@ static void ipa_cmd_validate_build(void)
	 * maximum size.  IPv4 and IPv6 filter tables have the same number
	 * 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 */
	BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_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,
	struct device *dev = &ipa->pdev->dev;
	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 */
	if (size > size_max) {
+11 −9
Original line number Diff line number Diff line
@@ -160,9 +160,9 @@ bool ipa_filter_map_valid(struct ipa *ipa, u32 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",
			count, IPA_FILTER_COUNT_MAX);
			count, ipa->filter_count);

		return false;
	}
@@ -178,7 +178,7 @@ static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count)
	if (!count)
		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 = filter_mask ? 1 : 2;
@@ -586,11 +586,13 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
	if (mem_ipv4->size != mem_ipv6->size)
		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);
	if (count < 2)
		return false;
	if (!filter)
	if (filter)
		ipa->filter_count = count - 1;	/* Filter map in first entry */
	else
		ipa->route_count = count;

	/* 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)
 *
 * The first entry in a filter table contains a bitmap indicating which
 * 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
 * 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
@@ -669,7 +671,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
 *	|\   |-------------------|
 *	| ---- zero rule address | \
 *	|\   |-------------------|  |
 *	| ---- zero rule address |  |	IPA_FILTER_COUNT_MAX
 *	| ---- zero rule address |  |	Max IPA filter count
 *	|    |-------------------|   >	or IPA route count,
 *	|	      ...	    |	whichever is greater
 *	 \   |-------------------|  |
@@ -687,7 +689,7 @@ int ipa_table_init(struct ipa *ipa)

	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
	 * aligned on a 128-byte boundary.  We put the "zero rule" at the
@@ -723,7 +725,7 @@ int ipa_table_init(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;
	size_t size;

+0 −3
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@

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:	IPA pointer