net: ipa: determine filter table size from memory region
authorAlex Elder <elder@linaro.org>
Tue, 25 Oct 2022 19:51:43 +0000 (14:51 -0500)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 27 Oct 2022 11:38:13 +0000 (13:38 +0200)
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>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ipa/ipa.h
drivers/net/ipa/ipa_cmd.c
drivers/net/ipa/ipa_table.c
drivers/net/ipa/ipa_table.h

index 5c95acc70bb33ab7c1a9244452f75f09b8d564ef..82225316a2e255205b9c97a3a85e8979102d8e7b 100644 (file)
@@ -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;
index 08e3f395a9453bf261894431ff51b9c2b9ec4b91..bb3dfa9a2bc81564c6e527302343c541e130b3d0 100644 (file)
@@ -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) {
index c9ab6a3fabbc3a8abd8d9edfba25d1df98cd71c0..db1992eaafaa9ef8b240542161495d695bc44776 100644 (file)
@@ -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;
 
index 79583b16f363f47df5875496bb0866bb2a9250ac..8a4dcd7df4c0fb173d32cd867cbe93ee024e1f50 100644 (file)
@@ -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