mbox series

[net-next,v2,00/14] Add PPE driver for Qualcomm IPQ9574 SoC

Message ID 20250108-qcom_ipq_ppe-v2-0-7394dbda7199@quicinc.com
Headers show
Series Add PPE driver for Qualcomm IPQ9574 SoC | expand

Message

Jie Luo Jan. 8, 2025, 1:47 p.m. UTC
The PPE (packet process engine) hardware block is available in Qualcomm
IPQ chipsets that support PPE architecture, such as IPQ9574 and IPQ5332.
The PPE in the IPQ9574 SoC includes six ethernet ports (6 GMAC and 6
XGMAC), which are used to connect with external PHY devices by PCS. The
PPE also includes packet processing offload capabilities for various
networking functions such as route and bridge flows, VLANs, different
tunnel protocols and VPN. It also includes an L2 switch function for
bridging packets among the 6 ethernet ports and the CPU port. The CPU
port enables packet transfer between the ethernet ports and the ARM
cores in the SoC, using the ethernet DMA.

This patch series is the first part of a three part series that will
together enable Ethernet function for IPQ9574 SoC. While support is
initially being added for IPQ9574 SoC, the driver will be easily
extendable to enable Ethernet support for other IPQ SoC such as IPQ5332.
The driver can also be extended later for adding support for L2/L3
network offload features that the PPE can support. The functionality
to be enabled by each of the three series (to be posted sequentially)
is as below:

Part 1: The PPE patch series (this series), which enables the platform
driver, probe and initialization/configuration of different PPE hardware
blocks.

Part 2: The PPE MAC patch series, which enables the phylink operations
for the PPE ethernet ports.

Part 3: The PPE EDMA patch series, which enables the Rx/Tx Ethernet DMA
and netdevice driver for the 6 PPE ethernet ports.

A more detailed description of the functions enabled by part 1 is below:
1. Initialize PPE device hardware functions such as buffer management,
   queue management, scheduler and clocks in order to bring up PPE
   device.
2. Enable platform driver and probe functions
3. Register debugfs file to provide access to various PPE packet
   counters. These statistics are recorded by the various hardware
   process counters, such as port RX/TX, CPU code and hardware queue
   counters.
4. A detailed introduction of PPE along with the PPE hardware diagram
   in the first two patches (dt-bindings and documentation).

Below is a reference to an earlier RFC discussion with the community
about enabling ethernet driver support for Qualcomm IPQ9574 SoC. This
writeup can help provide a higher level architectural view of various
other drivers that support the PPE such as clock and PCS drivers.
https://lore.kernel.org/linux-arm-msm/d2929bd2-bc9e-4733-a89f-2a187e8bf917@quicinc.com/

Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
Changes in v2:
- Represent the PPE hardware hierarchy in dtbindings, add PPE hardware diagram.
- Remove all SoC specific hardware properties from dtbindings since driver
  maintains them.
- Move out the PCS (UNIPHY) handling into a separate PCS driver posted
  separately at below.
  https://lore.kernel.org/all/20240110114033.32575-1-quic_luoj@quicinc.com/
- Move out the PPE MAC patches into a separate series to limit patch count to
  15 or less. (PPE MAC patches will be posted sequentially after this series).
- Rename the hardware initialization related files from ppe_ops.c[h] to
  ppe_config.c[h]
- Improve PPE driver documentation and diagram.
- Fix dtbinding check errors.
- Link to v1: https://lore.kernel.org/r/20240110114033.32575-1-quic_luoj@quicinc.com

---
Lei Wei (2):
      docs: networking: Add PPE driver documentation for Qualcomm IPQ9574 SoC
      net: ethernet: qualcomm: Initialize PPE L2 bridge settings

