2023-01-30 21:02:34

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 0/8] net: ipa: remaining IPA v5.0 support

This series includes almost all remaining IPA code changes required
to support IPA v5.0. IPA register definitions and configuration
data for IPA v5.0 will be sent later (soon). Note that the GSI
register definitions still require work. GSI for IPA v5.0 supports
up to 256 (rather than 32) channels, and this changes the way GSI
register offsets are calculated. A few GSI register fields also
change.

The first patch in this series increases the number of IPA endpoints
supported by the driver, from 32 to 36. The next updates the width
of the destination field for the IP_PACKET_INIT immediate command so
it can represent up to 256 endpoints rather than just 32. The next
adds a few definitions of some IPA registers and fields that are
first available in IPA v5.0.

The next two patches update the code that handles router and filter
table caches. Previously these were referred to as "hashed" tables,
and the IPv4 and IPv6 tables are now combined into one "unified"
table. The sixth and seventh patches add support for a new pulse
generator, which allows time periods to be specified with a wider
range of clock resolution. And the last patch just defines two new
memory regions that were not previously used.

-Alex

Alex Elder (8):
net: ipa: support more endpoints
net: ipa: extend endpoints in packet init command
net: ipa: define IPA v5.0+ registers
net: ipa: update table cache flushing
net: ipa: support zeroing new cache tables
net: ipa: greater timer granularity options
net: ipa: support a third pulse register
net: ipa: define two new memory regions

drivers/net/ipa/ipa_cmd.c | 32 ++++++++---
drivers/net/ipa/ipa_endpoint.c | 102 ++++++++++++++++++---------------
drivers/net/ipa/ipa_endpoint.h | 4 +-
drivers/net/ipa/ipa_main.c | 14 ++++-
drivers/net/ipa/ipa_mem.c | 8 ++-
drivers/net/ipa/ipa_mem.h | 8 ++-
drivers/net/ipa/ipa_reg.h | 43 ++++++++++++--
drivers/net/ipa/ipa_table.c | 61 ++++++++++++++------
8 files changed, 187 insertions(+), 85 deletions(-)

--
2.34.1



2023-01-30 21:03:08

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 1/8] net: ipa: support more endpoints

Increase the number of endpoints supported by the driver to 36,
which IPA v5.0 supports. This makes it impossible to check at build
time whether the supported number is too big to fit within the
(5-bit) PACKET_INIT destination endpoint field. Instead, convert
the build time check to compare against what fits in 8 bits.

Add a check in ipa_endpoint_config() to also ensure the hardware
reports an endpoint count that's in the expected range. Just
open-code 32 as the limit (the PACKET_INIT field mask is not
available where we'd want to use it).

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 13 +++++++++----
drivers/net/ipa/ipa_endpoint.c | 11 ++++++++++-
drivers/net/ipa/ipa_endpoint.h | 4 ++--
3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index bb3dfa9a2bc81..aa2b594ca5067 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2022 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
*/

#include <linux/types.h>
@@ -157,9 +157,14 @@ static void ipa_cmd_validate_build(void)
BUILD_BUG_ON(field_max(IP_FLTRT_FLAGS_HASH_ADDR_FMASK) !=
field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK));

- /* Valid endpoint numbers must fit in the IP packet init command */
- BUILD_BUG_ON(field_max(IPA_PACKET_INIT_DEST_ENDPOINT_FMASK) <
- IPA_ENDPOINT_MAX - 1);
+ /* Prior to IPA v5.0, we supported no more than 32 endpoints,
+ * and this was reflected in some 5-bit fields that held
+ * endpoint numbers. Starting with IPA v5.0, the widths of
+ * these fields were extended to 8 bits, meaning up to 256
+ * endpoints. If the driver claims to support more than
+ * that it's an error.
+ */
+ BUILD_BUG_ON(IPA_ENDPOINT_MAX - 1 > U8_MAX);
}

/* Validate a memory region holding a table */
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index ce7f2d6e447ed..8909ba8bfd0e9 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2022 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
*/

#include <linux/types.h>
@@ -1986,6 +1986,7 @@ int ipa_endpoint_config(struct ipa *ipa)
struct device *dev = &ipa->pdev->dev;
const struct ipa_reg *reg;
u32 endpoint_id;
+ u32 hw_limit;
u32 tx_count;
u32 rx_count;
u32 rx_base;
@@ -2031,6 +2032,14 @@ int ipa_endpoint_config(struct ipa *ipa)
return -EINVAL;
}

