| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/05 15:45 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch adds support for the Qualcomm IPQ5332 SoC to the Qualcomm PPE (Packet Process Engine) Ethernet driver and its Device Tree bindings. This is a platform driver for Qualcomm ARM-based IPQ SoCs (ARCH_QCOM) requiring specific SoC hardware that is not emulated in standard QEMU/GCE virtualized environments and is structurally unreachable on the amd64 target architecture.",
"WorthFuzzing": false
} |
| 1/1 | 2026/10/05 15:45 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit a6398d57a87f639b047305b768b2657cab5f564a\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Oct 5 15:45:10 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml\nindex 6d0b21a10732a..29dd34210ac89 100644\n--- a/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml\n+++ b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml\n@@ -28,11 +28,15 @@ description: |\n supporting various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There\n are 3 UNIPHY (PCS) instances supported on the IPQ9574.\n \n- Ethernet DMA is used to transmit and receive packets between the six Ethernet\n+ IPQ5332 uses the same PPE architecture with two front panel ports and two\n+ UNIPHY (PCS) instances. Its Ethernet datapath has a CPU port (port0) and\n+ two GMAC/XGMAC ports (port1 and port2).\n+\n+ Ethernet DMA is used to transmit and receive packets between the Ethernet\n ports and ARM host CPU.\n \n- The follow diagram shows the PPE hardware block along with its connectivity\n- to the external hardware blocks such clock hardware blocks (CMNPLL, GCC,\n+ The following diagram shows the IPQ9574 PPE hardware block and its\n+ connectivity to external clock hardware blocks (CMNPLL, GCC,\n NSS clock controller) and Ethernet PCS/PHY blocks. For depicting the PHY\n connectivity, one 4x1 Gbps PHY (QCA8075) and two 10 GBps PHYs are used as an\n example.\n@@ -77,24 +81,29 @@ description: |\n properties:\n compatible:\n enum:\n+ - qcom,ipq5332-ppe\n - qcom,ipq9574-ppe\n \n reg:\n maxItems: 1\n \n clocks:\n+ minItems: 4\n items:\n - description: PPE core clock\n - description: PPE APB (Advanced Peripheral Bus) clock\n - description: PPE IPE (Ingress Process Engine) clock\n - description: PPE BM, QM and scheduler clock\n+ - description: PPE sleep clock from GCC\n \n clock-names:\n+ minItems: 4\n items:\n - const: ppe\n - const: apb\n - const: ipe\n - const: btq\n+ - const: sleep\n \n resets:\n maxItems: 1\n@@ -105,6 +114,7 @@ properties:\n description: PPE switch miscellaneous interrupt\n \n interconnects:\n+ minItems: 4\n items:\n - description: Bus interconnect path leading to PPE switch core function\n - description: Bus interconnect path leading to PPE register access\n@@ -115,6 +125,7 @@ properties:\n - description: Bus interconnect path leading to enhanced memory NOC from NSS NOC\n \n interconnect-names:\n+ minItems: 4\n items:\n - const: ppe\n - const: ppe_cfg\n@@ -130,7 +141,9 @@ properties:\n description:\n EDMA (Ethernet DMA) is used to transmit packets between PPE and ARM\n host CPU. There are 32 TX descriptor rings, 32 TX completion rings,\n- 24 RX descriptor rings and 8 RX fill rings supported.\n+ 24 RX descriptor rings and 8 RX fill rings supported on IPQ9574.\n+ IPQ5332 supports 24 TX descriptor rings, 24 TX completion rings,\n+ 16 RX descriptor rings and 8 RX fill rings.\n \n properties:\n clocks:\n@@ -144,15 +157,18 @@ properties:\n - const: apb\n \n resets:\n- maxItems: 1\n- description: EDMA reset\n+ minItems: 1\n+ items:\n+ - description:\n+ EDMA system reset. On IPQ9574 this also resets the configuration.\n+ - description: EDMA configuration reset\n \n interrupts:\n- minItems: 65\n+ minItems: 49\n maxItems: 65\n \n interrupt-names:\n- minItems: 65\n+ minItems: 49\n maxItems: 65\n items:\n oneOf:\n@@ -165,6 +181,7 @@ properties:\n Interrupts \"rxfill_[0-7]\" are the Ethernet DMA RX fill ring interrupts.\n Interrupts \"rxdesc_[0-23]\" are the Ethernet DMA RX Descriptor ring interrupts.\n Interrupt \"misc\" is the Ethernet DMA miscellaneous error interrupt.\n+ On IPQ5332, only \"txcmpl_[0-23]\" and \"rxdesc_[0-15]\" are supported.\n \n required:\n - clocks\n@@ -174,8 +191,17 @@ properties:\n - interrupt-names\n \n ethernet-ports:\n+ type: object\n+ additionalProperties: false\n+\n+ properties:\n+ '#address-cells':\n+ const: 1\n+ '#size-cells':\n+ const: 0\n+\n patternProperties:\n- \"^ethernet-port@[1-6]+$\":\n+ \"^ethernet-port@[1-6]$\":\n type: object\n unevaluatedProperties: false\n $ref: ethernet-switch-port.yaml#\n@@ -229,6 +255,65 @@ required:\n \n allOf:\n - $ref: ethernet-switch.yaml\n+ - if:\n+ properties:\n+ compatible:\n+ contains:\n+ const: qcom,ipq5332-ppe\n+ then:\n+ properties:\n+ clocks:\n+ minItems: 5\n+ clock-names:\n+ minItems: 5\n+ interconnects:\n+ maxItems: 4\n+ interconnect-names:\n+ maxItems: 4\n+ ethernet-dma:\n+ properties:\n+ resets:\n+ minItems: 2\n+ interrupts:\n+ maxItems: 49\n+ interrupt-names:\n+ maxItems: 49\n+ items:\n+ oneOf:\n+ - pattern: '^txcmpl_(1?[0-9]|2[0-3])$'\n+ - pattern: '^rxfill_[0-7]$'\n+ - pattern: '^rxdesc_([0-9]|1[0-5])$'\n+ - const: misc\n+ ethernet-ports:\n+ patternProperties:\n+ \"^ethernet-port@[1-2]$\":\n+ properties:\n+ reg:\n+ maximum: 2\n+ \"^ethernet-port@[3-6]$\": false\n+ - if:\n+ properties:\n+ compatible:\n+ contains:\n+ const: qcom,ipq9574-ppe\n+ then:\n+ properties:\n+ clocks:\n+ maxItems: 4\n+ clock-names:\n+ maxItems: 4\n+ interconnects:\n+ minItems: 7\n+ interconnect-names:\n+ minItems: 7\n+ ethernet-dma:\n+ properties:\n+ resets:\n+ maxItems: 1\n+ interrupts:\n+ minItems: 65\n+ interrupt-names:\n+ minItems: 65\n \n unevaluatedProperties: false\n \ndiff --git a/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst\nindex 4ab299a28969a..caf8ab1431dee 100644\n--- a/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst\n+++ b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst\n@@ -96,6 +96,10 @@ The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS) sup\n various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There are 3 UNIPHY (PCS)\n instances supported on the IPQ9574.\n \n+IPQ5332 uses the same PPE architecture with two front panel ports and two UNIPHY\n+(PCS) instances. Its Ethernet datapath has a CPU port (port0) and two GMAC/XGMAC\n+ports (port1 and port2).\n+\n Ethernet DMA is used to transmit and receive packets between the Ethernet subsystem\n and ARM host CPU.\n \n@@ -118,6 +122,8 @@ PPE driver:\n through the UNIPHY PCS block. Each MAC block includes the GMAC and XGMAC blocks and\n the switch port can select to use GMAC or XMAC through a MUX selection according to\n the external PHY's capability.\n+ IPQ5332 has two MACs (MAC0 and MAC1), connected to switch ports port1 and\n+ port2 through two UNIPHY instances.\n - EDMA (Ethernet DMA)\n The Ethernet DMA is used to transmit and receive Ethernet packets between the PPE\n ports and the ARM cores.\n@@ -164,8 +170,9 @@ CPU code counters and queue counters.\n PPE Driver Supported SoCs\n =========================\n \n-The PPE driver supports the following IPQ SoC:\n+The PPE driver supports the following IPQ SoCs:\n \n+- IPQ5332\n - IPQ9574\n \n \ndiff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c\nindex 3c301e609d3e3..69e970db4a78b 100644\n--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c\n+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c\n@@ -11,6 +11,7 @@\n #include \u003clinux/module.h\u003e\n #include \u003clinux/of.h\u003e\n #include \u003clinux/platform_device.h\u003e\n+#include \u003clinux/property.h\u003e\n #include \u003clinux/regmap.h\u003e\n #include \u003clinux/reset.h\u003e\n \n@@ -18,13 +19,39 @@\n #include \"ppe_config.h\"\n #include \"ppe_debugfs.h\"\n \n-#define PPE_PORT_MAX\t\t8\n-#define PPE_CLK_RATE\t\t353000000\n+struct ppe_plat_data {\n+\tconst struct ppe_soc_config *soc_cfg;\n+\tconst struct icc_bulk_data *icc_data;\n+\tunsigned long ppe_clk_rate;\n+\tunsigned int num_icc, num_ports;\n+};\n \n-/* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0\n- * will be updated by the clock rate of PPE.\n- */\n-static const struct icc_bulk_data ppe_icc_data[] = {\n+/* IPQ5332 interconnect paths. Zero bandwidths use the PPE clock rate. */\n+static const struct icc_bulk_data ipq5332_icc_data[] = {\n+\t{\n+\t\t.name = \"ppe\",\n+\t\t.avg_bw = 0,\n+\t\t.peak_bw = 0,\n+\t},\n+\t{\n+\t\t.name = \"ppe_cfg\",\n+\t\t.avg_bw = 0,\n+\t\t.peak_bw = 0,\n+\t},\n+\t{\n+\t\t.name = \"qos_gen\",\n+\t\t.avg_bw = 6000,\n+\t\t.peak_bw = 6000,\n+\t},\n+\t{\n+\t\t.name = \"timeout_ref\",\n+\t\t.avg_bw = 6000,\n+\t\t.peak_bw = 6000,\n+\t},\n+};\n+\n+/* IPQ9574 interconnect paths. Zero bandwidths use the PPE clock rate. */\n+static const struct icc_bulk_data ipq9574_icc_data[] = {\n \t{\n \t\t.name = \"ppe\",\n \t\t.avg_bw = 0,\n@@ -62,6 +89,23 @@ static const struct icc_bulk_data ppe_icc_data[] = {\n \t},\n };\n \n+static const struct ppe_plat_data ipq5332_ppe_data = {\n+\t.soc_cfg = \u0026ipq5332_soc_config,\n+\t.icc_data = ipq5332_icc_data,\n+\t.ppe_clk_rate = 200000000,\n+\t.num_icc = ARRAY_SIZE(ipq5332_icc_data),\n+\t.num_ports = 3,\n+};\n+\n+static const struct ppe_plat_data ipq9574_ppe_data = {\n+\t.soc_cfg = \u0026ipq9574_soc_config,\n+\t.icc_data = ipq9574_icc_data,\n+\t.ppe_clk_rate = 353000000,\n+\t.num_icc = ARRAY_SIZE(ipq9574_icc_data),\n+\t.num_ports = 8,\n+};\n+\n+/* PPE register access ranges. */\n static const struct regmap_range ppe_readable_ranges[] = {\n \tregmap_reg_range(0x0, 0x1ff),\t\t/* Global */\n \tregmap_reg_range(0x400, 0x5ff),\t\t/* LPI CSR */\n@@ -99,7 +143,7 @@ static const struct regmap_access_table ppe_reg_table = {\n \t.n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),\n };\n \n-static const struct regmap_config regmap_config_ipq9574 = {\n+static const struct regmap_config ppe_reg_config = {\n \t.reg_bits = 32,\n \t.reg_stride = 4,\n \t.val_bits = 32,\n@@ -108,7 +152,8 @@ static const struct regmap_config regmap_config_ipq9574 = {\n \t.max_register = 0xbef800,\n };\n \n-static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)\n+static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev,\n+\t\t\t\t const struct icc_bulk_data *ppe_icc_data)\n {\n \tunsigned long ppe_rate = ppe_dev-\u003eclk_rate;\n \tstruct device *dev = ppe_dev-\u003edev;\n@@ -172,12 +217,17 @@ static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)\n \n static int qcom_ppe_probe(struct platform_device *pdev)\n {\n+\tconst struct ppe_plat_data *plat_data;\n \tstruct device *dev = \u0026pdev-\u003edev;\n \tstruct ppe_device *ppe_dev;\n \tvoid __iomem *base;\n \tint ret, num_icc;\n \n-\tnum_icc = ARRAY_SIZE(ppe_icc_data);\n+\tplat_data = device_get_match_data(dev);\n+\tif (!plat_data)\n+\t\treturn -EINVAL;\n+\n+\tnum_icc = plat_data-\u003enum_icc;\n \tppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc),\n \t\t\t GFP_KERNEL);\n \tif (!ppe_dev)\n@@ -187,20 +237,20 @@ static int qcom_ppe_probe(struct platform_device *pdev)\n \tif (IS_ERR(base))\n \t\treturn dev_err_probe(dev, PTR_ERR(base), \"PPE ioremap failed\\n\");\n \n-\tppe_dev-\u003eregmap = devm_regmap_init_mmio(dev, base, \u0026regmap_config_ipq9574);\n+\tppe_dev-\u003eregmap = devm_regmap_init_mmio(dev, base, \u0026ppe_reg_config);\n \tif (IS_ERR(ppe_dev-\u003eregmap))\n \t\treturn dev_err_probe(dev, PTR_ERR(ppe_dev-\u003eregmap),\n \t\t\t\t \"PPE initialize regmap failed\\n\");\n \tppe_dev-\u003edev = dev;\n-\tppe_dev-\u003eclk_rate = PPE_CLK_RATE;\n-\tppe_dev-\u003enum_ports = PPE_PORT_MAX;\n+\tppe_dev-\u003eclk_rate = plat_data-\u003eppe_clk_rate;\n+\tppe_dev-\u003enum_ports = plat_data-\u003enum_ports;\n \tppe_dev-\u003enum_icc_paths = num_icc;\n \n-\tret = ppe_clock_init_and_reset(ppe_dev);\n+\tret = ppe_clock_init_and_reset(ppe_dev, plat_data-\u003eicc_data);\n \tif (ret)\n \t\treturn dev_err_probe(dev, ret, \"PPE clock config failed\\n\");\n \n-\tret = ppe_hw_config(ppe_dev);\n+\tret = ppe_hw_config(ppe_dev, plat_data-\u003esoc_cfg);\n \tif (ret)\n \t\treturn dev_err_probe(dev, ret, \"PPE HW config failed\\n\");\n \n@@ -219,7 +269,8 @@ static void qcom_ppe_remove(struct platform_device *pdev)\n }\n \n static const struct of_device_id qcom_ppe_of_match[] = {\n-\t{ .compatible = \"qcom,ipq9574-ppe\" },\n+\t{ .compatible = \"qcom,ipq5332-ppe\", .data = \u0026ipq5332_ppe_data },\n+\t{ .compatible = \"qcom,ipq9574-ppe\", .data = \u0026ipq9574_ppe_data },\n \t{}\n };\n MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);\ndiff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c\nindex 125b73be92b13..91e6ee9524a60 100644\n--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c\n+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c\n@@ -174,6 +174,9 @@ struct ppe_port_schedule_resource {\n */\n static const int ipq9574_ppe_bm_group_config = 1550;\n \n+/* IPQ5332 BM group0 shared buffer limit. */\n+static const int ipq5332_ppe_bm_group_config = 360;\n+\n /* The buffer configurations per PPE port. There are 15 BM ports and\n * 4 BM groups supported by PPE. BM port (0-7) is for EDMA port 0,\n * BM port (8-13) is for PPE physical port 1-6 and BM port 14 is for\n@@ -230,6 +233,34 @@ static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {\n \t},\n };\n \n+/* IPQ5332: BM ports 0-7 serve EDMA, ports 8-9 serve ports 1-2. */\n+static const struct ppe_bm_port_config ipq5332_ppe_bm_port_config[] = {\n+\t{\n+\t\t/* Buffer configuration for the BM port ID 0-7 of EDMA. */\n+\t\t.port_id_start\t= 0,\n+\t\t.port_id_end\t= 7,\n+\t\t.pre_alloc\t= 12,\n+\t\t.in_fly_buf\t= 40,\n+\t\t.ceil\t\t= 30,\n+\t\t.weight\t\t= 7,\n+\t\t.resume_offset\t= 5,\n+\t\t.resume_ceil\t= 20,\n+\t\t.dynamic\t= true,\n+\t},\n+\t{\n+\t\t/* Buffer configuration for the BM port ID 8-9 of PPE ports. */\n+\t\t.port_id_start\t= 8,\n+\t\t.port_id_end\t= 9,\n+\t\t.pre_alloc\t= 12,\n+\t\t.in_fly_buf\t= 128,\n+\t\t.ceil\t\t= 48,\n+\t\t.weight\t\t= 7,\n+\t\t.resume_offset\t= 5,\n+\t\t.resume_ceil\t= 20,\n+\t\t.dynamic\t= true,\n+\t},\n+};\n+\n /* QM fetches the packet from PPE buffer management for transmitting the\n * packet out. The QM group configuration limits the total number of buffers\n * enqueued by all PPE hardware queues.\n@@ -240,6 +271,9 @@ static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {\n */\n static const int ipq9574_ppe_qm_group_config = 2000;\n \n+/* IPQ5332 QM group0 buffer limit. */\n+static const int ipq5332_ppe_qm_group_config = 500;\n+\n /* Default QM settings for unicast and multicast queues for IPQ9754. */\n static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {\n \t{\n@@ -264,6 +298,30 @@ static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {\n \t},\n };\n \n+/* IPQ5332 unicast and multicast queue thresholds. */\n+static const struct ppe_qm_queue_config ipq5332_ppe_qm_queue_config[] = {\n+\t{\n+\t\t/* QM settings for unicast queues 0 to 255. */\n+\t\t.queue_start\t= 0,\n+\t\t.queue_end\t= 255,\n+\t\t.prealloc_buf\t= 0,\n+\t\t.ceil\t\t= 300,\n+\t\t.weight\t\t= 7,\n+\t\t.resume_offset\t= 18,\n+\t\t.dynamic\t= true,\n+\t},\n+\t{\n+\t\t/* QM settings for multicast queues 256 to 299. */\n+\t\t.queue_start\t= 256,\n+\t\t.queue_end\t= 299,\n+\t\t.prealloc_buf\t= 0,\n+\t\t.ceil\t\t= 50,\n+\t\t.weight\t\t= 0,\n+\t\t.resume_offset\t= 18,\n+\t\t.dynamic\t= false,\n+\t},\n+};\n+\n /* PPE scheduler configuration for BM includes multiple entries. Each entry\n * indicates the primary port to be assigned the buffers for the ingress or\n * to release the buffers for the egress. Backup port ID will be used when\n@@ -372,6 +430,44 @@ static const struct ppe_scheduler_bm_config ipq9574_ppe_sch_bm_config[] = {\n \t{true, PPE_SCH_EGRESS, 7, false, 0},\n };\n \n+/* IPQ5332 BM arbitration. The invalid final slot is included in the\n+ * 32-slot scheduler depth.\n+ */\n+static const struct ppe_scheduler_bm_config ipq5332_ppe_sch_bm_config[] = {\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 0, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{true, PPE_SCH_EGRESS, 1, false, 0},\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 2, false, 0},\n+\t{true, PPE_SCH_INGRESS, 0, false, 0},\n+\t{true, PPE_SCH_EGRESS, 0, false, 0},\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 1, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{true, PPE_SCH_EGRESS, 2, false, 0},\n+\t{true, PPE_SCH_INGRESS, 0, false, 0},\n+\t{true, PPE_SCH_EGRESS, 0, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{true, PPE_SCH_EGRESS, 1, false, 0},\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 2, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{true, PPE_SCH_EGRESS, 0, false, 0},\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 1, false, 0},\n+\t{true, PPE_SCH_INGRESS, 0, false, 0},\n+\t{true, PPE_SCH_EGRESS, 2, false, 0},\n+\t{true, PPE_SCH_INGRESS, 2, false, 0},\n+\t{true, PPE_SCH_EGRESS, 0, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{true, PPE_SCH_EGRESS, 1, false, 0},\n+\t{true, PPE_SCH_INGRESS, 0, false, 0},\n+\t{true, PPE_SCH_EGRESS, 2, false, 0},\n+\t{true, PPE_SCH_INGRESS, 1, false, 0},\n+\t{false, PPE_SCH_INGRESS, 0, false, 0},\n+};\n+\n /* PPE scheduler configuration for QM includes multiple entries. Each entry\n * contains ports to be dispatched for enqueueing and dequeueing. The backup\n * port for dequeueing is supported to be used when the primary port for\n@@ -439,6 +535,22 @@ static const struct ppe_scheduler_qm_config ipq9574_ppe_sch_qm_config[] = {\n \t{0x98, 6, 5, true, 2},\n };\n \n+/* IPQ5332 QM arbitration. The enqueue bitmap is zero in every slot;\n+ * ensch_port identifies the enqueue port. Backup dequeue ports are disabled.\n+ */\n+static const struct ppe_scheduler_qm_config ipq5332_ppe_sch_qm_config[] = {\n+\t{0x0, 0x2, 0, false, 0x0},\n+\t{0x0, 0x1, 2, false, 0x0},\n+\t{0x0, 0x0, 1, false, 0x0},\n+\t{0x0, 0x0, 2, false, 0x0},\n+\t{0x0, 0x1, 0, false, 0x0},\n+\t{0x0, 0x2, 1, false, 0x0},\n+\t{0x0, 0x0, 2, false, 0x0},\n+\t{0x0, 0x0, 1, false, 0x0},\n+\t{0x0, 0x0, 2, false, 0x0},\n+\t{0x0, 0x0, 1, false, 0x0},\n+};\n+\n static const struct ppe_scheduler_port_config ppe_port_sch_config[] = {\n \t{\n \t\t.port\t\t= 0,\n@@ -732,6 +844,8 @@ static const struct ppe_scheduler_port_config ppe_port_sch_config[] = {\n \n /* The scheduler resource is applied to each PPE port, The resource\n * includes the unicast \u0026 multicast queues, flow nodes and DRR nodes.\n+ * Entries 1 and 2 serve ports 1 and 2 on both IPQ5332 and IPQ9574.\n+ * The reserved pool is the last entry.\n */\n static const struct ppe_port_schedule_resource ppe_scheduler_res[] = {\n \t{\t.ucastq_start\t= 0,\n@@ -835,6 +949,32 @@ static const struct ppe_port_schedule_resource ppe_scheduler_res[] = {\n \t},\n };\n \n+const struct ppe_soc_config ipq5332_soc_config = {\n+\t.bm_group_config = ipq5332_ppe_bm_group_config,\n+\t.bm_port_config = ipq5332_ppe_bm_port_config,\n+\t.bm_port_config_cnt = ARRAY_SIZE(ipq5332_ppe_bm_port_config),\n+\t.qm_group_config = ipq5332_ppe_qm_group_config,\n+\t.qm_queue_config = ipq5332_ppe_qm_queue_config,\n+\t.qm_queue_config_cnt = ARRAY_SIZE(ipq5332_ppe_qm_queue_config),\n+\t.sch_bm_config = ipq5332_ppe_sch_bm_config,\n+\t.sch_bm_config_cnt = ARRAY_SIZE(ipq5332_ppe_sch_bm_config),\n+\t.sch_qm_config = ipq5332_ppe_sch_qm_config,\n+\t.sch_qm_config_cnt = ARRAY_SIZE(ipq5332_ppe_sch_qm_config),\n+};\n+\n+const struct ppe_soc_config ipq9574_soc_config = {\n+\t.bm_group_config = ipq9574_ppe_bm_group_config,\n+\t.bm_port_config = ipq9574_ppe_bm_port_config,\n+\t.bm_port_config_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config),\n+\t.qm_group_config = ipq9574_ppe_qm_group_config,\n+\t.qm_queue_config = ipq9574_ppe_qm_queue_config,\n+\t.qm_queue_config_cnt = ARRAY_SIZE(ipq9574_ppe_qm_queue_config),\n+\t.sch_bm_config = ipq9574_ppe_sch_bm_config,\n+\t.sch_bm_config_cnt = ARRAY_SIZE(ipq9574_ppe_sch_bm_config),\n+\t.sch_qm_config = ipq9574_ppe_sch_qm_config,\n+\t.sch_qm_config_cnt = ARRAY_SIZE(ipq9574_ppe_sch_qm_config),\n+};\n+\n /* Set the PPE queue level scheduler configuration. */\n static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev,\n \t\t\t\t\t int node_id, int port,\n@@ -1080,7 +1220,12 @@ int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,\n \tif (port \u003e ppe_dev-\u003enum_ports)\n \t\treturn -EINVAL;\n \n-\tres = ppe_scheduler_res[port];\n+\t/* Port ID num_ports selects the reserved pool in the final entry. */\n+\tif (port == ppe_dev-\u003enum_ports)\n+\t\tres = ppe_scheduler_res[ARRAY_SIZE(ppe_scheduler_res) - 1];\n+\telse\n+\t\tres = ppe_scheduler_res[port];\n+\n \tswitch (type) {\n \tcase PPE_RES_UCAST:\n \t\t*res_start = res.ucastq_start;\n@@ -1427,7 +1572,8 @@ static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,\n }\n \n /* Configure the buffer threshold for the port flow control function. */\n-static int ppe_config_bm(struct ppe_device *ppe_dev)\n+static int ppe_config_bm(struct ppe_device *ppe_dev,\n+\t\t\t const struct ppe_soc_config *soc_cfg)\n {\n \tconst struct ppe_bm_port_config *port_cfg;\n \tunsigned int i, bm_port_id, port_cfg_cnt;\n@@ -1440,7 +1586,7 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)\n \t */\n \treg = PPE_BM_SHARED_GROUP_CFG_ADDR;\n \tval = FIELD_PREP(PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,\n-\t\t\t ipq9574_ppe_bm_group_config);\n+\t\t\t soc_cfg-\u003ebm_group_config);\n \tret = regmap_update_bits(ppe_dev-\u003eregmap, reg,\n \t\t\t\t PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,\n \t\t\t\t val);\n@@ -1448,8 +1594,8 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)\n \t\tgoto bm_config_fail;\n \n \t/* Configure buffer thresholds for the BM ports. */\n-\tport_cfg = ipq9574_ppe_bm_port_config;\n-\tport_cfg_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config);\n+\tport_cfg = soc_cfg-\u003ebm_port_config;\n+\tport_cfg_cnt = soc_cfg-\u003ebm_port_config_cnt;\n \tfor (i = 0; i \u003c port_cfg_cnt; i++) {\n \t\tfor (bm_port_id = port_cfg[i].port_id_start;\n \t\t bm_port_id \u003c= port_cfg[i].port_id_end; bm_port_id++) {\n@@ -1470,7 +1616,8 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)\n /* Configure PPE hardware queue depth, which is decided by the threshold\n * of queue.\n */\n-static int ppe_config_qm(struct ppe_device *ppe_dev)\n+static int ppe_config_qm(struct ppe_device *ppe_dev,\n+\t\t\t const struct ppe_soc_config *soc_cfg)\n {\n \tconst struct ppe_qm_queue_config *queue_cfg;\n \tint ret, i, queue_id, queue_cfg_count;\n@@ -1485,15 +1632,15 @@ static int ppe_config_qm(struct ppe_device *ppe_dev)\n \tif (ret)\n \t\tgoto qm_config_fail;\n \n-\tPPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);\n+\tPPE_AC_GRP_SET_BUF_LIMIT(group_cfg, soc_cfg-\u003eqm_group_config);\n \n \tret = regmap_bulk_write(ppe_dev-\u003eregmap, reg,\n \t\t\t\tgroup_cfg, ARRAY_SIZE(group_cfg));\n \tif (ret)\n \t\tgoto qm_config_fail;\n \n-\tqueue_cfg = ipq9574_ppe_qm_queue_config;\n-\tqueue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);\n+\tqueue_cfg = soc_cfg-\u003eqm_queue_config;\n+\tqueue_cfg_count = soc_cfg-\u003eqm_queue_config_cnt;\n \tfor (i = 0; i \u003c queue_cfg_count; i++) {\n \t\tqueue_id = queue_cfg[i].queue_start;\n \n@@ -1625,7 +1772,8 @@ static int ppe_node_scheduler_config(struct ppe_device *ppe_dev,\n /* Initialize scheduler settings for PPE buffer utilization and dispatching\n * packet on PPE queue.\n */\n-static int ppe_config_scheduler(struct ppe_device *ppe_dev)\n+static int ppe_config_scheduler(struct ppe_device *ppe_dev,\n+\t\t\t\tconst struct ppe_soc_config *soc_cfg)\n {\n \tconst struct ppe_scheduler_port_config *port_cfg;\n \tconst struct ppe_scheduler_qm_config *qm_cfg;\n@@ -1633,8 +1781,8 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev)\n \tint ret, i, count;\n \tu32 val, reg;\n \n-\tcount = ARRAY_SIZE(ipq9574_ppe_sch_bm_config);\n-\tbm_cfg = ipq9574_ppe_sch_bm_config;\n+\tcount = soc_cfg-\u003esch_bm_config_cnt;\n+\tbm_cfg = soc_cfg-\u003esch_bm_config;\n \n \t/* Configure the depth of BM scheduler entries. */\n \tval = FIELD_PREP(PPE_BM_SCH_CTRL_SCH_DEPTH, count);\n@@ -1664,8 +1812,8 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev)\n \t\t\tgoto sch_config_fail;\n \t}\n \n-\tcount = ARRAY_SIZE(ipq9574_ppe_sch_qm_config);\n-\tqm_cfg = ipq9574_ppe_sch_qm_config;\n+\tcount = soc_cfg-\u003esch_qm_config_cnt;\n+\tqm_cfg = soc_cfg-\u003esch_qm_config;\n \n \t/* Configure the depth of QM scheduler entries. */\n \tval = FIELD_PREP(PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH, count);\n@@ -1995,19 +2143,20 @@ static int ppe_bridge_init(struct ppe_device *ppe_dev)\n \treturn 0;\n }\n \n-int ppe_hw_config(struct ppe_device *ppe_dev)\n+int ppe_hw_config(struct ppe_device *ppe_dev,\n+\t\t const struct ppe_soc_config *soc_cfg)\n {\n \tint ret;\n \n-\tret = ppe_config_bm(ppe_dev);\n+\tret = ppe_config_bm(ppe_dev, soc_cfg);\n \tif (ret)\n \t\treturn ret;\n \n-\tret = ppe_config_qm(ppe_dev);\n+\tret = ppe_config_qm(ppe_dev, soc_cfg);\n \tif (ret)\n \t\treturn ret;\n \n-\tret = ppe_config_scheduler(ppe_dev);\n+\tret = ppe_config_scheduler(ppe_dev, soc_cfg);\n \tif (ret)\n \t\treturn ret;\n \ndiff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h\nindex 60493e51e0a43..b42731aa3e7e9 100644\n--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h\n+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h\n@@ -287,7 +287,40 @@ struct ppe_rss_hash_cfg {\n \tu8 hash_fin_outer[PPE_RSS_HASH_TUPLES];\n };\n \n-int ppe_hw_config(struct ppe_device *ppe_dev);\n+/**\n+ * struct ppe_soc_config - SoC-specific PPE hardware configuration.\n+ * @bm_group_config: Buffer Management (BM) group configuration.\n+ * @bm_port_config: Pointer to the BM port configuration array.\n+ * @bm_port_config_cnt: Number of entries in the BM port configuration array.\n+ * @qm_group_config: Queue Management (QM) group configuration.\n+ * @qm_queue_config: Pointer to the QM queue configuration array.\n+ * @qm_queue_config_cnt: Number of entries in the QM queue configuration array.\n+ * @sch_bm_config: Pointer to the BM scheduler arbitration array.\n+ * @sch_bm_config_cnt: Number of entries in the BM scheduler arbitration array.\n+ * @sch_qm_config: Pointer to the QM scheduler arbitration array.\n+ * @sch_qm_config_cnt: Number of entries in the QM scheduler arbitration array.\n+ */\n+struct ppe_soc_config {\n+\tint bm_group_config;\n+\tconst struct ppe_bm_port_config *bm_port_config;\n+\tunsigned int bm_port_config_cnt;\n+\n+\tint qm_group_config;\n+\tconst struct ppe_qm_queue_config *qm_queue_config;\n+\tunsigned int qm_queue_config_cnt;\n+\n+\tconst struct ppe_scheduler_bm_config *sch_bm_config;\n+\tunsigned int sch_bm_config_cnt;\n+\n+\tconst struct ppe_scheduler_qm_config *sch_qm_config;\n+\tunsigned int sch_qm_config_cnt;\n+};\n+\n+extern const struct ppe_soc_config ipq5332_soc_config;\n+extern const struct ppe_soc_config ipq9574_soc_config;\n+\n+int ppe_hw_config(struct ppe_device *ppe_dev,\n+\t\t const struct ppe_soc_config *soc_cfg);\n int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,\n \t\t\t int node_id, bool flow_level, int port,\n \t\t\t struct ppe_scheduler_cfg scheduler_cfg);\n"
} |
| 2/1 | 2026/10/05 15:45 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds support for the Qualcomm IPQ5332 SoC to the Qualcomm PPE (Packet Process Engine) Ethernet driver and its Device Tree bindings. This is a platform driver for Qualcomm ARM-based IPQ SoCs (ARCH_QCOM) requiring specific SoC hardware that is not emulated in standard QEMU/GCE virtualized environments and is structurally unreachable on the amd64 target architecture.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit a6398d57a87f639b047305b768b2657cab5f564a
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Oct 5 15:45:10 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
index 6d0b21a10732a..29dd34210ac89 100644
--- a/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
@@ -28,11 +28,15 @@ description: |
supporting various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There
are 3 UNIPHY (PCS) instances supported on the IPQ9574.
- Ethernet DMA is used to transmit and receive packets between the six Ethernet
+ IPQ5332 uses the same PPE architecture with two front panel ports and two
+ UNIPHY (PCS) instances. Its Ethernet datapath has a CPU port (port0) and
+ two GMAC/XGMAC ports (port1 and port2).
+
+ Ethernet DMA is used to transmit and receive packets between the Ethernet
ports and ARM host CPU.
- The follow diagram shows the PPE hardware block along with its connectivity
- to the external hardware blocks such clock hardware blocks (CMNPLL, GCC,
+ The following diagram shows the IPQ9574 PPE hardware block and its
+ connectivity to external clock hardware blocks (CMNPLL, GCC,
NSS clock controller) and Ethernet PCS/PHY blocks. For depicting the PHY
connectivity, one 4x1 Gbps PHY (QCA8075) and two 10 GBps PHYs are used as an
example.
@@ -77,24 +81,29 @@ description: |
properties:
compatible:
enum:
+ - qcom,ipq5332-ppe
- qcom,ipq9574-ppe
reg:
maxItems: 1
clocks:
+ minItems: 4
items:
- description: PPE core clock
- description: PPE APB (Advanced Peripheral Bus) clock
- description: PPE IPE (Ingress Process Engine) clock
- description: PPE BM, QM and scheduler clock
+ - description: PPE sleep clock from GCC
clock-names:
+ minItems: 4
items:
- const: ppe
- const: apb
- const: ipe
- const: btq
+ - const: sleep
resets:
maxItems: 1
@@ -105,6 +114,7 @@ properties:
description: PPE switch miscellaneous interrupt
interconnects:
+ minItems: 4
items:
- description: Bus interconnect path leading to PPE switch core function
- description: Bus interconnect path leading to PPE register access
@@ -115,6 +125,7 @@ properties:
- description: Bus interconnect path leading to enhanced memory NOC from NSS NOC
interconnect-names:
+ minItems: 4
items:
- const: ppe
- const: ppe_cfg
@@ -130,7 +141,9 @@ properties:
description:
EDMA (Ethernet DMA) is used to transmit packets between PPE and ARM
host CPU. There are 32 TX descriptor rings, 32 TX completion rings,
- 24 RX descriptor rings and 8 RX fill rings supported.
+ 24 RX descriptor rings and 8 RX fill rings supported on IPQ9574.
+ IPQ5332 supports 24 TX descriptor rings, 24 TX completion rings,
+ 16 RX descriptor rings and 8 RX fill rings.
properties:
clocks:
@@ -144,15 +157,18 @@ properties:
- const: apb
resets:
- maxItems: 1
- description: EDMA reset
+ minItems: 1
+ items:
+ - description:
+ EDMA system reset. On IPQ9574 this also resets the configuration.
+ - description: EDMA configuration reset
interrupts:
- minItems: 65
+ minItems: 49
maxItems: 65
interrupt-names:
- minItems: 65
+ minItems: 49
maxItems: 65
items:
oneOf:
@@ -165,6 +181,7 @@ properties:
Interrupts "rxfill_[0-7]" are the Ethernet DMA RX fill ring interrupts.
Interrupts "rxdesc_[0-23]" are the Ethernet DMA RX Descriptor ring interrupts.
Interrupt "misc" is the Ethernet DMA miscellaneous error interrupt.
+ On IPQ5332, only "txcmpl_[0-23]" and "rxdesc_[0-15]" are supported.
required:
- clocks
@@ -174,8 +191,17 @@ properties:
- interrupt-names
ethernet-ports:
+ type: object
+ additionalProperties: false
+
+ properties:
+ '#address-cells':
+ const: 1
+ '#size-cells':
+ const: 0
+
patternProperties:
- "^ethernet-port@[1-6]+$":
+ "^ethernet-port@[1-6]$":
type: object
unevaluatedProperties: false
$ref: ethernet-switch-port.yaml#
@@ -229,6 +255,65 @@ required:
allOf:
- $ref: ethernet-switch.yaml
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,ipq5332-ppe
+ then:
+ properties:
+ clocks:
+ minItems: 5
+ clock-names:
+ minItems: 5
+ interconnects:
+ maxItems: 4
+ interconnect-names:
+ maxItems: 4
+ ethernet-dma:
+ properties:
+ resets:
+ minItems: 2
+ interrupts:
+ maxItems: 49
+ interrupt-names:
+ maxItems: 49
+ items:
+ oneOf:
+ - pattern: '^txcmpl_(1?[0-9]|2[0-3])$'
+ - pattern: '^rxfill_[0-7]$'
+ - pattern: '^rxdesc_([0-9]|1[0-5])$'
+ - const: misc
+ ethernet-ports:
+ patternProperties:
+ "^ethernet-port@[1-2]$":
+ properties:
+ reg:
+ maximum: 2
+ "^ethernet-port@[3-6]$": false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,ipq9574-ppe
+ then:
+ properties:
+ clocks:
+ maxItems: 4
+ clock-names:
+ maxItems: 4
+ interconnects:
+ minItems: 7
+ interconnect-names:
+ minItems: 7
+ ethernet-dma:
+ properties:
+ resets:
+ maxItems: 1
+ interrupts:
+ minItems: 65
+ interrupt-names:
+ minItems: 65
unevaluatedProperties: false
diff --git a/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
index 4ab299a28969a..caf8ab1431dee 100644
--- a/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
+++ b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
@@ -96,6 +96,10 @@ The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS) sup
various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There are 3 UNIPHY (PCS)
instances supported on the IPQ9574.
+IPQ5332 uses the same PPE architecture with two front panel ports and two UNIPHY
+(PCS) instances. Its Ethernet datapath has a CPU port (port0) and two GMAC/XGMAC
+ports (port1 and port2).
+
Ethernet DMA is used to transmit and receive packets between the Ethernet subsystem
and ARM host CPU.
@@ -118,6 +122,8 @@ PPE driver:
through the UNIPHY PCS block. Each MAC block includes the GMAC and XGMAC blocks and
the switch port can select to use GMAC or XMAC through a MUX selection according to
the external PHY's capability.
+ IPQ5332 has two MACs (MAC0 and MAC1), connected to switch ports port1 and
+ port2 through two UNIPHY instances.
- EDMA (Ethernet DMA)
The Ethernet DMA is used to transmit and receive Ethernet packets between the PPE
ports and the ARM cores.
@@ -164,8 +170,9 @@ CPU code counters and queue counters.
PPE Driver Supported SoCs
=========================
-The PPE driver supports the following IPQ SoC:
+The PPE driver supports the following IPQ SoCs:
+- IPQ5332
- IPQ9574
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
index 3c301e609d3e3..69e970db4a78b 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
@@ -18,13 +19,39 @@
#include "ppe_config.h"
#include "ppe_debugfs.h"
-#define PPE_PORT_MAX 8
-#define PPE_CLK_RATE 353000000
+struct ppe_plat_data {
+ const struct ppe_soc_config *soc_cfg;
+ const struct icc_bulk_data *icc_data;
+ unsigned long ppe_clk_rate;
+ unsigned int num_icc, num_ports;
+};
-/* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0
- * will be updated by the clock rate of PPE.
- */
-static const struct icc_bulk_data ppe_icc_data[] = {
+/* IPQ5332 interconnect paths. Zero bandwidths use the PPE clock rate. */
+static const struct icc_bulk_data ipq5332_icc_data[] = {
+ {
+ .name = "ppe",
+ .avg_bw = 0,
+ .peak_bw = 0,
+ },
+ {
+ .name = "ppe_cfg",
+ .avg_bw = 0,
+ .peak_bw = 0,
+ },
+ {
+ .name = "qos_gen",
+ .avg_bw = 6000,
+ .peak_bw = 6000,
+ },
+ {
+ .name = "timeout_ref",
+ .avg_bw = 6000,
+ .peak_bw = 6000,
+ },
+};
+
+/* IPQ9574 interconnect paths. Zero bandwidths use the PPE clock rate. */
+static const struct icc_bulk_data ipq9574_icc_data[] = {
{
.name = "ppe",
.avg_bw = 0,
@@ -62,6 +89,23 @@ static const struct icc_bulk_data ppe_icc_data[] = {
},
};
+static const struct ppe_plat_data ipq5332_ppe_data = {
+ .soc_cfg = &ipq5332_soc_config,
+ .icc_data = ipq5332_icc_data,
+ .ppe_clk_rate = 200000000,
+ .num_icc = ARRAY_SIZE(ipq5332_icc_data),
+ .num_ports = 3,
+};
+
+static const struct ppe_plat_data ipq9574_ppe_data = {
+ .soc_cfg = &ipq9574_soc_config,
+ .icc_data = ipq9574_icc_data,
+ .ppe_clk_rate = 353000000,
+ .num_icc = ARRAY_SIZE(ipq9574_icc_data),
+ .num_ports = 8,
+};
+
+/* PPE register access ranges. */
static const struct regmap_range ppe_readable_ranges[] = {
regmap_reg_range(0x0, 0x1ff), /* Global */
regmap_reg_range(0x400, 0x5ff), /* LPI CSR */
@@ -99,7 +143,7 @@ static const struct regmap_access_table ppe_reg_table = {
.n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),
};
-static const struct regmap_config regmap_config_ipq9574 = {
+static const struct regmap_config ppe_reg_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
@@ -108,7 +152,8 @@ static const struct regmap_config regmap_config_ipq9574 = {
.max_register = 0xbef800,
};
-static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
+static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev,
+ const struct icc_bulk_data *ppe_icc_data)
{
unsigned long ppe_rate = ppe_dev->clk_rate;
struct device *dev = ppe_dev->dev;
@@ -172,12 +217,17 @@ static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
static int qcom_ppe_probe(struct platform_device *pdev)
{
+ const struct ppe_plat_data *plat_data;
struct device *dev = &pdev->dev;
struct ppe_device *ppe_dev;
void __iomem *base;
int ret, num_icc;
- num_icc = ARRAY_SIZE(ppe_icc_data);
+ plat_data = device_get_match_data(dev);
+ if (!plat_data)
+ return -EINVAL;
+
+ num_icc = plat_data->num_icc;
ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc),
GFP_KERNEL);
if (!ppe_dev)
@@ -187,20 +237,20 @@ static int qcom_ppe_probe(struct platform_device *pdev)
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, ®map_config_ipq9574);
+ ppe_dev->regmap = devm_regmap_init_mmio(dev, base, &ppe_reg_config);
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->clk_rate = plat_data->ppe_clk_rate;
+ ppe_dev->num_ports = plat_data->num_ports;
ppe_dev->num_icc_paths = num_icc;
- ret = ppe_clock_init_and_reset(ppe_dev);
+ ret = ppe_clock_init_and_reset(ppe_dev, plat_data->icc_data);
if (ret)
return dev_err_probe(dev, ret, "PPE clock config failed\n");
- ret = ppe_hw_config(ppe_dev);
+ ret = ppe_hw_config(ppe_dev, plat_data->soc_cfg);
if (ret)
return dev_err_probe(dev, ret, "PPE HW config failed\n");
@@ -219,7 +269,8 @@ static void qcom_ppe_remove(struct platform_device *pdev)
}
static const struct of_device_id qcom_ppe_of_match[] = {
- { .compatible = "qcom,ipq9574-ppe" },
+ { .compatible = "qcom,ipq5332-ppe", .data = &ipq5332_ppe_data },
+ { .compatible = "qcom,ipq9574-ppe", .data = &ipq9574_ppe_data },
{}
};
MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
index 125b73be92b13..91e6ee9524a60 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
@@ -174,6 +174,9 @@ struct ppe_port_schedule_resource {
*/
static const int ipq9574_ppe_bm_group_config = 1550;
+/* IPQ5332 BM group0 shared buffer limit. */
+static const int ipq5332_ppe_bm_group_config = 360;
+
/* The buffer configurations per PPE port. There are 15 BM ports and
* 4 BM groups supported by PPE. BM port (0-7) is for EDMA port 0,
* BM port (8-13) is for PPE physical port 1-6 and BM port 14 is for
@@ -230,6 +233,34 @@ static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
},
};
+/* IPQ5332: BM ports 0-7 serve EDMA, ports 8-9 serve ports 1-2. */
+static const struct ppe_bm_port_config ipq5332_ppe_bm_port_config[] = {
+ {
+ /* Buffer configuration for the BM port ID 0-7 of EDMA. */
+ .port_id_start = 0,
+ .port_id_end = 7,
+ .pre_alloc = 12,
+ .in_fly_buf = 40,
+ .ceil = 30,
+ .weight = 7,
+ .resume_offset = 5,
+ .resume_ceil = 20,
+ .dynamic = true,
+ },
+ {
+ /* Buffer configuration for the BM port ID 8-9 of PPE ports. */
+ .port_id_start = 8,
+ .port_id_end = 9,
+ .pre_alloc = 12,
+ .in_fly_buf = 128,
+ .ceil = 48,
+ .weight = 7,
+ .resume_offset = 5,
+ .resume_ceil = 20,
+ .dynamic = true,
+ },
+};
+
/* QM fetches the packet from PPE buffer management for transmitting the
* packet out. The QM group configuration limits the total number of buffers
* enqueued by all PPE hardware queues.
@@ -240,6 +271,9 @@ static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
*/
static const int ipq9574_ppe_qm_group_config = 2000;
+/* IPQ5332 QM group0 buffer limit. */
+static const int ipq5332_ppe_qm_group_config = 500;
+
/* Default QM settings for unicast and multicast queues for IPQ9754. */
static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
{
@@ -264,6 +298,30 @@ static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
},
};
+/* IPQ5332 unicast and multicast queue thresholds. */
+static const struct ppe_qm_queue_config ipq5332_ppe_qm_queue_config[] = {
+ {
+ /* QM settings for unicast queues 0 to 255. */
+ .queue_start = 0,
+ .queue_end = 255,
+ .prealloc_buf = 0,
+ .ceil = 300,
+ .weight = 7,
+ .resume_offset = 18,
+ .dynamic = true,
+ },
+ {
+ /* QM settings for multicast queues 256 to 299. */
+ .queue_start = 256,
+ .queue_end = 299,
+ .prealloc_buf = 0,
+ .ceil = 50,
+ .weight = 0,
+ .resume_offset = 18,
+ .dynamic = false,
+ },
+};
+
/* PPE scheduler configuration for BM includes multiple entries. Each entry
* indicates the primary port to be assigned the buffers for the ingress or
* to release the buffers for the egress. Backup port ID will be used when
@@ -372,6 +430,44 @@ static const struct ppe_scheduler_bm_config ipq9574_ppe_sch_bm_config[] = {
{true, PPE_SCH_EGRESS, 7, false, 0},
};
+/* IPQ5332 BM arbitration. The invalid final slot is included in the
+ * 32-slot scheduler depth.
+ */
+static const struct ppe_scheduler_bm_config ipq5332_ppe_sch_bm_config[] = {
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 0, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {true, PPE_SCH_EGRESS, 1, false, 0},
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 2, false, 0},
+ {true, PPE_SCH_INGRESS, 0, false, 0},
+ {true, PPE_SCH_EGRESS, 0, false, 0},
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 1, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {true, PPE_SCH_EGRESS, 2, false, 0},
+ {true, PPE_SCH_INGRESS, 0, false, 0},
+ {true, PPE_SCH_EGRESS, 0, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {true, PPE_SCH_EGRESS, 1, false, 0},
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 2, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {true, PPE_SCH_EGRESS, 0, false, 0},
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 1, false, 0},
+ {true, PPE_SCH_INGRESS, 0, false, 0},
+ {true, PPE_SCH_EGRESS, 2, false, 0},
+ {true, PPE_SCH_INGRESS, 2, false, 0},
+ {true, PPE_SCH_EGRESS, 0, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {true, PPE_SCH_EGRESS, 1, false, 0},
+ {true, PPE_SCH_INGRESS, 0, false, 0},
+ {true, PPE_SCH_EGRESS, 2, false, 0},
+ {true, PPE_SCH_INGRESS, 1, false, 0},
+ {false, PPE_SCH_INGRESS, 0, false, 0},
+};
+
/* PPE scheduler configuration for QM includes multiple entries. Each entry
* contains ports to be dispatched for enqueueing and dequeueing. The backup
* port for dequeueing is supported to be used when the primary port for
@@ -439,6 +535,22 @@ static const struct ppe_scheduler_qm_config ipq9574_ppe_sch_qm_config[] = {
{0x98, 6, 5, true, 2},
};
+/* IPQ5332 QM arbitration. The enqueue bitmap is zero in every slot;
+ * ensch_port identifies the enqueue port. Backup dequeue ports are disabled.
+ */
+static const struct ppe_scheduler_qm_config ipq5332_ppe_sch_qm_config[] = {
+ {0x0, 0x2, 0, false, 0x0},
+ {0x0, 0x1, 2, false, 0x0},
+ {0x0, 0x0, 1, false, 0x0},
+ {0x0, 0x0, 2, false, 0x0},
+ {0x0, 0x1, 0, false, 0x0},
+ {0x0, 0x2, 1, false, 0x0},
+ {0x0, 0x0, 2, false, 0x0},
+ {0x0, 0x0, 1, false, 0x0},
+ {0x0, 0x0, 2, false, 0x0},
+ {0x0, 0x0, 1, false, 0x0},
+};
+
static const struct ppe_scheduler_port_config ppe_port_sch_config[] = {
{
.port = 0,
@@ -732,6 +844,8 @@ static const 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.
+ * Entries 1 and 2 serve ports 1 and 2 on both IPQ5332 and IPQ9574.
+ * The reserved pool is the last entry.
*/
static const struct ppe_port_schedule_resource ppe_scheduler_res[] = {
{ .ucastq_start = 0,
@@ -835,6 +949,32 @@ static const struct ppe_port_schedule_resource ppe_scheduler_res[] = {
},
};
+const struct ppe_soc_config ipq5332_soc_config = {
+ .bm_group_config = ipq5332_ppe_bm_group_config,
+ .bm_port_config = ipq5332_ppe_bm_port_config,
+ .bm_port_config_cnt = ARRAY_SIZE(ipq5332_ppe_bm_port_config),
+ .qm_group_config = ipq5332_ppe_qm_group_config,
+ .qm_queue_config = ipq5332_ppe_qm_queue_config,
+ .qm_queue_config_cnt = ARRAY_SIZE(ipq5332_ppe_qm_queue_config),
+ .sch_bm_config = ipq5332_ppe_sch_bm_config,
+ .sch_bm_config_cnt = ARRAY_SIZE(ipq5332_ppe_sch_bm_config),
+ .sch_qm_config = ipq5332_ppe_sch_qm_config,
+ .sch_qm_config_cnt = ARRAY_SIZE(ipq5332_ppe_sch_qm_config),
+};
+
+const struct ppe_soc_config ipq9574_soc_config = {
+ .bm_group_config = ipq9574_ppe_bm_group_config,
+ .bm_port_config = ipq9574_ppe_bm_port_config,
+ .bm_port_config_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config),
+ .qm_group_config = ipq9574_ppe_qm_group_config,
+ .qm_queue_config = ipq9574_ppe_qm_queue_config,
+ .qm_queue_config_cnt = ARRAY_SIZE(ipq9574_ppe_qm_queue_config),
+ .sch_bm_config = ipq9574_ppe_sch_bm_config,
+ .sch_bm_config_cnt = ARRAY_SIZE(ipq9574_ppe_sch_bm_config),
+ .sch_qm_config = ipq9574_ppe_sch_qm_config,
+ .sch_qm_config_cnt = ARRAY_SIZE(ipq9574_ppe_sch_qm_config),
+};
+
/* Set the PPE queue level scheduler configuration. */
static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev,
int node_id, int port,
@@ -1080,7 +1220,12 @@ int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,
if (port > ppe_dev->num_ports)
return -EINVAL;
- res = ppe_scheduler_res[port];
+ /* Port ID num_ports selects the reserved pool in the final entry. */
+ if (port == ppe_dev->num_ports)
+ res = ppe_scheduler_res[ARRAY_SIZE(ppe_scheduler_res) - 1];
+ else
+ res = ppe_scheduler_res[port];
+
switch (type) {
case PPE_RES_UCAST:
*res_start = res.ucastq_start;
@@ -1427,7 +1572,8 @@ static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
}
/* Configure the buffer threshold for the port flow control function. */
-static int ppe_config_bm(struct ppe_device *ppe_dev)
+static int ppe_config_bm(struct ppe_device *ppe_dev,
+ const struct ppe_soc_config *soc_cfg)
{
const struct ppe_bm_port_config *port_cfg;
unsigned int i, bm_port_id, port_cfg_cnt;
@@ -1440,7 +1586,7 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)
*/
reg = PPE_BM_SHARED_GROUP_CFG_ADDR;
val = FIELD_PREP(PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
- ipq9574_ppe_bm_group_config);
+ soc_cfg->bm_group_config);
ret = regmap_update_bits(ppe_dev->regmap, reg,
PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
val);
@@ -1448,8 +1594,8 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)
goto bm_config_fail;
/* Configure buffer thresholds for the BM ports. */
- port_cfg = ipq9574_ppe_bm_port_config;
- port_cfg_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config);
+ port_cfg = soc_cfg->bm_port_config;
+ port_cfg_cnt = soc_cfg->bm_port_config_cnt;
for (i = 0; i < port_cfg_cnt; i++) {
for (bm_port_id = port_cfg[i].port_id_start;
bm_port_id <= port_cfg[i].port_id_end; bm_port_id++) {
@@ -1470,7 +1616,8 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)
/* Configure PPE hardware queue depth, which is decided by the threshold
* of queue.
*/
-static int ppe_config_qm(struct ppe_device *ppe_dev)
+static int ppe_config_qm(struct ppe_device *ppe_dev,
+ const struct ppe_soc_config *soc_cfg)
{
const struct ppe_qm_queue_config *queue_cfg;
int ret, i, queue_id, queue_cfg_count;
@@ -1485,15 +1632,15 @@ static int ppe_config_qm(struct ppe_device *ppe_dev)
if (ret)
goto qm_config_fail;
- PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);
+ PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, soc_cfg->qm_group_config);
ret = regmap_bulk_write(ppe_dev->regmap, reg,
group_cfg, ARRAY_SIZE(group_cfg));
if (ret)
goto qm_config_fail;
- queue_cfg = ipq9574_ppe_qm_queue_config;
- queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);
+ queue_cfg = soc_cfg->qm_queue_config;
+ queue_cfg_count = soc_cfg->qm_queue_config_cnt;
for (i = 0; i < queue_cfg_count; i++) {
queue_id = queue_cfg[i].queue_start;
@@ -1625,7 +1772,8 @@ static int ppe_node_scheduler_config(struct ppe_device *ppe_dev,
/* Initialize scheduler settings for PPE buffer utilization and dispatching
* packet on PPE queue.
*/
-static int ppe_config_scheduler(struct ppe_device *ppe_dev)
+static int ppe_config_scheduler(struct ppe_device *ppe_dev,
+ const struct ppe_soc_config *soc_cfg)
{
const struct ppe_scheduler_port_config *port_cfg;
const struct ppe_scheduler_qm_config *qm_cfg;
@@ -1633,8 +1781,8 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev)
int ret, i, count;
u32 val, reg;
- count = ARRAY_SIZE(ipq9574_ppe_sch_bm_config);
- bm_cfg = ipq9574_ppe_sch_bm_config;
+ count = soc_cfg->sch_bm_config_cnt;
+ bm_cfg = soc_cfg->sch_bm_config;
/* Configure the depth of BM scheduler entries. */
val = FIELD_PREP(PPE_BM_SCH_CTRL_SCH_DEPTH, count);
@@ -1664,8 +1812,8 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev)
goto sch_config_fail;
}
- count = ARRAY_SIZE(ipq9574_ppe_sch_qm_config);
- qm_cfg = ipq9574_ppe_sch_qm_config;
+ count = soc_cfg->sch_qm_config_cnt;
+ qm_cfg = soc_cfg->sch_qm_config;
/* Configure the depth of QM scheduler entries. */
val = FIELD_PREP(PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH, count);
@@ -1995,19 +2143,20 @@ static int ppe_bridge_init(struct ppe_device *ppe_dev)
return 0;
}
-int ppe_hw_config(struct ppe_device *ppe_dev)
+int ppe_hw_config(struct ppe_device *ppe_dev,
+ const struct ppe_soc_config *soc_cfg)
{
int ret;
- ret = ppe_config_bm(ppe_dev);
+ ret = ppe_config_bm(ppe_dev, soc_cfg);
if (ret)
return ret;
- ret = ppe_config_qm(ppe_dev);
+ ret = ppe_config_qm(ppe_dev, soc_cfg);
if (ret)
return ret;
- ret = ppe_config_scheduler(ppe_dev);
+ ret = ppe_config_scheduler(ppe_dev, soc_cfg);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
index 60493e51e0a43..b42731aa3e7e9 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
@@ -287,7 +287,40 @@ struct ppe_rss_hash_cfg {
u8 hash_fin_outer[PPE_RSS_HASH_TUPLES];
};
-int ppe_hw_config(struct ppe_device *ppe_dev);
+/**
+ * struct ppe_soc_config - SoC-specific PPE hardware configuration.
+ * @bm_group_config: Buffer Management (BM) group configuration.
+ * @bm_port_config: Pointer to the BM port configuration array.
+ * @bm_port_config_cnt: Number of entries in the BM port configuration array.
+ * @qm_group_config: Queue Management (QM) group configuration.
+ * @qm_queue_config: Pointer to the QM queue configuration array.
+ * @qm_queue_config_cnt: Number of entries in the QM queue configuration array.
+ * @sch_bm_config: Pointer to the BM scheduler arbitration array.
+ * @sch_bm_config_cnt: Number of entries in the BM scheduler arbitration array.
+ * @sch_qm_config: Pointer to the QM scheduler arbitration array.
+ * @sch_qm_config_cnt: Number of entries in the QM scheduler arbitration array.
+ */
+struct ppe_soc_config {
+ int bm_group_config;
+ const struct ppe_bm_port_config *bm_port_config;
+ unsigned int bm_port_config_cnt;
+
+ int qm_group_config;
+ const struct ppe_qm_queue_config *qm_queue_config;
+ unsigned int qm_queue_config_cnt;
+
+ const struct ppe_scheduler_bm_config *sch_bm_config;
+ unsigned int sch_bm_config_cnt;
+
+ const struct ppe_scheduler_qm_config *sch_qm_config;
+ unsigned int sch_qm_config_cnt;
+};
+
+extern const struct ppe_soc_config ipq5332_soc_config;
+extern const struct ppe_soc_config ipq9574_soc_config;
+
+int ppe_hw_config(struct ppe_device *ppe_dev,
+ const struct ppe_soc_config *soc_cfg);
int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
int node_id, bool flow_level, int port,
struct ppe_scheduler_cfg scheduler_cfg);
|
| 3/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13413 output: 34 thoughts: 204 Thoughts: Here's my analysis of the provided information: **Analyzing the Qualcomm PPE Patch** Okay, let's break this down. My initial reaction is to systematically dissect this patch. The modifications are clearly delineated across several files: the device tree binding (`qcom,ipq9574-ppe.yaml`), the documentation (`ppe.rst`), and the driver code itself (`ppe.c`, `ppe_config.c`, `ppe_config.h`). The target architecture, `amd64`, is also provided, which is useful for context. My first thought is to zero in on the `drivers/net/ethernet/qualcomm/ppe/` directory. That's where the heart of this change likely resides. I need to understand what the Qualcomm PPE is. Is it a Packet Processing Engine? What is its role within the network stack? Now, I need to check the Kconfig file within that directory. I'm going to either run a quick `grep` for "PPE" or just read through the Kconfig to see how this driver is configured, its dependencies, and any relevant options. This is crucial for understanding the impact of this patch and how it fits into the broader Qualcomm network device ecosystem. |
| 4/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "QCOM_PPE",
"PathPrefix": "drivers/net/ethernet/qualcomm/"
}Results: {
"Output": "drivers/net/ethernet/qualcomm/Kconfig=50=config QCOM_EMAC\n--\ndrivers/net/ethernet/qualcomm/Kconfig-62-\ndrivers/net/ethernet/qualcomm/Kconfig:63:config QCOM_PPE\ndrivers/net/ethernet/qualcomm/Kconfig-64-\ttristate \"Qualcomm PPE Ethernet support\"\n--\ndrivers/net/ethernet/qualcomm/Makefile=12=obj-y += emac/\ndrivers/net/ethernet/qualcomm/Makefile-13-\ndrivers/net/ethernet/qualcomm/Makefile:14:obj-$(CONFIG_QCOM_PPE) += ppe/\ndrivers/net/ethernet/qualcomm/Makefile-15-obj-$(CONFIG_RMNET) += rmnet/\n--\ndrivers/net/ethernet/qualcomm/ppe/Makefile-5-\ndrivers/net/ethernet/qualcomm/ppe/Makefile:6:obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o\ndrivers/net/ethernet/qualcomm/ppe/Makefile-7-qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o\n"
} |
| 5/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14204 output: 39 thoughts: 24 Thoughts: Here's a summary of my thought process, tailored for an expert like yourself: **Diving into the Qualcomm Ethernet Configuration** Okay, so I need to zero in on the Qualcomm ethernet driver configuration. My initial hunch is that something's amiss in the Kconfig. I'm thinking, "Let's start by checking `drivers/net/ethernet/qualcomm/Kconfig` around line 63. That's a reasonable spot to begin. Hopefully, I can find the answer quickly and don't need to dig deeper. I'll need to remember to check any dependencies if the configuration is conditional on anything." |
| 6/2 | 2026/10/05 15:45 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/qualcomm/Kconfig",
"FirstLine": 60,
"LineCount": 30
}Results: {
"Contents": " 60:\t\t low power, Receive-Side Scaling (RSS), and IEEE 1588-2008\n 61:\t\t Precision Clock Synchronization Protocol.\n 62:\t\n 63:\tconfig QCOM_PPE\n 64:\t\ttristate \"Qualcomm PPE Ethernet support\"\n 65:\t\tdepends on COMMON_CLK \u0026\u0026 HAS_IOMEM \u0026\u0026 OF\n 66:\t\tdepends on ARCH_QCOM || COMPILE_TEST\n 67:\t\tselect REGMAP_MMIO\n 68:\t\thelp\n 69:\t\t This driver supports the Qualcomm Technologies, Inc. packet\n 70:\t\t process engine (PPE) available with IPQ SoC. The PPE includes\n 71:\t\t the Ethernet MACs, Ethernet DMA (EDMA) and switch core that\n 72:\t\t supports L3 flow offload, L2 switch function, RSS and tunnel\n 73:\t\t offload.\n 74:\t\n 75:\t\t To compile this driver as a module, choose M here. The module\n 76:\t\t will be called qcom-ppe.\n 77:\t\n 78:\tsource \"drivers/net/ethernet/qualcomm/rmnet/Kconfig\"\n 79:\t\n 80:\tendif # NET_VENDOR_QUALCOMM\n"
} |
| 7/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14728 output: 43 thoughts: 754 Thoughts: **Analyzing the WorthFuzzing Status of a Qualcomm PPE Ethernet Driver** Okay, let's break this down. My initial thought is to check if this Qualcomm PPE Ethernet driver is even *reachable* in a standard fuzzing environment, specifically on my target architecture, amd64. The dependencies are clear: `COMMON_CLK`, `HAS_IOMEM`, and `OF`, and either `ARCH_QCOM` or `COMPILE_TEST`. This driver is for Qualcomm IPQ SoCs, like the IPQ9574 and IPQ5332, which are ARM-based networking chips. The immediate red flag is that my target is amd64. Even with `COMPILE_TEST`, can this thing even *probe* or run in QEMU or a typical virtualized setup? I need to go back and carefully reread the instructions. Specifically, Section 2 is crucial: when should I *not* fuzz? The negative criteria are clear. I need to ask myself: is this "structurally unreachable hardware"? This means vendor-specific PCIe switches, SmartNICs, or GPU drivers that need physical hardware not emulated by standard QEMU. Or, is it "Unreachable execution paths"? Alright, let's see. This *is* an SoC platform driver for Qualcomm IPQ SoCs, as confirmed by its OF compatible strings. My main question: can these platform devices, matching DeviceTree nodes for this specific Qualcomm SoC, even be instantiated on amd64 within standard QEMU? And I can see now, that the answer is *no*. There's no DeviceTree loaded with Qualcomm IPQ9574 or IPQ5332 PPE hardware on amd64. Can I get around this with, say, `of_platform` or a platform device created from userspace or debugfs/configfs? No, no chance. These platform devices that have specific OF match tables for SoC internal hardware blocks *cannot* probe without DeviceTree nodes or simulated platform devices, and the latter simply don't exist in my setup. Even configfs or mock platform devices can't help me here. VFIO and USB-gadget are the only examples which come to mind, but no for internal hardware blocks, no. Now, let's revisit the core principle: "REACHABILITY IS THE PRIMARY GATE." I can only discover bugs in *executable* code within standard virtualized environments. And, if the modified code is structurally unreachable, I should *not* fuzz it. This definitely seems to fall under "Code paths exclusive to architectures other than the target architecture," specifically because `ARCH_QCOM` is ARM/ARM64. The driver can’t even be *enabled* on amd64 unless `COMPILE_TEST` is used, and `COMPILE_TEST` is only for *compilation*. I'm still asking the question: is there any userspace interface or a way to reach this on amd64? So to be absolutely sure, I have to go through `drivers/net/ethernet/qualcomm/ppe/` completely and see if there is any other way to probe this. |
| 8/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "(probe|device_driver|module_platform)",
"PathPrefix": "drivers/net/ethernet/qualcomm/ppe/"
}Results: {
"Output": "drivers/net/ethernet/qualcomm/ppe/ppe.c-5-\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:6:/* PPE platform device probe, DTSI parser and PPE clock initializations. */\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-7-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c=155=static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-217-\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:218:static int qcom_ppe_probe(struct platform_device *pdev)\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-219-{\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-237-\tif (IS_ERR(base))\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:238:\t\treturn dev_err_probe(dev, PTR_ERR(base), \"PPE ioremap failed\\n\");\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-239-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-241-\tif (IS_ERR(ppe_dev-\u003eregmap))\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:242:\t\treturn dev_err_probe(dev, PTR_ERR(ppe_dev-\u003eregmap),\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-243-\t\t\t\t \"PPE initialize regmap failed\\n\");\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-250-\tif (ret)\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:251:\t\treturn dev_err_probe(dev, ret, \"PPE clock config failed\\n\");\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-252-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-254-\tif (ret)\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:255:\t\treturn dev_err_probe(dev, ret, \"PPE HW config failed\\n\");\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-256-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c=278=static struct platform_driver qcom_ppe_driver = {\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-282-\t},\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:283:\t.probe\t= qcom_ppe_probe,\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-284-\t.remove = qcom_ppe_remove,\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-285-};\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:286:module_platform_driver(qcom_ppe_driver);\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-287-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c=1575=static int ppe_config_bm(struct ppe_device *ppe_dev,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1584-\t * The buffer number of group 1-3 is already cleared to 0\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:1585:\t * after PPE reset during the probe of PPE driver.\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1586-\t */\n"
} |
| 9/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17149 output: 21 thoughts: 27 Thoughts: Okay, here's my summary, tailored for an expert audience, as if it were my thought process: **Diving into `ppe_config.c` Dependency Analysis** Alright, before I dive too deep into the weeds, let's take a strategic step back. I need a clear understanding of the call graph in `ppe_config.c`. Specifically, I want to identify all the functions that directly call `ppe_port_resource_get` or, for that matter, any other relevant function within that module that could potentially influence resource allocation or configuration. That’s the critical starting point to understanding its impact. I'll need to use some tools to do this efficiently, likely grepping for function calls. I also have to keep in mind, implicit calls through indirect pointers. I want to build a clear picture of its dependencies. |
| 10/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "ppe_port_resource_get"
}Results: {
"Output": "drivers/net/ethernet/qualcomm/ppe/ppe_config.c=1184=int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1199-/**\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:1200: * ppe_port_resource_get - Get PPE resource per port\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1201- * @ppe_dev: PPE device\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1210- */\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:1211:int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1212-\t\t\t enum ppe_resource_type type,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c=1867=static int ppe_queue_dest_init(struct ppe_device *ppe_dev)\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1874-\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:1875:\t\tret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_UCAST,\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1876-\t\t\t\t\t \u0026res_start, \u0026res_end);\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1891-\t\t/* Queue priority range supported by each PPE port */\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:1892:\t\tret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_L0_NODE,\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-1893-\t\t\t\t\t \u0026res_start, \u0026res_end);\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c=2056=static int ppe_queues_to_ring_init(struct ppe_device *ppe_dev)\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-2060-\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:2061:\tret = ppe_port_resource_get(ppe_dev, 0, PPE_RES_UCAST,\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-2062-\t\t\t\t \u0026queue_id, \u0026queue_max);\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h=335=int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h-338-\t\t\t\t int queue_offset);\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h:339:int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h-340-\t\t\t enum ppe_resource_type type,\n"
} |
| 11/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 18251 output: 20 thoughts: 75 Thoughts: Here's my analysis of that code snippet: **Deep Dive into `ppe_port_resource_get` Callers** Okay, so I need to understand the implications of `ppe_port_resource_get`. My first instinct is to trace its usage. From the text, it looks like `ppe_queue_dest_init` and `ppe_queues_to_ring_init` call it. And, I see these are part of `ppe_hw_config`, which itself is used during `qcom_ppe_probe`. Interesting. So it's used early during the device's initialization and hardware configuration. Makes sense. But to get a complete picture, I need to know *every* instance of `ppe_port_resource_get` being called. I'm going to run a full kernel-wide search to ensure I don't miss anything that could be related or, even worse, have different behavior. This will likely provide clues for the overall device behavior. |
| 12/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "qcom_ppe_probe"
}Results: {
"Output": "drivers/net/ethernet/qualcomm/ppe/ppe.c=155=static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev,\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-217-\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:218:static int qcom_ppe_probe(struct platform_device *pdev)\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-219-{\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c=278=static struct platform_driver qcom_ppe_driver = {\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-282-\t},\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:283:\t.probe\t= qcom_ppe_probe,\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-284-\t.remove = qcom_ppe_remove,\n"
} |
| 13/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 18821 output: 19 thoughts: 27 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience and presented in the first person: **Kernel Symbol Cross-Referencing - Deep Dive** Alright, so the first step in this investigation is to confirm the scope of this interaction. To avoid overlooking dependencies in the Linux kernel source, I need to do a thorough analysis of functions called within the `drivers/net/ethernet/qualcomm/ppe/` directory. I need to confirm which specific other parts of the kernel are also calling *into* this particular driver code. My goal here is to establish a complete picture of how the PPE driver integrates with the rest of the networking subsystem. This could be crucial to determining the impact of changes in one area to the functioning of another. I will be looking beyond basic direct calls, considering data structures, indirect calls through function pointers, and any subtle interactions, particularly within the network stack. I'll need to use my experience to recognize potential areas of concern that might not be immediately obvious in static analysis. |
| 14/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "ppe_config\\.h"
}Results: {
"Output": "Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst=149=The PPE driver files in drivers/net/ethernet/qualcomm/ppe/ are listed as below:\n--\nDocumentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst-154-- ppe_config.c\nDocumentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst:155:- ppe_config.h\nDocumentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst-156-- ppe_debugfs.c\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-18-#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:19:#include \"ppe_config.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-20-#include \"ppe_debugfs.h\"\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-16-#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:17:#include \"ppe_config.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-18-#include \"ppe_regs.h\"\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c-15-#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c:16:#include \"ppe_config.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c-17-#include \"ppe_debugfs.h\"\n"
} |
| 15/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 19503 output: 19 thoughts: 45 Thoughts: Here's my thought process, as if I were considering this code: **Checking Header File Dependencies in the PPE Module** Okay, so I'm looking at this `ppe_config.h` file. My initial thought is, where is it actually used? The text notes that `ppe_config.h` is only included by `ppe.c`, `ppe_config.c`, and `ppe_debugfs.c`. That's a limited scope, which is good for maintainability, but I need to make sure I have a complete picture. But, before I go deeper into those files, I need to know: what about `ppe.h`? Is that file also including `ppe_config.h`, or does it indirectly rely on it? I'll need to check the includes in `ppe.h` to see how everything is tied together. It's a key first step to understand the overall module dependency structure. |
| 16/2 | 2026/10/05 15:45 | tool | grepper |
0mArgs:{
"Expression": "\"ppe\\.h\""
}Results: {
"Output": "drivers/net/ethernet/qualcomm/ppe/ppe.c-17-\ndrivers/net/ethernet/qualcomm/ppe/ppe.c:18:#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe.c-19-#include \"ppe_config.h\"\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-15-\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c:16:#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.c-17-#include \"ppe_config.h\"\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h-10-\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h:11:#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_config.h-12-\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c-14-\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c:15:#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c-16-#include \"ppe_config.h\"\n--\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h-10-\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h:11:#include \"ppe.h\"\ndrivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h-12-\n"
} |
| 17/2 | 2026/10/05 15:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 20171 output: 114 thoughts: 1049 Thoughts: **Analysis of Qualcomm PPE Driver Patch for Fuzzing Suitability** Okay, so I'm looking at this patch and immediately see it's all contained within `drivers/net/ethernet/qualcomm/ppe/`. That's the Qualcomm Packet Process Engine driver. It's a platform driver specifically for Qualcomm IPQ5332 and IPQ9574 SoCs. The compatible strings are "qcom,ipq5332-ppe" and "qcom,ipq9574-ppe" - both Qualcomm IPQ SoCs, which are networking SoCs based on ARM/ARM64. Our target architecture for fuzzing is `amd64`. Now, according to the criteria in Section 2, we need to determine if we should set `WorthFuzzing=false`. The relevant criteria here is "Code paths exclusive to architectures other than the target architecture" and "Structurally unreachable hardware". The IPQ5332 and IPQ9574 are ARM/ARM64 SoCs. Specifically, the IPQ9574 is quad-core ARM Cortex-A73 and IPQ5332 is quad-core ARM Cortex-A53. On amd64, `ARCH_QCOM` is not defined in Kconfig. Even if `COMPILE_TEST` is enabled, this is a platform driver. It *binds* to specific OF compatible strings. Since there are no Qualcomm IPQ SoCs in a standard amd64 QEMU or GCE environment, the relevant platform devices are *never* created or probed. Therefore, the code is structurally unreachable on amd64 because: 1) It requires vendor-specific SoC hardware / physical SoC that is not emulated in standard QEMU. 2) The code paths are exclusive to architectures other than the target architecture. The patch itself touches documentation and the driver code. Specifically: * Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml * Documentation/networking/device\_drivers/ethernet/qualcomm/ppe/ppe.rst * drivers/net/ethernet/qualcomm/ppe/ppe.c * drivers/net/ethernet/qualcomm/ppe/ppe_config.c * drivers/net/ethernet/qualcomm/ppe/ppe_config.h This means it is just documentation and SoC-specific platform driver code for the Qualcomm IPQ5332 / IPQ9574 PPE. On amd64, none of this code can be executed or probed. Therefore, the verdict is `WorthFuzzing: false`, `EnableConfigs: []`, `FocusSymbols: []`. The patch adds support for the Qualcomm IPQ5332 SoC to the Qualcomm PPE (Packet Process Engine) Ethernet driver (`drivers/net/ethernet/qualcomm/ppe/`), along with corresponding Device Tree documentation. The modified code is part of a platform driver specifically for Qualcomm IPQ SoCs (`ARCH_QCOM`, ARM/ARM64) matching device tree compatibles `qcom,ipq5332-ppe` and `qcom,ipq9574-ppe`. On the target architecture (`amd64`), this SoC hardware is not present and cannot be probed or emulated in standard virtualized environments (QEMU/GCE), making the modified code structurally unreachable. We're good. Let's call `set-results`. |
| 18/2 | 2026/10/05 15:46 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch adds support for the Qualcomm IPQ5332 SoC to the Qualcomm PPE (Packet Process Engine) Ethernet driver and its Device Tree bindings. This is a platform driver for Qualcomm ARM-based IPQ SoCs (ARCH_QCOM) requiring specific SoC hardware that is not emulated in standard QEMU/GCE virtualized environments and is structurally unreachable on the amd64 target architecture.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds support for the Qualcomm IPQ5332 SoC to the Qualcomm PPE (Packet Process Engine) Ethernet driver and its Device Tree bindings. This is a platform driver for Qualcomm ARM-based IPQ SoCs (ARCH_QCOM) requiring specific SoC hardware that is not emulated in standard QEMU/GCE virtualized environments and is structurally unreachable on the amd64 target architecture.",
"WorthFuzzing": false
} |
| 19/1 | 2026/10/05 15:46 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|