AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/09/02 05:10 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch series adds support for Rockchip RK3568 Synopsys DesignWare Ethernet Physical Coding Sublayer (XPCS) and SGMII interface configuration for the Rockchip DWMAC driver, along with minor PCS init/exit handling updates for Intel DWMAC PCI and other SoC glue drivers (Renesas, Socfpga). These changes are restricted to vendor-specific SoC platform drivers (Rockchip RK3568, Renesas, Socfpga) and Intel DWMAC PCI hardware, none of which are emulated in standard QEMU or virtualized cloud environments like GCE. Therefore, the modified code cannot be executed during virtualized fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/09/02 05:10 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit f46a8f4c9952961b7f8f96af8f2f4461a8f95972\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Sep 2 05:10:11 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml b/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml\nnew file mode 100644\nindex 0000000000000..0852d0bcb66a2\n--- /dev/null\n+++ b/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml\n@@ -0,0 +1,110 @@\n+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)\n+%YAML 1.2\n+---\n+$id: http://devicetree.org/schemas/net/pcs/rockchip-dwxpcs.yaml#\n+$schema: http://devicetree.org/meta-schemas/core.yaml#\n+\n+title: Rockchip RK3568 Synopsys DesignWare Ethernet PCS\n+\n+maintainers:\n+  - Coia Prant \u003ccoiaprant@gmail.com\u003e\n+\n+description: |\n+  Rockchip RK3568 SoC integrates a Synopsys DesignWare Ethernet Physical\n+  Coding Sublayer (XPCS).\n+  The PCS provides an interface between the Media Access Control (MAC)\n+  and the Physical Medium Attachment (PMA) sublayer through a Media\n+  Independent Interface (GMII).\n+\n+  The XPCS is accessed over the APB3 bus and internally connected to a\n+  Naneng Combo SerDes PHY.\n+  It supports 1000BASE-X, SGMII and QSGMII modes.\n+\n+  The block contains four MII ports that can be individually enabled and\n+  routed to one of the Ethernet GMAC controllers via the pcs-handle\n+  property in the MAC device tree node.\n+\n+properties:\n+  compatible:\n+    const: rockchip,rk3568-xpcs\n+\n+  reg:\n+    maxItems: 1\n+\n+  \"#address-cells\":\n+    const: 1\n+\n+  \"#size-cells\":\n+    const: 0\n+\n+  clocks:\n+    items:\n+      - description: APB3 bus interface clock (clk_csr_i), required for register access\n+      - description: EEE clock (clk_eee_i), required for Energy Efficient Ethernet operation\n+\n+  clock-names:\n+    items:\n+      - const: csr\n+      - const: eee\n+\n+  phys:\n+    maxItems: 1\n+\n+  phy-names:\n+    const: serdes\n+\n+  power-domains:\n+    maxItems: 1\n+\n+patternProperties:\n+  \"^pcs-mii@[0-3]$\":\n+    type: object\n+    description:\n+      One of the four MII ports of the XPCS. The port is linked to an\n+      Ethernet MAC controller via the pcs-handle property in the MAC's\n+      device tree node.\n+\n+    properties:\n+      reg:\n+        description: MII port number.\n+        enum: [0, 1, 2, 3]\n+\n+    required:\n+      - reg\n+\n+    additionalProperties: false\n+\n+required:\n+  - compatible\n+  - reg\n+  - \"#address-cells\"\n+  - \"#size-cells\"\n+  - clocks\n+  - clock-names\n+  - phys\n+  - phy-names\n+  - power-domains\n+\n+additionalProperties: false\n+\n+examples:\n+  - |\n+    #include \u003cdt-bindings/clock/rk3568-cru.h\u003e\n+    #include \u003cdt-bindings/power/rk3568-power.h\u003e\n+    #include \u003cdt-bindings/phy/phy.h\u003e\n+\n+    pcs@fda00000 {\n+      compatible = \"rockchip,rk3568-xpcs\";\n+      reg = \u003c0xfda00000 0x200000\u003e;\n+      #address-cells = \u003c1\u003e;\n+      #size-cells = \u003c0\u003e;\n+      clocks = \u003c\u0026cru PCLK_XPCS\u003e, \u003c\u0026cru CLK_XPCS_EEE\u003e;\n+      clock-names = \"csr\", \"eee\";\n+      phys = \u003c\u0026combphy2 PHY_TYPE_SGMII\u003e;\n+      phy-names = \"serdes\";\n+      power-domains = \u003c\u0026power RK3568_PD_PIPE\u003e;\n+\n+      pcs-mii@0 {\n+        reg = \u003c0\u003e;\n+      };\n+    };\ndiff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml\nindex 379b08bd9e97a..8e898bce9af73 100644\n--- a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml\n+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml\n@@ -80,6 +80,15 @@ properties:\n     description:\n       Some additional pipe settings are accessed through GRF regs.\n \n+  rockchip,sgmii-mac-sel:\n+    $ref: /schemas/types.yaml#/definitions/uint32\n+    enum: [0, 1]\n+    default: 1\n+    description:\n+      Select gmac0 or gmac1 to be used as SGMII controller.\n+      The hardware reset value is GMAC1 (1). Set this to 0 to route\n+      SGMII to GMAC0.\n+\n   \"#phy-cells\":\n     const: 1\n \n@@ -105,6 +114,10 @@ allOf:\n           maxItems: 1\n         reset-names:\n           maxItems: 1\n+        rockchip,sgmii-mac-sel: true\n+    else:\n+      properties:\n+        rockchip,sgmii-mac-sel: false\n   - if:\n       properties:\n         compatible:\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 3a19da74d00c9..c3b17752cc817 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -23744,6 +23744,15 @@ S:\tMaintained\n F:\tDocumentation/devicetree/bindings/sound/rockchip,rk3576-sai.yaml\n F:\tsound/soc/rockchip/rockchip_sai.*\n \n+ROCKCHIP XPCS DRIVER\n+M:\tCoia Prant \u003ccoiaprant@gmail.com\u003e\n+L:\tnetdev@vger.kernel.org\n+L:\tlinux-rockchip@lists.infradead.org\n+S:\tMaintained\n+F:\tDocumentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml\n+F:\tdrivers/net/pcs/pcs-xpcs-rk.c\n+F:\tinclude/linux/pcs/pcs-xpcs-rk.h\n+\n ROCKER DRIVER\n M:\tJiri Pirko \u003cjiri@resnulli.us\u003e\n L:\tnetdev@vger.kernel.org\ndiff --git a/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts b/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts\nindex 58c1052ba8ef3..25caa44198843 100644\n--- a/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts\n+++ b/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts\n@@ -3,6 +3,7 @@\n /dts-v1/;\n \n #include \u003cdt-bindings/gpio/gpio.h\u003e\n+#include \u003cdt-bindings/leds/common.h\u003e\n #include \u003cdt-bindings/pinctrl/rockchip.h\u003e\n #include \u003cdt-bindings/soc/rockchip,vop2.h\u003e\n #include \"rk3568.dtsi\"\n@@ -242,6 +243,7 @@ \u0026combphy1 {\n \n \u0026combphy2 {\n \tstatus = \"okay\";\n+\trockchip,sgmii-mac-sel = \u003c0\u003e;\n };\n \n \u0026cpu0 {\n@@ -260,9 +262,18 @@ \u0026cpu3 {\n \tcpu-supply = \u003c\u0026vdd_cpu\u003e;\n };\n \n-/* Motorcomm YT8521SC LAN port (require SGMII) */\n+/* Motorcomm YT8521SC LAN port */\n \u0026gmac0 {\n-\tstatus = \"disabled\";\n+\tassigned-clocks = \u003c\u0026cru SCLK_GMAC0_RX_TX\u003e;\n+\tassigned-clock-parents = \u003c\u0026xpcs_gmac0_clk\u003e;\n+\tpcs-handle = \u003c\u0026xpcs_mii0\u003e;\n+\tmanaged = \"in-band-status\";\n+\tphy-handle = \u003c\u0026sgmii_phy\u003e;\n+\tphy-mode = \"sgmii\";\n+\tphy-supply = \u003c\u0026vcc_3v3\u003e;\n+\tpinctrl-names = \"default\";\n+\tpinctrl-0 = \u003c\u0026gmac0_miim\u003e;\n+\tstatus = \"okay\";\n };\n \n /* Motorcomm YT8521SC WAN port */\n@@ -341,6 +352,36 @@ \u0026i2s0_8ch {\n \tstatus = \"okay\";\n };\n \n+\u0026mdio0 {\n+\tsgmii_phy: ethernet-phy@3 {\n+\t\tcompatible = \"ethernet-phy-ieee802.3-c22\";\n+\t\treg = \u003c0x3\u003e;\n+\t\tmax-speed = \u003c1000\u003e;\n+\t\treset-assert-us = \u003c20000\u003e;\n+\t\treset-deassert-us = \u003c100000\u003e;\n+\t\treset-gpios = \u003c\u0026gpio3 RK_PC6 GPIO_ACTIVE_LOW\u003e;\n+\n+\t\tleds {\n+\t\t\t#address-cells = \u003c1\u003e;\n+\t\t\t#size-cells = \u003c0\u003e;\n+\n+\t\t\tled@1 {\n+\t\t\t\treg = \u003c1\u003e;\n+\t\t\t\tcolor = \u003cLED_COLOR_ID_AMBER\u003e;\n+\t\t\t\tfunction = LED_FUNCTION_LAN;\n+\t\t\t\tdefault-state = \"keep\";\n+\t\t\t};\n+\n+\t\t\tled@2 {\n+\t\t\t\treg = \u003c2\u003e;\n+\t\t\t\tcolor = \u003cLED_COLOR_ID_GREEN\u003e;\n+\t\t\t\tfunction = LED_FUNCTION_LAN;\n+\t\t\t\tdefault-state = \"keep\";\n+\t\t\t};\n+\t\t};\n+\t};\n+};\n+\n \u0026mdio1 {\n \trgmii_phy: ethernet-phy@3 {\n \t\tcompatible = \"ethernet-phy-ieee802.3-c22\";\n@@ -350,6 +391,25 @@ rgmii_phy: ethernet-phy@3 {\n \t\treset-gpios = \u003c\u0026gpio4 RK_PC0 GPIO_ACTIVE_LOW\u003e;\n \t\trx-internal-delay-ps = \u003c1500\u003e;\n \t\ttx-internal-delay-ps = \u003c1500\u003e;\n+\n+\t\tleds {\n+\t\t\t#address-cells = \u003c1\u003e;\n+\t\t\t#size-cells = \u003c0\u003e;\n+\n+\t\t\tled@1 {\n+\t\t\t\treg = \u003c1\u003e;\n+\t\t\t\tcolor = \u003cLED_COLOR_ID_AMBER\u003e;\n+\t\t\t\tfunction = LED_FUNCTION_WAN;\n+\t\t\t\tdefault-state = \"keep\";\n+\t\t\t};\n+\n+\t\t\tled@2 {\n+\t\t\t\treg = \u003c2\u003e;\n+\t\t\t\tcolor = \u003cLED_COLOR_ID_GREEN\u003e;\n+\t\t\t\tfunction = LED_FUNCTION_WAN;\n+\t\t\t\tdefault-state = \"keep\";\n+\t\t\t};\n+\t\t};\n \t};\n };\n \n@@ -586,3 +646,13 @@ \u0026xin32k {\n \tpinctrl-names = \"default\";\n \tpinctrl-0 = \u003c\u0026clk32k_out1\u003e;\n };\n+\n+\u0026xpcs {\n+\tstatus = \"okay\";\n+\tphys = \u003c\u0026combphy2 PHY_TYPE_SGMII\u003e;\n+\tphy-names = \"serdes\";\n+};\n+\n+\u0026xpcs_mii0 {\n+\tstatus = \"okay\";\n+};\ndiff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi\nindex 3bc653f027f1f..989e164c0eb39 100644\n--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi\n+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi\n@@ -110,6 +110,51 @@ sata0: sata@fc000000 {\n \t\tstatus = \"disabled\";\n \t};\n \n+\txpcs: pcs@fda00000 {\n+\t\tcompatible = \"rockchip,rk3568-xpcs\";\n+\t\t#address-cells = \u003c1\u003e;\n+\t\t#size-cells = \u003c0\u003e;\n+\t\treg = \u003c0x0 0xfda00000 0x0 0x200000\u003e;\n+\t\tclocks = \u003c\u0026cru PCLK_XPCS\u003e, \u003c\u0026cru CLK_XPCS_EEE\u003e;\n+\t\tclock-names = \"csr\", \"eee\";\n+\t\tpower-domains = \u003c\u0026power RK3568_PD_PIPE\u003e;\n+\t\tstatus = \"disabled\";\n+\n+\t\txpcs_mii0: pcs-mii@0 {\n+\t\t\treg = \u003c0\u003e;\n+\t\t\tstatus = \"disabled\";\n+\t\t};\n+\n+\t\txpcs_mii1: pcs-mii@1 {\n+\t\t\treg = \u003c1\u003e;\n+\t\t\tstatus = \"disabled\";\n+\t\t};\n+\n+\t\txpcs_mii2: pcs-mii@2 {\n+\t\t\treg = \u003c2\u003e;\n+\t\t\tstatus = \"disabled\";\n+\t\t};\n+\n+\t\txpcs_mii3: pcs-mii@3 {\n+\t\t\treg = \u003c3\u003e;\n+\t\t\tstatus = \"disabled\";\n+\t\t};\n+\t};\n+\n+\txpcs_gmac0_clk: xpcs-gmac0-clock {\n+\t\tcompatible = \"fixed-clock\";\n+\t\tclock-frequency = \u003c125000000\u003e;\n+\t\tclock-output-names = \"clk_gmac0_xpcs_mii\";\n+\t\t#clock-cells = \u003c0\u003e;\n+\t};\n+\n+\txpcs_gmac1_clk: xpcs-gmac1-clock {\n+\t\tcompatible = \"fixed-clock\";\n+\t\tclock-frequency = \u003c125000000\u003e;\n+\t\tclock-output-names = \"clk_gmac1_xpcs_mii\";\n+\t\t#clock-cells = \u003c0\u003e;\n+\t};\n+\n \tpipe_phy_grf0: syscon@fdc70000 {\n \t\tcompatible = \"rockchip,rk3568-pipe-phy-grf\", \"syscon\";\n \t\treg = \u003c0x0 0xfdc70000 0x0 0x1000\u003e;\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig\nindex e3dd5adda5aca..5088acc06982e 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig\n+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig\n@@ -170,6 +170,7 @@ config DWMAC_ROCKCHIP\n \tdefault ARCH_ROCKCHIP\n \tdepends on OF \u0026\u0026 (ARCH_ROCKCHIP || COMPILE_TEST)\n \tselect MFD_SYSCON\n+\tselect PCS_XPCS_ROCKCHIP\n \thelp\n \t  Support for Ethernet controller on Rockchip RK3288 SoC.\n \ndiff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c\nindex f5f9fa67ecd77..fd5f01c8941c1 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c\n@@ -603,13 +603,47 @@ static void common_default_data(struct plat_stmmacenet_data *plat)\n \tplat-\u003emdio_bus_data-\u003eneeds_reset = true;\n }\n \n+static int intel_mgbe_pcs_init(struct stmmac_priv *priv)\n+{\n+\tstruct fwnode_handle *devnode, *pcsnode;\n+\tstruct dw_xpcs *xpcs = NULL;\n+\tint addr;\n+\n+\tdevnode = dev_fwnode(priv-\u003edevice);\n+\n+\tif (fwnode_property_present(devnode, \"pcs-handle\")) {\n+\t\tpcsnode = fwnode_find_reference(devnode, \"pcs-handle\", 0);\n+\t\txpcs = xpcs_create_fwnode(pcsnode);\n+\t\tfwnode_handle_put(pcsnode);\n+\t} else {\n+\t\taddr = ffs(priv-\u003eplat-\u003emdio_bus_data-\u003epcs_mask) - 1;\n+\t\txpcs = xpcs_create_mdiodev(priv-\u003emii, addr);\n+\t}\n+\n+\tif (IS_ERR(xpcs))\n+\t\treturn PTR_ERR(xpcs);\n+\n+\txpcs_config_eee_mult_fact(xpcs, priv-\u003eplat-\u003emult_fact_100ns);\n+\n+\tpriv-\u003ehw-\u003expcs = xpcs;\n+\treturn 0;\n+}\n+\n+static void intel_mgbe_pcs_exit(struct stmmac_priv *priv)\n+{\n+\tif (!priv-\u003ehw-\u003expcs)\n+\t\treturn;\n+\n+\txpcs_destroy(priv-\u003ehw-\u003expcs);\n+\tpriv-\u003ehw-\u003expcs = NULL;\n+}\n+\n static struct phylink_pcs *intel_mgbe_select_pcs(struct stmmac_priv *priv,\n \t\t\t\t\t\t phy_interface_t interface)\n {\n-\t/* plat-\u003emdio_bus_data-\u003ehas_xpcs has been set true, so there\n-\t * should always be an XPCS. The original code would always\n-\t * return this if present.\n-\t */\n+\tif (!priv-\u003ehw-\u003expcs)\n+\t\treturn NULL;\n+\n \treturn xpcs_to_phylink_pcs(priv-\u003ehw-\u003expcs);\n }\n \n@@ -733,6 +767,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,\n \t    plat-\u003ephy_interface == PHY_INTERFACE_MODE_1000BASEX) {\n \t\tplat-\u003emdio_bus_data-\u003epcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR);\n \t\tplat-\u003edefault_an_inband = true;\n+\t\tplat-\u003epcs_init = intel_mgbe_pcs_init;\n+\t\tplat-\u003epcs_exit = intel_mgbe_pcs_exit;\n \t\tplat-\u003eselect_pcs = intel_mgbe_select_pcs;\n \t}\n \ndiff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c\nindex 19f34e18bfef2..9af32c26f9c14 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c\n@@ -81,8 +81,11 @@ static int renesas_gmac_pcs_init(struct stmmac_priv *priv)\n \n static void renesas_gmac_pcs_exit(struct stmmac_priv *priv)\n {\n-\tif (priv-\u003ehw-\u003ephylink_pcs)\n-\t\tmiic_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tif (!priv-\u003ehw-\u003ephylink_pcs)\n+\t\treturn;\n+\n+\tmiic_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tpriv-\u003ehw-\u003ephylink_pcs = NULL;\n }\n \n static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv,\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c\nindex 8d7042e689261..e47ca1bec5b8b 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c\n@@ -20,6 +20,7 @@\n #include \u003clinux/delay.h\u003e\n #include \u003clinux/mfd/syscon.h\u003e\n #include \u003clinux/regmap.h\u003e\n+#include \u003clinux/pcs/pcs-xpcs-rk.h\u003e\n #include \u003clinux/pm_runtime.h\u003e\n \n #include \"stmmac_platform.h\"\n@@ -47,6 +48,7 @@ struct rk_gmac_ops {\n \tvoid (*set_to_rgmii)(struct rk_priv_data *bsp_priv,\n \t\t\t     int tx_delay, int rx_delay);\n \tvoid (*set_to_rmii)(struct rk_priv_data *bsp_priv);\n+\tvoid (*set_to_sgmii)(struct rk_priv_data *bsp_priv);\n \tint (*set_speed)(struct rk_priv_data *bsp_priv,\n \t\t\t phy_interface_t interface, int speed);\n \tvoid (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);\n@@ -63,6 +65,7 @@ struct rk_gmac_ops {\n \tbool clock_grf_reg_in_php;\n \tbool supports_rgmii;\n \tbool supports_rmii;\n+\tbool supports_sgmii;\n \tbool php_grf_required;\n \tbool regs_valid;\n \tu32 regs[];\n@@ -98,6 +101,7 @@ struct rk_priv_data {\n \tbool integrated_phy;\n \tbool supports_rgmii;\n \tbool supports_rmii;\n+\tbool supports_sgmii;\n \n \tstruct clk_bulk_data *clks;\n \tint num_clks;\n@@ -809,6 +813,8 @@ static const struct rk_gmac_ops rk3528_ops = {\n #define RK3568_GRF_GMAC1_CON1\t\t0x038c\n \n /* RK3568_GRF_GMAC0_CON1 \u0026\u0026 RK3568_GRF_GMAC1_CON1 */\n+#define RK3568_GMAC_MODE_RMII_RGMII\t\tGRF_CLR_BIT(7)\n+#define RK3568_GMAC_MODE_SGMII_QSGMII\t\tGRF_BIT(7)\n #define RK3568_GMAC_FLOW_CTRL\t\t\tGRF_BIT(3)\n #define RK3568_GMAC_FLOW_CTRL_CLR\t\tGRF_CLR_BIT(3)\n #define RK3568_GMAC_RXCLK_DLY_ENABLE\t\tGRF_BIT(1)\n@@ -851,18 +857,32 @@ static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,\n \t\t     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));\n \n \tregmap_write(bsp_priv-\u003egrf, con1,\n+\t\t     RK3568_GMAC_MODE_RMII_RGMII |\n \t\t     RK3568_GMAC_RXCLK_DLY_ENABLE |\n \t\t     RK3568_GMAC_TXCLK_DLY_ENABLE);\n }\n \n+static void rk3568_set_to_sgmii(struct rk_priv_data *bsp_priv)\n+{\n+\tu32 con1;\n+\n+\tcon1 = (bsp_priv-\u003eid == 1) ? RK3568_GRF_GMAC1_CON1 :\n+\t\t\t\t     RK3568_GRF_GMAC0_CON1;\n+\n+\tregmap_write(bsp_priv-\u003egrf, con1, RK3568_GMAC_MODE_SGMII_QSGMII);\n+}\n+\n static const struct rk_gmac_ops rk3568_ops = {\n \t.init = rk3568_init,\n \t.set_to_rgmii = rk3568_set_to_rgmii,\n+\t.set_to_sgmii = rk3568_set_to_sgmii,\n+\n \t.set_speed = rk_set_clk_mac_speed,\n \n \t.gmac_phy_intf_sel_mask = GENMASK_U16(6, 4),\n \n \t.supports_rmii = true,\n+\t.supports_sgmii = true,\n \n \t.regs_valid = true,\n \t.regs = {\n@@ -1208,6 +1228,43 @@ static void rk_phy_powerdown(struct rk_priv_data *bsp_priv)\n \t\tdev_err(bsp_priv-\u003edev, \"fail to disable phy-supply\\n\");\n }\n \n+static int rk_pcs_init(struct stmmac_priv *priv)\n+{\n+\tstruct device_node *np = priv-\u003edevice-\u003eof_node;\n+\tstruct device_node *pcs_node;\n+\tstruct dw_xpcs *xpcs;\n+\n+\tpcs_node = of_parse_phandle(np, \"pcs-handle\", 0);\n+\tif (!pcs_node)\n+\t\treturn -ENODEV;\n+\n+\txpcs = xpcs_rk_create(priv-\u003edevice, pcs_node);\n+\tof_node_put(pcs_node);\n+\tif (IS_ERR(xpcs))\n+\t\treturn PTR_ERR(xpcs);\n+\n+\tpriv-\u003ehw-\u003expcs = xpcs;\n+\treturn 0;\n+}\n+\n+static void rk_pcs_exit(struct stmmac_priv *priv)\n+{\n+\tif (!priv-\u003ehw-\u003expcs)\n+\t\treturn;\n+\n+\txpcs_destroy(priv-\u003ehw-\u003expcs);\n+\tpriv-\u003ehw-\u003expcs = NULL;\n+}\n+\n+static struct phylink_pcs *rk_select_pcs(struct stmmac_priv *priv,\n+\t\t\t\t\t phy_interface_t interface)\n+{\n+\tif (!priv-\u003ehw-\u003expcs)\n+\t\treturn NULL;\n+\n+\treturn xpcs_to_phylink_pcs(priv-\u003ehw-\u003expcs);\n+}\n+\n static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,\n \t\t\t\t\t  struct plat_stmmacenet_data *plat,\n \t\t\t\t\t  const struct rk_gmac_ops *ops)\n@@ -1330,6 +1387,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,\n \n \tbsp_priv-\u003esupports_rgmii = ops-\u003esupports_rgmii || !!ops-\u003eset_to_rgmii;\n \tbsp_priv-\u003esupports_rmii = ops-\u003esupports_rmii || !!ops-\u003eset_to_rmii;\n+\tbsp_priv-\u003esupports_sgmii = ops-\u003esupports_sgmii || !!ops-\u003eset_to_sgmii;\n \n \tif (ops-\u003einit) {\n \t\tret = ops-\u003einit(bsp_priv);\n@@ -1361,6 +1419,10 @@ static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)\n \t\tif (!bsp_priv-\u003esupports_rmii)\n \t\t\treturn -EINVAL;\n \t\tbreak;\n+\tcase PHY_INTERFACE_MODE_SGMII:\n+\t\tif (!bsp_priv-\u003esupports_sgmii)\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n \tdefault:\n \t\tdev_err(bsp_priv-\u003edev,\n \t\t\t\"unsupported interface %d\", bsp_priv-\u003ephy_iface);\n@@ -1379,16 +1441,19 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)\n \tif (ret)\n \t\treturn ret;\n \n+\tret = gmac_clk_enable(bsp_priv, true);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (bsp_priv-\u003ephy_iface == PHY_INTERFACE_MODE_SGMII)\n+\t\tgoto set_mode;\n+\n \tret = rk_get_phy_intf_sel(bsp_priv-\u003ephy_iface);\n \tif (ret \u003c 0)\n-\t\treturn ret;\n+\t\tgoto clk_disable;\n \n \tintf = ret;\n \n-\tret = gmac_clk_enable(bsp_priv, true);\n-\tif (ret)\n-\t\treturn ret;\n-\n \tif (bsp_priv-\u003egmac_phy_intf_sel_mask ||\n \t    bsp_priv-\u003egmac_rmii_mode_mask) {\n \t\t/* If defined, encode the phy_intf_sel value */\n@@ -1399,10 +1464,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)\n \t\t\t\t      bsp_priv-\u003egmac_rmii_mode_mask);\n \n \t\tret = rk_write_gmac_grf_reg(bsp_priv, val);\n-\t\tif (ret \u003c 0) {\n-\t\t\tgmac_clk_enable(bsp_priv, false);\n-\t\t\treturn ret;\n-\t\t}\n+\t\tif (ret \u003c 0)\n+\t\t\tgoto clk_disable;\n \t}\n \n \tif (bsp_priv-\u003eclock.rmii_mode_mask) {\n@@ -1410,13 +1473,12 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)\n \t\t\t\t     bsp_priv-\u003eclock.rmii_mode_mask);\n \n \t\tret = rk_write_clock_grf_reg(bsp_priv, val);\n-\t\tif (ret \u003c 0) {\n-\t\t\tgmac_clk_enable(bsp_priv, false);\n-\t\t\treturn ret;\n-\t\t}\n+\t\tif (ret \u003c 0)\n+\t\t\tgoto clk_disable;\n \t}\n \n-\t/*rmii or rgmii*/\n+set_mode:\n+\t/* rmii, rgmii, sgmii */\n \tswitch (bsp_priv-\u003ephy_iface) {\n \tcase PHY_INTERFACE_MODE_RGMII:\n \t\tdev_info(dev, \"init for RGMII\\n\");\n@@ -1447,15 +1509,20 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)\n \t\tif (bsp_priv-\u003eops-\u003eset_to_rmii)\n \t\t\tbsp_priv-\u003eops-\u003eset_to_rmii(bsp_priv);\n \t\tbreak;\n+\tcase PHY_INTERFACE_MODE_SGMII:\n+\t\tdev_info(dev, \"init for SGMII\\n\");\n+\t\tif (bsp_priv-\u003eops-\u003eset_to_sgmii)\n+\t\t\tbsp_priv-\u003eops-\u003eset_to_sgmii(bsp_priv);\n+\t\tbreak;\n \tdefault:\n \t\tdev_err(dev, \"NO interface defined!\\n\");\n+\t\tret = -EINVAL;\n+\t\tgoto clk_disable;\n \t}\n \n \tret = rk_phy_powerup(bsp_priv);\n-\tif (ret) {\n-\t\tgmac_clk_enable(bsp_priv, false);\n-\t\treturn ret;\n-\t}\n+\tif (ret)\n+\t\tgoto clk_disable;\n \n \tpm_runtime_get_sync(dev);\n \n@@ -1463,6 +1530,10 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)\n \t\tbsp_priv-\u003eops-\u003eintegrated_phy_powerup(bsp_priv);\n \n \treturn 0;\n+\n+clk_disable:\n+\tgmac_clk_enable(bsp_priv, false);\n+\treturn ret;\n }\n \n static void rk_gmac_powerdown(struct rk_priv_data *gmac)\n@@ -1486,6 +1557,9 @@ static void rk_get_interfaces(struct stmmac_priv *priv, void *bsp_priv,\n \n \tif (rk-\u003esupports_rmii)\n \t\t__set_bit(PHY_INTERFACE_MODE_RMII, interfaces);\n+\n+\tif (rk-\u003esupports_sgmii)\n+\t\t__set_bit(PHY_INTERFACE_MODE_SGMII, interfaces);\n }\n \n static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i,\n@@ -1602,6 +1676,17 @@ static int rk_gmac_probe(struct platform_device *pdev)\n \tplat_dat-\u003esuspend = rk_gmac_suspend;\n \tplat_dat-\u003eresume = rk_gmac_resume;\n \n+\tif (plat_dat-\u003ephy_interface == PHY_INTERFACE_MODE_SGMII) {\n+\t\t/* SGMII clock always runs at 125 MHz */\n+\t\tplat_dat-\u003eset_clk_tx_rate = NULL;\n+\n+\t\t/* SGMII requires a PCS */\n+\t\tplat_dat-\u003edefault_an_inband = true;\n+\t\tplat_dat-\u003epcs_init = rk_pcs_init;\n+\t\tplat_dat-\u003epcs_exit = rk_pcs_exit;\n+\t\tplat_dat-\u003eselect_pcs = rk_select_pcs;\n+\t}\n+\n \tplat_dat-\u003ebsp_priv = rk_gmac_setup(pdev, plat_dat, data);\n \tif (IS_ERR(plat_dat-\u003ebsp_priv))\n \t\treturn PTR_ERR(plat_dat-\u003ebsp_priv);\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c\nindex 13634965bc19a..01df4776edb3f 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c\n@@ -35,8 +35,11 @@ static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv)\n \n static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv)\n {\n-\tif (priv-\u003ehw-\u003ephylink_pcs)\n-\t\tmiic_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tif (!priv-\u003ehw-\u003ephylink_pcs)\n+\t\treturn;\n+\n+\tmiic_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tpriv-\u003ehw-\u003ephylink_pcs = NULL;\n }\n \n static struct phylink_pcs *rzn1_dwmac_select_pcs(struct stmmac_priv *priv,\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c\nindex 1d7f0a57d2889..6d4bc1fe8f751 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c\n@@ -539,8 +539,11 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)\n \n static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv)\n {\n-\tif (priv-\u003ehw-\u003ephylink_pcs)\n-\t\tlynx_pcs_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tif (!priv-\u003ehw-\u003ephylink_pcs)\n+\t\treturn;\n+\n+\tlynx_pcs_destroy(priv-\u003ehw-\u003ephylink_pcs);\n+\tpriv-\u003ehw-\u003ephylink_pcs = NULL;\n }\n \n static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv,\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c\nindex afe98ff5bdcb0..d2f77f0c223a7 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c\n@@ -426,36 +426,15 @@ int stmmac_mdio_reset(struct mii_bus *bus)\n int stmmac_pcs_setup(struct net_device *ndev)\n {\n \tstruct stmmac_priv *priv = netdev_priv(ndev);\n-\tstruct fwnode_handle *devnode, *pcsnode;\n-\tstruct dw_xpcs *xpcs = NULL;\n-\tint addr, ret;\n-\n-\tdevnode = dev_fwnode(priv-\u003edevice);\n-\n-\tif (priv-\u003eplat-\u003epcs_init) {\n-\t\tret = priv-\u003eplat-\u003epcs_init(priv);\n-\t} else if (fwnode_property_present(devnode, \"pcs-handle\")) {\n-\t\tpcsnode = fwnode_find_reference(devnode, \"pcs-handle\", 0);\n-\t\txpcs = xpcs_create_fwnode(pcsnode);\n-\t\tfwnode_handle_put(pcsnode);\n-\t\tret = PTR_ERR_OR_ZERO(xpcs);\n-\t} else if (priv-\u003eplat-\u003emdio_bus_data \u0026\u0026\n-\t\t   priv-\u003eplat-\u003emdio_bus_data-\u003epcs_mask) {\n-\t\taddr = ffs(priv-\u003eplat-\u003emdio_bus_data-\u003epcs_mask) - 1;\n-\t\txpcs = xpcs_create_mdiodev(priv-\u003emii, addr);\n-\t\tret = PTR_ERR_OR_ZERO(xpcs);\n-\t} else {\n+\tint ret;\n+\n+\tif (!priv-\u003eplat-\u003epcs_init)\n \t\treturn 0;\n-\t}\n \n+\tret = priv-\u003eplat-\u003epcs_init(priv);\n \tif (ret)\n \t\treturn dev_err_probe(priv-\u003edevice, ret, \"No xPCS found\\n\");\n \n-\tif (xpcs)\n-\t\txpcs_config_eee_mult_fact(xpcs, priv-\u003eplat-\u003emult_fact_100ns);\n-\n-\tpriv-\u003ehw-\u003expcs = xpcs;\n-\n \treturn 0;\n }\n \n@@ -463,14 +442,10 @@ void stmmac_pcs_clean(struct net_device *ndev)\n {\n \tstruct stmmac_priv *priv = netdev_priv(ndev);\n \n-\tif (priv-\u003eplat-\u003epcs_exit)\n-\t\tpriv-\u003eplat-\u003epcs_exit(priv);\n-\n-\tif (!priv-\u003ehw-\u003expcs)\n+\tif (!priv-\u003eplat-\u003epcs_exit)\n \t\treturn;\n \n-\txpcs_destroy(priv-\u003ehw-\u003expcs);\n-\tpriv-\u003ehw-\u003expcs = NULL;\n+\tpriv-\u003eplat-\u003epcs_exit(priv);\n }\n \n struct stmmac_clk_rate {\ndiff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig\nindex e417fd66f660a..88bc40791e69f 100644\n--- a/drivers/net/pcs/Kconfig\n+++ b/drivers/net/pcs/Kconfig\n@@ -12,6 +12,29 @@ config PCS_XPCS\n \t  This module provides a driver and helper functions for Synopsys\n \t  DesignWare XPCS controllers.\n \n+if PCS_XPCS\n+\n+config PCS_XPCS_PLATFORM\n+\ttristate \"Generic XPCS controller support\"\n+\tdefault PCS_XPCS\n+\thelp\n+\t  Generic DWXPCS driver for platforms that don't require any\n+\t  platform specific code to function or is using platform\n+\t  data for setup.\n+\n+\t  If you have a controller with this interface, say Y or M here.\n+\n+config PCS_XPCS_ROCKCHIP\n+\ttristate \"Rockchip XPCS controller support\"\n+\tdefault ARCH_ROCKCHIP\n+\tdepends on OF \u0026\u0026 (ARCH_ROCKCHIP || COMPILE_TEST)\n+\thelp\n+\t  Support for XPCS controller on Rockchip RK356x SoC.\n+\n+\t  If you have a Rockchip SoC with this interface, say Y or M here.\n+\n+endif # PCS_XPCS\n+\n config PCS_LYNX\n \ttristate\n \thelp\ndiff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile\nindex 4f7920618b900..c809b7f942a51 100644\n--- a/drivers/net/pcs/Makefile\n+++ b/drivers/net/pcs/Makefile\n@@ -1,10 +1,9 @@\n # SPDX-License-Identifier: GPL-2.0\n # Makefile for Linux PCS drivers\n \n-pcs_xpcs-$(CONFIG_PCS_XPCS)\t:= pcs-xpcs.o pcs-xpcs-plat.o \\\n-\t\t\t\t   pcs-xpcs-nxp.o pcs-xpcs-wx.o\n-\n-obj-$(CONFIG_PCS_XPCS)\t\t+= pcs_xpcs.o\n+obj-$(CONFIG_PCS_XPCS) += pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o\n+obj-$(CONFIG_PCS_XPCS_PLATFORM) += pcs-xpcs-plat.o\n+obj-$(CONFIG_PCS_XPCS_ROCKCHIP) += pcs-xpcs-rk.o\n obj-$(CONFIG_PCS_LYNX)\t\t+= pcs-lynx.o\n obj-$(CONFIG_PCS_MTK_LYNXI)\t+= pcs-mtk-lynxi.o\n obj-$(CONFIG_PCS_RZN1_MIIC)\t+= pcs-rzn1-miic.o\ndiff --git a/drivers/net/pcs/pcs-xpcs-rk.c b/drivers/net/pcs/pcs-xpcs-rk.c\nnew file mode 100644\nindex 0000000000000..4ef20b093dada\n--- /dev/null\n+++ b/drivers/net/pcs/pcs-xpcs-rk.c\n@@ -0,0 +1,561 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Rockchip XPCS platform device driver\n+ *\n+ * Based on the Synopsys DesignWare XPCS platform driver.\n+ * Copyright (C) 2024 Serge Semin\n+ *\n+ * Adapted for Rockchip SoCs, with reference to the Rockchip OEM driver.\n+ * Copyright (C) 2026 Coia Prant\n+ */\n+\n+#include \u003clinux/atomic.h\u003e\n+#include \u003clinux/bitfield.h\u003e\n+#include \u003clinux/clk.h\u003e\n+#include \u003clinux/device.h\u003e\n+#include \u003clinux/io.h\u003e\n+#include \u003clinux/iopoll.h\u003e\n+#include \u003clinux/mdio.h\u003e\n+#include \u003clinux/module.h\u003e\n+#include \u003clinux/of.h\u003e\n+#include \u003clinux/of_platform.h\u003e\n+#include \u003clinux/pcs/pcs-xpcs-rk.h\u003e\n+#include \u003clinux/phy.h\u003e\n+#include \u003clinux/phy/phy.h\u003e\n+#include \u003clinux/platform_device.h\u003e\n+#include \u003clinux/pm_domain.h\u003e\n+#include \u003clinux/pm_runtime.h\u003e\n+#include \u003clinux/property.h\u003e\n+#include \u003clinux/sizes.h\u003e\n+\n+#include \"pcs-xpcs.h\"\n+\n+struct dw_xpcs_rk {\n+\tstruct platform_device *pdev;\n+\tstruct mii_bus *bus;\n+\tvoid __iomem *reg_base;\n+\tstruct phy *serdes_phy;\n+\tstruct clk *csr_clk;\n+\tstruct clk *eee_clk;\n+};\n+\n+static ptrdiff_t xpcs_rk_addr_format(int dev, int reg)\n+{\n+\treturn FIELD_PREP(0x70000, dev) | FIELD_PREP(0xffff, reg);\n+}\n+\n+static int xpcs_rk_read_reg(struct dw_xpcs_rk *pxpcs, int dev, int reg)\n+{\n+\tptrdiff_t csr;\n+\tint ret;\n+\n+\tcsr = xpcs_rk_addr_format(dev, reg);\n+\n+\tret = pm_runtime_resume_and_get(\u0026pxpcs-\u003epdev-\u003edev);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = readl(pxpcs-\u003ereg_base + (csr \u003c\u003c 2)) \u0026 0xffff;\n+\n+\tpm_runtime_put(\u0026pxpcs-\u003epdev-\u003edev);\n+\treturn ret;\n+}\n+\n+static int xpcs_rk_write_reg(struct dw_xpcs_rk *pxpcs, int dev, int reg, u16 val)\n+{\n+\tptrdiff_t csr;\n+\tint ret;\n+\n+\tcsr = xpcs_rk_addr_format(dev, reg);\n+\n+\tret = pm_runtime_resume_and_get(\u0026pxpcs-\u003epdev-\u003edev);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\twritel(val, pxpcs-\u003ereg_base + (csr \u003c\u003c 2));\n+\n+\tpm_runtime_put(\u0026pxpcs-\u003epdev-\u003edev);\n+\treturn 0;\n+}\n+\n+#define ROCKCHIP_MMD_MII1\t2\n+#define ROCKCHIP_MMD_MII2\t3\n+#define ROCKCHIP_MMD_MII3\t4\n+#define ROCKCHIP_MMD_PMAPMD\t6\n+#define ROCKCHIP_MMD_MII\t7\n+\n+static bool xpcs_rk_mdio_addr_validate(int addr)\n+{\n+\treturn !(addr \u003c 0 || addr \u003e 3);\n+}\n+\n+static int xpcs_rk_mdio_read_remapping(int addr, int dev, int reg)\n+{\n+\tswitch (dev) {\n+\tcase MDIO_MMD_PMAPMD:\n+\t\treturn ROCKCHIP_MMD_PMAPMD;\n+\tcase MDIO_MMD_VEND2:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENXIO;\n+\t}\n+\n+\t/* read remapping to MII is performed by HW */\n+\tswitch (addr) {\n+\tcase 0:\n+\t\treturn ROCKCHIP_MMD_MII;\n+\tcase 1:\n+\t\treturn ROCKCHIP_MMD_MII1;\n+\tcase 2:\n+\t\treturn ROCKCHIP_MMD_MII2;\n+\tcase 3:\n+\t\treturn ROCKCHIP_MMD_MII3;\n+\tdefault:\n+\t\treturn -ENODEV;\n+\t}\n+}\n+\n+static int xpcs_rk_mdio_write_remapping(int addr, int dev, int reg)\n+{\n+\tswitch (dev) {\n+\tcase MDIO_MMD_PMAPMD:\n+\t\treturn ROCKCHIP_MMD_PMAPMD;\n+\tcase MDIO_MMD_VEND2:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENXIO;\n+\t}\n+\n+\t/* Writable only on MII */\n+\tswitch (reg) {\n+\tcase DW_VR_MII_AN_CTRL:\n+\tcase DW_VR_MII_AN_INTR_STS:\n+\tcase DW_VR_MII_EEE_MCTRL0:\n+\tcase DW_VR_MII_EEE_MCTRL1:\n+\tcase DW_VR_MII_DIG_CTRL2:\n+\t\treturn ROCKCHIP_MMD_MII;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tswitch (addr) {\n+\tcase 0:\n+\t\treturn ROCKCHIP_MMD_MII;\n+\tcase 1:\n+\t\treturn ROCKCHIP_MMD_MII1;\n+\tcase 2:\n+\t\treturn ROCKCHIP_MMD_MII2;\n+\tcase 3:\n+\t\treturn ROCKCHIP_MMD_MII3;\n+\tdefault:\n+\t\treturn -ENODEV;\n+\t}\n+}\n+\n+static int xpcs_rk_read_c22(struct mii_bus *bus, int addr, int reg)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = bus-\u003epriv;\n+\tint dev;\n+\n+\tif (!xpcs_rk_mdio_addr_validate(addr))\n+\t\treturn -ENODEV;\n+\n+\tdev = xpcs_rk_mdio_read_remapping(addr, MDIO_MMD_VEND2, reg);\n+\tif (dev \u003c 0)\n+\t\treturn 0xffff;\n+\n+\treturn xpcs_rk_read_reg(pxpcs, dev, reg);\n+}\n+\n+static int xpcs_rk_write_c22(struct mii_bus *bus, int addr, int reg, u16 val)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = bus-\u003epriv;\n+\tint dev;\n+\n+\tif (!xpcs_rk_mdio_addr_validate(addr))\n+\t\treturn -ENODEV;\n+\n+\tdev = xpcs_rk_mdio_write_remapping(addr, MDIO_MMD_VEND2, reg);\n+\tif (dev \u003c 0)\n+\t\treturn 0;\n+\n+\treturn xpcs_rk_write_reg(pxpcs, dev, reg, val);\n+}\n+\n+static int xpcs_rk_read_c45(struct mii_bus *bus, int addr, int dev, int reg)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = bus-\u003epriv;\n+\n+\tif (!xpcs_rk_mdio_addr_validate(addr))\n+\t\treturn -ENODEV;\n+\n+\tdev = xpcs_rk_mdio_read_remapping(addr, dev, reg);\n+\tif (dev \u003c 0)\n+\t\treturn 0xffff;\n+\n+\treturn xpcs_rk_read_reg(pxpcs, dev, reg);\n+}\n+\n+static int xpcs_rk_write_c45(struct mii_bus *bus, int addr, int dev, int reg, u16 val)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = bus-\u003epriv;\n+\n+\tif (!xpcs_rk_mdio_addr_validate(addr))\n+\t\treturn -ENODEV;\n+\n+\tdev = xpcs_rk_mdio_write_remapping(addr, dev, reg);\n+\tif (dev \u003c 0)\n+\t\treturn 0;\n+\n+\treturn xpcs_rk_write_reg(pxpcs, dev, reg, val);\n+}\n+\n+static struct dw_xpcs_rk *xpcs_rk_create_data(struct platform_device *pdev)\n+{\n+\tstruct dw_xpcs_rk *pxpcs;\n+\n+\tpxpcs = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*pxpcs), GFP_KERNEL);\n+\tif (!pxpcs)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tpxpcs-\u003epdev = pdev;\n+\n+\tdev_set_drvdata(\u0026pdev-\u003edev, pxpcs);\n+\n+\treturn pxpcs;\n+}\n+\n+static int xpcs_rk_serdes_phy_init(struct dw_xpcs_rk *pxpcs)\n+{\n+\tstruct device *dev = \u0026pxpcs-\u003epdev-\u003edev;\n+\n+\tpxpcs-\u003eserdes_phy = devm_phy_get(dev, \"serdes\");\n+\tif (IS_ERR(pxpcs-\u003eserdes_phy))\n+\t\treturn dev_err_probe(dev, PTR_ERR(pxpcs-\u003eserdes_phy),\n+\t\t\t\t\t\"Failed to get SerDes PHY\\n\");\n+\n+\treturn 0;\n+}\n+\n+static void xpcs_rk_serdes_phy_poweroff(void *data)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = data;\n+\tstruct device *dev = \u0026pxpcs-\u003epdev-\u003edev;\n+\n+\tphy_power_off(pxpcs-\u003eserdes_phy);\n+\tphy_exit(pxpcs-\u003eserdes_phy);\n+\n+\tdev_pm_genpd_rpm_always_on(dev, false);\n+}\n+\n+static int xpcs_rk_serdes_phy_poweron(struct dw_xpcs_rk *pxpcs)\n+{\n+\tstruct device *dev = \u0026pxpcs-\u003epdev-\u003edev;\n+\tint ret;\n+\n+\t/*\n+\t * The power domain is required and must be enabled, which allows us to\n+\t * dynamically turn the CSR clock on/off using PM while keeping the PCS\n+\t * powered on.\n+\t */\n+\tret = dev_pm_genpd_rpm_always_on(dev, true);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to power on power-domains\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = phy_init(pxpcs-\u003eserdes_phy);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to init SerDes PHY\\n\");\n+\t\tgoto pm_domain;\n+\t}\n+\n+\tret = phy_power_on(pxpcs-\u003eserdes_phy);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to power on SerDes PHY\\n\");\n+\t\tgoto serdes_phy;\n+\t}\n+\n+\tret = devm_add_action_or_reset(dev, xpcs_rk_serdes_phy_poweroff, pxpcs);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to register devm for SerDes PHY: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+\n+serdes_phy:\n+\tphy_exit(pxpcs-\u003eserdes_phy);\n+pm_domain:\n+\tdev_pm_genpd_rpm_always_on(dev, false);\n+\treturn ret;\n+}\n+\n+static int xpcs_rk_init_res(struct dw_xpcs_rk *pxpcs)\n+{\n+\tstruct platform_device *pdev = pxpcs-\u003epdev;\n+\tstruct device *dev = \u0026pdev-\u003edev;\n+\tstruct resource *res;\n+\n+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n+\tif (!res) {\n+\t\tdev_err(dev, \"No reg-space found\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (resource_size(res) \u003c SZ_2M) {\n+\t\tdev_err(dev, \"Invalid reg-space size\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tpxpcs-\u003ereg_base = devm_ioremap_resource(dev, res);\n+\tif (IS_ERR(pxpcs-\u003ereg_base)) {\n+\t\tdev_err(dev, \"Failed to map reg-space\\n\");\n+\t\treturn PTR_ERR(pxpcs-\u003ereg_base);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void xpcs_rk_exit_clk(void *data)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = data;\n+\n+\tclk_disable_unprepare(pxpcs-\u003eeee_clk);\n+}\n+\n+static int xpcs_rk_init_clk(struct dw_xpcs_rk *pxpcs)\n+{\n+\tstruct device *dev = \u0026pxpcs-\u003epdev-\u003edev;\n+\tint ret;\n+\n+\tpxpcs-\u003ecsr_clk = devm_clk_get(dev, \"csr\");\n+\tif (IS_ERR(pxpcs-\u003ecsr_clk))\n+\t\treturn dev_err_probe(dev, PTR_ERR(pxpcs-\u003ecsr_clk),\n+\t\t\t\t\t \"Failed to get CSR clock\\n\");\n+\n+\tpm_runtime_set_suspended(dev);\n+\tret = devm_pm_runtime_enable(dev);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to enable runtime-PM\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tpxpcs-\u003eeee_clk = devm_clk_get(dev, \"eee\");\n+\tif (IS_ERR(pxpcs-\u003eeee_clk))\n+\t\treturn dev_err_probe(dev, PTR_ERR(pxpcs-\u003eeee_clk),\n+\t\t\t\t\t \"Failed to get EEE clock\\n\");\n+\n+\tret = clk_prepare_enable(pxpcs-\u003eeee_clk);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to enable EEE clock\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = devm_add_action_or_reset(dev, xpcs_rk_exit_clk, pxpcs);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to register devm for EEE clock: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int xpcs_rk_init_bus(struct dw_xpcs_rk *pxpcs)\n+{\n+\tstruct device *dev = \u0026pxpcs-\u003epdev-\u003edev;\n+\tstatic atomic_t id = ATOMIC_INIT(-1);\n+\tstruct mii_bus *bus;\n+\tint ret;\n+\n+\tbus = devm_mdiobus_alloc_size(dev, 0);\n+\tif (!bus)\n+\t\treturn -ENOMEM;\n+\n+\tbus-\u003ename = \"Rockchip DW XPCS MCI/APB3\";\n+\tbus-\u003eread = xpcs_rk_read_c22;\n+\tbus-\u003ewrite = xpcs_rk_write_c22;\n+\tbus-\u003eread_c45 = xpcs_rk_read_c45;\n+\tbus-\u003ewrite_c45 = xpcs_rk_write_c45;\n+\tbus-\u003ephy_mask = ~0;\n+\tbus-\u003eparent = dev;\n+\tbus-\u003epriv = pxpcs;\n+\n+\tsnprintf(bus-\u003eid, MII_BUS_ID_SIZE,\n+\t\t \"rockchip_dwxpcs-%x\", atomic_inc_return(\u0026id));\n+\n+\t/*\n+\t * MDIO-bus here serves as just a back-end engine abstracting out\n+\t * the MDIO and MCI/APB3 IO interfaces utilized for the Rockchip DWXPCS CSRs\n+\t * access.\n+\t */\n+\tret = devm_mdiobus_register(dev, bus);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Failed to create MDIO bus\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tpxpcs-\u003ebus = bus;\n+\treturn 0;\n+}\n+\n+static int xpcs_rk_probe(struct platform_device *pdev)\n+{\n+\tstruct dw_xpcs_rk *pxpcs;\n+\tint ret;\n+\n+\tpxpcs = xpcs_rk_create_data(pdev);\n+\tif (IS_ERR(pxpcs))\n+\t\treturn PTR_ERR(pxpcs);\n+\n+\t/*\n+\t * The XPCS may be attached to a power domain (e.g. PD_PIPE). The domain\n+\t * must be powered on before any register access, otherwise the SoC will\n+\t * trigger a synchronous external abort (SError).\n+\t *\n+\t * Accessing the XPCS registers also requires a TX clock from the SerDes,\n+\t * which is needed for the soft reset.\n+\t */\n+\tret = xpcs_rk_serdes_phy_init(pxpcs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = xpcs_rk_serdes_phy_poweron(pxpcs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = xpcs_rk_init_res(pxpcs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = xpcs_rk_init_clk(pxpcs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = xpcs_rk_init_bus(pxpcs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static void xpcs_rk_remove(struct platform_device *pdev)\n+{\n+\t/*\n+\t * Force the device into suspend state to gate the CSR clock. This\n+\t * prevents clock leakage after devm resources are released.\n+\t *\n+\t * This is safe because:\n+\t *   1. The device link (DL_FLAG_AUTOREMOVE_CONSUMER) prevents unbind\n+\t *      while any consumer (MAC) is still attached.\n+\t *   2. No MDIO access will occur after this point, as the MAC driver\n+\t *      has already been unbound (or we are being removed because no\n+\t *      consumer exists).\n+\t */\n+\tpm_runtime_force_suspend(\u0026pdev-\u003edev);\n+}\n+\n+static const struct of_device_id xpcs_rk_of_ids[] = {\n+\t{ .compatible = \"rockchip,rk3568-xpcs\" },\n+\t{ /* sentinel */ },\n+};\n+MODULE_DEVICE_TABLE(of, xpcs_rk_of_ids);\n+\n+struct dw_xpcs *xpcs_rk_create(struct device *dev, struct device_node *np)\n+{\n+\tstruct platform_device *pdev;\n+\tstruct device_node *pcs_np;\n+\tstruct dw_xpcs_rk *pxpcs;\n+\tstruct dw_xpcs *xpcs;\n+\tu32 port;\n+\n+\tif (!of_device_is_available(np))\n+\t\treturn ERR_PTR(-ENODEV);\n+\n+\tif (of_property_read_u32(np, \"reg\", \u0026port))\n+\t\treturn ERR_PTR(-EINVAL);\n+\n+\tif (!xpcs_rk_mdio_addr_validate((int)port))\n+\t\treturn ERR_PTR(-EINVAL);\n+\n+\t/* The XPCS pdev is attached to the parent node */\n+\tpcs_np = of_get_parent(np);\n+\tif (!pcs_np)\n+\t\treturn ERR_PTR(-ENODEV);\n+\n+\tif (!of_device_is_available(pcs_np)) {\n+\t\tof_node_put(pcs_np);\n+\t\treturn ERR_PTR(-ENODEV);\n+\t}\n+\n+\tif (!of_match_node(xpcs_rk_of_ids, pcs_np)) {\n+\t\tof_node_put(pcs_np);\n+\t\treturn ERR_PTR(-EINVAL);\n+\t}\n+\n+\tpdev = of_find_device_by_node(pcs_np);\n+\tof_node_put(pcs_np);\n+\tif (!pdev)\n+\t\treturn ERR_PTR(-EPROBE_DEFER);\n+\n+\tdevice_lock(\u0026pdev-\u003edev);\n+\tpxpcs = platform_get_drvdata(pdev);\n+\tif (!pxpcs || !pxpcs-\u003ebus) {\n+\t\tdevice_unlock(\u0026pdev-\u003edev);\n+\t\tput_device(\u0026pdev-\u003edev);\n+\t\treturn ERR_PTR(-EPROBE_DEFER);\n+\t}\n+\n+\txpcs = xpcs_create_mdiodev(pxpcs-\u003ebus, (int)port);\n+\tdevice_unlock(\u0026pdev-\u003edev);\n+\tif (IS_ERR(xpcs)) {\n+\t\tput_device(\u0026pdev-\u003edev);\n+\t\treturn xpcs;\n+\t}\n+\n+\tif (!device_link_add(dev, \u0026pdev-\u003edev, DL_FLAG_AUTOREMOVE_CONSUMER)) {\n+\t\txpcs_destroy(xpcs);\n+\t\tput_device(\u0026pdev-\u003edev);\n+\t\treturn ERR_PTR(-ENOMEM);\n+\t}\n+\n+\tput_device(\u0026pdev-\u003edev);\n+\treturn xpcs;\n+}\n+EXPORT_SYMBOL_GPL(xpcs_rk_create);\n+\n+static int xpcs_rk_pm_runtime_suspend(struct device *dev)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = dev_get_drvdata(dev);\n+\n+\tclk_disable_unprepare(pxpcs-\u003ecsr_clk);\n+\n+\treturn 0;\n+}\n+\n+static int xpcs_rk_pm_runtime_resume(struct device *dev)\n+{\n+\tstruct dw_xpcs_rk *pxpcs = dev_get_drvdata(dev);\n+\n+\treturn clk_prepare_enable(pxpcs-\u003ecsr_clk);\n+}\n+\n+static DEFINE_RUNTIME_DEV_PM_OPS(xpcs_rk_pm_ops,\n+\t\t\t   xpcs_rk_pm_runtime_suspend,\n+\t\t\t   xpcs_rk_pm_runtime_resume,\n+\t\t\t   NULL);\n+\n+static struct platform_driver xpcs_rk_driver = {\n+\t.probe = xpcs_rk_probe,\n+\t.remove = xpcs_rk_remove,\n+\t.driver = {\n+\t\t.name = \"rk_xpcs-dwxpcs\",\n+\t\t.pm = pm_ptr(\u0026xpcs_rk_pm_ops),\n+\t\t.of_match_table = xpcs_rk_of_ids,\n+\t},\n+};\n+module_platform_driver(xpcs_rk_driver);\n+\n+MODULE_DESCRIPTION(\"Rockchip XPCS platform device driver\");\n+MODULE_AUTHOR(\"Coia Prant \u003ccoiaprant@gmail.com\u003e\");\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c\nindex 0337e2bcc0125..50b9cdf94fdaa 100644\n--- a/drivers/net/pcs/pcs-xpcs.c\n+++ b/drivers/net/pcs/pcs-xpcs.c\n@@ -816,9 +816,14 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,\n \tif (ret \u003c 0)\n \t\treturn ret;\n \n+\t/* Clear CL37 AN complete status */\n+\tret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n \tif (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)\n \t\tret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_BMCR,\n-\t\t\t\t mdio_ctrl | BMCR_ANENABLE);\n+\t\t\t\t mdio_ctrl | BMCR_ANENABLE | BMCR_ANRESTART);\n \n \treturn ret;\n }\n@@ -1093,10 +1098,15 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,\n \t\treturn 0;\n \t}\n \n-\t/* Clear AN complete status or interrupt */\n-\tif (state-\u003ean_complete)\n+\tif (state-\u003ean_complete) {\n+\t\t/* Clear AN complete status or interrupt */\n \t\txpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);\n \n+\t\t/* Initiate the next round of AN */\n+\t\txpcs_modify(xpcs, MDIO_MMD_VEND2, MII_BMCR, BMCR_ANRESTART,\n+\t\t\t    BMCR_ANRESTART);\n+\t}\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c\nindex 7843356a4dd47..919bb97a4b182 100644\n--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c\n+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c\n@@ -186,6 +186,7 @@ struct rockchip_combphy_grfcfg {\n \tstruct combphy_reg pipe_xpcs_phy_ready;\n \tstruct combphy_reg pipe_pcie1l0_sel;\n \tstruct combphy_reg pipe_pcie1l1_sel;\n+\tstruct combphy_reg pipe_sgmii_mac_sel;\n \tstruct combphy_reg u3otg0_port_en;\n \tstruct combphy_reg u3otg1_port_en;\n };\n@@ -212,6 +213,7 @@ struct rockchip_combphy_priv {\n \tbool enable_ssc;\n \tbool ext_refclk;\n \tstruct clk *refclk;\n+\tu32 sgmii_mac_sel;\n };\n \n static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,\n@@ -375,6 +377,9 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy\n \n \tpriv-\u003eext_refclk = device_property_present(dev, \"rockchip,ext-refclk\");\n \n+\tpriv-\u003esgmii_mac_sel = 1;\n+\tdevice_property_read_u32(dev, \"rockchip,sgmii-mac-sel\", \u0026priv-\u003esgmii_mac_sel);\n+\n \tpriv-\u003ephy_rst = devm_reset_control_get_exclusive(dev, \"phy\");\n \t/* fallback to old behaviour */\n \tif (PTR_ERR(priv-\u003ephy_rst) == -ENOENT)\n@@ -873,6 +878,8 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)\n \t\tbreak;\n \n \tcase PHY_TYPE_SGMII:\n+\t\trockchip_combphy_param_write(priv-\u003epipe_grf, \u0026cfg-\u003epipe_sgmii_mac_sel,\n+\t\t\t\t\tpriv-\u003esgmii_mac_sel \u003e 0);\n \t\trockchip_combphy_param_write(priv-\u003epipe_grf, \u0026cfg-\u003epipe_xpcs_phy_ready, true);\n \t\trockchip_combphy_param_write(priv-\u003ephy_grf, \u0026cfg-\u003epipe_phymode_sel, true);\n \t\trockchip_combphy_param_write(priv-\u003ephy_grf, \u0026cfg-\u003epipe_sel_qsgmii, true);\n@@ -984,6 +991,7 @@ static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {\n \t.con3_for_sata\t\t= { 0x000c, 15, 0, 0x00, 0x4407 },\n \t/* pipe-grf */\n \t.pipe_con0_for_sata\t= { 0x0000, 15, 0, 0x00, 0x2220 },\n+\t.pipe_sgmii_mac_sel\t= { 0x0040, 1, 1, 0x00, 0x01 },\n \t.pipe_xpcs_phy_ready\t= { 0x0040, 2, 2, 0x00, 0x01 },\n \t.u3otg0_port_en\t\t= { 0x0104, 15, 0, 0x0181, 0x1100 },\n \t.u3otg1_port_en\t\t= { 0x0144, 15, 0, 0x0181, 0x1100 },\ndiff --git a/include/linux/pcs/pcs-xpcs-rk.h b/include/linux/pcs/pcs-xpcs-rk.h\nnew file mode 100644\nindex 0000000000000..28723d5bd75cc\n--- /dev/null\n+++ b/include/linux/pcs/pcs-xpcs-rk.h\n@@ -0,0 +1,11 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+#ifndef __LINUX_PCS_XPCS_ROCKCHIP_H\n+#define __LINUX_PCS_XPCS_ROCKCHIP_H\n+\n+#include \u003clinux/device.h\u003e\n+#include \u003clinux/of.h\u003e\n+#include \u003clinux/pcs/pcs-xpcs.h\u003e\n+\n+struct dw_xpcs *xpcs_rk_create(struct device *dev, struct device_node *np);\n+\n+#endif /* __LINUX_PCS_XPCS_ROCKCHIP_H */\n"
}