Luo Jie (12):
      dt-bindings: net: Add PPE for Qualcomm IPQ9574 SoC
      net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC
      net: ethernet: qualcomm: Initialize PPE buffer management for IPQ9574
      net: ethernet: qualcomm: Initialize PPE queue management for IPQ9574
      net: ethernet: qualcomm: Initialize the PPE scheduler settings
      net: ethernet: qualcomm: Initialize PPE queue settings
      net: ethernet: qualcomm: Initialize PPE service code settings
      net: ethernet: qualcomm: Initialize PPE port control settings
      net: ethernet: qualcomm: Initialize PPE RSS hash settings
      net: ethernet: qualcomm: Initialize PPE queue to Ethernet DMA ring mapping
      net: ethernet: qualcomm: Add PPE debugfs support for PPE counters
      MAINTAINERS: Add maintainer for Qualcomm PPE driver

 .../devicetree/bindings/net/qcom,ipq9574-ppe.yaml  |  459 +++++
 .../networking/device_drivers/ethernet/index.rst   |    1 +
 .../device_drivers/ethernet/qualcomm/ppe/ppe.rst   |  197 ++
 MAINTAINERS                                        |    8 +
 drivers/net/ethernet/qualcomm/Kconfig              |   15 +
 drivers/net/ethernet/qualcomm/Makefile             |    1 +
 drivers/net/ethernet/qualcomm/ppe/Makefile         |    7 +
 drivers/net/ethernet/qualcomm/ppe/ppe.c            |  234 +++
 drivers/net/ethernet/qualcomm/ppe/ppe.h            |   39 +
 drivers/net/ethernet/qualcomm/ppe/ppe_config.c     | 2003 ++++++++++++++++++++
 drivers/net/ethernet/qualcomm/ppe/ppe_config.h     |  313 +++
 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c    |  692 +++++++
 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h    |   16 +
 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h       |  559 ++++++
 14 files changed, 4544 insertions(+)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20250108-qcom_ipq_ppe-aa4c4fa0ab73

Best regards,

Comments

Jie Luo Jan. 9, 2025, 2:18 p.m. UTC | #1
On 1/9/2025 3:19 AM, Christophe JAILLET wrote:
> Le 08/01/2025 à 14:47, Luo Jie a écrit :
>> The PPE (Packet Process Engine) hardware block is available
>> on Qualcomm IPQ SoC that support PPE architecture, such as
>> IPQ9574.
>>
>> The PPE in IPQ9574 includes six integrated ethernet MAC
>> (for 6 PPE ports), buffer management, queue management and
>> scheduler functions. The MACs can connect with the external
>> PHY or switch devices using the UNIPHY PCS block available
>> in the SoC.
>>
>> The PPE also includes various packet processing offload
>> capabilities such as L3 routing and L2 bridging, VLAN and
>> tunnel processing offload. It also includes Ethernet DMA
>> function for transferring packets between ARM cores and
>> PPE ethernet ports.
>>
>> This patch adds the base source files and Makefiles for
>> the PPE driver such as platform driver registration,
>> clock initialization, and PPE reset routines.
>>
>> Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
>> ---
> 
> ...
> 
>> +static int qcom_ppe_probe(struct platform_device *pdev)
>> +{
>> +    struct device *dev = &pdev->dev;
>> +    struct ppe_device *ppe_dev;
>> +    void __iomem *base;
>> +    int ret, num_icc;
>> +
>> +    num_icc = ARRAY_SIZE(ppe_icc_data);
>> +    ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, 
>> num_icc),
>> +                   GFP_KERNEL);
>> +    if (!ppe_dev)
>> +        return dev_err_probe(dev, -ENOMEM, "PPE alloc memory failed\n");
> 
> Usually, no error message in logged in case of devm_kzalloc().
> It is already loud enough.
> 

OK. Will remove.

