Skip to content

Commit

Permalink
Merge branch 'net-ipa-don-t-use-fixed-table-sizes'
Browse files Browse the repository at this point in the history
Alex Elder says:

====================
net: ipa: don't use fixed table sizes

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.
====================

Link: https://lore.kernel.org/r/20221025195143.255934-1-elder@linaro.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Paolo Abeni committed Oct 27, 2022
2 parents d5e2d03 + f787d84 commit 99c8eb4
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 113 deletions.
19 changes: 10 additions & 9 deletions drivers/net/ipa/data/ipa_data-v3.1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
27 changes: 14 additions & 13 deletions drivers/net/ipa/data/ipa_data-v3.5.1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
17 changes: 9 additions & 8 deletions drivers/net/ipa/data/ipa_data-v4.11.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
17 changes: 9 additions & 8 deletions drivers/net/ipa/data/ipa_data-v4.2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
17 changes: 9 additions & 8 deletions drivers/net/ipa/data/ipa_data-v4.5.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
17 changes: 9 additions & 8 deletions drivers/net/ipa/data/ipa_data-v4.9.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
6 changes: 6 additions & 0 deletions drivers/net/ipa/ipa.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ 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
* @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
Expand Down Expand Up @@ -84,6 +87,9 @@ struct ipa {

dma_addr_t table_addr;
__le64 *table_virt;
u32 route_count;
u32 modem_route_count;
u32 filter_count;

struct ipa_interrupt *interrupt;
bool uc_powered;
Expand Down
21 changes: 8 additions & 13 deletions drivers/net/ipa/ipa_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,12 @@ 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)
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 */
BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_SIZE_FMASK) !=
field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK));
Expand All @@ -178,12 +170,15 @@ 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 : ipa->filter_count + 1;
size *= sizeof(__le64);

/* 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;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ipa/ipa_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ipa/ipa_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ipa/ipa_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/ipa/ipa_qmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -352,15 +353,15 @@ 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);
if (mem->size) {
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);
Expand Down
Loading

0 comments on commit 99c8eb4

Please sign in to comment.