2/1 2026/09/02 05:10 agent patch-evaluator
0m Model:
core

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch series adds support for Rockchip RK3568 Synopsys DesignWare Ethernet Physical Coding Sublayer (XPCS) and SGMII interface configuration for the Rockchip DWMAC driver, along with minor PCS init/exit handling updates for Intel DWMAC PCI and other SoC glue drivers (Renesas, Socfpga). These changes are restricted to vendor-specific SoC platform drivers (Rockchip RK3568, Renesas, Socfpga) and Intel DWMAC PCI hardware, none of which are emulated in standard QEMU or virtualized cloud environments like GCE. Therefore, the modified code cannot be executed during virtualized fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a '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:
For your convenience, here is the diff of the changes:
commit f46a8f4c9952961b7f8f96af8f2f4461a8f95972
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Sep 2 05:10:11 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml b/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml
new file mode 100644
index 0000000000000..0852d0bcb66a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/rockchip-dwxpcs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3568 Synopsys DesignWare Ethernet PCS
+
+maintainers:
+  - Coia Prant <coiaprant@gmail.com>
+
+description: |
+  Rockchip RK3568 SoC integrates a Synopsys DesignWare Ethernet Physical
+  Coding Sublayer (XPCS).
+  The PCS provides an interface between the Media Access Control (MAC)
+  and the Physical Medium Attachment (PMA) sublayer through a Media
+  Independent Interface (GMII).
+
+  The XPCS is accessed over the APB3 bus and internally connected to a
+  Naneng Combo SerDes PHY.
+  It supports 1000BASE-X, SGMII and QSGMII modes.
+
+  The block contains four MII ports that can be individually enabled and
+  routed to one of the Ethernet GMAC controllers via the pcs-handle
+  property in the MAC device tree node.
+
+properties:
+  compatible:
+    const: rockchip,rk3568-xpcs
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  clocks:
+    items:
+      - description: APB3 bus interface clock (clk_csr_i), required for register access
+      - description: EEE clock (clk_eee_i), required for Energy Efficient Ethernet operation
+
+  clock-names:
+    items:
+      - const: csr
+      - const: eee
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: serdes
+
+  power-domains:
+    maxItems: 1
+
+patternProperties:
+  "^pcs-mii@[0-3]$":
+    type: object
+    description:
+      One of the four MII ports of the XPCS. The port is linked to an
+      Ethernet MAC controller via the pcs-handle property in the MAC's
+      device tree node.
+
+    properties:
+      reg:
+        description: MII port number.
+        enum: [0, 1, 2, 3]
+
+    required:
+      - reg
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - clocks
+  - clock-names
+  - phys
+  - phy-names
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/power/rk3568-power.h>
+    #include <dt-bindings/phy/phy.h>
+
+    pcs@fda00000 {
+      compatible = "rockchip,rk3568-xpcs";
+      reg = <0xfda00000 0x200000>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+      clocks = <&cru PCLK_XPCS>, <&cru CLK_XPCS_EEE>;
+      clock-names = "csr", "eee";
+      phys = <&combphy2 PHY_TYPE_SGMII>;
+      phy-names = "serdes";
+      power-domains = <&power RK3568_PD_PIPE>;
+
+      pcs-mii@0 {
+        reg = <0>;
+      };
+    };
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
index 379b08bd9e97a..8e898bce9af73 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
@@ -80,6 +80,15 @@ properties:
     description:
       Some additional pipe settings are accessed through GRF regs.
 