>> +
>> +    base = devm_platform_ioremap_resource(pdev, 0);
>> +    if (IS_ERR(base))
>> +        return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap 
>> failed\n");
>> +
>> +    ppe_dev->regmap = devm_regmap_init_mmio(dev, base, 
>> &regmap_config_ipq9574);
>> +    if (IS_ERR(ppe_dev->regmap))
>> +        return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap),
>> +                     "PPE initialize regmap failed\n");
>> +    ppe_dev->dev = dev;
>> +    ppe_dev->clk_rate = PPE_CLK_RATE;
>> +    ppe_dev->num_ports = PPE_PORT_MAX;
>> +    ppe_dev->num_icc_paths = num_icc;
>> +
>> +    ret = ppe_clock_init_and_reset(ppe_dev);
>> +    if (ret)
>> +        return dev_err_probe(dev, ret, "PPE clock config failed\n");
>> +
>> +    platform_set_drvdata(pdev, ppe_dev);
>> +
>> +    return 0;
>> +}
>> +
>> +static const struct of_device_id qcom_ppe_of_match[] = {
>> +    { .compatible = "qcom,ipq9574-ppe" },
>> +    {},
> 
> The ending comma after a terminator like that is not needed.

Will remove it.

> 
>> +};
> 
> ...
> 
> CJ
>
Jie Luo Jan. 9, 2025, 2:20 p.m. UTC | #2
On 1/9/2025 3:29 AM, Christophe JAILLET wrote:
> Le 08/01/2025 à 14:47, Luo Jie a écrit :
>> Configure unicast and multicast hardware queues for the PPE
>> ports to enable packet forwarding between the ports.
>>
>> Each PPE port is assigned with a range of queues. The queue ID
>> selection for a packet is decided by the queue base and queue
>> offset that is configured based on the internal priority and
>> the RSS hash value of the packet.
>>
>> Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
> 
> ...
> 
>> +        /* Initialize the queue offset of RSS hash as 0 to avoid the
>> +         * random hardware value that will lead to the unexpected
>> +         * destination queue generated.
>> +         */
>> +        index = 0;
> 
> Useless.

Will remove it.

> 
>> +        for (index = 0; index < PPE_QUEUE_HASH_NUM; index++) {
>> +            ret = ppe_queue_ucast_offset_hash_set(ppe_dev, port_id,
>> +                                  index, 0);
>> +            if (ret)
>> +                return ret;
>> +        }
>> +    }
>> +
>> +    return 0;
>> +}
> 
> ...
> 
> CJ
>
Simon Horman Jan. 9, 2025, 5:52 p.m. UTC | #3
On Wed, Jan 08, 2025 at 09:47:14PM +0800, Luo Jie wrote:
> Configure unicast and multicast hardware queues for the PPE
> ports to enable packet forwarding between the ports.
> 
> Each PPE port is assigned with a range of queues. The queue ID
> selection for a packet is decided by the queue base and queue
> offset that is configured based on the internal priority and
> the RSS hash value of the packet.
> 
> Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
> ---
>  drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 357 ++++++++++++++++++++++++-
>  drivers/net/ethernet/qualcomm/ppe/ppe_config.h |  63 +++++
>  drivers/net/ethernet/qualcomm/ppe/ppe_regs.h   |  21 ++
>  3 files changed, 440 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c

...

> @@ -673,6 +701,111 @@ static struct ppe_scheduler_port_config ppe_port_sch_config[] = {
>  	},
>  };
>  
> +/* The scheduler resource is applied to each PPE port, The resource
> + * includes the unicast & multicast queues, flow nodes and DRR nodes.
> + */
> +static struct ppe_port_schedule_resource ppe_scheduler_res[] = {
> +	{	.ucastq_start	= 0,
> +		.ucastq_end	= 63,
> +		.mcastq_start	= 256,
> +		.ucastq_end	= 271,

Hi Luo Jie,

This appears to duplicate the initialisation of .ucastq_end.
Should the line above initialise .mcastq_end instead?

Likewise for other elements of this array.

Flagged by W=1 builds with both clang-19 and gcc-14.

> +		.flow_id_start	= 0,
> +		.flow_id_end	= 0,
> +		.l0node_start	= 0,
> +		.l0node_end	= 7,
> +		.l1node_start	= 0,
> +		.l1node_end	= 0,
> +	},
> +	{	.ucastq_start	= 144,
> +		.ucastq_end	= 159,
> +		.mcastq_start	= 272,
> +		.ucastq_end	= 275,
> +		.flow_id_start	= 36,
> +		.flow_id_end	= 39,
> +		.l0node_start	= 48,
> +		.l0node_end	= 63,
> +		.l1node_start	= 8,
> +		.l1node_end	= 11,
> +	},

...

> +};