+ /* Until IPA v5.0, the max endpoint ID was 32 */
+ hw_limit = ipa->version < IPA_VERSION_5_0 ? 32 : U8_MAX + 1;
+ if (limit > hw_limit) {
+ dev_err(dev, "unexpected endpoint count, %u > %u\n",
+ limit, hw_limit);
+ return -EINVAL;
+ }
+
/* Allocate and initialize the available endpoint bitmap */
ipa->available = bitmap_zalloc(limit, GFP_KERNEL);
if (!ipa->available)
diff --git a/drivers/net/ipa/ipa_endpoint.h b/drivers/net/ipa/ipa_endpoint.h
index 4a5c3bc549df5..3ad2e802040aa 100644
--- a/drivers/net/ipa/ipa_endpoint.h
+++ b/drivers/net/ipa/ipa_endpoint.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2022 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
*/
#ifndef _IPA_ENDPOINT_H_
#define _IPA_ENDPOINT_H_
@@ -38,7 +38,7 @@ enum ipa_endpoint_name {
IPA_ENDPOINT_COUNT, /* Number of names (not an index) */
};

-#define IPA_ENDPOINT_MAX 32 /* Max supported by driver */
+#define IPA_ENDPOINT_MAX 36 /* Max supported by driver */

/**
* struct ipa_endpoint_tx - Endpoint configuration for TX endpoints
--
2.34.1


2023-01-30 21:03:30

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 2/8] net: ipa: extend endpoints in packet init command

The IP_PACKET_INIT immediate command defines the destination
endpoint to which a packet should be sent. Prior to IPA v5.0, a
5 bit field in that command represents the endpoint, but starting
with IPA v5.0, the field is extended to 8 bits to support more than
32 endpoints.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index aa2b594ca5067..5d3a875e50fee 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -94,11 +94,11 @@ struct ipa_cmd_register_write {
/* IPA_CMD_IP_PACKET_INIT */

struct ipa_cmd_ip_packet_init {
- u8 dest_endpoint;
+ u8 dest_endpoint; /* Full 8 bits used for IPA v5.0+ */
u8 reserved[7];
};

-/* Field masks for ipa_cmd_ip_packet_init dest_endpoint field */
+/* Field mask for ipa_cmd_ip_packet_init dest_endpoint field (unused v5.0+) */
#define IPA_PACKET_INIT_DEST_ENDPOINT_FMASK GENMASK(4, 0)

/* IPA_CMD_DMA_SHARED_MEM */
@@ -491,8 +491,13 @@ static void ipa_cmd_ip_packet_init_add(struct gsi_trans *trans, u8 endpoint_id)
cmd_payload = ipa_cmd_payload_alloc(ipa, &payload_addr);
payload = &cmd_payload->ip_packet_init;

- payload->dest_endpoint = u8_encode_bits(endpoint_id,
- IPA_PACKET_INIT_DEST_ENDPOINT_FMASK);
+ if (ipa->version < IPA_VERSION_5_0) {
+ payload->dest_endpoint =
+ u8_encode_bits(endpoint_id,
+ IPA_PACKET_INIT_DEST_ENDPOINT_FMASK);
+ } else {
+ payload->dest_endpoint = endpoint_id;
+ }

gsi_trans_cmd_add(trans, payload, sizeof(*payload), payload_addr,
opcode);
--
2.34.1


2023-01-30 21:03:59

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 4/8] net: ipa: update table cache flushing