+  rockchip,sgmii-mac-sel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1]
+    default: 1
+    description:
+      Select gmac0 or gmac1 to be used as SGMII controller.
+      The hardware reset value is GMAC1 (1). Set this to 0 to route
+      SGMII to GMAC0.
+
   "#phy-cells":
     const: 1
 
@@ -105,6 +114,10 @@ allOf:
           maxItems: 1
         reset-names:
           maxItems: 1
+        rockchip,sgmii-mac-sel: true
+    else:
+      properties:
+        rockchip,sgmii-mac-sel: false
   - if:
       properties:
         compatible:
diff --git a/MAINTAINERS b/MAINTAINERS
index 3a19da74d00c9..c3b17752cc817 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23744,6 +23744,15 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/sound/rockchip,rk3576-sai.yaml
 F:	sound/soc/rockchip/rockchip_sai.*
 
+ROCKCHIP XPCS DRIVER
+M:	Coia Prant <coiaprant@gmail.com>
+L:	netdev@vger.kernel.org
+L:	linux-rockchip@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/net/pcs/rockchip-dwxpcs.yaml
+F:	drivers/net/pcs/pcs-xpcs-rk.c
+F:	include/linux/pcs/pcs-xpcs-rk.h
+
 ROCKER DRIVER
 M:	Jiri Pirko <jiri@resnulli.us>
 L:	netdev@vger.kernel.org
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts b/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts
index 58c1052ba8ef3..25caa44198843 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts
@@ -3,6 +3,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
 #include "rk3568.dtsi"
