Currently, routing and filter tables are assumed to have a fixed
size for all platforms. In fact, these tables can support many more
entries than what has been assumed; the only limitation is the size
of the IPA-resident memory regions that contain them.
This series rearranges things so that the size of the table is
determined from the memory region size defined in configuration
data, rather than assuming it is fixed.
This will required for IPA versions 5.0+, where the number of
entries in a routing table is larger.
-Alex
Alex Elder (4):
net: ipa: record the route table size in the IPA structure
net: ipa: determine route table size from memory region
net: ipa: don't assume 8 modem routing table entries
net: ipa: determine filter table size from memory region
drivers/net/ipa/data/ipa_data-v3.1.c | 19 ++++----
drivers/net/ipa/data/ipa_data-v3.5.1.c | 27 ++++++------
drivers/net/ipa/data/ipa_data-v4.11.c | 17 +++----
drivers/net/ipa/data/ipa_data-v4.2.c | 17 +++----
drivers/net/ipa/data/ipa_data-v4.5.c | 17 +++----
drivers/net/ipa/data/ipa_data-v4.9.c | 17 +++----
drivers/net/ipa/ipa.h | 6 +++
drivers/net/ipa/ipa_cmd.c | 21 ++++-----
drivers/net/ipa/ipa_data.h | 2 +
drivers/net/ipa/ipa_main.c | 6 +++
drivers/net/ipa/ipa_mem.c | 4 +-
drivers/net/ipa/ipa_qmi.c | 9 ++--
drivers/net/ipa/ipa_table.c | 61 ++++++++++++++------------
drivers/net/ipa/ipa_table.h | 13 +-----
14 files changed, 123 insertions(+), 113 deletions(-)
--
2.34.1
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 <[email protected]>
---
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(-)
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
--
2.34.1
Currently all platforms are assumed allot 8 routing table entries
for use by the modem. Instead, add a new configuration data entry
that defines the number of modem routing table entries, and record
that in the IPA structure.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/data/ipa_data-v3.1.c | 19 +++++++++---------
drivers/net/ipa/data/ipa_data-v3.5.1.c | 27 +++++++++++++-------------
drivers/net/ipa/data/ipa_data-v4.11.c | 17 ++++++++--------
drivers/net/ipa/data/ipa_data-v4.2.c | 17 ++++++++--------
drivers/net/ipa/data/ipa_data-v4.5.c | 17 ++++++++--------
drivers/net/ipa/data/ipa_data-v4.9.c | 17 ++++++++--------
drivers/net/ipa/ipa.h | 2 ++
drivers/net/ipa/ipa_data.h | 2 ++
drivers/net/ipa/ipa_main.c | 6 ++++++
drivers/net/ipa/ipa_mem.c | 4 ++--
drivers/net/ipa/ipa_qmi.c | 9 +++++----
drivers/net/ipa/ipa_table.c | 21 +++++++++-----------
drivers/net/ipa/ipa_table.h | 7 ++-----
13 files changed, 88 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ipa/data/ipa_data-v3.1.c b/drivers/net/ipa/data/ipa_data-v3.1.c
index e0d71f6092729..3380fb3483b2c 100644
--- a/drivers/net/ipa/data/ipa_data-v3.1.c
+++ b/drivers/net/ipa/data/ipa_data-v3.1.c
@@ -525,13 +525,14 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v3.1 */
const struct ipa_data ipa_data_v3_1 = {
- .version = IPA_VERSION_3_1,
- .backward_compat = BIT(BCR_CMDQ_L_LACK_ONE_ENTRY),
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .version = IPA_VERSION_3_1,
+ .backward_compat = BIT(BCR_CMDQ_L_LACK_ONE_ENTRY),
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/data/ipa_data-v3.5.1.c b/drivers/net/ipa/data/ipa_data-v3.5.1.c
index 383ef18900654..47591faf8bd62 100644
--- a/drivers/net/ipa/data/ipa_data-v3.5.1.c
+++ b/drivers/net/ipa/data/ipa_data-v3.5.1.c
@@ -406,17 +406,18 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v3.5.1 */
const struct ipa_data ipa_data_v3_5_1 = {
- .version = IPA_VERSION_3_5_1,
- .backward_compat = BIT(BCR_CMDQ_L_LACK_ONE_ENTRY) |
- BIT(BCR_TX_NOT_USING_BRESP) |
- BIT(BCR_SUSPEND_L2_IRQ) |
- BIT(BCR_HOLB_DROP_L2_IRQ) |
- BIT(BCR_DUAL_TX),
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .version = IPA_VERSION_3_5_1,
+ .backward_compat = BIT(BCR_CMDQ_L_LACK_ONE_ENTRY) |
+ BIT(BCR_TX_NOT_USING_BRESP) |
+ BIT(BCR_SUSPEND_L2_IRQ) |
+ BIT(BCR_HOLB_DROP_L2_IRQ) |
+ BIT(BCR_DUAL_TX),
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/data/ipa_data-v4.11.c b/drivers/net/ipa/data/ipa_data-v4.11.c
index a204e439c23d3..1b4b52501ee33 100644
--- a/drivers/net/ipa/data/ipa_data-v4.11.c
+++ b/drivers/net/ipa/data/ipa_data-v4.11.c
@@ -394,12 +394,13 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v4.11 */
const struct ipa_data ipa_data_v4_11 = {
- .version = IPA_VERSION_4_11,
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .version = IPA_VERSION_4_11,
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/data/ipa_data-v4.2.c b/drivers/net/ipa/data/ipa_data-v4.2.c
index 04f574fe006f0..199ed0ed868b9 100644
--- a/drivers/net/ipa/data/ipa_data-v4.2.c
+++ b/drivers/net/ipa/data/ipa_data-v4.2.c
@@ -372,13 +372,14 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v4.2 */
const struct ipa_data ipa_data_v4_2 = {
- .version = IPA_VERSION_4_2,
+ .version = IPA_VERSION_4_2,
/* backward_compat value is 0 */
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/data/ipa_data-v4.5.c b/drivers/net/ipa/data/ipa_data-v4.5.c
index 684239e71f46a..19b549f2998b8 100644
--- a/drivers/net/ipa/data/ipa_data-v4.5.c
+++ b/drivers/net/ipa/data/ipa_data-v4.5.c
@@ -450,12 +450,13 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v4.5 */
const struct ipa_data ipa_data_v4_5 = {
- .version = IPA_VERSION_4_5,
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .version = IPA_VERSION_4_5,
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/data/ipa_data-v4.9.c b/drivers/net/ipa/data/ipa_data-v4.9.c
index 2333e15f95338..d30fc1fe6ca22 100644
--- a/drivers/net/ipa/data/ipa_data-v4.9.c
+++ b/drivers/net/ipa/data/ipa_data-v4.9.c
@@ -444,12 +444,13 @@ static const struct ipa_power_data ipa_power_data = {
/* Configuration data for an SoC having IPA v4.9. */
const struct ipa_data ipa_data_v4_9 = {
- .version = IPA_VERSION_4_9,
- .qsb_count = ARRAY_SIZE(ipa_qsb_data),
- .qsb_data = ipa_qsb_data,
- .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
- .endpoint_data = ipa_gsi_endpoint_data,
- .resource_data = &ipa_resource_data,
- .mem_data = &ipa_mem_data,
- .power_data = &ipa_power_data,
+ .version = IPA_VERSION_4_9,
+ .qsb_count = ARRAY_SIZE(ipa_qsb_data),
+ .qsb_data = ipa_qsb_data,
+ .modem_route_count = 8,
+ .endpoint_count = ARRAY_SIZE(ipa_gsi_endpoint_data),
+ .endpoint_data = ipa_gsi_endpoint_data,
+ .resource_data = &ipa_resource_data,
+ .mem_data = &ipa_mem_data,
+ .power_data = &ipa_power_data,
};
diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index aa39509e209a3..5c95acc70bb33 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -40,6 +40,7 @@ struct ipa_interrupt;
* @table_addr: DMA 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
+ * @modem_route_count: Number of modem entries in a routing 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
@@ -86,6 +87,7 @@ struct ipa {
dma_addr_t table_addr;
__le64 *table_virt;
u32 route_count;
+ u32 modem_route_count;
struct ipa_interrupt *interrupt;
bool uc_powered;
diff --git a/drivers/net/ipa/ipa_data.h b/drivers/net/ipa/ipa_data.h
index e5a6ce75c7ddd..412edbfac7862 100644
--- a/drivers/net/ipa/ipa_data.h
+++ b/drivers/net/ipa/ipa_data.h
@@ -222,6 +222,7 @@ struct ipa_power_data {
* @backward_compat: BCR register value (prior to IPA v4.5 only)
* @qsb_count: number of entries in the qsb_data array
* @qsb_data: Qualcomm System Bus configuration data
+ * @modem_route_count: number of modem entries in a routing table
* @endpoint_count: number of entries in the endpoint_data array
* @endpoint_data: IPA endpoint/GSI channel data
* @resource_data: IPA resource configuration data
@@ -233,6 +234,7 @@ struct ipa_data {
u32 backward_compat;
u32 qsb_count; /* number of entries in qsb_data[] */
const struct ipa_qsb_data *qsb_data;
+ u32 modem_route_count;
u32 endpoint_count; /* number of entries in endpoint_data[] */
const struct ipa_gsi_endpoint_data *endpoint_data;
const struct ipa_resource_data *resource_data;
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 3461ad3029ab8..ce5eadad671f3 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -739,6 +739,11 @@ static int ipa_probe(struct platform_device *pdev)
return -EINVAL;
}
+ if (!data->modem_route_count) {
+ dev_err(dev, "modem_route_count cannot be zero\n");
+ return -EINVAL;
+ }
+
/* If we need Trust Zone, make sure it's available */
modem_init = of_property_read_bool(dev->of_node, "modem-init");
if (!modem_init)
@@ -763,6 +768,7 @@ static int ipa_probe(struct platform_device *pdev)
dev_set_drvdata(dev, ipa);
ipa->power = power;
ipa->version = data->version;
+ ipa->modem_route_count = data->modem_route_count;
init_completion(&ipa->completion);
ret = ipa_reg_init(ipa);
diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index a3d2317452ac6..cb95402018394 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -618,9 +618,9 @@ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data)
ipa->mem = mem_data->local;
/* Check the route and filter table memory regions */
- if (!ipa_table_mem_valid(ipa, 0))
+ if (!ipa_table_mem_valid(ipa, false))
return -EINVAL;
- if (!ipa_table_mem_valid(ipa, IPA_ROUTE_MODEM_COUNT))
+ if (!ipa_table_mem_valid(ipa, true))
return -EINVAL;
ret = dma_set_mask_and_coherent(&ipa->pdev->dev, DMA_BIT_MASK(64));
diff --git a/drivers/net/ipa/ipa_qmi.c b/drivers/net/ipa/ipa_qmi.c
index 8295fd4b70d16..f70f0a1d1cdac 100644
--- a/drivers/net/ipa/ipa_qmi.c
+++ b/drivers/net/ipa/ipa_qmi.c
@@ -284,6 +284,7 @@ static const struct ipa_init_modem_driver_req *
init_modem_driver_req(struct ipa_qmi *ipa_qmi)
{
struct ipa *ipa = container_of(ipa_qmi, struct ipa, qmi);
+ u32 modem_route_count = ipa->modem_route_count;
static struct ipa_init_modem_driver_req req;
const struct ipa_mem *mem;
@@ -308,12 +309,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE);
req.v4_route_tbl_info_valid = 1;
req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
- req.v4_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
+ req.v4_route_tbl_info.end = modem_route_count - 1;
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE);
req.v6_route_tbl_info_valid = 1;
req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
- req.v6_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
+ req.v6_route_tbl_info.end = modem_route_count - 1;
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER);
req.v4_filter_tbl_start_valid = 1;
@@ -352,7 +353,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v4_hash_route_tbl_info_valid = 1;
req.v4_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset;
- req.v4_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
+ req.v4_hash_route_tbl_info.end = modem_route_count - 1;
}
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED);
@@ -360,7 +361,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v6_hash_route_tbl_info_valid = 1;
req.v6_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset;
- req.v6_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
+ req.v6_hash_route_tbl_info.end = modem_route_count - 1;
}
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED);
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 23d3f081ac8e1..c9ab6a3fabbc3 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -129,9 +129,6 @@ static void ipa_table_validate_build(void)
* assumes that it can be written using a pointer to __le64.
*/
BUILD_BUG_ON(IPA_ZERO_RULE_SIZE != sizeof(__le64));
-
- /* The modem must be allotted at least one route table entry */
- BUILD_BUG_ON(!IPA_ROUTE_MODEM_COUNT);
}
static const struct ipa_mem *
@@ -281,6 +278,7 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem)
* */
static int ipa_route_reset(struct ipa *ipa, bool modem)
{
+ u32 modem_route_count = ipa->modem_route_count;
struct gsi_trans *trans;
u16 first;
u16 count;
@@ -295,10 +293,10 @@ static int ipa_route_reset(struct ipa *ipa, bool modem)
if (modem) {
first = 0;
- count = IPA_ROUTE_MODEM_COUNT;
+ count = modem_route_count;
} else {
- first = IPA_ROUTE_MODEM_COUNT;
- count = ipa->route_count - IPA_ROUTE_MODEM_COUNT;
+ first = modem_route_count;
+ count = ipa->route_count - modem_route_count;
}
ipa_table_reset_add(trans, false, first, count, IPA_MEM_V4_ROUTE);
@@ -511,9 +509,9 @@ static void ipa_filter_config(struct ipa *ipa, bool modem)
}
}
-static bool ipa_route_id_modem(u32 route_id)
+static bool ipa_route_id_modem(struct ipa *ipa, u32 route_id)
{
- return route_id < IPA_ROUTE_MODEM_COUNT;
+ return route_id < ipa->modem_route_count;
}
/**
@@ -549,7 +547,7 @@ static void ipa_route_config(struct ipa *ipa, bool modem)
return;
for (route_id = 0; route_id < ipa->route_count; route_id++)
- if (ipa_route_id_modem(route_id) == modem)
+ if (ipa_route_id_modem(ipa, route_id) == modem)
ipa_route_tuple_zero(ipa, route_id);
}
@@ -565,10 +563,9 @@ void ipa_table_config(struct ipa *ipa)
/* Verify the sizes of all IPA table filter or routing table memory regions
* are valid. If valid, this records the size of the routing table.
*/
-bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
+bool ipa_table_mem_valid(struct ipa *ipa, bool filter)
{
bool hash_support = ipa_table_hash_support(ipa);
- bool filter = !modem_route_count;
const struct ipa_mem *mem_hashed;
const struct ipa_mem *mem_ipv4;
const struct ipa_mem *mem_ipv6;
@@ -611,7 +608,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
/* Routing tables must be able to hold all modem entries,
* plus at least one entry for the AP.
*/
- if (count < modem_route_count + 1)
+ if (count < ipa->modem_route_count + 1)
return false;
}
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 31363292dc1db..79583b16f363f 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -13,9 +13,6 @@ struct ipa;
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
#define IPA_FILTER_COUNT_MAX 14
-/* The number of route table entries allotted to the modem */
-#define IPA_ROUTE_MODEM_COUNT 8
-
/**
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer
@@ -78,8 +75,8 @@ void ipa_table_exit(struct ipa *ipa);
/**
* ipa_table_mem_valid() - Validate sizes of table memory regions
* @ipa: IPA pointer
- * @modem_route_count: Number of modem route table entries
+ * @filter: Whether to check filter or routing tables
*/
-bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count);
+bool ipa_table_mem_valid(struct ipa *ipa, bool filter);
#endif /* _IPA_TABLE_H_ */
--
2.34.1
Currently we assume that any routing table contains a fixed number
of entries. The number of entries in a routing table can actually
vary, depending only on the size of the IPA-local memory region used
to hold the table.
Stop assuming that a routing table has exactly 15 entries. Instead,
determine the number of entries in a routing table by dividing its
memory region size by the size of an entry.
The number of entries is computed early, when ipa_table_mem_valid()
is called by ipa_table_init().
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 17 ++++++++---------
drivers/net/ipa/ipa_table.c | 14 +++++---------
drivers/net/ipa/ipa_table.h | 3 ---
3 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index de2cd86aa9e28..08e3f395a9453 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -145,18 +145,15 @@ union ipa_cmd_payload {
static void ipa_cmd_validate_build(void)
{
- /* The sizes of a filter and route tables need to fit into fields
- * in the ipa_cmd_hw_ip_fltrt_init structure. Although hashed tables
+ /* The size of a filter table needs to fit into fields in the
+ * ipa_cmd_hw_ip_fltrt_init structure. Although hashed tables
* might not be used, non-hashed and hashed tables have the same
* maximum size. IPv4 and IPv6 filter tables have the same number
- * of entries, as and IPv4 and IPv6 route tables have the same number
* of entries.
*/
-#define TABLE_SIZE (TABLE_COUNT_MAX * sizeof(__le64))
-#define TABLE_COUNT_MAX max_t(u32, IPA_ROUTE_COUNT_MAX, IPA_FILTER_COUNT_MAX)
+#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_COUNT_MAX
#undef TABLE_SIZE
/* Hashed and non-hashed fields are assumed to be the same size */
@@ -178,12 +175,14 @@ bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem,
u32 size_max = field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK);
const char *table = route ? "route" : "filter";
struct device *dev = &ipa->pdev->dev;
+ u32 size;
+
+ size = route ? ipa->route_count * sizeof(__le64) : mem->size;
/* Size must fit in the immediate command field that holds it */
- if (mem->size > size_max) {
+ if (size > size_max) {
dev_err(dev, "%s table region size too large\n", table);
- dev_err(dev, " (0x%04x > 0x%04x)\n",
- mem->size, size_max);
+ dev_err(dev, " (0x%04x > 0x%04x)\n", size, size_max);
return false;
}
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 0815c8967e914..23d3f081ac8e1 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -130,12 +130,8 @@ static void ipa_table_validate_build(void)
*/
BUILD_BUG_ON(IPA_ZERO_RULE_SIZE != sizeof(__le64));
- /* Impose a practical limit on the number of routes */
- BUILD_BUG_ON(IPA_ROUTE_COUNT_MAX > 32);
/* The modem must be allotted at least one route table entry */
BUILD_BUG_ON(!IPA_ROUTE_MODEM_COUNT);
- /* AP must too, but we can't use more than what is available */
- BUILD_BUG_ON(IPA_ROUTE_MODEM_COUNT >= IPA_ROUTE_COUNT_MAX);
}
static const struct ipa_mem *
@@ -593,18 +589,18 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
if (mem_ipv4->size != mem_ipv6->size)
return false;
- /* Record the number of routing table entries */
+ /* Compute the number of entries, and for routing tables, record it */
+ count = mem_ipv4->size / sizeof(__le64);
+ if (count < 2)
+ return false;
if (!filter)
- ipa->route_count = IPA_ROUTE_COUNT_MAX;
+ ipa->route_count = count;
/* Table offset and size must fit in TABLE_INIT command fields */
if (!ipa_cmd_table_init_valid(ipa, mem_ipv4, !filter))
return false;
/* Make sure the regions are big enough */
- count = mem_ipv4->size / sizeof(__le64);
- if (count < 2)
- return false;
if (filter) {
/* Filter tables must able to hold the endpoint bitmap plus
* an entry for each endpoint that supports filtering
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 65d96debd3917..31363292dc1db 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -16,9 +16,6 @@ struct ipa;
/* The number of route table entries allotted to the modem */
#define IPA_ROUTE_MODEM_COUNT 8
-/* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
-#define IPA_ROUTE_COUNT_MAX 15
-
/**
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer
--
2.34.1
The non-hashed routing tables for IPv4 and IPv6 will be the same
size. And if supported, the hashed routing tables will be the same
size as the non-hashed tables.
Record the size (number of entries) of all routing tables in the IPA
structure. For now, initialize this field using IPA_ROUTE_TABLE_MAX,
and just do so when the first route table is validated.
Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa.h | 2 ++
drivers/net/ipa/ipa_table.c | 22 +++++++++++++++-------
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h
index 09ead433ec38e..aa39509e209a3 100644
--- a/drivers/net/ipa/ipa.h
+++ b/drivers/net/ipa/ipa.h
@@ -39,6 +39,7 @@ struct ipa_interrupt;
* @power: IPA power information
* @table_addr: DMA 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
* @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
@@ -84,6 +85,7 @@ struct ipa {
dma_addr_t table_addr;
__le64 *table_virt;
+ u32 route_count;
struct ipa_interrupt *interrupt;
bool uc_powered;
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 58a1a9da3133e..0815c8967e914 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -185,7 +185,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_MAX));
+ WARN_ON(count > max_t(u32, IPA_FILTER_COUNT_MAX, ipa->route_count));
/* Skip over the zero rule and possibly the filter mask */
skip = filter_mask ? 1 : 2;
@@ -302,7 +302,7 @@ static int ipa_route_reset(struct ipa *ipa, bool modem)
count = IPA_ROUTE_MODEM_COUNT;
} else {
first = IPA_ROUTE_MODEM_COUNT;
- count = IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT;
+ count = ipa->route_count - IPA_ROUTE_MODEM_COUNT;
}
ipa_table_reset_add(trans, false, first, count, IPA_MEM_V4_ROUTE);
@@ -552,7 +552,7 @@ static void ipa_route_config(struct ipa *ipa, bool modem)
if (!ipa_table_hash_support(ipa))
return;
- for (route_id = 0; route_id < IPA_ROUTE_COUNT_MAX; route_id++)
+ for (route_id = 0; route_id < ipa->route_count; route_id++)
if (ipa_route_id_modem(route_id) == modem)
ipa_route_tuple_zero(ipa, route_id);
}
@@ -566,7 +566,9 @@ void ipa_table_config(struct ipa *ipa)
ipa_route_config(ipa, true);
}
-/* Zero modem_route_count means filter table memory check */
+/* Verify the sizes of all IPA table filter or routing table memory regions
+ * are valid. If valid, this records the size of the routing table.
+ */
bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
{
bool hash_support = ipa_table_hash_support(ipa);
@@ -591,6 +593,10 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
if (mem_ipv4->size != mem_ipv6->size)
return false;
+ /* Record the number of routing table entries */
+ if (!filter)
+ ipa->route_count = IPA_ROUTE_COUNT_MAX;
+
/* Table offset and size must fit in TABLE_INIT command fields */
if (!ipa_cmd_table_init_valid(ipa, mem_ipv4, !filter))
return false;
@@ -671,7 +677,7 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
* | ---- zero rule address | \
* |\ |-------------------| |
* | ---- zero rule address | | IPA_FILTER_COUNT_MAX
- * | |-------------------| > or IPA_ROUTE_COUNT_MAX,
+ * | |-------------------| > or IPA route count,
* | ... | whichever is greater
* \ |-------------------| |
* ---- zero rule address | /
@@ -679,15 +685,17 @@ bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
*/
int ipa_table_init(struct ipa *ipa)
{
- u32 count = max_t(u32, IPA_FILTER_COUNT_MAX, IPA_ROUTE_COUNT_MAX);
struct device *dev = &ipa->pdev->dev;
dma_addr_t addr;
__le64 le_addr;
__le64 *virt;
size_t size;
+ u32 count;
ipa_table_validate_build();
+ count = max_t(u32, IPA_FILTER_COUNT_MAX, 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
* base of the table area allocated here. The DMA address returned
@@ -722,7 +730,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_MAX);
+ u32 count = max_t(u32, 1 + IPA_FILTER_COUNT_MAX, ipa->route_count);
struct device *dev = &ipa->pdev->dev;
size_t size;
--
2.34.1
Hello:
This series was applied to netdev/net-next.git (master)
by Paolo Abeni <[email protected]>:
On Tue, 25 Oct 2022 14:51:39 -0500 you wrote:
> Currently, routing and filter tables are assumed to have a fixed
> size for all platforms. In fact, these tables can support many more
> entries than what has been assumed; the only limitation is the size
> of the IPA-resident memory regions that contain them.
>
> This series rearranges things so that the size of the table is
> determined from the memory region size defined in configuration
> data, rather than assuming it is fixed.
>
> [...]
Here is the summary with links:
- [net-next,1/4] net: ipa: record the route table size in the IPA structure
https://git.kernel.org/netdev/net-next/c/fc094058ce01
- [net-next,2/4] net: ipa: determine route table size from memory region
https://git.kernel.org/netdev/net-next/c/0439e6743c5c
- [net-next,3/4] net: ipa: don't assume 8 modem routing table entries
https://git.kernel.org/netdev/net-next/c/8defab8bdfb1
- [net-next,4/4] net: ipa: determine filter table size from memory region
https://git.kernel.org/netdev/net-next/c/f787d8483015
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html