[net-next,4/4] net: ipa: determine filter table size from memory region

Message ID 20221025195143.255934-5-elder@linaro.org
State New
Headers
Series net: ipa: don't use fixed table sizes |

Commit Message

Alex Elder Oct. 25, 2022, 7:51 p.m. UTC
  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: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/ipa.h       |  2 ++
 drivers/net/ipa/ipa_cmd.c   |  8 ++------
 drivers/net/ipa/ipa_table.c | 20 +++++++++++---------
 drivers/net/ipa/ipa_table.h |  3 ---
 4 files changed, 15 insertions(+), 18 deletions(-)
  

Patch

diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index 5c95acc70bb33..82225316a2e25 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -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;
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 08e3f395a9453..bb3dfa9a2bc81 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -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) {
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index c9ab6a3fabbc3..db1992eaafaa9 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -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;
 
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 79583b16f363f..8a4dcd7df4c0f 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -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