@@ -242,6 +243,7 @@ &combphy1 {
 
 &combphy2 {
 	status = "okay";
+	rockchip,sgmii-mac-sel = <0>;
 };
 
 &cpu0 {
@@ -260,9 +262,18 @@ &cpu3 {
 	cpu-supply = <&vdd_cpu>;
 };
 
-/* Motorcomm YT8521SC LAN port (require SGMII) */
+/* Motorcomm YT8521SC LAN port */
 &gmac0 {
-	status = "disabled";
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>;
+	assigned-clock-parents = <&xpcs_gmac0_clk>;
+	pcs-handle = <&xpcs_mii0>;
+	managed = "in-band-status";
+	phy-handle = <&sgmii_phy>;
+	phy-mode = "sgmii";
+	phy-supply = <&vcc_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim>;
+	status = "okay";
 };
 
 /* Motorcomm YT8521SC WAN port */
@@ -341,6 +352,36 @@ &i2s0_8ch {
 	status = "okay";
 };
 
+&mdio0 {
+	sgmii_phy: ethernet-phy@3 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x3>;
+		max-speed = <1000>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>;
+
+		leds {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			led@1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_AMBER>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+
+			led@2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+		};
+	};
+};
+
 &mdio1 {
 	rgmii_phy: ethernet-phy@3 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -350,6 +391,25 @@ rgmii_phy: ethernet-phy@3 {
 		reset-gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_LOW>;
 		rx-internal-delay-ps = <1500>;
 		tx-internal-delay-ps = <1500>;
+
+		leds {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			led@1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_AMBER>;
+				function = LED_FUNCTION_WAN;
+				default-state = "keep";
+			};
+
+			led@2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+				function = LED_FUNCTION_WAN;
+				default-state = "keep";
+			};
+		};
 	};
 };
 