Update the code that causes filter and router table caches to be
flushed so that it supports IPA versions 5.0+. It adds a comment in
ipa_hardware_config_hashing() that explains that cacheing does not
need to be enabled, just as before, because it's enabled by default.
(For the record, the FILT_ROUT_CACHE_CFG register would have been
used if we wanted to explicitly enable these.)

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 6 +++++-
drivers/net/ipa/ipa_main.c | 7 ++++++-
drivers/net/ipa/ipa_table.c | 23 ++++++++++++++++-------
3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 5d3a875e50fee..16169641ddebe 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -295,7 +295,11 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
* offset will fit in a register write IPA immediate command.
*/
if (ipa_table_hash_support(ipa)) {
- reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
+ if (ipa->version < IPA_VERSION_5_0)
+ reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
+ else
+ reg = ipa_reg(ipa, FILT_ROUT_CACHE_FLUSH);
+
offset = ipa_reg_offset(reg);
name = "filter/route hash flush";
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 4fb92f7719741..f3466b913394c 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2018-2022 Linaro Ltd.
+ * Copyright (C) 2018-2023 Linaro Ltd.
*/

#include <linux/types.h>
@@ -432,6 +432,11 @@ static void ipa_hardware_config_hashing(struct ipa *ipa)
{
const struct ipa_reg *reg;

+ /* Other than IPA v4.2, all versions enable "hashing". Starting
+ * with IPA v5.0, the filter and router tables are implemented
+ * differently, but the default configuration enables this feature
+ * (now referred to as "cacheing"), so there's nothing to do here.
+ */
if (ipa->version != IPA_VERSION_4_2)
return;

diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index b81e27b613549..32ed9fec2ca74 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2018-2022 Linaro Ltd.
+ * Copyright (C) 2018-2023 Linaro Ltd.
*/

#include <linux/types.h>
@@ -359,13 +359,22 @@ int ipa_table_hash_flush(struct ipa *ipa)
return -EBUSY;
}

- reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
- offset = ipa_reg_offset(reg);
+ if (ipa->version < IPA_VERSION_5_0) {
+ reg = ipa_reg(ipa, FILT_ROUT_HASH_FLUSH);
+ offset = ipa_reg_offset(reg);

- val = ipa_reg_bit(reg, IPV6_ROUTER_HASH);
- val |= ipa_reg_bit(reg, IPV6_FILTER_HASH);
- val |= ipa_reg_bit(reg, IPV4_ROUTER_HASH);
- val |= ipa_reg_bit(reg, IPV4_FILTER_HASH);
+ val = ipa_reg_bit(reg, IPV6_ROUTER_HASH);
+ val |= ipa_reg_bit(reg, IPV6_FILTER_HASH);
+ val |= ipa_reg_bit(reg, IPV4_ROUTER_HASH);
+ val |= ipa_reg_bit(reg, IPV4_FILTER_HASH);
+ } else {
+ reg = ipa_reg(ipa, FILT_ROUT_CACHE_FLUSH);
+ offset = ipa_reg_offset(reg);
+
+ /* IPA v5.0+ uses a unified cache (both IPv4 and IPv6) */
+ val = ipa_reg_bit(reg, ROUTER_CACHE);
+ val |= ipa_reg_bit(reg, FILTER_CACHE);
+ }

ipa_cmd_register_write_add(trans, offset, val, val, false);

--
2.34.1


2023-01-30 21:04:03

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 6/8] net: ipa: greater timer granularity options

Starting with IPA v5.0, the head-of-line blocking timer has more
than two pulse generators available to define timer granularity.
To prepare for that, change the way the field value is encoded
to use ipa_reg_encode() rather than ipa_reg_bit().