...
Jie Luo Jan. 10, 2025, 3:38 p.m. UTC | #4
On 1/10/2025 1:52 AM, Simon Horman wrote:
> On Wed, Jan 08, 2025 at 09:47:14PM +0800, Luo Jie wrote:
>> Configure unicast and multicast hardware queues for the PPE
>> ports to enable packet forwarding between the ports.
>>
>> Each PPE port is assigned with a range of queues. The queue ID
>> selection for a packet is decided by the queue base and queue
>> offset that is configured based on the internal priority and
>> the RSS hash value of the packet.
>>
>> Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
>> ---
>>   drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 357 ++++++++++++++++++++++++-
>>   drivers/net/ethernet/qualcomm/ppe/ppe_config.h |  63 +++++
>>   drivers/net/ethernet/qualcomm/ppe/ppe_regs.h   |  21 ++
>>   3 files changed, 440 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
> 
> ...
> 
>> @@ -673,6 +701,111 @@ static struct ppe_scheduler_port_config ppe_port_sch_config[] = {
>>   	},
>>   };
>>   
>> +/* The scheduler resource is applied to each PPE port, The resource
>> + * includes the unicast & multicast queues, flow nodes and DRR nodes.
>> + */
>> +static struct ppe_port_schedule_resource ppe_scheduler_res[] = {
>> +	{	.ucastq_start	= 0,
>> +		.ucastq_end	= 63,
>> +		.mcastq_start	= 256,
>> +		.ucastq_end	= 271,
> 
> Hi Luo Jie,
> 
> This appears to duplicate the initialisation of .ucastq_end.
> Should the line above initialise .mcastq_end instead?
> 
> Likewise for other elements of this array.
> 
> Flagged by W=1 builds with both clang-19 and gcc-14.

Thanks for pointing to this. I will update the code and build the
patches with latest GCC version gcc-14 flagged by W=1 to check the
patches.

> 
>> +		.flow_id_start	= 0,
>> +		.flow_id_end	= 0,
>> +		.l0node_start	= 0,
>> +		.l0node_end	= 7,
>> +		.l1node_start	= 0,
>> +		.l1node_end	= 0,
>> +	},
>> +	{	.ucastq_start	= 144,
>> +		.ucastq_end	= 159,
>> +		.mcastq_start	= 272,
>> +		.ucastq_end	= 275,
>> +		.flow_id_start	= 36,
>> +		.flow_id_end	= 39,
>> +		.l0node_start	= 48,
>> +		.l0node_end	= 63,
>> +		.l1node_start	= 8,
>> +		.l1node_end	= 11,
>> +	},
> 
> ...
> 
>> +};
> 
> ...
Jie Luo Jan. 10, 2025, 3:47 p.m. UTC | #5
On 1/9/2025 5:15 PM, Krzysztof Kozlowski wrote:
> On Wed, Jan 08, 2025 at 09:47:08PM +0800, Luo Jie wrote:
>> +    required:
>> +      - clocks
>> +      - clock-names
>> +      - resets
>> +      - interrupts
>> +      - interrupt-names
>> +
>> +  ethernet-ports:
> 
> This device really looks like DSA or other ethernet switch, so I would
> really expect proper $ref in top-level.

Sure, agree that the PPE is better modeled as an Ethernet switch. I will
add and use the $ref ethernet-switch.yaml in the top-level.

> 
>> +    type: object
>> +    additionalProperties: false
>> +    properties:
>> +      '#address-cells':
>> +        const: 1
>> +      '#size-cells':
>> +        const: 0
>> +
>> +    patternProperties:
>> +      "^port@[1-6]$":
>> +        type: object
>> +        $ref: ethernet-controller.yaml#
> 
> Everything here is duplicating DSA or ethernet-switch, so that's
> surprising.

I will remove the current 'ethernet-ports' node and the "$ref: ethernet-
controller.yaml#" from the port node. As the top-level $ref, will use 
ethernet-switch.yaml instead.

The PPE Ethernet port node requires the additional DT properties clocks
and resets, which will be added into the switch port node. Thanks.

> 
>> +        unevaluatedProperties: false
>> +        description:
>> +          PPE port that includes the MAC used to connect the external
>> +          switch or PHY via the PCS.
> 
> Best regards,
> Krzysztof
>