@@ -586,3 +646,13 @@ &xin32k {
 	pinctrl-names = "default";
 	pinctrl-0 = <&clk32k_out1>;
 };
+
+&xpcs {
+	status = "okay";
+	phys = <&combphy2 PHY_TYPE_SGMII>;
+	phy-names = "serdes";
+};
+
+&xpcs_mii0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 3bc653f027f1f..989e164c0eb39 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -110,6 +110,51 @@ sata0: sata@fc000000 {
 		status = "disabled";
 	};
 
+	xpcs: pcs@fda00000 {
+		compatible = "rockchip,rk3568-xpcs";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x0 0xfda00000 0x0 0x200000>;
+		clocks = <&cru PCLK_XPCS>, <&cru CLK_XPCS_EEE>;
+		clock-names = "csr", "eee";
+		power-domains = <&power RK3568_PD_PIPE>;
+		status = "disabled";
+
+		xpcs_mii0: pcs-mii@0 {
+			reg = <0>;
+			status = "disabled";
+		};
+
+		xpcs_mii1: pcs-mii@1 {
+			reg = <1>;
+			status = "disabled";
+		};
+
+		xpcs_mii2: pcs-mii@2 {
+			reg = <2>;
+			status = "disabled";
+		};
+
+		xpcs_mii3: pcs-mii@3 {
+			reg = <3>;
+			status = "disabled";
+		};
+	};
+
+	xpcs_gmac0_clk: xpcs-gmac0-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "clk_gmac0_xpcs_mii";
+		#clock-cells = <0>;
+	};
+
+	xpcs_gmac1_clk: xpcs-gmac1-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "clk_gmac1_xpcs_mii";
+		#clock-cells = <0>;
+	};
+
 	pipe_phy_grf0: syscon@fdc70000 {
 		compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
 		reg = <0x0 0xfdc70000 0x0 0x1000>;
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index e3dd5adda5aca..5088acc06982e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -170,6 +170,7 @@ config DWMAC_ROCKCHIP
 	default ARCH_ROCKCHIP
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
 	select MFD_SYSCON
+	select PCS_XPCS_ROCKCHIP
 	help
 	  Support for Ethernet controller on Rockchip RK3288 SoC.
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index f5f9fa67ecd77..fd5f01c8941c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -603,13 +603,47 @@ static void common_default_data(struct plat_stmmacenet_data *plat)
 	plat->mdio_bus_data->needs_reset = true;
 }
 
+static int intel_mgbe_pcs_init(struct stmmac_priv *priv)
+{
+	struct fwnode_handle *devnode, *pcsnode;
+	struct dw_xpcs *xpcs = NULL;
+	int addr;
+
+	devnode = dev_fwnode(priv->device);
+
+	if (fwnode_property_present(devnode, "pcs-handle")) {
+		pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0);
+		xpcs = xpcs_create_fwnode(pcsnode);
+		fwnode_handle_put(pcsnode);
+	} else {
+		addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1;
+		xpcs = xpcs_create_mdiodev(priv->mii, addr);
+	}
+
+	if (IS_ERR(xpcs))
+		return PTR_ERR(xpcs);
+
+	xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns);
+
+	priv->hw->xpcs = xpcs;
+	return 0;
+}
+
+static void intel_mgbe_pcs_exit(struct stmmac_priv *priv)
+{
+	if (!priv->hw->xpcs)
+		return;
+
+	xpcs_destroy(priv->hw->xpcs);
+	priv->hw->xpcs = NULL;
+}
+
 static struct phylink_pcs *intel_mgbe_select_pcs(struct stmmac_priv *priv,
 						 phy_interface_t interface)
 {
-	/* plat->mdio_bus_data->has_xpcs has been set true, so there
-	 * should always be an XPCS. The original code would always
-	 * return this if present.
-	 */
+	if (!priv->hw->xpcs)
+		return NULL;
+
 	return xpcs_to_phylink_pcs(priv->hw->xpcs);
 }
 
@@ -733,6 +767,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
 	    plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
 		plat->mdio_bus_data->pcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR);
 		plat->default_an_inband = true;
+		plat->pcs_init = intel_mgbe_pcs_init;
+		plat->pcs_exit = intel_mgbe_pcs_exit;
 		plat->select_pcs = intel_mgbe_select_pcs;
 	}
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
index 19f34e18bfef2..9af32c26f9c14 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
@@ -81,8 +81,11 @@ static int renesas_gmac_pcs_init(struct stmmac_priv *priv)
 
 static void renesas_gmac_pcs_exit(struct stmmac_priv *priv)
 {
-	if (priv->hw->phylink_pcs)
-		miic_destroy(priv->hw->phylink_pcs);
+	if (!priv->hw->phylink_pcs)
+		return;
+
+	miic_destroy(priv->hw->phylink_pcs);
+	priv->hw->phylink_pcs = NULL;
 }
 
 static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 8d7042e689261..e47ca1bec5b8b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/pcs/pcs-xpcs-rk.h>
 #include <linux/pm_runtime.h>
 
 #include "stmmac_platform.h"
@@ -47,6 +48,7 @@ struct rk_gmac_ops {
 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
 			     int tx_delay, int rx_delay);
 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
+	void (*set_to_sgmii)(struct rk_priv_data *bsp_priv);
 	int (*set_speed)(struct rk_priv_data *bsp_priv,
 			 phy_interface_t interface, int speed);
 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
@@ -63,6 +65,7 @@ struct rk_gmac_ops {
 	bool clock_grf_reg_in_php;
 	bool supports_rgmii;
 	bool supports_rmii;
+	bool supports_sgmii;
 	bool php_grf_required;
 	bool regs_valid;
 	u32 regs[];
@@ -98,6 +101,7 @@ struct rk_priv_data {
 	bool integrated_phy;
 	bool supports_rgmii;
 	bool supports_rmii;
+	bool supports_sgmii;
 
 	struct clk_bulk_data *clks;
 	int num_clks;
@@ -809,6 +813,8 @@ static const struct rk_gmac_ops rk3528_ops = {
 #define RK3568_GRF_GMAC1_CON1		0x038c
 
 /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
+#define RK3568_GMAC_MODE_RMII_RGMII		GRF_CLR_BIT(7)
+#define RK3568_GMAC_MODE_SGMII_QSGMII		GRF_BIT(7)
 #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
 #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
 #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
@@ -851,18 +857,32 @@ static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
 
 	regmap_write(bsp_priv->grf, con1,
+		     RK3568_GMAC_MODE_RMII_RGMII |
 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
 }
 
+static void rk3568_set_to_sgmii(struct rk_priv_data *bsp_priv)
+{
+	u32 con1;
+
+	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
+				     RK3568_GRF_GMAC0_CON1;
+
+	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_MODE_SGMII_QSGMII);
+}
+
 static const struct rk_gmac_ops rk3568_ops = {
 	.init = rk3568_init,
 	.set_to_rgmii = rk3568_set_to_rgmii,
+	.set_to_sgmii = rk3568_set_to_sgmii,
+
 	.set_speed = rk_set_clk_mac_speed,
 
 	.gmac_phy_intf_sel_mask = GENMASK_U16(6, 4),
 
 	.supports_rmii = true,
+	.supports_sgmii = true,
 
 	.regs_valid = true,
 	.regs = {
@@ -1208,6 +1228,43 @@ static void rk_phy_powerdown(struct rk_priv_data *bsp_priv)
 		dev_err(bsp_priv->dev, "fail to disable phy-supply\n");
 }
 
+static int rk_pcs_init(struct stmmac_priv *priv)
+{
+	struct device_node *np = priv->device->of_node;
+	struct device_node *pcs_node;
+	struct dw_xpcs *xpcs;
+
+	pcs_node = of_parse_phandle(np, "pcs-handle", 0);
+	if (!pcs_node)
+		return -ENODEV;
+
+	xpcs = xpcs_rk_create(priv->device, pcs_node);
+	of_node_put(pcs_node);
+	if (IS_ERR(xpcs))
+		return PTR_ERR(xpcs);
+
+	priv->hw->xpcs = xpcs;
+	return 0;
+}
+
+static void rk_pcs_exit(struct stmmac_priv *priv)
+{
+	if (!priv->hw->xpcs)
+		return;
+
+	xpcs_destroy(priv->hw->xpcs);
+	priv->hw->xpcs = NULL;
+}
+
+static struct phylink_pcs *rk_select_pcs(struct stmmac_priv *priv,
+					 phy_interface_t interface)
+{
+	if (!priv->hw->xpcs)
+		return NULL;
+
+	return xpcs_to_phylink_pcs(priv->hw->xpcs);
+}
+
 static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
 					  struct plat_stmmacenet_data *plat,
 					  const struct rk_gmac_ops *ops)
@@ -1330,6 +1387,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
 
 	bsp_priv->supports_rgmii = ops->supports_rgmii || !!ops->set_to_rgmii;
 	bsp_priv->supports_rmii = ops->supports_rmii || !!ops->set_to_rmii;
+	bsp_priv->supports_sgmii = ops->supports_sgmii || !!ops->set_to_sgmii;
 
 	if (ops->init) {
 		ret = ops->init(bsp_priv);
@@ -1361,6 +1419,10 @@ static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
 		if (!bsp_priv->supports_rmii)
 			return -EINVAL;
 		break;
+	case PHY_INTERFACE_MODE_SGMII:
+		if (!bsp_priv->supports_sgmii)
+			return -EINVAL;
+		break;
 	default:
 		dev_err(bsp_priv->dev,
 			"unsupported interface %d", bsp_priv->phy_iface);
@@ -1379,16 +1441,19 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 	if (ret)
 		return ret;
 
+	ret = gmac_clk_enable(bsp_priv, true);
+	if (ret)
+		return ret;
+
+	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_SGMII)
+		goto set_mode;
+
 	ret = rk_get_phy_intf_sel(bsp_priv->phy_iface);
 	if (ret < 0)
-		return ret;
+		goto clk_disable;
 
 	intf = ret;
 
-	ret = gmac_clk_enable(bsp_priv, true);
-	if (ret)
-		return ret;
-
 	if (bsp_priv->gmac_phy_intf_sel_mask ||
 	    bsp_priv->gmac_rmii_mode_mask) {
 		/* If defined, encode the phy_intf_sel value */
@@ -1399,10 +1464,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 				      bsp_priv->gmac_rmii_mode_mask);
 
 		ret = rk_write_gmac_grf_reg(bsp_priv, val);
-		if (ret < 0) {
-			gmac_clk_enable(bsp_priv, false);
-			return ret;
-		}
+		if (ret < 0)
+			goto clk_disable;
 	}
 
 	if (bsp_priv->clock.rmii_mode_mask) {
@@ -1410,13 +1473,12 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 				     bsp_priv->clock.rmii_mode_mask);
 
 		ret = rk_write_clock_grf_reg(bsp_priv, val);
-		if (ret < 0) {
-			gmac_clk_enable(bsp_priv, false);
-			return ret;
-		}
+		if (ret < 0)
+			goto clk_disable;
 	}
 
-	/*rmii or rgmii*/
+set_mode:
+	/* rmii, rgmii, sgmii */
 	switch (bsp_priv->phy_iface) {
 	case PHY_INTERFACE_MODE_RGMII:
 		dev_info(dev, "init for RGMII\n");
@@ -1447,15 +1509,20 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 		if (bsp_priv->ops->set_to_rmii)
 			bsp_priv->ops->set_to_rmii(bsp_priv);
 		break;
+	case PHY_INTERFACE_MODE_SGMII:
+		dev_info(dev, "init for SGMII\n");
+		if (bsp_priv->ops->set_to_sgmii)
+			bsp_priv->ops->set_to_sgmii(bsp_priv);
+		break;
 	default:
 		dev_err(dev, "NO interface defined!\n");
+		ret = -EINVAL;
+		goto clk_disable;
 	}
 
 	ret = rk_phy_powerup(bsp_priv);
-	if (ret) {
-		gmac_clk_enable(bsp_priv, false);
-		return ret;
-	}
+	if (ret)
+		goto clk_disable;
 
 	pm_runtime_get_sync(dev);
 
@@ -1463,6 +1530,10 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 		bsp_priv->ops->integrated_phy_powerup(bsp_priv);
 
 	return 0;
+
+clk_disable:
+	gmac_clk_enable(bsp_priv, false);
+	return ret;
 }
 
 static void rk_gmac_powerdown(struct rk_priv_data *gmac)
@@ -1486,6 +1557,9 @@ static void rk_get_interfaces(struct stmmac_priv *priv, void *bsp_priv,
 
 	if (rk->supports_rmii)
 		__set_bit(PHY_INTERFACE_MODE_RMII, interfaces);
+
+	if (rk->supports_sgmii)
+		__set_bit(PHY_INTERFACE_MODE_SGMII, interfaces);
 }
 
 static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i,
@@ -1602,6 +1676,17 @@ static int rk_gmac_probe(struct platform_device *pdev)
 	plat_dat->suspend = rk_gmac_suspend;
 	plat_dat->resume = rk_gmac_resume;
 
+	if (plat_dat->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+		/* SGMII clock always runs at 125 MHz */
+		plat_dat->set_clk_tx_rate = NULL;
+
+		/* SGMII requires a PCS */
+		plat_dat->default_an_inband = true;
+		plat_dat->pcs_init = rk_pcs_init;
+		plat_dat->pcs_exit = rk_pcs_exit;
+		plat_dat->select_pcs = rk_select_pcs;
+	}
+
 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
 	if (IS_ERR(plat_dat->bsp_priv))
 		return PTR_ERR(plat_dat->bsp_priv);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c
index 13634965bc19a..01df4776edb3f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c
@@ -35,8 +35,11 @@ static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv)
 
 static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv)
 {
-	if (priv->hw->phylink_pcs)
-		miic_destroy(priv->hw->phylink_pcs);
+	if (!priv->hw->phylink_pcs)
+		return;
+
+	miic_destroy(priv->hw->phylink_pcs);
+	priv->hw->phylink_pcs = NULL;
 }
 
 static struct phylink_pcs *rzn1_dwmac_select_pcs(struct stmmac_priv *priv,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 1d7f0a57d2889..6d4bc1fe8f751 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -539,8 +539,11 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)
 
 static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv)
 {
-	if (priv->hw->phylink_pcs)
-		lynx_pcs_destroy(priv->hw->phylink_pcs);
+	if (!priv->hw->phylink_pcs)
+		return;
+
+	lynx_pcs_destroy(priv->hw->phylink_pcs);
+	priv->hw->phylink_pcs = NULL;
 }
 
 static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index afe98ff5bdcb0..d2f77f0c223a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -426,36 +426,15 @@ int stmmac_mdio_reset(struct mii_bus *bus)
 int stmmac_pcs_setup(struct net_device *ndev)
 {
 	struct stmmac_priv *priv = netdev_priv(ndev);
-	struct fwnode_handle *devnode, *pcsnode;
-	struct dw_xpcs *xpcs = NULL;
-	int addr, ret;
-
-	devnode = dev_fwnode(priv->device);
-
-	if (priv->plat->pcs_init) {
-		ret = priv->plat->pcs_init(priv);
-	} else if (fwnode_property_present(devnode, "pcs-handle")) {
-		pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0);
-		xpcs = xpcs_create_fwnode(pcsnode);
-		fwnode_handle_put(pcsnode);
-		ret = PTR_ERR_OR_ZERO(xpcs);
-	} else if (priv->plat->mdio_bus_data &&
-		   priv->plat->mdio_bus_data->pcs_mask) {
-		addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1;
-		xpcs = xpcs_create_mdiodev(priv->mii, addr);
-		ret = PTR_ERR_OR_ZERO(xpcs);
-	} else {
+	int ret;
+
+	if (!priv->plat->pcs_init)
 		return 0;
-	}
 
+	ret = priv->plat->pcs_init(priv);
 	if (ret)
 		return dev_err_probe(priv->device, ret, "No xPCS found\n");
 
-	if (xpcs)
-		xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns);
-
-	priv->hw->xpcs = xpcs;
-
 	return 0;
 }
 