The aggregation granularity selection could (in principle) also use
an additional pulse generator starting with IPA v5.0. Encode the
AGGR_GRAN_SEL field differently to allow that as well.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_endpoint.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 8909ba8bfd0e9..c029209191d41 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -965,7 +965,7 @@ static u32 aggr_time_limit_encode(struct ipa *ipa, const struct ipa_reg *reg,
ret = ipa_qtime_val(microseconds, max);
if (ret < 0) {
val = -ret;
- gran_sel = ipa_reg_bit(reg, AGGR_GRAN_SEL);
+ gran_sel = ipa_reg_encode(reg, AGGR_GRAN_SEL, 1);
} else {
val = ret;
gran_sel = 0;
@@ -1057,7 +1057,7 @@ static u32 hol_block_timer_encode(struct ipa *ipa, const struct ipa_reg *reg,
ret = ipa_qtime_val(microseconds, max);
if (ret < 0) {
val = -ret;
- gran_sel = ipa_reg_bit(reg, TIMER_GRAN_SEL);
+ gran_sel = ipa_reg_encode(reg, TIMER_GRAN_SEL, 1);
} else {
val = ret;
gran_sel = 0;
--
2.34.1


2023-01-30 21:04:13

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 3/8] net: ipa: define IPA v5.0+ registers

Define some new registers that appear starting with IPA v5.0, along
with enumerated types identifying their fields. Code that uses
these will be added by upcoming patches.

Most of the new registers are related to filter and routing tables,
and in particular, their "hashed" variant. These tables are better
described as "cached", where a hash value determines which entries
are cached. From now on, naming related to this functionality will
use "cache" instead of "hash", and that is reflected in these new
register names. Some registers for managing these caches and their
contents have changed as well.

A few other new field definitions for registers (unrelated to table
caches) are also defined.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_reg.h | 43 ++++++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
index b1a3c2c7e1674..82d43eca170ec 100644
--- a/drivers/net/ipa/ipa_reg.h
+++ b/drivers/net/ipa/ipa_reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2018-2022 Linaro Ltd.
+ * Copyright (C) 2018-2023 Linaro Ltd.
*/
#ifndef _IPA_REG_H_
#define _IPA_REG_H_
@@ -59,8 +59,10 @@ enum ipa_reg_id {
SHARED_MEM_SIZE,
QSB_MAX_WRITES,
QSB_MAX_READS,
- FILT_ROUT_HASH_EN,
- FILT_ROUT_HASH_FLUSH,
+ FILT_ROUT_HASH_EN, /* Not IPA v5.0+ */
+ FILT_ROUT_CACHE_CFG, /* IPA v5.0+ */
+ FILT_ROUT_HASH_FLUSH, /* Not IPA v5.0+ */
+ FILT_ROUT_CACHE_FLUSH, /* IPA v5.0+ */
STATE_AGGR_ACTIVE,
IPA_BCR, /* Not IPA v4.5+ */
LOCAL_PKT_PROC_CNTXT,
@@ -95,7 +97,9 @@ enum ipa_reg_id {
ENDP_INIT_SEQ, /* TX only */
ENDP_STATUS,
ENDP_FILTER_ROUTER_HSH_CFG, /* Not IPA v4.2 */
- /* The IRQ registers are only used for GSI_EE_AP */
+ ENDP_FILTER_CACHE_CFG, /* IPA v5.0+ */
+ ENDP_ROUTER_CACHE_CFG, /* IPA v5.0+ */
+ /* The IRQ registers that follow are only used for GSI_EE_AP */
IPA_IRQ_STTS,
IPA_IRQ_EN,
IPA_IRQ_CLR,
@@ -251,14 +255,28 @@ enum ipa_reg_qsb_max_reads_field_id {
GEN_QMB_1_MAX_READS_BEATS, /* IPA v4.0+ */
};

+/* FILT_ROUT_CACHE_CFG register */
+enum ipa_reg_filt_rout_cache_cfg_field_id {
+ ROUTER_CACHE_EN,
+ FILTER_CACHE_EN,
+ LOW_PRI_HASH_HIT_DISABLE,
+ LRU_EVICTION_THRESHOLD,
+};
+
/* FILT_ROUT_HASH_EN and FILT_ROUT_HASH_FLUSH registers */
-enum ipa_reg_rout_hash_field_id {
+enum ipa_reg_filt_rout_hash_field_id {
IPV6_ROUTER_HASH,
IPV6_FILTER_HASH,
IPV4_ROUTER_HASH,
IPV4_FILTER_HASH,
};

+/* FILT_ROUT_CACHE_FLUSH register */
+enum ipa_reg_filt_rout_cache_field_id {
+ ROUTER_CACHE,
+ FILTER_CACHE,
+};
+
/* BCR register */
enum ipa_bcr_compat {
BCR_CMDQ_L_LACK_ONE_ENTRY = 0x0, /* Not IPA v4.2+ */
@@ -298,6 +316,7 @@ enum ipa_reg_ipa_tx_cfg_field_id {
DUAL_TX_ENABLE, /* v4.5+ */
SSPND_PA_NO_START_STATE, /* v4,2+, not v4.5 */
SSPND_PA_NO_BQ_STATE, /* v4.2 only */
+ HOLB_STICKY_DROP_EN, /* v5.0+ */
};

/* FLAVOR_0 register */
@@ -333,6 +352,7 @@ enum ipa_reg_timers_pulse_gran_cfg_field_id {
PULSE_GRAN_0,
PULSE_GRAN_1,
PULSE_GRAN_2,
+ PULSE_GRAN_3,
};

/* Values for IPA_GRAN_x fields of TIMERS_PULSE_GRAN_CFG */
@@ -415,6 +435,8 @@ enum ipa_reg_endp_init_hdr_ext_field_id {
HDR_TOTAL_LEN_OR_PAD_OFFSET_MSB, /* v4.5+ */
HDR_OFST_PKT_SIZE_MSB, /* v4.5+ */
HDR_ADDITIONAL_CONST_LEN_MSB, /* v4.5+ */
+ HDR_BYTES_TO_REMOVE_VALID, /* v5.0+ */
+ HDR_BYTES_TO_REMOVE, /* v5.0+ */
};

/* ENDP_INIT_MODE register */
@@ -573,6 +595,17 @@ enum ipa_reg_endp_filter_router_hsh_cfg_field_id {
ROUTER_HASH_MSK_ALL, /* Bitwise OR of the above 6 fields */
};

+/* ENDP_FILTER_CACHE_CFG and ENDP_ROUTER_CACHE_CFG registers */
+enum ipa_reg_endp_cache_cfg_field_id {
+ CACHE_MSK_SRC_ID,
+ CACHE_MSK_SRC_IP,
+ CACHE_MSK_DST_IP,
+ CACHE_MSK_SRC_PORT,
+ CACHE_MSK_DST_PORT,
+ CACHE_MSK_PROTOCOL,
+ CACHE_MSK_METADATA,
+};
+
/* IPA_IRQ_STTS, IPA_IRQ_EN, and IPA_IRQ_CLR registers */
/**
* enum ipa_irq_id - Bit positions representing type of IPA IRQ
--
2.34.1


2023-01-30 21:04:15

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 5/8] net: ipa: support zeroing new cache tables

IPA v5.0+ separates the configuration of entries in the cached
(previously "hashed") routing and filtering tables into distinct
registers. Previously a single "filter and router" register updated
entries in both tables at once; now the routing and filter table
caches have separate registers that define their content.

This patch updates the code that zeroes entries in the cached filter
and router tables to support IPA versions including v5.0+.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_table.c | 38 +++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 32ed9fec2ca74..b9d505191f884 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -499,13 +499,22 @@ static void ipa_filter_tuple_zero(struct ipa_endpoint *endpoint)
u32 offset;
u32 val;

- reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);
+ if (ipa->version < IPA_VERSION_5_0) {
+ reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);

- offset = ipa_reg_n_offset(reg, endpoint_id);
- val = ioread32(endpoint->ipa->reg_virt + offset);
+ offset = ipa_reg_n_offset(reg, endpoint_id);
+ val = ioread32(endpoint->ipa->reg_virt + offset);

- /* Zero all filter-related fields, preserving the rest */
- val &= ~ipa_reg_fmask(reg, FILTER_HASH_MSK_ALL);
+ /* Zero all filter-related fields, preserving the rest */
+ val &= ~ipa_reg_fmask(reg, FILTER_HASH_MSK_ALL);
+ } else {
+ /* IPA v5.0 separates filter and router cache configuration */
+ reg = ipa_reg(ipa, ENDP_FILTER_CACHE_CFG);
+ offset = ipa_reg_n_offset(reg, endpoint_id);
+
+ /* Zero all filter-related fields */
+ val = 0;
+ }

iowrite32(val, endpoint->ipa->reg_virt + offset);
}
@@ -549,13 +558,22 @@ static void ipa_route_tuple_zero(struct ipa *ipa, u32 route_id)
u32 offset;
u32 val;

- reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);
- offset = ipa_reg_n_offset(reg, route_id);
+ if (ipa->version < IPA_VERSION_5_0) {
+ reg = ipa_reg(ipa, ENDP_FILTER_ROUTER_HSH_CFG);
+ offset = ipa_reg_n_offset(reg, route_id);

- val = ioread32(ipa->reg_virt + offset);
+ val = ioread32(ipa->reg_virt + offset);

- /* Zero all route-related fields, preserving the rest */
- val &= ~ipa_reg_fmask(reg, ROUTER_HASH_MSK_ALL);
+ /* Zero all route-related fields, preserving the rest */
+ val &= ~ipa_reg_fmask(reg, ROUTER_HASH_MSK_ALL);
+ } else {
+ /* IPA v5.0 separates filter and router cache configuration */
+ reg = ipa_reg(ipa, ENDP_ROUTER_CACHE_CFG);
+ offset = ipa_reg_n_offset(reg, route_id);
+
+ /* Zero all route-related fields */
+ val = 0;
+ }

iowrite32(val, ipa->reg_virt + offset);
}
--
2.34.1


2023-01-30 21:04:18

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 7/8] net: ipa: support a third pulse register

The AP has third pulse generator available starting with IPA v5.0.
Redefine ipa_qtime_val() to support that possibility. Pass the IPA
pointer as an argument so the version can be determined. And stop
using the sign of the returned tick count to indicate which of two
pulse generators to use.

Instead, have the caller provide the address of a variable that will
hold the selected pulse generator for the Qtime value. And for
version 5.0, check whether the third pulse generator best represents
the time period.

Add code in ipa_qtime_config() to configure the fourth pulse
generator for IPA v5.0+; in that case configure both the third and
fourth pulse generators to use 10 msec granularity.

Consistently use "ticks" for local variables that represent a tick
count.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_endpoint.c | 91 +++++++++++++++++-----------------
drivers/net/ipa/ipa_main.c | 7 ++-
2 files changed, 52 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index c029209191d41..798dfa4484d5a 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -922,64 +922,72 @@ static void ipa_endpoint_init_mode(struct ipa_endpoint *endpoint)
iowrite32(val, ipa->reg_virt + offset);
}

-/* For IPA v4.5+, times are expressed using Qtime. The AP uses one of two
- * pulse generators (0 and 1) to measure elapsed time. In ipa_qtime_config()
- * they're configured to have granularity 100 usec and 1 msec, respectively.
- *
- * The return value is the positive or negative Qtime value to use to
- * express the (microsecond) time provided. A positive return value
- * means pulse generator 0 can be used; otherwise use pulse generator 1.
+/* For IPA v4.5+, times are expressed using Qtime. A time is represented
+ * at one of several available granularities, which are configured in
+ * ipa_qtime_config(). Three (or, starting with IPA v5.0, four) pulse
+ * generators are set up with different "tick" periods. A Qtime value
+ * encodes a tick count along with an indication of a pulse generator
+ * (which has a fixed tick period). Two pulse generators are always
+ * available to the AP; a third is available starting with IPA v5.0.
+ * This function determines which pulse generator most accurately
+ * represents the time period provided, and returns the tick count to
+ * use to represent that time.
*/
-static int ipa_qtime_val(u32 microseconds, u32 max)
+static u32
+ipa_qtime_val(struct ipa *ipa, u32 microseconds, u32 max, u32 *select)
{
- u32 val;
+ u32 which = 0;
+ u32 ticks;

- /* Use 100 microsecond granularity if possible */
- val = DIV_ROUND_CLOSEST(microseconds, 100);
- if (val <= max)
- return (int)val;
+ /* Pulse generator 0 has 100 microsecond granularity */
+ ticks = DIV_ROUND_CLOSEST(microseconds, 100);
+ if (ticks <= max)
+ goto out;

- /* Have to use pulse generator 1 (millisecond granularity) */
- val = DIV_ROUND_CLOSEST(microseconds, 1000);
- WARN_ON(val > max);
+ /* Pulse generator 1 has millisecond granularity */
+ which = 1;
+ ticks = DIV_ROUND_CLOSEST(microseconds, 1000);
+ if (ticks <= max)
+ goto out;

- return (int)-val;
+ if (ipa->version >= IPA_VERSION_5_0) {
+ /* Pulse generator 2 has 10 millisecond granularity */
+ which = 2;
+ ticks = DIV_ROUND_CLOSEST(microseconds, 100);
+ }
+ WARN_ON(ticks > max);
+out:
+ *select = which;
+
+ return ticks;
}

/* Encode the aggregation timer limit (microseconds) based on IPA version */
static u32 aggr_time_limit_encode(struct ipa *ipa, const struct ipa_reg *reg,
u32 microseconds)
{
+ u32 ticks;
u32 max;
- u32 val;

if (!microseconds)
return 0; /* Nothing to compute if time limit is 0 */

max = ipa_reg_field_max(reg, TIME_LIMIT);
if (ipa->version >= IPA_VERSION_4_5) {
- u32 gran_sel;
- int ret;
+ u32 select;

- /* Compute the Qtime limit value to use */
- ret = ipa_qtime_val(microseconds, max);
- if (ret < 0) {
- val = -ret;
- gran_sel = ipa_reg_encode(reg, AGGR_GRAN_SEL, 1);
- } else {
- val = ret;
- gran_sel = 0;
- }
+ ticks = ipa_qtime_val(ipa, microseconds, max, &select);

- return gran_sel | ipa_reg_encode(reg, TIME_LIMIT, val);
+ return ipa_reg_encode(reg, AGGR_GRAN_SEL, select) |
+ ipa_reg_encode(reg, TIME_LIMIT, ticks);
}

/* We program aggregation granularity in ipa_hardware_config() */
- val = DIV_ROUND_CLOSEST(microseconds, IPA_AGGR_GRANULARITY);
- WARN(val > max, "aggr_time_limit too large (%u > %u usec)\n",
+ ticks = DIV_ROUND_CLOSEST(microseconds, IPA_AGGR_GRANULARITY);
+ WARN(ticks > max, "aggr_time_limit too large (%u > %u usec)\n",
microseconds, max * IPA_AGGR_GRANULARITY);

- return ipa_reg_encode(reg, TIME_LIMIT, val);
+ return ipa_reg_encode(reg, TIME_LIMIT, ticks);
}

static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
@@ -1050,20 +1058,13 @@ static u32 hol_block_timer_encode(struct ipa *ipa, const struct ipa_reg *reg,

if (ipa->version >= IPA_VERSION_4_5) {
u32 max = ipa_reg_field_max(reg, TIMER_LIMIT);
- u32 gran_sel;
- int ret;
+ u32 select;
+ u32 ticks;

- /* Compute the Qtime limit value to use */
- ret = ipa_qtime_val(microseconds, max);
- if (ret < 0) {
- val = -ret;
- gran_sel = ipa_reg_encode(reg, TIMER_GRAN_SEL, 1);
- } else {
- val = ret;
- gran_sel = 0;
- }
+ ticks = ipa_qtime_val(ipa, microseconds, max, &select);

- return gran_sel | ipa_reg_encode(reg, TIMER_LIMIT, val);
+ return ipa_reg_encode(reg, TIMER_GRAN_SEL, 1) |
+ ipa_reg_encode(reg, TIMER_LIMIT, ticks);
}

/* Use 64 bit arithmetic to avoid overflow */
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index f3466b913394c..60d7c558163f1 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -390,7 +390,12 @@ static void ipa_qtime_config(struct ipa *ipa)
reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG);
val = ipa_reg_encode(reg, PULSE_GRAN_0, IPA_GRAN_100_US);
val |= ipa_reg_encode(reg, PULSE_GRAN_1, IPA_GRAN_1_MS);
- val |= ipa_reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_1_MS);
+ if (ipa->version >= IPA_VERSION_5_0) {
+ val |= ipa_reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_10_MS);
+ val |= ipa_reg_encode(reg, PULSE_GRAN_3, IPA_GRAN_10_MS);
+ } else {
+ val |= ipa_reg_encode(reg, PULSE_GRAN_2, IPA_GRAN_1_MS);
+ }