@@ -463,14 +442,10 @@ void stmmac_pcs_clean(struct net_device *ndev)
 {
 	struct stmmac_priv *priv = netdev_priv(ndev);
 
-	if (priv->plat->pcs_exit)
-		priv->plat->pcs_exit(priv);
-
-	if (!priv->hw->xpcs)
+	if (!priv->plat->pcs_exit)
 		return;
 
-	xpcs_destroy(priv->hw->xpcs);
-	priv->hw->xpcs = NULL;
+	priv->plat->pcs_exit(priv);
 }
 
 struct stmmac_clk_rate {
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index e417fd66f660a..88bc40791e69f 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -12,6 +12,29 @@ config PCS_XPCS
 	  This module provides a driver and helper functions for Synopsys
 	  DesignWare XPCS controllers.
 
+if PCS_XPCS
+
+config PCS_XPCS_PLATFORM
+	tristate "Generic XPCS controller support"
+	default PCS_XPCS
+	help
+	  Generic DWXPCS driver for platforms that don't require any
+	  platform specific code to function or is using platform
+	  data for setup.
+
+	  If you have a controller with this interface, say Y or M here.
+
+config PCS_XPCS_ROCKCHIP
+	tristate "Rockchip XPCS controller support"
+	default ARCH_ROCKCHIP
+	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+	help
+	  Support for XPCS controller on Rockchip RK356x SoC.
+
+	  If you have a Rockchip SoC with this interface, say Y or M here.
+
+endif # PCS_XPCS
+
 config PCS_LYNX
 	tristate
 	help
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index 4f7920618b900..c809b7f942a51 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -1,10 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for Linux PCS drivers
 
-pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-plat.o \
-				   pcs-xpcs-nxp.o pcs-xpcs-wx.o
-
-obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
+obj-$(CONFIG_PCS_XPCS) += pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
+obj-$(CONFIG_PCS_XPCS_PLATFORM) += pcs-xpcs-plat.o
+obj-$(CONFIG_PCS_XPCS_ROCKCHIP) += pcs-xpcs-rk.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
 obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
diff --git a/drivers/net/pcs/pcs-xpcs-rk.c b/drivers/net/pcs/pcs-xpcs-rk.c
new file mode 100644
index 0000000000000..4ef20b093dada
--- /dev/null
+++ b/drivers/net/pcs/pcs-xpcs-rk.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip XPCS platform device driver
+ *
+ * Based on the Synopsys DesignWare XPCS platform driver.
+ * Copyright (C) 2024 Serge Semin
+ *
+ * Adapted for Rockchip SoCs, with reference to the Rockchip OEM driver.
+ * Copyright (C) 2026 Coia Prant
+ */
+
+#include <linux/atomic.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pcs/pcs-xpcs-rk.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/sizes.h>
+
+#include "pcs-xpcs.h"
+
+struct dw_xpcs_rk {
+	struct platform_device *pdev;
+	struct mii_bus *bus;
+	void __iomem *reg_base;
+	struct phy *serdes_phy;
+	struct clk *csr_clk;
+	struct clk *eee_clk;
+};
+
+static ptrdiff_t xpcs_rk_addr_format(int dev, int reg)
+{
+	return FIELD_PREP(0x70000, dev) | FIELD_PREP(0xffff, reg);
+}
+
+static int xpcs_rk_read_reg(struct dw_xpcs_rk *pxpcs, int dev, int reg)
+{
+	ptrdiff_t csr;
+	int ret;
+
+	csr = xpcs_rk_addr_format(dev, reg);
+
+	ret = pm_runtime_resume_and_get(&pxpcs->pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = readl(pxpcs->reg_base + (csr << 2)) & 0xffff;
+
+	pm_runtime_put(&pxpcs->pdev->dev);
+	return ret;
+}
+
+static int xpcs_rk_write_reg(struct dw_xpcs_rk *pxpcs, int dev, int reg, u16 val)
+{
+	ptrdiff_t csr;
+	int ret;
+
+	csr = xpcs_rk_addr_format(dev, reg);
+
+	ret = pm_runtime_resume_and_get(&pxpcs->pdev->dev);
+	if (ret)
+		return ret;
+
+	writel(val, pxpcs->reg_base + (csr << 2));
+
+	pm_runtime_put(&pxpcs->pdev->dev);
+	return 0;
+}
+
+#define ROCKCHIP_MMD_MII1	2
+#define ROCKCHIP_MMD_MII2	3
+#define ROCKCHIP_MMD_MII3	4
+#define ROCKCHIP_MMD_PMAPMD	6
+#define ROCKCHIP_MMD_MII	7
+
+static bool xpcs_rk_mdio_addr_validate(int addr)
+{
+	return !(addr < 0 || addr > 3);
+}
+
+static int xpcs_rk_mdio_read_remapping(int addr, int dev, int reg)
+{
+	switch (dev) {
+	case MDIO_MMD_PMAPMD:
+		return ROCKCHIP_MMD_PMAPMD;
+	case MDIO_MMD_VEND2:
+		break;
+	default:
+		return -ENXIO;
+	}
+
+	/* read remapping to MII is performed by HW */
+	switch (addr) {
+	case 0:
+		return ROCKCHIP_MMD_MII;
+	case 1:
+		return ROCKCHIP_MMD_MII1;
+	case 2:
+		return ROCKCHIP_MMD_MII2;
+	case 3:
+		return ROCKCHIP_MMD_MII3;
+	default:
+		return -ENODEV;
+	}
+}
+
+static int xpcs_rk_mdio_write_remapping(int addr, int dev, int reg)
+{
+	switch (dev) {
+	case MDIO_MMD_PMAPMD:
+		return ROCKCHIP_MMD_PMAPMD;
+	case MDIO_MMD_VEND2:
+		break;
+	default:
+		return -ENXIO;
+	}
+
+	/* Writable only on MII */
+	switch (reg) {
+	case DW_VR_MII_AN_CTRL:
+	case DW_VR_MII_AN_INTR_STS:
+	case DW_VR_MII_EEE_MCTRL0:
+	case DW_VR_MII_EEE_MCTRL1:
+	case DW_VR_MII_DIG_CTRL2:
+		return ROCKCHIP_MMD_MII;
+	default:
+		break;
+	}
+
+	switch (addr) {
+	case 0:
+		return ROCKCHIP_MMD_MII;
+	case 1:
+		return ROCKCHIP_MMD_MII1;
+	case 2:
+		return ROCKCHIP_MMD_MII2;
+	case 3:
+		return ROCKCHIP_MMD_MII3;
+	default:
+		return -ENODEV;
+	}
+}
+
+static int xpcs_rk_read_c22(struct mii_bus *bus, int addr, int reg)
+{
+	struct dw_xpcs_rk *pxpcs = bus->priv;
+	int dev;
+
+	if (!xpcs_rk_mdio_addr_validate(addr))
+		return -ENODEV;
+
+	dev = xpcs_rk_mdio_read_remapping(addr, MDIO_MMD_VEND2, reg);
+	if (dev < 0)
+		return 0xffff;
+
+	return xpcs_rk_read_reg(pxpcs, dev, reg);
+}
+
+static int xpcs_rk_write_c22(struct mii_bus *bus, int addr, int reg, u16 val)
+{
+	struct dw_xpcs_rk *pxpcs = bus->priv;
+	int dev;
+
+	if (!xpcs_rk_mdio_addr_validate(addr))
+		return -ENODEV;
+
+	dev = xpcs_rk_mdio_write_remapping(addr, MDIO_MMD_VEND2, reg);
+	if (dev < 0)
+		return 0;
+
+	return xpcs_rk_write_reg(pxpcs, dev, reg, val);
+}
+
+static int xpcs_rk_read_c45(struct mii_bus *bus, int addr, int dev, int reg)
+{
+	struct dw_xpcs_rk *pxpcs = bus->priv;
+
+	if (!xpcs_rk_mdio_addr_validate(addr))
+		return -ENODEV;
+
+	dev = xpcs_rk_mdio_read_remapping(addr, dev, reg);
+	if (dev < 0)
+		return 0xffff;
+
+	return xpcs_rk_read_reg(pxpcs, dev, reg);
+}
+
+static int xpcs_rk_write_c45(struct mii_bus *bus, int addr, int dev, int reg, u16 val)
+{
+	struct dw_xpcs_rk *pxpcs = bus->priv;
+
+	if (!xpcs_rk_mdio_addr_validate(addr))
+		return -ENODEV;
+
+	dev = xpcs_rk_mdio_write_remapping(addr, dev, reg);
+	if (dev < 0)
+		return 0;
+
+	return xpcs_rk_write_reg(pxpcs, dev, reg, val);
+}
+
+static struct dw_xpcs_rk *xpcs_rk_create_data(struct platform_device *pdev)
+{
+	struct dw_xpcs_rk *pxpcs;
+
+	pxpcs = devm_kzalloc(&pdev->dev, sizeof(*pxpcs), GFP_KERNEL);
+	if (!pxpcs)
+		return ERR_PTR(-ENOMEM);
+
+	pxpcs->pdev = pdev;
+
+	dev_set_drvdata(&pdev->dev, pxpcs);
+
+	return pxpcs;
+}
+
+static int xpcs_rk_serdes_phy_init(struct dw_xpcs_rk *pxpcs)
+{
+	struct device *dev = &pxpcs->pdev->dev;
+
+	pxpcs->serdes_phy = devm_phy_get(dev, "serdes");
+	if (IS_ERR(pxpcs->serdes_phy))
+		return dev_err_probe(dev, PTR_ERR(pxpcs->serdes_phy),
+					"Failed to get SerDes PHY\n");
+
+	return 0;
+}
+
+static void xpcs_rk_serdes_phy_poweroff(void *data)
+{
+	struct dw_xpcs_rk *pxpcs = data;
+	struct device *dev = &pxpcs->pdev->dev;
+
+	phy_power_off(pxpcs->serdes_phy);
+	phy_exit(pxpcs->serdes_phy);
+
+	dev_pm_genpd_rpm_always_on(dev, false);
+}
+
+static int xpcs_rk_serdes_phy_poweron(struct dw_xpcs_rk *pxpcs)
+{
+	struct device *dev = &pxpcs->pdev->dev;
+	int ret;
+
+	/*
+	 * The power domain is required and must be enabled, which allows us to
+	 * dynamically turn the CSR clock on/off using PM while keeping the PCS
+	 * powered on.
+	 */
+	ret = dev_pm_genpd_rpm_always_on(dev, true);
+	if (ret) {
+		dev_err(dev, "Failed to power on power-domains\n");
+		return ret;
+	}
+
+	ret = phy_init(pxpcs->serdes_phy);
+	if (ret) {
+		dev_err(dev, "Failed to init SerDes PHY\n");
+		goto pm_domain;
+	}
+
+	ret = phy_power_on(pxpcs->serdes_phy);
+	if (ret) {
+		dev_err(dev, "Failed to power on SerDes PHY\n");
+		goto serdes_phy;
+	}
+
+	ret = devm_add_action_or_reset(dev, xpcs_rk_serdes_phy_poweroff, pxpcs);
+	if (ret) {
+		dev_err(dev, "Failed to register devm for SerDes PHY: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+
+serdes_phy:
+	phy_exit(pxpcs->serdes_phy);
+pm_domain:
+	dev_pm_genpd_rpm_always_on(dev, false);
+	return ret;
+}
+
+static int xpcs_rk_init_res(struct dw_xpcs_rk *pxpcs)
+{
+	struct platform_device *pdev = pxpcs->pdev;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "No reg-space found\n");
+		return -EINVAL;
+	}
+
+	if (resource_size(res) < SZ_2M) {
+		dev_err(dev, "Invalid reg-space size\n");
+		return -EINVAL;
+	}
+
+	pxpcs->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(pxpcs->reg_base)) {
+		dev_err(dev, "Failed to map reg-space\n");
+		return PTR_ERR(pxpcs->reg_base);
+	}
+
+	return 0;
+}
+
+static void xpcs_rk_exit_clk(void *data)
+{
+	struct dw_xpcs_rk *pxpcs = data;
+
+	clk_disable_unprepare(pxpcs->eee_clk);
+}
+
+static int xpcs_rk_init_clk(struct dw_xpcs_rk *pxpcs)
+{
+	struct device *dev = &pxpcs->pdev->dev;
+	int ret;
+
+	pxpcs->csr_clk = devm_clk_get(dev, "csr");
+	if (IS_ERR(pxpcs->csr_clk))
+		return dev_err_probe(dev, PTR_ERR(pxpcs->csr_clk),
+					 "Failed to get CSR clock\n");
+
+	pm_runtime_set_suspended(dev);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret) {
+		dev_err(dev, "Failed to enable runtime-PM\n");
+		return ret;
+	}
+
+	pxpcs->eee_clk = devm_clk_get(dev, "eee");
+	if (IS_ERR(pxpcs->eee_clk))
+		return dev_err_probe(dev, PTR_ERR(pxpcs->eee_clk),
+					 "Failed to get EEE clock\n");
+
+	ret = clk_prepare_enable(pxpcs->eee_clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable EEE clock\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, xpcs_rk_exit_clk, pxpcs);
+	if (ret) {
+		dev_err(dev, "Failed to register devm for EEE clock: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int xpcs_rk_init_bus(struct dw_xpcs_rk *pxpcs)
+{
+	struct device *dev = &pxpcs->pdev->dev;
+	static atomic_t id = ATOMIC_INIT(-1);
+	struct mii_bus *bus;
+	int ret;
+
+	bus = devm_mdiobus_alloc_size(dev, 0);
+	if (!bus)
+		return -ENOMEM;
+
+	bus->name = "Rockchip DW XPCS MCI/APB3";
+	bus->read = xpcs_rk_read_c22;
+	bus->write = xpcs_rk_write_c22;
+	bus->read_c45 = xpcs_rk_read_c45;
+	bus->write_c45 = xpcs_rk_write_c45;
+	bus->phy_mask = ~0;
+	bus->parent = dev;
+	bus->priv = pxpcs;
+
+	snprintf(bus->id, MII_BUS_ID_SIZE,
+		 "rockchip_dwxpcs-%x", atomic_inc_return(&id));
+
+	/*
+	 * MDIO-bus here serves as just a back-end engine abstracting out
+	 * the MDIO and MCI/APB3 IO interfaces utilized for the Rockchip DWXPCS CSRs
+	 * access.
+	 */
+	ret = devm_mdiobus_register(dev, bus);
+	if (ret) {
+		dev_err(dev, "Failed to create MDIO bus\n");
+		return ret;
+	}
+
+	pxpcs->bus = bus;
+	return 0;
+}
+
+static int xpcs_rk_probe(struct platform_device *pdev)
+{
+	struct dw_xpcs_rk *pxpcs;
+	int ret;
+
+	pxpcs = xpcs_rk_create_data(pdev);
+	if (IS_ERR(pxpcs))
+		return PTR_ERR(pxpcs);
+
+	/*
+	 * The XPCS may be attached to a power domain (e.g. PD_PIPE). The domain
+	 * must be powered on before any register access, otherwise the SoC will
+	 * trigger a synchronous external abort (SError).
+	 *
+	 * Accessing the XPCS registers also requires a TX clock from the SerDes,
+	 * which is needed for the soft reset.
+	 */
+	ret = xpcs_rk_serdes_phy_init(pxpcs);
+	if (ret)
+		return ret;
+
+	ret = xpcs_rk_serdes_phy_poweron(pxpcs);
+	if (ret)
+		return ret;
+
+	ret = xpcs_rk_init_res(pxpcs);
+	if (ret)
+		return ret;
+
+	ret = xpcs_rk_init_clk(pxpcs);
+	if (ret)
+		return ret;
+
+	ret = xpcs_rk_init_bus(pxpcs);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void xpcs_rk_remove(struct platform_device *pdev)
+{
+	/*
+	 * Force the device into suspend state to gate the CSR clock. This
+	 * prevents clock leakage after devm resources are released.
+	 *
+	 * This is safe because:
+	 *   1. The device link (DL_FLAG_AUTOREMOVE_CONSUMER) prevents unbind
+	 *      while any consumer (MAC) is still attached.
+	 *   2. No MDIO access will occur after this point, as the MAC driver
+	 *      has already been unbound (or we are being removed because no
+	 *      consumer exists).
+	 */
+	pm_runtime_force_suspend(&pdev->dev);
+}
+
+static const struct of_device_id xpcs_rk_of_ids[] = {
+	{ .compatible = "rockchip,rk3568-xpcs" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, xpcs_rk_of_ids);
+
+struct dw_xpcs *xpcs_rk_create(struct device *dev, struct device_node *np)
+{
+	struct platform_device *pdev;
+	struct device_node *pcs_np;
+	struct dw_xpcs_rk *pxpcs;
+	struct dw_xpcs *xpcs;
+	u32 port;
+
+	if (!of_device_is_available(np))
+		return ERR_PTR(-ENODEV);
+
+	if (of_property_read_u32(np, "reg", &port))
+		return ERR_PTR(-EINVAL);
+
+	if (!xpcs_rk_mdio_addr_validate((int)port))
+		return ERR_PTR(-EINVAL);
+
+	/* The XPCS pdev is attached to the parent node */
+	pcs_np = of_get_parent(np);
+	if (!pcs_np)
+		return ERR_PTR(-ENODEV);
+
+	if (!of_device_is_available(pcs_np)) {
+		of_node_put(pcs_np);
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (!of_match_node(xpcs_rk_of_ids, pcs_np)) {
+		of_node_put(pcs_np);
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdev = of_find_device_by_node(pcs_np);
+	of_node_put(pcs_np);
+	if (!pdev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	device_lock(&pdev->dev);
+	pxpcs = platform_get_drvdata(pdev);
+	if (!pxpcs || !pxpcs->bus) {
+		device_unlock(&pdev->dev);
+		put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	xpcs = xpcs_create_mdiodev(pxpcs->bus, (int)port);
+	device_unlock(&pdev->dev);
+	if (IS_ERR(xpcs)) {
+		put_device(&pdev->dev);
+		return xpcs;
+	}
+
+	if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
+		xpcs_destroy(xpcs);
+		put_device(&pdev->dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	put_device(&pdev->dev);
+	return xpcs;
+}
+EXPORT_SYMBOL_GPL(xpcs_rk_create);
+
+static int xpcs_rk_pm_runtime_suspend(struct device *dev)
+{
+	struct dw_xpcs_rk *pxpcs = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(pxpcs->csr_clk);
+
+	return 0;
+}
+
+static int xpcs_rk_pm_runtime_resume(struct device *dev)
+{
+	struct dw_xpcs_rk *pxpcs = dev_get_drvdata(dev);
+
+	return clk_prepare_enable(pxpcs->csr_clk);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(xpcs_rk_pm_ops,
+			   xpcs_rk_pm_runtime_suspend,
+			   xpcs_rk_pm_runtime_resume,
+			   NULL);
+
+static struct platform_driver xpcs_rk_driver = {
+	.probe = xpcs_rk_probe,
+	.remove = xpcs_rk_remove,
+	.driver = {
+		.name = "rk_xpcs-dwxpcs",
+		.pm = pm_ptr(&xpcs_rk_pm_ops),
+		.of_match_table = xpcs_rk_of_ids,
+	},
+};
+module_platform_driver(xpcs_rk_driver);
+
+MODULE_DESCRIPTION("Rockchip XPCS platform device driver");
+MODULE_AUTHOR("Coia Prant <coiaprant@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 0337e2bcc0125..50b9cdf94fdaa 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -816,9 +816,14 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
 	if (ret < 0)
 		return ret;
 
+	/* Clear CL37 AN complete status */
+	ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
+	if (ret < 0)
+		return ret;
+
 	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
 		ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MII_BMCR,
-				 mdio_ctrl | BMCR_ANENABLE);
+				 mdio_ctrl | BMCR_ANENABLE | BMCR_ANRESTART);
 
 	return ret;
 }
@@ -1093,10 +1098,15 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
 		return 0;
 	}
 
-	/* Clear AN complete status or interrupt */
-	if (state->an_complete)
+	if (state->an_complete) {
+		/* Clear AN complete status or interrupt */
 		xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
 
+		/* Initiate the next round of AN */
+		xpcs_modify(xpcs, MDIO_MMD_VEND2, MII_BMCR, BMCR_ANRESTART,
+			    BMCR_ANRESTART);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 7843356a4dd47..919bb97a4b182 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -186,6 +186,7 @@ struct rockchip_combphy_grfcfg {
 	struct combphy_reg pipe_xpcs_phy_ready;
 	struct combphy_reg pipe_pcie1l0_sel;
 	struct combphy_reg pipe_pcie1l1_sel;
+	struct combphy_reg pipe_sgmii_mac_sel;
 	struct combphy_reg u3otg0_port_en;
 	struct combphy_reg u3otg1_port_en;
 };
@@ -212,6 +213,7 @@ struct rockchip_combphy_priv {
 	bool enable_ssc;
 	bool ext_refclk;
 	struct clk *refclk;
+	u32 sgmii_mac_sel;
 };
 
 static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,
@@ -375,6 +377,9 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy
 
 	priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
 
+	priv->sgmii_mac_sel = 1;
+	device_property_read_u32(dev, "rockchip,sgmii-mac-sel", &priv->sgmii_mac_sel);
+
 	priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy");
 	/* fallback to old behaviour */
 	if (PTR_ERR(priv->phy_rst) == -ENOENT)
@@ -873,6 +878,8 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
 		break;
 
 	case PHY_TYPE_SGMII:
+		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_sgmii_mac_sel,
+					priv->sgmii_mac_sel > 0);
 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
@@ -984,6 +991,7 @@ static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
 	/* pipe-grf */
 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
+	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
 	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
 	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
diff --git a/include/linux/pcs/pcs-xpcs-rk.h b/include/linux/pcs/pcs-xpcs-rk.h
new file mode 100644
index 0000000000000..28723d5bd75cc
--- /dev/null
+++ b/include/linux/pcs/pcs-xpcs-rk.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_XPCS_ROCKCHIP_H
+#define __LINUX_PCS_XPCS_ROCKCHIP_H
+
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/pcs/pcs-xpcs.h>
+
+struct dw_xpcs *xpcs_rk_create(struct device *dev, struct device_node *np);
+
+#endif /* __LINUX_PCS_XPCS_ROCKCHIP_H */

3/2 2026/09/02 05:10 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 20629
							output: 18
							thoughts: 1299
						

Thoughts:
**Fuzzing Evaluation: A Deep Dive**

Okay, so I need to decide if this patch series warrants fuzzing. First, I need to understand what's actually being changed. The diff touches a few key areas: Device Tree bindings and documentation, the `MAINTAINERS` file, some DTS files for the Rockchip RK3568, and a significant amount of code in the networking stack, specifically around Ethernet drivers and PCS (Physical Coding Sublayer) drivers.

Looking at the code, it's clear this is focused on bringing up SGMII support for Rockchip's DWMAC, and introducing a new Rockchip XPCS platform driver. There are also changes to Intel DWMAC and a few other platform drivers (Renesas, Socfpga). The patch also includes refactoring of `stmmac_mdio.c` and modifications to `pcs-xpcs.c`.

Now, the important question: should this be fuzzed? Let's consider the "WorthFuzzing" rules.  I immediately need to rule out changes that are purely decorative, or affect code that's unreachable in virtualized environments like QEMU or GCE. I need to be careful with vendor-specific drivers (like those requiring specific PCIe cards) and drivers that are only concerned with removal or shutdown callbacks.

Here's the breakdown of my thoughts:

1.  **Rockchip stuff:** The `pcs-xpcs-rk.c`, `phy-rockchip-naneng-combphy.c`, and `dwmac-rk.c` drivers are all Rockchip SoC platform drivers. These **cannot** be directly run in a standard QEMU environment, which emulates x86\_64 or generic ARM64 (virt machines), and so these should be excluded.
2.  **Intel DWMAC:** `dwmac-intel.c` is more interesting, but QEMU doesn't emulate the Intel mgbe/dwmac PCI device directly. That's a blocker.
3.  **Other Platform Drivers:** Renesas and Socfpga drivers (`dwmac-renesas-gbeth.c`, `dwmac-rzn1.c`, `dwmac-socfpga.c`) likely also fall into the same category, being SoC-specific.
4.  **`stmmac_mdio.c` and `pcs-xpcs.c`:** These are the core pieces that look more general. The real question is whether QEMU, or any virtualized environment I'm familiar with, *uses* `stmmac` or `pcs-xpcs`, or if this functionality is tied to physical SoC hardware. This is a point to confirm.  I need to check how `stmmac_pcs_setup`, `stmmac_pcs_clean`, `xpcs_config_aneg_c37_sgmii`, and `xpcs_get_state_c37_sgmii` are actually used in a virtual environment.

Therefore, my next step is a deep dive with `grep`. I need to search the QEMU source and the kernel configuration to confirm if there are any supported hardware and associated drivers that are worth fuzzing.



4/2 2026/09/02 05:10 tool grepper
0m Args:
{
  "Expression": "stmmac_"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 11575 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml=255=examples:\n--\nDocumentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml-402-        snps,fixed-burst;\nDocumentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml:403:        snps,axi-config = \u003c\u0026gmac1_stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml-404-\n--\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml=137=examples:\n--\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-155-        snps,tso;\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml:156:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-157-\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml:158:        stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-159-            snps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-181-        snps,tso;\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml:182:        snps,axi-config = \u003c\u0026stmmac_axi_setup_gmac1\u003e;\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-183-\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml:184:        stmmac_axi_setup_gmac1: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/eswin,eic7700-eth.yaml-185-            snps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml=57=examples:\n--\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml-66-\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml:67:    stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml-68-        snps,lpi_en;\n--\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml-120-        snps,pbl = \u003c0x4\u003e;\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml:121:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/intel,dwmac-plat.yaml-122-        snps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml=249=examples:\n--\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml-285-        snps,force_thresh_dma_mode;\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml:286:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml-287-        snps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml-292-\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml:293:        stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml-294-            snps,lpi_en;\n--\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml=654=examples:\n--\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml-670-        clock-names = \"stmmaceth\";\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml:671:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml-672-        snps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml-674-\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml:675:        stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/snps,dwmac.yaml-676-            snps,wr_osr_lmt = \u003c0xf\u003e;\n--\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml=67=examples:\n--\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml-90-      snps,mtl-tx-config = \u003c\u0026gmac0_mtl_tx_setup\u003e;\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml:91:      snps,axi-config = \u003c\u0026gmac0_stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml-92-\n--\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml-108-\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml:109:      gmac0_stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml-110-        snps,blen = \u003c16 8 4 0 0 0 0\u003e;\n--\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml=95=examples:\n--\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml-118-      snps,mtl-tx-config = \u003c\u0026gmac0_mtl_tx_setup\u003e;\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml:119:      snps,axi-config = \u003c\u0026gmac0_stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml-120-\n--\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml-145-\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml:146:      gmac0_stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml-147-        snps,blen = \u003c16 8 4 0 0 0 0\u003e;\n--\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml=154=examples:\n--\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml-175-        snps,force_thresh_dma_mode;\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml:176:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml-177-        snps,en-tx-lpi-clockgating;\n--\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml-192-\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml:193:        stmmac_axi_setup: stmmac-axi-config {\nDocumentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml-194-            snps,lpi_en;\n--\nDocumentation/devicetree/bindings/net/stm32-dwmac.yaml=162=examples:\n--\nDocumentation/devicetree/bindings/net/stm32-dwmac.yaml-184-        snps,pbl = \u003c2\u003e;\nDocumentation/devicetree/bindings/net/stm32-dwmac.yaml:185:        snps,axi-config = \u003c\u0026stmmac_axi_config_0\u003e;\nDocumentation/devicetree/bindings/net/stm32-dwmac.yaml-186-        snps,tso;\n--\nDocumentation/devicetree/bindings/net/thead,th1520-gmac.yaml=87=examples:\n--\nDocumentation/devicetree/bindings/net/thead,th1520-gmac.yaml-98-        snps,fixed-burst;\nDocumentation/devicetree/bindings/net/thead,th1520-gmac.yaml:99:        snps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\nDocumentation/devicetree/bindings/net/thead,th1520-gmac.yaml-100-        snps,pbl = \u003c32\u003e;\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=107=syntax (e.g. for PCI module)::\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-108-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:109:    modprobe stmmac_pci [\u003coption\u003e=\u003cVAL1\u003e,\u003cVAL2\u003e,...]\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-110-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=352=finds::\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-361-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:362:        struct stmmac_mdio_bus_data *mdio_bus_data;\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-363-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-365-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:366:        struct stmmac_dma_cfg *dma_cfg;\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-367-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=387=JUMBO frames::\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-430-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:431:        struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES];\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:432:        struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES];\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-433-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=448=is used to configure the AMBA bridge to generate more efficient STBus traffic::\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-454-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:455:        struct clk *stmmac_clk;\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-456-        struct clk *pclk;\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-463-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:464:        struct reset_control *stmmac_rst;\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-465-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-467-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:468:        struct stmmac_axi *axi;\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-469-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=502=For MDIO bus data, we have:\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-505-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:506:    struct stmmac_mdio_bus_data {\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-507-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=528=For DMA engine configuration, we have:\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-531-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:532:    struct stmmac_dma_cfg {\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-533-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=564=For DMA AXI parameters, we have:\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-567-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:568:    struct stmmac_axi {\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-569-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=601=For the RX Queues configuration, we have:\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-604-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:605:    struct stmmac_rxq_cfg {\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-606-\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=628=For the TX Queues configuration, we have:\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-631-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:632:    struct stmmac_txq_cfg {\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-633-\n--\narch/arm/boot/dts/axis/artpec6.dtsi=287=\t\tethernet: ethernet@f8010000 {\n--\narch/arm/boot/dts/axis/artpec6.dtsi-296-\narch/arm/boot/dts/axis/artpec6.dtsi:297:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/axis/artpec6.dtsi-298-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\narch/arm/boot/dts/axis/artpec6.dtsi-307-\narch/arm/boot/dts/axis/artpec6.dtsi:308:\t\t\tstmmac_axi_setup: stmmac-axi-config {\narch/arm/boot/dts/axis/artpec6.dtsi-309-\t\t\t\tsnps,wr_osr_lmt = \u003c1\u003e;\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi=325=\t\tscm {\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-329-\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi:330:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-331-\t\tsnps,wr_osr_lmt = \u003c7\u003e;\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi=1291=\t\tgmac0: ethernet@37000000 {\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1297-\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi:1298:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1299-\t\t\tsnps,pbl = \u003c32\u003e;\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi=1315=\t\tgmac1: ethernet@37200000 {\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1321-\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi:1322:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1323-\t\t\tsnps,pbl = \u003c32\u003e;\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi=1339=\t\tgmac2: ethernet@37400000 {\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1345-\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi:1346:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1347-\t\t\tsnps,pbl = \u003c32\u003e;\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi=1363=\t\tgmac3: ethernet@37600000 {\n--\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1369-\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi:1370:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/qcom/qcom-ipq8064.dtsi-1371-\t\t\tsnps,pbl = \u003c32\u003e;\n--\narch/arm/boot/dts/rockchip/rv1126.dtsi=633=\tgmac: ethernet@ffc40000 {\n--\narch/arm/boot/dts/rockchip/rv1126.dtsi-653-\narch/arm/boot/dts/rockchip/rv1126.dtsi:654:\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm/boot/dts/rockchip/rv1126.dtsi-655-\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\narch/arm/boot/dts/rockchip/rv1126.dtsi=659=\t\tmdio: mdio {\n--\narch/arm/boot/dts/rockchip/rv1126.dtsi-664-\narch/arm/boot/dts/rockchip/rv1126.dtsi:665:\t\tstmmac_axi_setup: stmmac-axi-config {\narch/arm/boot/dts/rockchip/rv1126.dtsi-666-\t\t\tsnps,wr_osr_lmt = \u003c4\u003e;\n--\narch/arm/boot/dts/st/stm32mp131.dtsi=1730=\t\t\tethernet1: ethernet@5800a000 {\n--\narch/arm/boot/dts/st/stm32mp131.dtsi-1751-\t\t\t\tsnps,pbl = \u003c2\u003e;\narch/arm/boot/dts/st/stm32mp131.dtsi:1752:\t\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_config_1\u003e;\narch/arm/boot/dts/st/stm32mp131.dtsi-1753-\t\t\t\tsnps,tso;\n--\narch/arm/boot/dts/st/stm32mp131.dtsi-1758-\narch/arm/boot/dts/st/stm32mp131.dtsi:1759:\t\t\t\tstmmac_axi_config_1: stmmac-axi-config {\narch/arm/boot/dts/st/stm32mp131.dtsi-1760-\t\t\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm/boot/dts/st/stm32mp133.dtsi=74=\tethernet2: ethernet@5800e000 {\n--\narch/arm/boot/dts/st/stm32mp133.dtsi-94-\t\tsnps,pbl = \u003c2\u003e;\narch/arm/boot/dts/st/stm32mp133.dtsi:95:\t\tsnps,axi-config = \u003c\u0026stmmac_axi_config_2\u003e;\narch/arm/boot/dts/st/stm32mp133.dtsi-96-\t\tsnps,tso;\n--\narch/arm/boot/dts/st/stm32mp133.dtsi-101-\narch/arm/boot/dts/st/stm32mp133.dtsi:102:\t\tstmmac_axi_config_2: stmmac-axi-config {\narch/arm/boot/dts/st/stm32mp133.dtsi-103-\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm/boot/dts/st/stm32mp151.dtsi=1962=\t\t\tethernet0: ethernet@5800a000 {\n--\narch/arm/boot/dts/st/stm32mp151.dtsi-1982-\t\t\t\tsnps,pbl = \u003c2\u003e;\narch/arm/boot/dts/st/stm32mp151.dtsi:1983:\t\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_config_0\u003e;\narch/arm/boot/dts/st/stm32mp151.dtsi-1984-\t\t\t\tsnps,tso;\n--\narch/arm/boot/dts/st/stm32mp151.dtsi-1987-\narch/arm/boot/dts/st/stm32mp151.dtsi:1988:\t\t\t\tstmmac_axi_config_0: stmmac-axi-config {\narch/arm/boot/dts/st/stm32mp151.dtsi-1989-\t\t\t\t\tsnps,wr_osr_lmt = \u003c0x7\u003e;\n--\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi=856=\t\tgmac1: ethernet@4510000 {\n--\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi-870-\t\t\tsnps,fixed-burst;\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi:871:\t\t\tsnps,axi-config = \u003c\u0026gmac1_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi-872-\t\t\tsnps,mtl-rx-config = \u003c\u0026gmac1_mtl_rx_setup\u003e;\n--\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi=882=\t\t\tgmac1_mtl_rx_setup: rx-queues-config {\n--\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi-887-\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi:888:\t\t\tgmac1_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/allwinner/sun55i-a523.dtsi-889-\t\t\t\tsnps,wr_osr_lmt = \u003c0xf\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi=555=\t\tgmac0: ethernet@10810000 {\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-602-\t\t\tsnps,perfect-filter-entries = \u003c64\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:603:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_emac0_setup\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-604-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_emac0_setup\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-613-\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:614:\t\t\tstmmac_axi_emac0_setup: stmmac-axi-config {\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-615-\t\t\t\tsnps,wr_osr_lmt = \u003c31\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi=701=\t\tgmac1: ethernet@10820000 {\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-748-\t\t\tsnps,perfect-filter-entries = \u003c64\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:749:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_emac1_setup\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-750-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_emac1_setup\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-759-\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:760:\t\t\tstmmac_axi_emac1_setup: stmmac-axi-config {\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-761-\t\t\t\tsnps,wr_osr_lmt = \u003c31\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi=847=\t\tgmac2: ethernet@10830000 {\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-894-\t\t\tsnps,perfect-filter-entries = \u003c64\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:895:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_emac2_setup\u003e;\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-896-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_emac2_setup\u003e;\n--\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-905-\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:906:\t\t\tstmmac_axi_emac2_setup: stmmac-axi-config {\narch/arm64/boot/dts/intel/socfpga_agilex5.dtsi-907-\t\t\t\tsnps,wr_osr_lmt = \u003c31\u003e;\n--\narch/arm64/boot/dts/mediatek/mt2712e.dtsi=681=\tuart4: serial@11019000 {\n--\narch/arm64/boot/dts/mediatek/mt2712e.dtsi-693-\narch/arm64/boot/dts/mediatek/mt2712e.dtsi:694:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/mediatek/mt2712e.dtsi-695-\t\tsnps,wr_osr_lmt = \u003c0x7\u003e;\n--\narch/arm64/boot/dts/mediatek/mt2712e.dtsi=730=\teth: ethernet@1101c000 {\n--\narch/arm64/boot/dts/mediatek/mt2712e.dtsi-753-\t\tmediatek,pericfg = \u003c\u0026pericfg\u003e;\narch/arm64/boot/dts/mediatek/mt2712e.dtsi:754:\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/mediatek/mt2712e.dtsi-755-\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\narch/arm64/boot/dts/mediatek/mt8188.dtsi=1736=\t\teth: ethernet@11021000 {\n--\narch/arm64/boot/dts/mediatek/mt8188.dtsi-1757-\t\t\tmediatek,pericfg = \u003c\u0026infracfg_ao\u003e;\narch/arm64/boot/dts/mediatek/mt8188.dtsi:1758:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/mediatek/mt8188.dtsi-1759-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\narch/arm64/boot/dts/mediatek/mt8188.dtsi=1766=\t\t\teth_mdio: mdio {\n--\narch/arm64/boot/dts/mediatek/mt8188.dtsi-1771-\narch/arm64/boot/dts/mediatek/mt8188.dtsi:1772:\t\t\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/mediatek/mt8188.dtsi-1773-\t\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/mediatek/mt8195.dtsi=1301=\t\teth: ethernet@11021000 {\n--\narch/arm64/boot/dts/mediatek/mt8195.dtsi-1325-\t\t\tmediatek,pericfg = \u003c\u0026infracfg_ao\u003e;\narch/arm64/boot/dts/mediatek/mt8195.dtsi:1326:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/mediatek/mt8195.dtsi-1327-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup\u003e;\n--\narch/arm64/boot/dts/mediatek/mt8195.dtsi=1334=\t\t\tmdio {\n--\narch/arm64/boot/dts/mediatek/mt8195.dtsi-1339-\narch/arm64/boot/dts/mediatek/mt8195.dtsi:1340:\t\t\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/mediatek/mt8195.dtsi-1341-\t\t\t\tsnps,wr_osr_lmt = \u003c0x7\u003e;\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi=770=\t\teth0: ethernet@11c30000 {\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-814-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a08g046.dtsi:815:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-816-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi=887=\t\teth1: ethernet@11c40000 {\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-931-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a08g046.dtsi:932:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-933-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi=1032=\t\twdt0: watchdog@12800800 {\n--\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-1046-\narch/arm64/boot/dts/renesas/r9a08g046.dtsi:1047:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a08g046.dtsi-1048-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi=1839=\t\teth0: ethernet@15c30000 {\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-1871-\t\t\tsnps,force_sf_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g047.dtsi:1872:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-1873-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi=1939=\t\teth1: ethernet@15c40000 {\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-1971-\t\t\tsnps,force_sf_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g047.dtsi:1972:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-1973-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi=2146=\t\tvspd1: vsp@164b0000 {\n--\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-2160-\narch/arm64/boot/dts/renesas/r9a09g047.dtsi:2161:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a09g047.dtsi-2162-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi=1510=\t\teth0: ethernet@15c30000 {\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1543-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g056.dtsi:1544:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1545-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi=1611=\t\teth1: ethernet@15c40000 {\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1644-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g056.dtsi:1645:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1646-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi=1788=\t\tvspd: vsp@16480000 {\n--\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1801-\narch/arm64/boot/dts/renesas/r9a09g056.dtsi:1802:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a09g056.dtsi-1803-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi=1640=\t\teth0: ethernet@15c30000 {\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1673-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g057.dtsi:1674:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1675-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi=1741=\t\teth1: ethernet@15c40000 {\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1774-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g057.dtsi:1775:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1776-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi=1918=\t\tvspd: vsp@16480000 {\n--\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1931-\narch/arm64/boot/dts/renesas/r9a09g057.dtsi:1932:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a09g057.dtsi-1933-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi=534=\t\tgmac0: ethernet@80100000 {\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-576-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi:577:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-578-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi=680=\t\tgmac1: ethernet@92000000 {\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-722-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi:723:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-724-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi=826=\t\tgmac2: ethernet@92010000 {\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-868-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi:869:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-870-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup2\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi=1372=\t\t\tsdhi1_vqmmc: vqmmc-regulator {\n--\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-1380-\narch/arm64/boot/dts/renesas/r9a09g077.dtsi:1381:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a09g077.dtsi-1382-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi=534=\t\tgmac0: ethernet@80100000 {\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-577-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi:578:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-579-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup0\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi=681=\t\tgmac1: ethernet@92000000 {\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-724-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi:725:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-726-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup1\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi=828=\t\tgmac2: ethernet@92010000 {\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-871-\t\t\tsnps,force_thresh_dma_mode;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi:872:\t\t\tsnps,axi-config = \u003c\u0026stmmac_axi_setup\u003e;\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-873-\t\t\tsnps,mtl-rx-config = \u003c\u0026mtl_rx_setup2\u003e;\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi=1375=\t\t\tsdhi1_vqmmc: vqmmc-regulator {\n--\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-1383-\narch/arm64/boot/dts/renesas/r9a09g087.dtsi:1384:\tstmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/renesas/r9a09g087.dtsi-1385-\t\tsnps,lpi_en;\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi=1058=\t\tgmac0: ethernet@ffbd0000 {\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1075-\t\t\trockchip,grf = \u003c\u0026vo_grf\u003e;\narch/arm64/boot/dts/rockchip/rk3528.dtsi:1076:\t\t\tsnps,axi-config = \u003c\u0026gmac0_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1077-\t\t\tsnps,mixed-burst;\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi=1088=\t\t\t\trmii0_phy: ethernet-phy@2 {\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1099-\narch/arm64/boot/dts/rockchip/rk3528.dtsi:1100:\t\t\tgmac0_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1101-\t\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi=1117=\t\tgmac1: ethernet@ffbe0000 {\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1134-\t\t\trockchip,grf = \u003c\u0026vpu_grf\u003e;\narch/arm64/boot/dts/rockchip/rk3528.dtsi:1135:\t\t\tsnps,axi-config = \u003c\u0026gmac1_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1136-\t\t\tsnps,mixed-burst;\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi=1142=\t\t\tmdio1: mdio {\n--\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1147-\narch/arm64/boot/dts/rockchip/rk3528.dtsi:1148:\t\t\tgmac1_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/rockchip/rk3528.dtsi-1149-\t\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3568.dtsi=306=\tgmac0: ethernet@fe2a0000 {\n--\narch/arm64/boot/dts/rockchip/rk3568.dtsi-322-\t\trockchip,grf = \u003c\u0026grf\u003e;\narch/arm64/boot/dts/rockchip/rk3568.dtsi:323:\t\tsnps,axi-config = \u003c\u0026gmac0_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/rockchip/rk3568.dtsi-324-\t\tsnps,mixed-burst;\n--\narch/arm64/boot/dts/rockchip/rk3568.dtsi=330=\t\tmdio0: mdio {\n--\narch/arm64/boot/dts/rockchip/rk3568.dtsi-335-\narch/arm64/boot/dts/rockchip/rk3568.dtsi:336:\t\tgmac0_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/rockchip/rk3568.dtsi-337-\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi=700=\tgmac1: ethernet@fe010000 {\n--\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi-716-\t\trockchip,grf = \u003c\u0026grf\u003e;\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi:717:\t\tsnps,axi-config = \u003c\u0026gmac1_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi-718-\t\tsnps,mixed-burst;\n--\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi=724=\t\tmdio1: mdio {\n--\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi-729-\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi:730:\t\tgmac1_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/rockchip/rk356x-base.dtsi-731-\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3576.dtsi=1835=\t\tgmac0: ethernet@2a220000 {\n--\narch/arm64/boot/dts/rockchip/rk3576.dtsi-1852-\t\t\trockchip,php-grf = \u003c\u0026ioc_grf\u003e;\narch/arm64/boot/dts/rockchip/rk3576.dtsi:1853:\t\t\tsnps,axi-config = \u003c\u0026gmac0_stmmac_axi_setup\u003e;\narch/arm64/boot/dts/rockchip/rk3576.dtsi-1854-\t\t\tsnps,mixed-burst;\n--\narch/arm64/boot/dts/rockchip/rk3576.dtsi=1860=\t\t\tmdio0: mdio {\n--\narch/arm64/boot/dts/rockchip/rk3576.dtsi-1865-\narch/arm64/boot/dts/rockchip/rk3576.dtsi:1866:\t\t\tgmac0_stmmac_axi_setup: stmmac-axi-config {\narch/arm64/boot/dts/rockchip/rk3576.dtsi-1867-\t\t\t\tsnps,blen = \u003c0 0 0 0 16 8 4\u003e;\n--\narch/arm64/boot/dts/rockchip/rk3576.dtsi=1883=\t\tgmac1: ethernet@2a230000 {\n--\n\n"
}

5/2 2026/09/02 05:10 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 37216
							output: 48
							thoughts: 359
						

Thoughts:
**My Assessment of QEMU and the `stmmac` Driver**

Okay, let's break this down. First, `stmmac` – right, that's the driver for Synopsys DesignWare Ethernet MACs. It's ubiquitous in embedded systems, the Rockchips, Allwinners, STM32s, Renesas, Socfpgas, and even Intel SoCs. My immediate question is, does QEMU emulate this directly, or is there a pathway to it within the standard environments, particularly the ones that would be relevant for my work with syzkaller on x86_64 or arm64 virt machines?

My first instinct is to see what network devices QEMU natively supports. E1000, e1000e, igb, rtl8139, the usual suspects. But, hold on... does it actually emulate `dwmac` or `stmmac` directly? Ah, on *specific* ARM boards, like STM32, there's `dwc_eth_qos` or `stm32_dwmac` or similar. However, that's not what I'm targeting here; those are for specialized cases. So, for the general QEMU / GCE x86_64 and arm64 virtual machines, there's no `stmmac` device present. No virtual or emulated `stmmac` at all in the standard builds. That's a key piece of information.

Wait, then what about the `dwmac-intel.c` file? Looking at that, it's a PCI driver. So, my next step is to examine that in more detail and see how it fits into the broader picture. Let's inspect `dwmac-intel.c` to see if that helps me.



6/2 2026/09/02 05:10 tool grepper
0m Args:
{
  "Expression": "MODULE_DEVICE_TABLE\\(pci",
  "PathPrefix": "drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c"
}

Results:
{
  "Output": "drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=1431=static const struct pci_device_id intel_eth_pci_id_table[] = {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1450-};\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1451:MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1452-\n"
}

7/2 2026/09/02 05:10 llm patch-evaluator
0m Model:
gemini-3.7-flash

Args:
null

Results:
null

Tokens:
							input: 38177
							output: 171
							thoughts: 1333
						

Thoughts:
**Analysis of the Patch: WorthFuzzing Evaluation**

Okay, here's the breakdown of my thought process on this patch. I'm looking at a complex set of changes. It seems like the patch touches a bunch of drivers: `dwmac-intel.c`, `dwmac-rk.c`, `pcs-xpcs-rk.c`, `phy-rockchip-naneng-combphy.c`, `dwmac-renesas-gbeth.c`, `dwmac-rzn1.c`, `dwmac-socfpga.c`, `stmmac_mdio.c`, and `pcs-xpcs.c`. These are all related to Ethernet, specifically drivers for various hardware: Intel PCIe devices, Rockchip platforms, Renesas SoCs, Intel/Altera SoC platforms, and some common stmmac and pcs code.

First, let's establish the context, by carefully reviewing the instructions. I need to determine if this code is "WorthFuzzing" or not. Based on the prompt, I need to make a judgement call. Modifications to documentation or Kconfig/Makefile? Check. Purely decorative changes? Check. Constants or macros that don't functionally alter execution flow? Not yet. Impossible code paths in a virtualized environment? Hmm... let's explore. Vendor-specific PCIe switch/SmartNIC/GPU drivers needing physical PCIe hardware? That is also a strong possibility. Finally, driver teardown callbacks that only execute during hot-unplug operations? Not directly relevant.

Now, let's break down the patch components: Device tree bindings for Rockchip hardware (both xpcs and the combphy), MAINTAINERS, more device tree files, Kconfig and Makefile changes, and various Rockchip-specific drivers (like the xpcs driver and the GMAC driver). I also see Renesas drivers, Intel/Altera SoC drivers, common stmmac and pcs code, and some Intel PCI driver. So it's a mix of hardware-specific and more general stmmac/pcs code.

The crux of this analysis is whether this code can be reached in standard virtualized environments like QEMU or GCE. Here's where it clicks: None of this is reachable in standard QEMU or GCE because these platforms don't emulate the specific hardware being targeted here. No virtual or emulated devices exist for stmmac or dw_xpcs, and the network interfaces provided in QEMU don't use these drivers. Neither the Rockchip SoCs nor the Intel DWMAC PCI devices exist in this virtualized environment. No virtual or emulated devices instantiate stmmac or dw_xpcs.

I've re-reviewed everything to ensure the analysis is complete. There are no core networking interfaces, arch-generic drivers, or mock interfaces affected. The code requires specific, physical hardware. It seems like the patch only contains code that is unreachable in QEMU or GCE.

Therefore, `WorthFuzzing=false` is the right call here. The patch modifications are confined to hardware-specific drivers (Rockchip, Renesas, Intel) that are not emulated in virtualized environments. The set-results parameters are clear: `WorthFuzzing: false`, `EnableConfigs: []`, `FocusSymbols: []`, with a concise reasoning. Let's make the call to `set-results`.



8/2 2026/09/02 05:10 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch series adds support for Rockchip RK3568 Synopsys DesignWare Ethernet Physical Coding Sublayer (XPCS) and SGMII interface configuration for the Rockchip DWMAC driver, along with minor PCS init/exit handling updates for Intel DWMAC PCI and other SoC glue drivers (Renesas, Socfpga). These changes are restricted to vendor-specific SoC platform drivers (Rockchip RK3568, Renesas, Socfpga) and Intel DWMAC PCI hardware, none of which are emulated in standard QEMU or virtualized cloud environments like GCE. Therefore, the modified code cannot be executed during virtualized fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch series adds support for Rockchip RK3568 Synopsys DesignWare Ethernet Physical Coding Sublayer (XPCS) and SGMII interface configuration for the Rockchip DWMAC driver, along with minor PCS init/exit handling updates for Intel DWMAC PCI and other SoC glue drivers (Renesas, Socfpga). These changes are restricted to vendor-specific SoC platform drivers (Rockchip RK3568, Renesas, Socfpga) and Intel DWMAC PCI hardware, none of which are emulated in standard QEMU or virtualized cloud environments like GCE. Therefore, the modified code cannot be executed during virtualized fuzzing.",
  "WorthFuzzing": false
}

9/1 2026/09/02 05:10 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)