iowrite32(val, ipa->reg_virt + ipa_reg_offset(reg));

--
2.34.1


2023-01-30 21:05:11

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 8/8] net: ipa: define two new memory regions

IPA v5.0 uses two memory regions not previously used. Define them
and treat them as valid only for IPA v5.0.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_mem.c | 8 +++++++-
drivers/net/ipa/ipa_mem.h | 8 +++++---
2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 9ec5af323f731..a07776e20cb0d 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2022 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
*/

#include <linux/types.h>
@@ -163,6 +163,12 @@ static bool ipa_mem_id_valid(struct ipa *ipa, enum ipa_mem_id mem_id)
return false;
break;

+ case IPA_MEM_AP_V4_FILTER:
+ case IPA_MEM_AP_V6_FILTER:
+ if (version != IPA_VERSION_5_0)
+ return false;
+ break;
+
case IPA_MEM_NAT_TABLE:
case IPA_MEM_STATS_FILTER_ROUTE:
if (version < IPA_VERSION_4_5)
diff --git a/drivers/net/ipa/ipa_mem.h b/drivers/net/ipa/ipa_mem.h
index 570bfdd99bffb..868e9c20e8c41 100644
--- a/drivers/net/ipa/ipa_mem.h
+++ b/drivers/net/ipa/ipa_mem.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */

/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2021 Linaro Ltd.
+ * Copyright (C) 2019-2023 Linaro Ltd.
*/
#ifndef _IPA_MEM_H_
#define _IPA_MEM_H_
@@ -62,13 +62,15 @@ enum ipa_mem_id {
IPA_MEM_PDN_CONFIG, /* 0/2 canaries (IPA v4.0+) */
IPA_MEM_STATS_QUOTA_MODEM, /* 2/4 canaries (IPA v4.0+) */
IPA_MEM_STATS_QUOTA_AP, /* 0 canaries, optional (IPA v4.0+) */
- IPA_MEM_STATS_TETHERING, /* 0 canaries (IPA v4.0+) */
+ IPA_MEM_STATS_TETHERING, /* 0 canaries, optional (IPA v4.0+) */
IPA_MEM_STATS_DROP, /* 0 canaries, optional (IPA v4.0+) */
- /* The next 5 filter and route statistics regions are optional */
+ /* The next 7 filter and route statistics regions are optional */
IPA_MEM_STATS_V4_FILTER, /* 0 canaries (IPA v4.0-v4.2) */
IPA_MEM_STATS_V6_FILTER, /* 0 canaries (IPA v4.0-v4.2) */
IPA_MEM_STATS_V4_ROUTE, /* 0 canaries (IPA v4.0-v4.2) */
IPA_MEM_STATS_V6_ROUTE, /* 0 canaries (IPA v4.0-v4.2) */
+ IPA_MEM_AP_V4_FILTER, /* 2 canaries (IPA v5.0) */
+ IPA_MEM_AP_V6_FILTER, /* 0 canaries (IPA v5.0) */
IPA_MEM_STATS_FILTER_ROUTE, /* 0 canaries (IPA v4.5+) */
IPA_MEM_NAT_TABLE, /* 4 canaries, optional (IPA v4.5+) */
IPA_MEM_END_MARKER, /* 1 canary (not a real region) */
--
2.34.1


2023-01-31 11:40:23

by Leon Romanovsky

[permalink] [raw]
Subject: Re: [PATCH net-next 0/8] net: ipa: remaining IPA v5.0 support

On Mon, Jan 30, 2023 at 03:01:50PM -0600, Alex Elder wrote:
> This series includes almost all remaining IPA code changes required
> to support IPA v5.0. IPA register definitions and configuration
> data for IPA v5.0 will be sent later (soon). Note that the GSI
> register definitions still require work. GSI for IPA v5.0 supports
> up to 256 (rather than 32) channels, and this changes the way GSI
> register offsets are calculated. A few GSI register fields also
> change.
>
> The first patch in this series increases the number of IPA endpoints
> supported by the driver, from 32 to 36. The next updates the width
> of the destination field for the IP_PACKET_INIT immediate command so
> it can represent up to 256 endpoints rather than just 32. The next
> adds a few definitions of some IPA registers and fields that are
> first available in IPA v5.0.
>
> The next two patches update the code that handles router and filter
> table caches. Previously these were referred to as "hashed" tables,
> and the IPv4 and IPv6 tables are now combined into one "unified"
> table. The sixth and seventh patches add support for a new pulse
> generator, which allows time periods to be specified with a wider
> range of clock resolution. And the last patch just defines two new
> memory regions that were not previously used.
>
> -Alex
>
> Alex Elder (8):
> net: ipa: support more endpoints
> net: ipa: extend endpoints in packet init command
> net: ipa: define IPA v5.0+ registers
> net: ipa: update table cache flushing
> net: ipa: support zeroing new cache tables
> net: ipa: greater timer granularity options
> net: ipa: support a third pulse register
> net: ipa: define two new memory regions
>

Thanks,
Reviewed-by: Leon Romanovsky <[email protected]>

2023-02-01 05:51:05

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH net-next 0/8] net: ipa: remaining IPA v5.0 support

Hello:

This series was applied to netdev/net-next.git (master)
by Jakub Kicinski <[email protected]>:

On Mon, 30 Jan 2023 15:01:50 -0600 you wrote:
> This series includes almost all remaining IPA code changes required
> to support IPA v5.0. IPA register definitions and configuration
> data for IPA v5.0 will be sent later (soon). Note that the GSI
> register definitions still require work. GSI for IPA v5.0 supports
> up to 256 (rather than 32) channels, and this changes the way GSI
> register offsets are calculated. A few GSI register fields also
> change.
>
> [...]

Here is the summary with links:
- [net-next,1/8] net: ipa: support more endpoints
https://git.kernel.org/netdev/net-next/c/07abde549bc1
- [net-next,2/8] net: ipa: extend endpoints in packet init command
https://git.kernel.org/netdev/net-next/c/c84ddc119704
- [net-next,3/8] net: ipa: define IPA v5.0+ registers
https://git.kernel.org/netdev/net-next/c/8ba59716d16a
- [net-next,4/8] net: ipa: update table cache flushing
https://git.kernel.org/netdev/net-next/c/8e7c89d84a2b
- [net-next,5/8] net: ipa: support zeroing new cache tables
(no matching commit)
- [net-next,6/8] net: ipa: greater timer granularity options
https://git.kernel.org/netdev/net-next/c/32079a4ab106
- [net-next,7/8] net: ipa: support a third pulse register
(no matching commit)
- [net-next,8/8] net: ipa: define two new memory regions
https://git.kernel.org/netdev/net-next/c/5157d6bfcad3

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html