| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/23 16:09 | flow | patch-triage |
8mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies Device Tree bindings and adds SerDes lane polarity and LED control callbacks for Realtek RTL8261 series 10Gbps Ethernet PHYs (RTL8261C, RTL8261CE). The modified driver code interacts with physical Realtek PHY transceiver hardware via MDIO/MMD registers based on Device Tree firmware node properties (tx-polarity, rx-polarity, leds). This physical PHY hardware and its DT bindings are not present or emulated in standard virtualized environments (QEMU/GCE on amd64), making the changes structurally unreachable for fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/09/23 16:09 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 0970ed796c012b690ab89924ea16f472a9347de6\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Sep 23 16:09:39 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml\nindex 07b39ef1fc624..b21efcb9b2551 100644\n--- a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml\n+++ b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml\n@@ -27,6 +27,9 @@ properties:\n - ethernet-phy-id001c.c862\n - ethernet-phy-id001c.c878\n - ethernet-phy-id001c.c880\n+ - ethernet-phy-id001c.c898\n+ - ethernet-phy-id001c.c899\n+ - ethernet-phy-id001c.c89a\n - ethernet-phy-id001c.c910\n - ethernet-phy-id001c.c912\n - ethernet-phy-id001c.c913\n@@ -74,15 +77,35 @@ unevaluatedProperties: false\n \n allOf:\n - $ref: ethernet-phy.yaml#\n+ - $ref: /schemas/phy/phy-common-props.yaml#\n - if:\n not:\n properties:\n compatible:\n contains:\n- const: ethernet-phy-id001c.c916\n+ enum:\n+ - ethernet-phy-id001c.c898\n+ - ethernet-phy-id001c.c899\n+ - ethernet-phy-id001c.c89a\n+ - ethernet-phy-id001c.c916\n then:\n properties:\n leds: false\n+ - if:\n+ not:\n+ properties:\n+ compatible:\n+ contains:\n+ enum:\n+ - ethernet-phy-id001c.c898\n+ - ethernet-phy-id001c.c899\n+ - ethernet-phy-id001c.c89a\n+ then:\n+ properties:\n+ rx-polarity: false\n+ rx-polarity-names: false\n+ tx-polarity: false\n+ tx-polarity-names: false\n \n examples:\n - |\n@@ -96,3 +119,30 @@ examples:\n realtek,aldps-enable;\n };\n };\n+\n+ - |\n+ #include \u003cdt-bindings/leds/common.h\u003e\n+ #include \u003cdt-bindings/phy/phy.h\u003e\n+\n+ mdio {\n+ #address-cells = \u003c1\u003e;\n+ #size-cells = \u003c0\u003e;\n+\n+ ethernet-phy@0 {\n+ compatible = \"ethernet-phy-id001c.c899\";\n+ reg = \u003c0\u003e;\n+ tx-polarity = \u003cPHY_POL_INVERT\u003e;\n+ rx-polarity = \u003cPHY_POL_INVERT\u003e;\n+\n+ leds {\n+ #address-cells = \u003c1\u003e;\n+ #size-cells = \u003c0\u003e;\n+\n+ led@3 {\n+ reg = \u003c3\u003e;\n+ color = \u003cLED_COLOR_ID_GREEN\u003e;\n+ function = LED_FUNCTION_LAN;\n+ };\n+ };\n+ };\n+ };\ndiff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig\nindex a741b34d193ed..a9272aebe26d3 100644\n--- a/drivers/net/phy/realtek/Kconfig\n+++ b/drivers/net/phy/realtek/Kconfig\n@@ -1,6 +1,7 @@\n # SPDX-License-Identifier: GPL-2.0-only\n config REALTEK_PHY\n \ttristate \"Realtek PHYs\"\n+\tselect PHY_COMMON_PROPS\n \tselect PHY_PACKAGE\n \thelp\n \t Currently supports RTL821x/RTL822x and fast ethernet PHYs\ndiff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c\nindex 1e670638dd1c7..b1f020aa77604 100644\n--- a/drivers/net/phy/realtek/realtek_main.c\n+++ b/drivers/net/phy/realtek/realtek_main.c\n@@ -13,9 +13,11 @@\n #include \u003clinux/firmware.h\u003e\n #include \u003clinux/of.h\u003e\n #include \u003clinux/phy.h\u003e\n+#include \u003clinux/phy/phy-common-props.h\u003e\n #include \u003clinux/pm_wakeirq.h\u003e\n #include \u003clinux/netdevice.h\u003e\n #include \u003clinux/module.h\u003e\n+#include \u003clinux/property.h\u003e\n #include \u003clinux/delay.h\u003e\n #include \u003clinux/clk.h\u003e\n #include \u003clinux/string_choices.h\u003e\n@@ -164,6 +166,7 @@\n #define RTL822X_VND1_SERDES_INBAND_DISABLE\t0x71d0\n #define RTL822X_VND1_SERDES_INBAND_ENABLE\t0x70d0\n #define RTL822X_VND1_SERDES_DATA\t\t0x7589\n+#define RTL822X_VND1_SERDES_RDATA\t\t0x758a\n \n #define RTL822X_VND2_TO_PAGE(reg)\t\t((reg) \u003e\u003e 4)\n #define RTL822X_VND2_TO_PAGE_REG(reg)\t\t(16 + (((reg) \u0026 GENMASK(3, 0)) \u003e\u003e 1))\n@@ -180,12 +183,15 @@\n #define RTL822X_VND2_LCR_LINK_100\t\tBIT(1)\n #define RTL822X_VND2_LCR_LINK_1000\t\tBIT(2)\n #define RTL822X_VND2_LCR_LINK_2500\t\tBIT(5)\n+#define RTL822X_VND2_LCR_LINK_5000\t\tBIT(6)\n+#define RTL822X_VND2_LCR_LINK_10000\t\tBIT(4)\n \n #define RTL822X_VND2_LCR6\t\t\t0xd040\n #define RTL822X_VND2_LED_ACT(x)\t\t\tBIT(x)\n \n #define RTL822X_VND2_LCR7\t\t\t0xd044\n #define RTL822X_VND2_LED_POLAR(x)\t\tBIT(x)\n+#define RTL822X_VND2_LED_EN(x)\t\t\tBIT((x) + 4)\n \n #define RTL8224_MII_RTCT\t\t\t0x11\n #define RTL8224_MII_RTCT_ENABLE\t\t\tBIT(0)\n@@ -271,6 +277,18 @@\n #define RTL8261X_INT_ALDPS_CHG\t\tBIT(9)\n #define RTL8261X_INT_JABBER\t\tBIT(10)\n \n+/* SerDes lane polarity, behind the VEND1 SerDes command window. This is not\n+ * the global inversion bit that other Realtek 10G PHYs use; the bit\n+ * assignment below has only been verified on an RTL8261CE reporting PHY ID\n+ * 0x001cc899.\n+ */\n+#define RTL8261X_SERDES_POL_REG0\t0x0000\n+#define RTL8261X_SERDES_POL_REG0_TX\tBIT(8)\n+#define RTL8261X_SERDES_POL_REG0_RX\tBIT(9)\n+#define RTL8261X_SERDES_POL_REGC2\t0x00c2\n+#define RTL8261X_SERDES_POL_REGC2_TX\tBIT(14)\n+#define RTL8261X_SERDES_POL_REGC2_RX\tBIT(13)\n+\n #define RTL8261X_INT_MASK_DEFAULT\t(RTL8261X_INT_AUTONEG_DONE | \\\n \t\t\t\t\t RTL8261X_INT_LINK_CHG | \\\n \t\t\t\t\t RTL8261X_INT_AUTONEG_ERROR | \\\n@@ -290,6 +308,7 @@\n #define FW_SUB_MAGIC_8261D\t\t0x32363144\n #define RTL8261X_POLL_TIMEOUT_MS\t100\n #define RTL8261X_MAX_MMD_DEV\t\t31\n+#define RTL8261X_LED_COUNT\t\t4\n \n #define RTL8261C_CE_FW_NAME\t\"rtl_nic/rtl8261c.bin\"\n #define RTL8261D_FW_NAME\t\"rtl_nic/rtl8261d.bin\"\n@@ -349,6 +368,11 @@ struct rtl8261x_priv {\n \tconst char *fw_name;\n \tu32 fw_sub_magic;\n \tbool fw_loaded;\n+\t/* LCR7's polarity bit doubles as the manual on/off level in\n+\t * led_brightness_set(), so the configured polarity is kept here\n+\t * to restore it whenever hardware control is set up again.\n+\t */\n+\tu8 led_active_low;\n };\n \n static int rtl821x_read_page(struct phy_device *phydev)\n@@ -708,18 +732,147 @@ static int rtl8261x_config_aneg(struct phy_device *phydev)\n \treturn 0;\n }\n \n+static int rtl822x_serdes_wait(struct phy_device *phydev)\n+{\n+\tint poll;\n+\n+\treturn phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,\n+\t\t\t\t\t RTL822X_VND1_SERDES_CMD, poll,\n+\t\t\t\t\t !(poll \u0026 RTL822X_VND1_SERDES_CMD_BUSY),\n+\t\t\t\t\t 500, 100000, false);\n+}\n+\n+static int rtl822x_serdes_read(struct phy_device *phydev, u16 reg)\n+{\n+\tint ret;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,\n+\t\t\t RTL822X_VND1_SERDES_CMD_BUSY);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\tret = rtl822x_serdes_wait(phydev);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\treturn phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_RDATA);\n+}\n+\n+static int rtl822x_serdes_write(struct phy_device *phydev, u16 reg, u16 val)\n+{\n+\tint ret;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_DATA, val);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,\n+\t\t\t RTL822X_VND1_SERDES_CMD_WRITE |\n+\t\t\t RTL822X_VND1_SERDES_CMD_BUSY);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\treturn rtl822x_serdes_wait(phydev);\n+}\n+\n+static int rtl822x_serdes_modify(struct phy_device *phydev, u16 reg,\n+\t\t\t\t u16 mask, u16 set)\n+{\n+\tint val;\n+\n+\tval = rtl822x_serdes_read(phydev, reg);\n+\tif (val \u003c 0)\n+\t\treturn val;\n+\n+\tif ((val \u0026 mask) == set)\n+\t\treturn 0;\n+\n+\treturn rtl822x_serdes_write(phydev, reg, (val \u0026 ~mask) | set);\n+}\n+\n+/* The host-side SerDes lanes are only inverted when the board says so.\n+ * Lanes the firmware node does not describe are left as the boot loader\n+ * and PHY firmware left them.\n+ */\n+static int rtl8261x_config_serdes_polarity(struct phy_device *phydev)\n+{\n+\tbool tx_present, rx_present, tx_invert = false, rx_invert = false;\n+\tu16 reg0_mask = 0, reg0_set = 0, regc2_mask = 0, regc2_set = 0;\n+\tstruct fwnode_handle *fwnode = dev_fwnode(\u0026phydev-\u003emdio.dev);\n+\tconst char *mode = phy_modes(phydev-\u003einterface);\n+\tunsigned int pol;\n+\tint ret;\n+\n+\ttx_present = fwnode_property_present(fwnode, \"tx-polarity\");\n+\trx_present = fwnode_property_present(fwnode, \"rx-polarity\");\n+\tif (!tx_present \u0026\u0026 !rx_present)\n+\t\treturn 0;\n+\n+\tif (tx_present) {\n+\t\tret = phy_get_manual_tx_polarity(fwnode, mode, \u0026pol);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\ttx_invert = pol == PHY_POL_INVERT;\n+\t}\n+\n+\tif (rx_present) {\n+\t\tret = phy_get_manual_rx_polarity(fwnode, mode, \u0026pol);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\trx_invert = pol == PHY_POL_INVERT;\n+\t}\n+\n+\tif (tx_present) {\n+\t\treg0_mask |= RTL8261X_SERDES_POL_REG0_TX;\n+\t\tregc2_mask |= RTL8261X_SERDES_POL_REGC2_TX;\n+\t\tif (tx_invert) {\n+\t\t\treg0_set |= RTL8261X_SERDES_POL_REG0_TX;\n+\t\t\tregc2_set |= RTL8261X_SERDES_POL_REGC2_TX;\n+\t\t}\n+\t}\n+\n+\tif (rx_present) {\n+\t\treg0_mask |= RTL8261X_SERDES_POL_REG0_RX;\n+\t\tregc2_mask |= RTL8261X_SERDES_POL_REGC2_RX;\n+\t\tif (rx_invert) {\n+\t\t\treg0_set |= RTL8261X_SERDES_POL_REG0_RX;\n+\t\t\tregc2_set |= RTL8261X_SERDES_POL_REGC2_RX;\n+\t\t}\n+\t}\n+\n+\tret = rtl822x_serdes_modify(phydev, RTL8261X_SERDES_POL_REG0,\n+\t\t\t\t reg0_mask, reg0_set);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\treturn rtl822x_serdes_modify(phydev, RTL8261X_SERDES_POL_REGC2,\n+\t\t\t\t regc2_mask, regc2_set);\n+}\n+\n static int rtl8261x_config_init(struct phy_device *phydev)\n {\n \tstruct rtl8261x_priv *priv = phydev-\u003epriv;\n+\tint ret;\n \n \t/* The firmware parameters are preserved across IEEE soft resets and\n \t * suspend/resume cycles. Reloading is only necessary after a power\n \t * cycle or hard reset.\n \t */\n-\tif (priv-\u003efw_name \u0026\u0026 !priv-\u003efw_loaded)\n-\t\treturn rtl8261x_fw_load(phydev);\n+\tif (priv-\u003efw_name \u0026\u0026 !priv-\u003efw_loaded) {\n+\t\tret = rtl8261x_fw_load(phydev);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n \n-\treturn 0;\n+\treturn rtl8261x_config_serdes_polarity(phydev);\n }\n \n static int rtl821x_probe(struct phy_device *phydev)\n@@ -2120,30 +2273,6 @@ static int rtl822xb_config_init(struct phy_device *phydev)\n \treturn rtl822x_set_serdes_option_mode(phydev, false);\n }\n \n-static int rtl822x_serdes_write(struct phy_device *phydev, u16 reg, u16 val)\n-{\n-\tint ret, poll;\n-\n-\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);\n-\tif (ret \u003c 0)\n-\t\treturn ret;\n-\n-\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_DATA, val);\n-\tif (ret \u003c 0)\n-\t\treturn ret;\n-\n-\tret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,\n-\t\t\t RTL822X_VND1_SERDES_CMD_WRITE |\n-\t\t\t RTL822X_VND1_SERDES_CMD_BUSY);\n-\tif (ret \u003c 0)\n-\t\treturn ret;\n-\n-\treturn phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,\n-\t\t\t\t\t RTL822X_VND1_SERDES_CMD, poll,\n-\t\t\t\t\t !(poll \u0026 RTL822X_VND1_SERDES_CMD_BUSY),\n-\t\t\t\t\t 500, 100000, false);\n-}\n-\n static int rtl822x_config_inband(struct phy_device *phydev, unsigned int modes)\n {\n \treturn rtl822x_serdes_write(phydev, RTL822X_VND1_SERDES_ADDR_AUTONEG,\n@@ -2410,6 +2539,215 @@ static int rtl822xb_led_brightness_set(struct phy_device *phydev, u8 index,\n \t\t\t\t\t RTL822X_VND2_LED_POLAR(index));\n }\n \n+static int rtl8261x_led_hw_is_supported(struct phy_device *phydev, u8 index,\n+\t\t\t\t\tunsigned long rules)\n+{\n+\tconst unsigned long act_mask = BIT(TRIGGER_NETDEV_RX) |\n+\t\t\t\t BIT(TRIGGER_NETDEV_TX);\n+\tconst unsigned long link_mask = BIT(TRIGGER_NETDEV_LINK) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_10) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_100) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_1000) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_2500) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_5000) |\n+\t\t\t\t\tBIT(TRIGGER_NETDEV_LINK_10000);\n+\n+\tif (index \u003e= RTL8261X_LED_COUNT)\n+\t\treturn -EINVAL;\n+\n+\t/* Filter out any other unsupported triggers. */\n+\tif (rules \u0026 ~(link_mask | act_mask))\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* RX and TX are not differentiated, they are not possible\n+\t * without combination with a link trigger.\n+\t */\n+\tif ((rules \u0026 act_mask) \u0026\u0026 !(rules \u0026 link_mask))\n+\t\treturn -EOPNOTSUPP;\n+\n+\treturn 0;\n+}\n+\n+static int rtl8261x_led_hw_control_get(struct phy_device *phydev, u8 index,\n+\t\t\t\t unsigned long *rules)\n+{\n+\tconst u16 all_links = RTL822X_VND2_LCR_LINK_10 |\n+\t\t\t RTL822X_VND2_LCR_LINK_100 |\n+\t\t\t RTL822X_VND2_LCR_LINK_1000 |\n+\t\t\t RTL822X_VND2_LCR_LINK_2500 |\n+\t\t\t RTL822X_VND2_LCR_LINK_5000 |\n+\t\t\t RTL822X_VND2_LCR_LINK_10000;\n+\tint val;\n+\n+\tif (index \u003e= RTL8261X_LED_COUNT)\n+\t\treturn -EINVAL;\n+\n+\tval = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LED(index));\n+\tif (val \u003c 0)\n+\t\treturn val;\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_10)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_10, rules);\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_100)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_100, rules);\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_1000)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_1000, rules);\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_2500)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_2500, rules);\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_5000)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_5000, rules);\n+\n+\tif (val \u0026 RTL822X_VND2_LCR_LINK_10000)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK_10000, rules);\n+\n+\tif ((val \u0026 all_links) == all_links)\n+\t\t__set_bit(TRIGGER_NETDEV_LINK, rules);\n+\n+\tval = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6);\n+\tif (val \u003c 0)\n+\t\treturn val;\n+\n+\tif (val \u0026 RTL822X_VND2_LED_ACT(index)) {\n+\t\t__set_bit(TRIGGER_NETDEV_RX, rules);\n+\t\t__set_bit(TRIGGER_NETDEV_TX, rules);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int rtl8261x_led_hw_control_set(struct phy_device *phydev, u8 index,\n+\t\t\t\t unsigned long rules)\n+{\n+\tstruct rtl8261x_priv *priv = phydev-\u003epriv;\n+\tu16 lcr7 = RTL822X_VND2_LED_EN(index);\n+\tu16 val = 0;\n+\tbool act;\n+\tint ret;\n+\n+\tif (index \u003e= RTL8261X_LED_COUNT)\n+\t\treturn -EINVAL;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_10, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_10;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_100, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_100;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_1000, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_1000;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_2500, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_2500;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_5000, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_5000;\n+\n+\tif (test_bit(TRIGGER_NETDEV_LINK, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_LINK_10000, \u0026rules))\n+\t\tval |= RTL822X_VND2_LCR_LINK_10000;\n+\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND2,\n+\t\t\t RTL822X_VND2_LED(index), val);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\tact = test_bit(TRIGGER_NETDEV_RX, \u0026rules) ||\n+\t test_bit(TRIGGER_NETDEV_TX, \u0026rules);\n+\n+\tret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6,\n+\t\t\t RTL822X_VND2_LED_ACT(index), act ?\n+\t\t\t RTL822X_VND2_LED_ACT(index) : 0);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\t/* Enable the output and restore the configured polarity, which\n+\t * led_brightness_set() may have used as a level.\n+\t */\n+\tif (priv-\u003eled_active_low \u0026 BIT(index))\n+\t\tlcr7 |= RTL822X_VND2_LED_POLAR(index);\n+\n+\treturn phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,\n+\t\t\t RTL822X_VND2_LED_EN(index) |\n+\t\t\t RTL822X_VND2_LED_POLAR(index), lcr7);\n+}\n+\n+static int rtl8261x_led_brightness_set(struct phy_device *phydev, u8 index,\n+\t\t\t\t enum led_brightness value)\n+{\n+\tstruct rtl8261x_priv *priv = phydev-\u003epriv;\n+\tu16 lcr7 = RTL822X_VND2_LED_EN(index);\n+\tbool active_low, on;\n+\tint ret;\n+\n+\tif (index \u003e= RTL8261X_LED_COUNT)\n+\t\treturn -EINVAL;\n+\n+\t/* clear HW LED setup */\n+\tret = phy_write_mmd(phydev, MDIO_MMD_VEND2,\n+\t\t\t RTL822X_VND2_LED(index), 0);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\t/* clear HW LED blink */\n+\tret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6,\n+\t\t\t\t RTL822X_VND2_LED_ACT(index));\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n+\n+\t/* With no link condition selected the output sits at its idle\n+\t * level, so inverting the polarity turns the LED on.\n+\t */\n+\tactive_low = priv-\u003eled_active_low \u0026 BIT(index);\n+\ton = value != LED_OFF;\n+\tif (on != active_low)\n+\t\tlcr7 |= RTL822X_VND2_LED_POLAR(index);\n+\n+\treturn phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,\n+\t\t\t RTL822X_VND2_LED_EN(index) |\n+\t\t\t RTL822X_VND2_LED_POLAR(index), lcr7);\n+}\n+\n+static int rtl8261x_led_polarity_set(struct phy_device *phydev, int index,\n+\t\t\t\t unsigned long modes)\n+{\n+\tstruct rtl8261x_priv *priv = phydev-\u003epriv;\n+\tbool active_low = false;\n+\tu32 mode;\n+\n+\tif (index \u003e= RTL8261X_LED_COUNT)\n+\t\treturn -EINVAL;\n+\n+\tfor_each_set_bit(mode, \u0026modes, __PHY_LED_MODES_NUM) {\n+\t\tswitch (mode) {\n+\t\tcase PHY_LED_ACTIVE_LOW:\n+\t\t\tactive_low = true;\n+\t\t\tbreak;\n+\t\tcase PHY_LED_ACTIVE_HIGH:\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (active_low)\n+\t\tpriv-\u003eled_active_low |= BIT(index);\n+\telse\n+\t\tpriv-\u003eled_active_low \u0026= ~BIT(index);\n+\n+\treturn phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,\n+\t\t\t RTL822X_VND2_LED_POLAR(index),\n+\t\t\t active_low ? RTL822X_VND2_LED_POLAR(index) : 0);\n+}\n+\n static int rtl822xb_led_hw_is_supported(struct phy_device *phydev, u8 index,\n \t\t\t\t\tunsigned long rules)\n {\n@@ -3374,6 +3712,11 @@ static struct phy_driver realtek_drvs[] = {\n \t\t.soft_reset\t\t= genphy_c45_pma_soft_reset,\n \t\t.suspend\t\t= genphy_c45_pma_suspend,\n \t\t.resume\t\t\t= genphy_c45_pma_resume,\n+\t\t.led_brightness_set\t= rtl8261x_led_brightness_set,\n+\t\t.led_hw_is_supported\t= rtl8261x_led_hw_is_supported,\n+\t\t.led_hw_control_get\t= rtl8261x_led_hw_control_get,\n+\t\t.led_hw_control_set\t= rtl8261x_led_hw_control_set,\n+\t\t.led_polarity_set\t= rtl8261x_led_polarity_set,\n \t}, {\n \t\tPHY_ID_MATCH_EXACT(RTL_8261CE_CG),\n \t\t.name\t\t\t= \"Realtek RTL8261CE 10Gbps PHY\",\n@@ -3387,6 +3730,11 @@ static struct phy_driver realtek_drvs[] = {\n \t\t.soft_reset\t\t= genphy_c45_pma_soft_reset,\n \t\t.suspend\t\t= genphy_c45_pma_suspend,\n \t\t.resume\t\t\t= genphy_c45_pma_resume,\n+\t\t.led_brightness_set\t= rtl8261x_led_brightness_set,\n+\t\t.led_hw_is_supported\t= rtl8261x_led_hw_is_supported,\n+\t\t.led_hw_control_get\t= rtl8261x_led_hw_control_get,\n+\t\t.led_hw_control_set\t= rtl8261x_led_hw_control_set,\n+\t\t.led_polarity_set\t= rtl8261x_led_polarity_set,\n \t}, {\n \t\tPHY_ID_MATCH_EXACT(RTL_8261D_VM),\n \t\t.name\t\t\t= \"Realtek RTL8261D_VM 10Gbps PHY\",\n"
} |
| 2/1 | 2026/09/23 16:09 | agent | patch-evaluator |
8mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies Device Tree bindings and adds SerDes lane polarity and LED control callbacks for Realtek RTL8261 series 10Gbps Ethernet PHYs (RTL8261C, RTL8261CE). The modified driver code interacts with physical Realtek PHY transceiver hardware via MDIO/MMD registers based on Device Tree firmware node properties (tx-polarity, rx-polarity, leds). This physical PHY hardware and its DT bindings are not present or emulated in standard virtualized environments (QEMU/GCE on amd64), making the changes structurally unreachable for fuzzing.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 0970ed796c012b690ab89924ea16f472a9347de6
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Sep 23 16:09:39 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
index 07b39ef1fc624..b21efcb9b2551 100644
--- a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
+++ b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
@@ -27,6 +27,9 @@ properties:
- ethernet-phy-id001c.c862
- ethernet-phy-id001c.c878
- ethernet-phy-id001c.c880
+ - ethernet-phy-id001c.c898
+ - ethernet-phy-id001c.c899
+ - ethernet-phy-id001c.c89a
- ethernet-phy-id001c.c910
- ethernet-phy-id001c.c912
- ethernet-phy-id001c.c913
@@ -74,15 +77,35 @@ unevaluatedProperties: false
allOf:
- $ref: ethernet-phy.yaml#
+ - $ref: /schemas/phy/phy-common-props.yaml#
- if:
not:
properties:
compatible:
contains:
- const: ethernet-phy-id001c.c916
+ enum:
+ - ethernet-phy-id001c.c898
+ - ethernet-phy-id001c.c899
+ - ethernet-phy-id001c.c89a
+ - ethernet-phy-id001c.c916
then:
properties:
leds: false
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - ethernet-phy-id001c.c898
+ - ethernet-phy-id001c.c899
+ - ethernet-phy-id001c.c89a
+ then:
+ properties:
+ rx-polarity: false
+ rx-polarity-names: false
+ tx-polarity: false
+ tx-polarity-names: false
examples:
- |
@@ -96,3 +119,30 @@ examples:
realtek,aldps-enable;
};
};
+
+ - |
+ #include <dt-bindings/leds/common.h>
+ #include <dt-bindings/phy/phy.h>
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c899";
+ reg = <0>;
+ tx-polarity = <PHY_POL_INVERT>;
+ rx-polarity = <PHY_POL_INVERT>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
+ };
+ };
diff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig
index a741b34d193ed..a9272aebe26d3 100644
--- a/drivers/net/phy/realtek/Kconfig
+++ b/drivers/net/phy/realtek/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config REALTEK_PHY
tristate "Realtek PHYs"
+ select PHY_COMMON_PROPS
select PHY_PACKAGE
help
Currently supports RTL821x/RTL822x and fast ethernet PHYs
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index 1e670638dd1c7..b1f020aa77604 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -13,9 +13,11 @@
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/phy.h>
+#include <linux/phy/phy-common-props.h>
#include <linux/pm_wakeirq.h>
#include <linux/netdevice.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/string_choices.h>
@@ -164,6 +166,7 @@
#define RTL822X_VND1_SERDES_INBAND_DISABLE 0x71d0
#define RTL822X_VND1_SERDES_INBAND_ENABLE 0x70d0
#define RTL822X_VND1_SERDES_DATA 0x7589
+#define RTL822X_VND1_SERDES_RDATA 0x758a
#define RTL822X_VND2_TO_PAGE(reg) ((reg) >> 4)
#define RTL822X_VND2_TO_PAGE_REG(reg) (16 + (((reg) & GENMASK(3, 0)) >> 1))
@@ -180,12 +183,15 @@
#define RTL822X_VND2_LCR_LINK_100 BIT(1)
#define RTL822X_VND2_LCR_LINK_1000 BIT(2)
#define RTL822X_VND2_LCR_LINK_2500 BIT(5)
+#define RTL822X_VND2_LCR_LINK_5000 BIT(6)
+#define RTL822X_VND2_LCR_LINK_10000 BIT(4)
#define RTL822X_VND2_LCR6 0xd040
#define RTL822X_VND2_LED_ACT(x) BIT(x)
#define RTL822X_VND2_LCR7 0xd044
#define RTL822X_VND2_LED_POLAR(x) BIT(x)
+#define RTL822X_VND2_LED_EN(x) BIT((x) + 4)
#define RTL8224_MII_RTCT 0x11
#define RTL8224_MII_RTCT_ENABLE BIT(0)
@@ -271,6 +277,18 @@
#define RTL8261X_INT_ALDPS_CHG BIT(9)
#define RTL8261X_INT_JABBER BIT(10)
+/* SerDes lane polarity, behind the VEND1 SerDes command window. This is not
+ * the global inversion bit that other Realtek 10G PHYs use; the bit
+ * assignment below has only been verified on an RTL8261CE reporting PHY ID
+ * 0x001cc899.
+ */
+#define RTL8261X_SERDES_POL_REG0 0x0000
+#define RTL8261X_SERDES_POL_REG0_TX BIT(8)
+#define RTL8261X_SERDES_POL_REG0_RX BIT(9)
+#define RTL8261X_SERDES_POL_REGC2 0x00c2
+#define RTL8261X_SERDES_POL_REGC2_TX BIT(14)
+#define RTL8261X_SERDES_POL_REGC2_RX BIT(13)
+
#define RTL8261X_INT_MASK_DEFAULT (RTL8261X_INT_AUTONEG_DONE | \
RTL8261X_INT_LINK_CHG | \
RTL8261X_INT_AUTONEG_ERROR | \
@@ -290,6 +308,7 @@
#define FW_SUB_MAGIC_8261D 0x32363144
#define RTL8261X_POLL_TIMEOUT_MS 100
#define RTL8261X_MAX_MMD_DEV 31
+#define RTL8261X_LED_COUNT 4
#define RTL8261C_CE_FW_NAME "rtl_nic/rtl8261c.bin"
#define RTL8261D_FW_NAME "rtl_nic/rtl8261d.bin"
@@ -349,6 +368,11 @@ struct rtl8261x_priv {
const char *fw_name;
u32 fw_sub_magic;
bool fw_loaded;
+ /* LCR7's polarity bit doubles as the manual on/off level in
+ * led_brightness_set(), so the configured polarity is kept here
+ * to restore it whenever hardware control is set up again.
+ */
+ u8 led_active_low;
};
static int rtl821x_read_page(struct phy_device *phydev)
@@ -708,18 +732,147 @@ static int rtl8261x_config_aneg(struct phy_device *phydev)
return 0;
}
+static int rtl822x_serdes_wait(struct phy_device *phydev)
+{
+ int poll;
+
+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ RTL822X_VND1_SERDES_CMD, poll,
+ !(poll & RTL822X_VND1_SERDES_CMD_BUSY),
+ 500, 100000, false);
+}
+
+static int rtl822x_serdes_read(struct phy_device *phydev, u16 reg)
+{
+ int ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,
+ RTL822X_VND1_SERDES_CMD_BUSY);
+ if (ret < 0)
+ return ret;
+
+ ret = rtl822x_serdes_wait(phydev);
+ if (ret < 0)
+ return ret;
+
+ return phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_RDATA);
+}
+
+static int rtl822x_serdes_write(struct phy_device *phydev, u16 reg, u16 val)
+{
+ int ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_DATA, val);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,
+ RTL822X_VND1_SERDES_CMD_WRITE |
+ RTL822X_VND1_SERDES_CMD_BUSY);
+ if (ret < 0)
+ return ret;
+
+ return rtl822x_serdes_wait(phydev);
+}
+
+static int rtl822x_serdes_modify(struct phy_device *phydev, u16 reg,
+ u16 mask, u16 set)
+{
+ int val;
+
+ val = rtl822x_serdes_read(phydev, reg);
+ if (val < 0)
+ return val;
+
+ if ((val & mask) == set)
+ return 0;
+
+ return rtl822x_serdes_write(phydev, reg, (val & ~mask) | set);
+}
+
+/* The host-side SerDes lanes are only inverted when the board says so.
+ * Lanes the firmware node does not describe are left as the boot loader
+ * and PHY firmware left them.
+ */
+static int rtl8261x_config_serdes_polarity(struct phy_device *phydev)
+{
+ bool tx_present, rx_present, tx_invert = false, rx_invert = false;
+ u16 reg0_mask = 0, reg0_set = 0, regc2_mask = 0, regc2_set = 0;
+ struct fwnode_handle *fwnode = dev_fwnode(&phydev->mdio.dev);
+ const char *mode = phy_modes(phydev->interface);
+ unsigned int pol;
+ int ret;
+
+ tx_present = fwnode_property_present(fwnode, "tx-polarity");
+ rx_present = fwnode_property_present(fwnode, "rx-polarity");
+ if (!tx_present && !rx_present)
+ return 0;
+
+ if (tx_present) {
+ ret = phy_get_manual_tx_polarity(fwnode, mode, &pol);
+ if (ret)
+ return ret;
+ tx_invert = pol == PHY_POL_INVERT;
+ }
+
+ if (rx_present) {
+ ret = phy_get_manual_rx_polarity(fwnode, mode, &pol);
+ if (ret)
+ return ret;
+ rx_invert = pol == PHY_POL_INVERT;
+ }
+
+ if (tx_present) {
+ reg0_mask |= RTL8261X_SERDES_POL_REG0_TX;
+ regc2_mask |= RTL8261X_SERDES_POL_REGC2_TX;
+ if (tx_invert) {
+ reg0_set |= RTL8261X_SERDES_POL_REG0_TX;
+ regc2_set |= RTL8261X_SERDES_POL_REGC2_TX;
+ }
+ }
+
+ if (rx_present) {
+ reg0_mask |= RTL8261X_SERDES_POL_REG0_RX;
+ regc2_mask |= RTL8261X_SERDES_POL_REGC2_RX;
+ if (rx_invert) {
+ reg0_set |= RTL8261X_SERDES_POL_REG0_RX;
+ regc2_set |= RTL8261X_SERDES_POL_REGC2_RX;
+ }
+ }
+
+ ret = rtl822x_serdes_modify(phydev, RTL8261X_SERDES_POL_REG0,
+ reg0_mask, reg0_set);
+ if (ret < 0)
+ return ret;
+
+ return rtl822x_serdes_modify(phydev, RTL8261X_SERDES_POL_REGC2,
+ regc2_mask, regc2_set);
+}
+
static int rtl8261x_config_init(struct phy_device *phydev)
{
struct rtl8261x_priv *priv = phydev->priv;
+ int ret;
/* The firmware parameters are preserved across IEEE soft resets and
* suspend/resume cycles. Reloading is only necessary after a power
* cycle or hard reset.
*/
- if (priv->fw_name && !priv->fw_loaded)
- return rtl8261x_fw_load(phydev);
+ if (priv->fw_name && !priv->fw_loaded) {
+ ret = rtl8261x_fw_load(phydev);
+ if (ret)
+ return ret;
+ }
- return 0;
+ return rtl8261x_config_serdes_polarity(phydev);
}
static int rtl821x_probe(struct phy_device *phydev)
@@ -2120,30 +2273,6 @@ static int rtl822xb_config_init(struct phy_device *phydev)
return rtl822x_set_serdes_option_mode(phydev, false);
}
-static int rtl822x_serdes_write(struct phy_device *phydev, u16 reg, u16 val)
-{
- int ret, poll;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);
- if (ret < 0)
- return ret;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_DATA, val);
- if (ret < 0)
- return ret;
-
- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,
- RTL822X_VND1_SERDES_CMD_WRITE |
- RTL822X_VND1_SERDES_CMD_BUSY);
- if (ret < 0)
- return ret;
-
- return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- RTL822X_VND1_SERDES_CMD, poll,
- !(poll & RTL822X_VND1_SERDES_CMD_BUSY),
- 500, 100000, false);
-}
-
static int rtl822x_config_inband(struct phy_device *phydev, unsigned int modes)
{
return rtl822x_serdes_write(phydev, RTL822X_VND1_SERDES_ADDR_AUTONEG,
@@ -2410,6 +2539,215 @@ static int rtl822xb_led_brightness_set(struct phy_device *phydev, u8 index,
RTL822X_VND2_LED_POLAR(index));
}
+static int rtl8261x_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+{
+ const unsigned long act_mask = BIT(TRIGGER_NETDEV_RX) |
+ BIT(TRIGGER_NETDEV_TX);
+ const unsigned long link_mask = BIT(TRIGGER_NETDEV_LINK) |
+ BIT(TRIGGER_NETDEV_LINK_10) |
+ BIT(TRIGGER_NETDEV_LINK_100) |
+ BIT(TRIGGER_NETDEV_LINK_1000) |
+ BIT(TRIGGER_NETDEV_LINK_2500) |
+ BIT(TRIGGER_NETDEV_LINK_5000) |
+ BIT(TRIGGER_NETDEV_LINK_10000);
+
+ if (index >= RTL8261X_LED_COUNT)
+ return -EINVAL;
+
+ /* Filter out any other unsupported triggers. */
+ if (rules & ~(link_mask | act_mask))
+ return -EOPNOTSUPP;
+
+ /* RX and TX are not differentiated, they are not possible
+ * without combination with a link trigger.
+ */
+ if ((rules & act_mask) && !(rules & link_mask))
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static int rtl8261x_led_hw_control_get(struct phy_device *phydev, u8 index,
+ unsigned long *rules)
+{
+ const u16 all_links = RTL822X_VND2_LCR_LINK_10 |
+ RTL822X_VND2_LCR_LINK_100 |
+ RTL822X_VND2_LCR_LINK_1000 |
+ RTL822X_VND2_LCR_LINK_2500 |
+ RTL822X_VND2_LCR_LINK_5000 |
+ RTL822X_VND2_LCR_LINK_10000;
+ int val;
+
+ if (index >= RTL8261X_LED_COUNT)
+ return -EINVAL;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LED(index));
+ if (val < 0)
+ return val;
+
+ if (val & RTL822X_VND2_LCR_LINK_10)
+ __set_bit(TRIGGER_NETDEV_LINK_10, rules);
+
+ if (val & RTL822X_VND2_LCR_LINK_100)
+ __set_bit(TRIGGER_NETDEV_LINK_100, rules);
+
+ if (val & RTL822X_VND2_LCR_LINK_1000)
+ __set_bit(TRIGGER_NETDEV_LINK_1000, rules);
+
+ if (val & RTL822X_VND2_LCR_LINK_2500)
+ __set_bit(TRIGGER_NETDEV_LINK_2500, rules);
+
+ if (val & RTL822X_VND2_LCR_LINK_5000)
+ __set_bit(TRIGGER_NETDEV_LINK_5000, rules);
+
+ if (val & RTL822X_VND2_LCR_LINK_10000)
+ __set_bit(TRIGGER_NETDEV_LINK_10000, rules);
+
+ if ((val & all_links) == all_links)
+ __set_bit(TRIGGER_NETDEV_LINK, rules);
+
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6);
+ if (val < 0)
+ return val;
+
+ if (val & RTL822X_VND2_LED_ACT(index)) {
+ __set_bit(TRIGGER_NETDEV_RX, rules);
+ __set_bit(TRIGGER_NETDEV_TX, rules);
+ }
+
+ return 0;
+}
+
+static int rtl8261x_led_hw_control_set(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+{
+ struct rtl8261x_priv *priv = phydev->priv;
+ u16 lcr7 = RTL822X_VND2_LED_EN(index);
+ u16 val = 0;
+ bool act;
+ int ret;
+
+ if (index >= RTL8261X_LED_COUNT)
+ return -EINVAL;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_10, &rules))
+ val |= RTL822X_VND2_LCR_LINK_10;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_100, &rules))
+ val |= RTL822X_VND2_LCR_LINK_100;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
+ val |= RTL822X_VND2_LCR_LINK_1000;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
+ val |= RTL822X_VND2_LCR_LINK_2500;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_5000, &rules))
+ val |= RTL822X_VND2_LCR_LINK_5000;
+
+ if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
+ test_bit(TRIGGER_NETDEV_LINK_10000, &rules))
+ val |= RTL822X_VND2_LCR_LINK_10000;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
+ RTL822X_VND2_LED(index), val);
+ if (ret < 0)
+ return ret;
+
+ act = test_bit(TRIGGER_NETDEV_RX, &rules) ||
+ test_bit(TRIGGER_NETDEV_TX, &rules);
+
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6,
+ RTL822X_VND2_LED_ACT(index), act ?
+ RTL822X_VND2_LED_ACT(index) : 0);
+ if (ret < 0)
+ return ret;
+
+ /* Enable the output and restore the configured polarity, which
+ * led_brightness_set() may have used as a level.
+ */
+ if (priv->led_active_low & BIT(index))
+ lcr7 |= RTL822X_VND2_LED_POLAR(index);
+
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,
+ RTL822X_VND2_LED_EN(index) |
+ RTL822X_VND2_LED_POLAR(index), lcr7);
+}
+
+static int rtl8261x_led_brightness_set(struct phy_device *phydev, u8 index,
+ enum led_brightness value)
+{
+ struct rtl8261x_priv *priv = phydev->priv;
+ u16 lcr7 = RTL822X_VND2_LED_EN(index);
+ bool active_low, on;
+ int ret;
+
+ if (index >= RTL8261X_LED_COUNT)
+ return -EINVAL;
+
+ /* clear HW LED setup */
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
+ RTL822X_VND2_LED(index), 0);
+ if (ret < 0)
+ return ret;
+
+ /* clear HW LED blink */
+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR6,
+ RTL822X_VND2_LED_ACT(index));
+ if (ret < 0)
+ return ret;
+
+ /* With no link condition selected the output sits at its idle
+ * level, so inverting the polarity turns the LED on.
+ */
+ active_low = priv->led_active_low & BIT(index);
+ on = value != LED_OFF;
+ if (on != active_low)
+ lcr7 |= RTL822X_VND2_LED_POLAR(index);
+
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,
+ RTL822X_VND2_LED_EN(index) |
+ RTL822X_VND2_LED_POLAR(index), lcr7);
+}
+
+static int rtl8261x_led_polarity_set(struct phy_device *phydev, int index,
+ unsigned long modes)
+{
+ struct rtl8261x_priv *priv = phydev->priv;
+ bool active_low = false;
+ u32 mode;
+
+ if (index >= RTL8261X_LED_COUNT)
+ return -EINVAL;
+
+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
+ switch (mode) {
+ case PHY_LED_ACTIVE_LOW:
+ active_low = true;
+ break;
+ case PHY_LED_ACTIVE_HIGH:
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ if (active_low)
+ priv->led_active_low |= BIT(index);
+ else
+ priv->led_active_low &= ~BIT(index);
+
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_LCR7,
+ RTL822X_VND2_LED_POLAR(index),
+ active_low ? RTL822X_VND2_LED_POLAR(index) : 0);
+}
+
static int rtl822xb_led_hw_is_supported(struct phy_device *phydev, u8 index,
unsigned long rules)
{
@@ -3374,6 +3712,11 @@ static struct phy_driver realtek_drvs[] = {
.soft_reset = genphy_c45_pma_soft_reset,
.suspend = genphy_c45_pma_suspend,
.resume = genphy_c45_pma_resume,
+ .led_brightness_set = rtl8261x_led_brightness_set,
+ .led_hw_is_supported = rtl8261x_led_hw_is_supported,
+ .led_hw_control_get = rtl8261x_led_hw_control_get,
+ .led_hw_control_set = rtl8261x_led_hw_control_set,
+ .led_polarity_set = rtl8261x_led_polarity_set,
}, {
PHY_ID_MATCH_EXACT(RTL_8261CE_CG),
.name = "Realtek RTL8261CE 10Gbps PHY",
@@ -3387,6 +3730,11 @@ static struct phy_driver realtek_drvs[] = {
.soft_reset = genphy_c45_pma_soft_reset,
.suspend = genphy_c45_pma_suspend,
.resume = genphy_c45_pma_resume,
+ .led_brightness_set = rtl8261x_led_brightness_set,
+ .led_hw_is_supported = rtl8261x_led_hw_is_supported,
+ .led_hw_control_get = rtl8261x_led_hw_control_get,
+ .led_hw_control_set = rtl8261x_led_hw_control_set,
+ .led_polarity_set = rtl8261x_led_polarity_set,
}, {
PHY_ID_MATCH_EXACT(RTL_8261D_VM),
.name = "Realtek RTL8261D_VM 10Gbps PHY",
|
| 3/2 | 2026/09/23 16:09 | llm | patch-evaluator |
4mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11099 output: 19 thoughts: 630 Thoughts: **Analyzing the Realtek Ethernet PHY Driver Patch** Okay, so this patch is touching the Realtek ethernet PHY driver, specifically files within `drivers/net/phy/realtek/`. It's modifying `realtek_main.c`, `Kconfig`, and the device tree bindings documentation (`rtl82xx.yaml`). Let's break this down further and consider how testable this is. First, the modifications. It looks like we're getting new Device Tree (DT) bindings for PHY polarity and LEDs, specifically for the RTL8261x. Then, in the `Kconfig`, it's just selecting `PHY_COMMON_PROPS` for the REALTEK_PHY. The meat of the change, though, is in `realtek_main.c`. This is where we see functions for reading and configuring SerDes polarity for the RTL8261x (`rtl8261x_config_serdes_polarity`) – which is being called during initialization. There are also new LED functions: `rtl8261x_led_hw_is_supported`, `rtl8261x_led_hw_control_get`, `rtl8261x_led_hw_control_set`, `rtl8261x_led_brightness_set`, and `rtl8261x_led_polarity_set`. These LED functions are then hooked up to `realtek_drvs[]`, specifically for RTL_8261N_CG and RTL_8261CE_CG. Now, the crucial question: can we even get to this code? I'm looking at the driver, and it's a PHY driver registered using `module_phy_driver(realtek_drvs)`. That means it's a PHY device, and typically PHYs are instantiated through the MDIO bus. So, can syzkaller or a standard QEMU environment handle MDIO bus instantiation or specifically, this Realtek PHY? I need to figure out if it's possible to create these virtual PHYs in a way that will exercise this new code. Let me quickly re-read the prompt. Ah, Section 2 is relevant. It mentions "Structurally unreachable hardware" like vendor-specific PCIe switches, and also lists "Unreachable execution paths" like driver teardown on physical PCI hot-unplug. The question is: does an ethernet PHY require physical hardware to be instantiated? I need to see if there's any kind of virtual MDIO bus or emulated driver, or if syzkaller has mechanisms for creating these devices. I'll need to grep the kernel source and syzkaller for related code, specifically looking for `mdio` or `phy_device` creation. That will be the key to assessing whether this patch is testable in our environment. |
| 4/2 | 2026/09/23 16:14 | tool | grepper |
0mArgs:{
"Expression": "phy_device_create"
}Results: {
"Output": "drivers/net/mdio/fwnode_mdio.c=117=int fwnode_mdiobus_register_phy(struct mii_bus *bus,\n--\ndrivers/net/mdio/fwnode_mdio.c-134-\telse\ndrivers/net/mdio/fwnode_mdio.c:135:\t\tphy = phy_device_create(bus, addr, phy_id, 0, NULL);\ndrivers/net/mdio/fwnode_mdio.c-136-\tif (IS_ERR(phy)) {\n--\ndrivers/net/phy/nxp-tja11xx.c=551=static void tja1102_p1_register(struct work_struct *work)\n--\ndrivers/net/phy/nxp-tja11xx.c-585-\t\t/* Real PHY ID of Port 1 is 0 */\ndrivers/net/phy/nxp-tja11xx.c:586:\t\tphy = phy_device_create(bus, addr, PHY_ID_TJA1102, false, NULL);\ndrivers/net/phy/nxp-tja11xx.c-587-\t\tif (IS_ERR(phy)) {\n--\ndrivers/net/phy/nxp-tja11xx.c-592-\ndrivers/net/phy/nxp-tja11xx.c:593:\t\t/* Overwrite parent device. phy_device_create() set parent to\ndrivers/net/phy/nxp-tja11xx.c-594-\t\t * the mii_bus-\u003edev, which is not correct in case.\n--\ndrivers/net/phy/phy_device.c=638=static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)\n--\ndrivers/net/phy/phy_device.c-657-\ndrivers/net/phy/phy_device.c:658:struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,\ndrivers/net/phy/phy_device.c-659-\t\t\t\t bool is_c45,\n--\ndrivers/net/phy/phy_device.c-749-}\ndrivers/net/phy/phy_device.c:750:EXPORT_SYMBOL(phy_device_create);\ndrivers/net/phy/phy_device.c-751-\n--\ndrivers/net/phy/phy_device.c=981=struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)\n--\ndrivers/net/phy/phy_device.c-1006-\t\tif (!r)\ndrivers/net/phy/phy_device.c:1007:\t\t\treturn phy_device_create(bus, addr, phy_id,\ndrivers/net/phy/phy_device.c-1008-\t\t\t\t\t\t true, \u0026c45_ids);\n--\ndrivers/net/phy/phy_device.c-1010-\ndrivers/net/phy/phy_device.c:1011:\treturn phy_device_create(bus, addr, phy_id, is_c45, \u0026c45_ids);\ndrivers/net/phy/phy_device.c-1012-}\n--\ninclude/linux/phy.h=2167=int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,\n--\ninclude/linux/phy.h-2169-\ninclude/linux/phy.h:2170:struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,\ninclude/linux/phy.h-2171-\t\t\t\t bool is_c45,\n"
} |
| 5/2 | 2026/09/23 16:14 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13309 output: 21 thoughts: 219 Thoughts: **Investigating Realtek RTL8261 PHY Instantiation** Okay, so I'm trying to figure out how these PHY drivers, specifically for something like a Realtek RTL8261, get instantiated within the kernel. My understanding is that the process hinges on matching the `phy_id` of a `struct phy_device` on an `mii_bus` to a specific PHY driver, right? For example, the `RTL_8261N_CG` driver would be identified by `0x001cc898` or something similar. Now, a crucial question pops up: can I actually find a *physical* Realtek RTL8261 PHY present in a standard QEMU or Google Compute Engine setup? From memory, QEMU typically emulates things like Intel e1000, virtio-net, rtl8139, and pcnet. I don't recall seeing direct Realtek PHY emulation there. So, probably not! Hold on, though. What about USB Ethernet dongles? Could they be the pathway? Maybe a USB gadget configuration, or even a `dummy_hcd` scenario? I need to check if there are any USB Ethernet drivers that actually use the `phy_device` structure and have built-in support for an RTL8261 PHY. I should probably do a quick grep across the kernel source. I'll search for `RTL_8261` or, just to broaden the net, `realtek_drvs`. That should help pinpoint if this type of PHY is actually used in a USB Ethernet context. |
| 6/2 | 2026/09/23 16:14 | tool | grepper |
0mArgs:{
"Expression": "RTL_8261"
}Results: {
"Output": "drivers/net/phy/realtek/realtek_main.c-148-#define RTL8261X_EXT_DATA_REG\t\t\t0xa438\ndrivers/net/phy/realtek/realtek_main.c:149:#define RTL_8261X_SUB_PHY_ID_ADDR\t\t0x801d\ndrivers/net/phy/realtek/realtek_main.c-150-\n--\ndrivers/net/phy/realtek/realtek_main.c-263-#define RTL_8251B\t\t\t\t0x001cc862\ndrivers/net/phy/realtek/realtek_main.c:264:#define RTL_8261C\t\t\t\t0x001cc890\ndrivers/net/phy/realtek/realtek_main.c:265:#define RTL_8261C_CG\t\t\t\t0x001cc898\ndrivers/net/phy/realtek/realtek_main.c:266:#define RTL_8261CE_CG\t\t\t\t0x001cc899\ndrivers/net/phy/realtek/realtek_main.c:267:#define RTL_8261D_VM\t\t\t\t0x001cc89a\ndrivers/net/phy/realtek/realtek_main.c-268-\n--\ndrivers/net/phy/realtek/realtek_main.c=418=static int rtl8261x_probe(struct phy_device *phydev)\n--\ndrivers/net/phy/realtek/realtek_main.c-430-\tret = phy_write_mmd(phydev, MDIO_MMD_VEND2, RTL8261X_EXT_ADDR_REG,\ndrivers/net/phy/realtek/realtek_main.c:431:\t\t\t RTL_8261X_SUB_PHY_ID_ADDR);\ndrivers/net/phy/realtek/realtek_main.c-432-\tif (ret \u003c 0)\n--\ndrivers/net/phy/realtek/realtek_main.c=3191=static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,\n--\ndrivers/net/phy/realtek/realtek_main.c-3200-\tcase RTL_8251B:\ndrivers/net/phy/realtek/realtek_main.c:3201:\tcase RTL_8261C:\ndrivers/net/phy/realtek/realtek_main.c-3202-\tcase 0x001cc841:\n--\ndrivers/net/phy/realtek/realtek_main.c=3399=static struct phy_driver realtek_drvs[] = {\n--\ndrivers/net/phy/realtek/realtek_main.c-3702-\t}, {\ndrivers/net/phy/realtek/realtek_main.c:3703:\t\tPHY_ID_MATCH_EXACT(RTL_8261C_CG),\ndrivers/net/phy/realtek/realtek_main.c-3704-\t\t.name\t\t\t= \"Realtek RTL8261C/D 10Gbps PHY\",\n--\ndrivers/net/phy/realtek/realtek_main.c-3720-\t}, {\ndrivers/net/phy/realtek/realtek_main.c:3721:\t\tPHY_ID_MATCH_EXACT(RTL_8261CE_CG),\ndrivers/net/phy/realtek/realtek_main.c-3722-\t\t.name\t\t\t= \"Realtek RTL8261CE 10Gbps PHY\",\n--\ndrivers/net/phy/realtek/realtek_main.c-3738-\t}, {\ndrivers/net/phy/realtek/realtek_main.c:3739:\t\tPHY_ID_MATCH_EXACT(RTL_8261D_VM),\ndrivers/net/phy/realtek/realtek_main.c-3740-\t\t.name\t\t\t= \"Realtek RTL8261D_VM 10Gbps PHY\",\n"
} |
| 7/2 | 2026/09/23 16:14 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14933 output: 32 thoughts: 52 Thoughts: Okay, let's break this down. **Investigating USB Ethernet Driver Interaction with PHYs** Right, so I need to figure out how USB Ethernet drivers are handling their PHY connections. My initial thought is, do any of these drivers in the USB Ethernet space (specifically) utilize the phylib infrastructure to probe for and manage external PHY devices? That would be the cleanest approach, so I'll start by looking for that direct link. I'm going to look for direct calls. My approach will be to inspect the USB Ethernet driver code for any mentions of `phy_device`, `phy_connect`, or maybe even `mdio` since `mdio` is the common interface. I'll need to go through the code under `drivers/net/usb/` to see how the drivers actually talk to their physical layer interfaces. Understanding this is key to getting a good grasp on how the USB Ethernet drivers are architected in relation to the PHY devices they use. |
| 8/2 | 2026/09/23 16:14 | tool | grepper |
0mArgs:{
"Expression": "phy_connect|phy_attach",
"PathPrefix": "drivers/net/usb"
}Results: {
"Output": "drivers/net/usb/asix_devices.c=703=static int ax88772_init_phy(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-722-\ndrivers/net/usb/asix_devices.c:723:\tphy_attached_info(priv-\u003ephydev);\ndrivers/net/usb/asix_devices.c-724-\n--\ndrivers/net/usb/ax88172a.c=261=static int ax88172a_reset(struct usbnet *dev)\n--\ndrivers/net/usb/ax88172a.c-313-\ndrivers/net/usb/ax88172a.c:314:\tpriv-\u003ephydev = phy_connect(dev-\u003enet, priv-\u003ephy_name,\ndrivers/net/usb/ax88172a.c-315-\t\t\t\t \u0026ax88172a_adjust_link,\n--\ndrivers/net/usb/smsc95xx.c=1147=static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/smsc95xx.c-1284-\ndrivers/net/usb/smsc95xx.c:1285:\tret = phy_connect_direct(dev-\u003enet, pdata-\u003ephydev,\ndrivers/net/usb/smsc95xx.c-1286-\t\t\t\t \u0026smsc95xx_handle_link_change,\n--\ndrivers/net/usb/smsc95xx.c-1292-\ndrivers/net/usb/smsc95xx.c:1293:\tphy_attached_info(dev-\u003enet-\u003ephydev);\ndrivers/net/usb/smsc95xx.c-1294-\n"
} |
| 9/2 | 2026/09/23 16:14 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15695 output: 40 thoughts: 213 Thoughts: Okay, let's break this down. **Investigating USB Ethernet and MII Bus Emulation** First off, I'm trying to figure out if we can get USB Ethernet drivers to emulate an MII bus, which is crucial for PHY interaction. Now, a key observation is that `asix_devices.c` and `smsc95xx.c` both seem to register an internal MII bus within the `smsc95xx` driver itself. That’s a good starting point. The next question: can we leverage something like `raw-gadget` or syzkaller to emulate USB devices in this context? Syzkaller does have USB emulation, using `dummy_hcd` or `raw-gadget`. The core of my question is this: can this USB emulation actually simulate an MII bus and return the correct PHY IDs? It's all about how finely we can control the emulation. I need to see how the drivers handle this, so let's look at a few examples: `asix_devices.c`, `smsc75xx.c`, and `r8152`. Wait, no, hold on - the `r8152` driver does *not* use `phylib`, and it's PHY code isn't in `realtek_main.c` as I initially suspected, it's all handled internally within `r8152.c`. That changes things. Okay, back to `asix_devices.c`. I need to check how the PHY is initialized. Let's delve into `ax88772_init_phy`. This is where the core logic likely resides. |
| 10/2 | 2026/09/23 16:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/asix_devices.c",
"FirstLine": 690,
"LineCount": 45
}Results: {
"Contents": " 690:\t\t\tmdiobus_free(priv-\u003emdio);\n 691:\t\t\tpriv-\u003emdio = NULL;\n 692:\t\t}\n 693:\t\n 694:\t\treturn ret;\n 695:\t}\n 696:\t\n 697:\tstatic void ax88772_mdio_unregister(struct asix_common_private *priv)\n 698:\t{\n 699:\t\tmdiobus_unregister(priv-\u003emdio);\n 700:\t\tmdiobus_free(priv-\u003emdio);\n 701:\t}\n 702:\t\n 703:\tstatic int ax88772_init_phy(struct usbnet *dev)\n 704:\t{\n 705:\t\tstruct asix_common_private *priv = dev-\u003edriver_priv;\n 706:\t\tint ret;\n 707:\t\n 708:\t\tpriv-\u003ephydev = mdiobus_get_phy(priv-\u003emdio, priv-\u003ephy_addr);\n 709:\t\tif (!priv-\u003ephydev) {\n 710:\t\t\tnetdev_err(dev-\u003enet, \"Could not find PHY\\n\");\n 711:\t\t\treturn -ENODEV;\n 712:\t\t}\n 713:\t\n 714:\t\tret = phylink_connect_phy(priv-\u003ephylink, priv-\u003ephydev);\n 715:\t\tif (ret) {\n 716:\t\t\tnetdev_err(dev-\u003enet, \"Could not connect PHY\\n\");\n 717:\t\t\treturn ret;\n 718:\t\t}\n 719:\t\n 720:\t\tphy_suspend(priv-\u003ephydev);\n 721:\t\tpriv-\u003ephydev-\u003emac_managed_pm = true;\n 722:\t\n 723:\t\tphy_attached_info(priv-\u003ephydev);\n 724:\t\n 725:\t\tif (priv-\u003eembd_phy)\n 726:\t\t\treturn 0;\n 727:\t\n 728:\t\t/* In case main PHY is not the embedded PHY and MAC is RMII clock\n 729:\t\t * provider, we need to suspend embedded PHY by keeping PLL enabled\n 730:\t\t * (AX_SWRESET_IPPD == 0).\n 731:\t\t */\n 732:\t\tpriv-\u003ephydev_int = mdiobus_get_phy(priv-\u003emdio, AX_EMBD_PHY_ADDR);\n 733:\t\tif (!priv-\u003ephydev_int) {\n 734:\t\t\trtnl_lock();\n"
} |
| 11/2 | 2026/09/23 16:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 16981 output: 40 thoughts: 38 Thoughts: Okay, let's dive into this. Here's my understanding, presented as a personal thought process, as if I were considering this myself: **MDIO Bus Scanning in `ax88772_mdio_register`** Wait a second! My internal radar is pinging a question: How *exactly* does this `ax88772_mdio_register` function go about the process of scanning the MDIO bus? We know it's *supposed* to register the MDIO bus, but the registration itself must involve some kind of device discovery. I need to refresh my memory and pinpoint the section of code responsible for the MDIO bus scanning. Let's get right back to the code for `ax88772_mdio_register` and find out! |
| 12/2 | 2026/09/23 16:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/asix_devices.c",
"FirstLine": 660,
"LineCount": 35
}Results: {
"Contents": " 660:\t\tstruct usbnet *dev = usb_get_intfdata(intf);\n 661:\t\tstruct asix_common_private *priv = dev-\u003edriver_priv;\n 662:\t\n 663:\t\tif (priv \u0026\u0026 priv-\u003eresume)\n 664:\t\t\tpriv-\u003eresume(dev);\n 665:\t\n 666:\t\treturn usbnet_resume(intf);\n 667:\t}\n 668:\t\n 669:\tstatic int ax88772_init_mdio(struct usbnet *dev)\n 670:\t{\n 671:\t\tstruct asix_common_private *priv = dev-\u003edriver_priv;\n 672:\t\tint ret;\n 673:\t\n 674:\t\tpriv-\u003emdio = mdiobus_alloc();\n 675:\t\tif (!priv-\u003emdio)\n 676:\t\t\treturn -ENOMEM;\n 677:\t\n 678:\t\tpriv-\u003emdio-\u003epriv = dev;\n 679:\t\tpriv-\u003emdio-\u003eread = \u0026asix_mdio_bus_read;\n 680:\t\tpriv-\u003emdio-\u003ewrite = \u0026asix_mdio_bus_write;\n 681:\t\tpriv-\u003emdio-\u003ename = \"Asix MDIO Bus\";\n 682:\t\tpriv-\u003emdio-\u003ephy_mask = ~(BIT(priv-\u003ephy_addr \u0026 0x1f) | BIT(AX_EMBD_PHY_ADDR));\n 683:\t\t/* mii bus name is usb-\u003cusb bus number\u003e-\u003cusb device number\u003e */\n 684:\t\tsnprintf(priv-\u003emdio-\u003eid, MII_BUS_ID_SIZE, \"usb-%03d:%03d\",\n 685:\t\t\t dev-\u003eudev-\u003ebus-\u003ebusnum, dev-\u003eudev-\u003edevnum);\n 686:\t\n 687:\t\tret = mdiobus_register(priv-\u003emdio);\n 688:\t\tif (ret) {\n 689:\t\t\tnetdev_err(dev-\u003enet, \"Could not register MDIO bus (err %d)\\n\", ret);\n 690:\t\t\tmdiobus_free(priv-\u003emdio);\n 691:\t\t\tpriv-\u003emdio = NULL;\n 692:\t\t}\n 693:\t\n 694:\t\treturn ret;\n"
} |
| 13/2 | 2026/09/23 16:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17833 output: 44 thoughts: 184 Thoughts: Here's my thought process, distilled: **Digging into MDIO Bus Registration** Okay, first things first, what's *really* going on inside `mdiobus_register`? I need to get a clear picture. Ah, right, it's that bus scanning business. It's using `bus->read` to hit addresses 0 through 31, grabbing those `MII_PHYSID1` and `MII_PHYSID2` values. Got it. Now, a crucial question surfaces: are we dealing with Clause 22 or Clause 45 accesses during this scan? Gotta keep that distinction sharp. Different registers, different access methods... important detail to lock down. Next on the list, I need to confirm the PHY ID for RTL8261. This information is key to understanding how the driver is working. Let's check in `realtek_drvs`. Okay, I see: `PHY_ID_MATCH_EXACT(RTL_8261C_CG)`, `PHY_ID_MATCH_EXACT(RTL_8261CE_CG)`, and `PHY_ID_MATCH_EXACT(RTL_8261D_VM)`. These are the precise PHY IDs the driver is targeting. I need to understand how RTL8261 is defined and registered. Gotta chase that breadcrumb to the source to understand the registration process. |
| 14/2 | 2026/09/23 16:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/realtek/realtek_main.c",
"FirstLine": 3695,
"LineCount": 60
}Results: {
"Contents": "3695:\t\t}, {\n3696:\t\t\tPHY_ID_MATCH_EXACT(0x001cc960),\n3697:\t\t\t.name\t\t= \"RTL8366S Gigabit Ethernet\",\n3698:\t\t\t.suspend\t= genphy_suspend,\n3699:\t\t\t.resume\t\t= genphy_resume,\n3700:\t\t\t.read_mmd\t= genphy_read_mmd_unsupported,\n3701:\t\t\t.write_mmd\t= genphy_write_mmd_unsupported,\n3702:\t\t}, {\n3703:\t\t\tPHY_ID_MATCH_EXACT(RTL_8261C_CG),\n3704:\t\t\t.name\t\t\t= \"Realtek RTL8261C/D 10Gbps PHY\",\n3705:\t\t\t.probe\t\t\t= rtl8261x_probe,\n3706:\t\t\t.config_init\t\t= rtl8261x_config_init,\n3707:\t\t\t.get_features\t\t= rtl8261x_get_features,\n3708:\t\t\t.config_aneg\t\t= rtl8261x_config_aneg,\n3709:\t\t\t.read_status\t\t= rtl8261x_read_status,\n3710:\t\t\t.config_intr\t\t= rtl8261x_config_intr,\n3711:\t\t\t.handle_interrupt\t= rtl8261x_handle_interrupt,\n3712:\t\t\t.soft_reset\t\t= genphy_c45_pma_soft_reset,\n3713:\t\t\t.suspend\t\t= genphy_c45_pma_suspend,\n3714:\t\t\t.resume\t\t\t= genphy_c45_pma_resume,\n3715:\t\t\t.led_brightness_set\t= rtl8261x_led_brightness_set,\n3716:\t\t\t.led_hw_is_supported\t= rtl8261x_led_hw_is_supported,\n3717:\t\t\t.led_hw_control_get\t= rtl8261x_led_hw_control_get,\n3718:\t\t\t.led_hw_control_set\t= rtl8261x_led_hw_control_set,\n3719:\t\t\t.led_polarity_set\t= rtl8261x_led_polarity_set,\n3720:\t\t}, {\n3721:\t\t\tPHY_ID_MATCH_EXACT(RTL_8261CE_CG),\n3722:\t\t\t.name\t\t\t= \"Realtek RTL8261CE 10Gbps PHY\",\n3723:\t\t\t.probe\t\t\t= rtl8261x_probe,\n3724:\t\t\t.config_init\t\t= rtl8261x_config_init,\n3725:\t\t\t.get_features\t\t= rtl8261x_get_features,\n3726:\t\t\t.config_aneg\t\t= rtl8261x_config_aneg,\n3727:\t\t\t.read_status\t\t= rtl8261x_read_status,\n3728:\t\t\t.config_intr\t\t= rtl8261x_config_intr,\n3729:\t\t\t.handle_interrupt\t= rtl8261x_handle_interrupt,\n3730:\t\t\t.soft_reset\t\t= genphy_c45_pma_soft_reset,\n3731:\t\t\t.suspend\t\t= genphy_c45_pma_suspend,\n3732:\t\t\t.resume\t\t\t= genphy_c45_pma_resume,\n3733:\t\t\t.led_brightness_set\t= rtl8261x_led_brightness_set,\n3734:\t\t\t.led_hw_is_supported\t= rtl8261x_led_hw_is_supported,\n3735:\t\t\t.led_hw_control_get\t= rtl8261x_led_hw_control_get,\n3736:\t\t\t.led_hw_control_set\t= rtl8261x_led_hw_control_set,\n3737:\t\t\t.led_polarity_set\t= rtl8261x_led_polarity_set,\n3738:\t\t}, {\n3739:\t\t\tPHY_ID_MATCH_EXACT(RTL_8261D_VM),\n3740:\t\t\t.name\t\t\t= \"Realtek RTL8261D_VM 10Gbps PHY\",\n3741:\t\t\t.probe\t\t\t= rtl8261x_probe,\n3742:\t\t\t.config_init\t\t= rtl8261x_config_init,\n3743:\t\t\t.get_features\t\t= rtl8261x_get_features,\n3744:\t\t\t.config_aneg\t\t= rtl8261x_config_aneg,\n3745:\t\t\t.read_status\t\t= rtl8261x_read_status,\n3746:\t\t\t.config_intr\t\t= rtl8261x_config_intr,\n3747:\t\t\t.handle_interrupt\t= rtl8261x_handle_interrupt,\n3748:\t\t\t.soft_reset\t\t= genphy_c45_pma_soft_reset,\n3749:\t\t\t.suspend\t\t= genphy_c45_pma_suspend,\n3750:\t\t\t.resume\t\t\t= genphy_c45_pma_resume,\n3751:\t\t},\n3752:\t};\n3753:\t\n3754:\tmodule_phy_driver(realtek_drvs);\n"
} |
| 15/2 | 2026/09/23 16:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 19785 output: 37 thoughts: 1223 Thoughts: **PHY Driver Matching and Fuzzing Feasibility** Okay, so I'm trying to figure out how PHY driver matching works, specifically within the context of whether a Realtek RTL8261 PHY driver might be accessible or fuzzable by something like syzkaller. Let's see… looking at `phy_bus_match` in `phy_device.c`, it seems the matching is based on a combination of OF matching, a check for SFP buses, and then either custom match functions within the `phy_driver` struct, or a direct comparison of PHY IDs and masks. I need to determine if syzkaller can even reach this code. First, I need to check syzkaller's device coverage. Does it fuzz MDIO or PHY devices? I need to consult the guidelines. According to the instructions, I need to think about whether the changes fall into the "WorthFuzzing=false" or "WorthFuzzing=true" categories. Based on the instructions, my immediate question is whether this RTL8261 is reachable. Is it accessible via virtual buses, or is it structurally unreachable hardware? RTL8261 is a 10Gbps Ethernet PHY chip. It's a *physical* transceiver chip, often found paired with an Ethernet MAC on physical boards, like embedded routers or network cards. The key question is its bus. It's connected to the MDIO bus, a two-wire serial bus between MACs and PHYs. So, is there an MDIO controller in standard QEMU on amd64? Let's see what network devices are emulated by QEMU. e1000/e1000e seem to have internal PHYs, not relying on phylib and MDIO. The same goes for rtl8139, virtio-net, pcnet32, ne2k_pci, and igb, which have their own PHY handling. *However*, r8169 does use `drivers/net/phy/realtek/`! This could be a critical point. Does `r8169` *actually* use `drivers/net/phy/realtek/realtek_main.c`? I need to investigate `r8169` immediately to verify if this is a viable path. |
| 16/2 | 2026/09/23 16:15 | tool | grepper |
0mError:no matches Args: {
"Expression": "realtek",
"PathPrefix": "drivers/net/ethernet/realtek/r8169"
}Results: {
"error": "no matches"
} |
| 17/2 | 2026/09/23 16:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 21562 output: 48 thoughts: 25 Thoughts: Here's my thought process, as requested: **Network Driver Exploration: Targeting PHY and MDIO** Okay, so I need to dig into this network driver, and I think focusing on the `r8169_main.c` file is a good starting point. I want to see how the driver interacts with the PHY (Physical Layer) and the MDIO (Management Data Input/Output) interface. These are key components for network communication. A quick search for "phy_" or "mdio" within that specific file should reveal the relevant function calls, structures, and register accesses that manage the physical link and how the driver communicates with the underlying hardware. Knowing that will give me a better understanding of how the driver initializes, configures, and monitors the network interface. |
| 18/2 | 2026/09/23 16:16 | tool | grepper |
0mError:no matches Args: {
"Expression": "phy_driver|mdiobus_register|phy_connect",
"PathPrefix": "drivers/net/ethernet/realtek/r8169"
}Results: {
"error": "no matches"
} |
| 19/2 | 2026/09/23 16:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 21811 output: 34 thoughts: 27 Thoughts: Okay, let's see. My first thought is: **Gotta investigate those Realtek drivers, specifically in relation to `mdiobus_register`.** It makes sense to start with a grep to find where that function is actually being used within the `drivers/net/ethernet/realtek/` directory. That's the most logical starting point for understanding how the MDIO bus is being utilized and managed in these Realtek Ethernet devices. The goal is to quickly find the relevant files and functions. I expect I'll probably find multiple instances, probably involving device initialization, probe functions, and perhaps even some interrupt handlers, if MDIO is used to handle link status or other events. I will expect to find a couple of files that are likely candidates. From there I can more directly look into the register usage. I'm hoping I can piece together a better mental map of the driver architecture this way. |
| 20/2 | 2026/09/23 16:16 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_register",
"PathPrefix": "drivers/net/ethernet/realtek"
}Results: {
"Output": "drivers/net/ethernet/realtek/r8169_main.c=5571=static int r8169_mdio_register(struct rtl8169_private *tp)\n--\ndrivers/net/ethernet/realtek/r8169_main.c-5605-\ndrivers/net/ethernet/realtek/r8169_main.c:5606:\tret = devm_mdiobus_register(\u0026pdev-\u003edev, new_bus);\ndrivers/net/ethernet/realtek/r8169_main.c-5607-\tif (ret)\n"
} |
| 21/2 | 2026/09/23 16:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 22229 output: 48 thoughts: 76 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience: **Kernel Module Deep Dive** Wow, *there* it is! Line 5606 in `r8169_main.c`: `devm_mdiobus_register(&pdev->dev, new_bus);`. That's where the MDIO bus registration is happening within the Realtek r8169 driver. I need to understand the surrounding context. Time to zoom in on `drivers/net/ethernet/realtek/r8169_main.c`, and start my scan around line 5571. What’s the initialization flow like here? What's going on with that `pdev` struct? Is this happening at probe time? Post-probe? I bet I'll find the device initialization. Is this where the `new_bus` object is populated? Are they using managed resources for the MDIO bus? Good use of `devm_mdiobus_register`. Gotta see how they’re handling potential errors and how the bus is un-registered on driver unload. This should be interesting to see how the bus is brought up. Let's see how much memory that module can use. |
| 22/2 | 2026/09/23 16:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/realtek/r8169_main.c",
"FirstLine": 5570,
"LineCount": 60
}Results: {
"Contents": "5570:\t\n5571:\tstatic int r8169_mdio_register(struct rtl8169_private *tp)\n5572:\t{\n5573:\t\tstruct pci_dev *pdev = tp-\u003epci_dev;\n5574:\t\tstruct mii_bus *new_bus;\n5575:\t\tint ret;\n5576:\t\n5577:\t\t/* On some boards with this chip version the BIOS is buggy and misses\n5578:\t\t * to reset the PHY page selector. This results in the PHY ID read\n5579:\t\t * accessing registers on a different page, returning a more or\n5580:\t\t * less random value. Fix this by resetting the page selector first.\n5581:\t\t */\n5582:\t\tif (tp-\u003emac_version == RTL_GIGA_MAC_VER_25 ||\n5583:\t\t tp-\u003emac_version == RTL_GIGA_MAC_VER_26)\n5584:\t\t\tr8169_mdio_write(tp, 0x1f, 0);\n5585:\t\n5586:\t\tnew_bus = devm_mdiobus_alloc(\u0026pdev-\u003edev);\n5587:\t\tif (!new_bus)\n5588:\t\t\treturn -ENOMEM;\n5589:\t\n5590:\t\tnew_bus-\u003ename = \"r8169\";\n5591:\t\tnew_bus-\u003epriv = tp;\n5592:\t\tnew_bus-\u003eparent = \u0026pdev-\u003edev;\n5593:\t\tnew_bus-\u003eirq[0] = PHY_MAC_INTERRUPT;\n5594:\t\tnew_bus-\u003ephy_mask = GENMASK(31, 1);\n5595:\t\tsnprintf(new_bus-\u003eid, MII_BUS_ID_SIZE, \"r8169-%x-%x\",\n5596:\t\t\t pci_domain_nr(pdev-\u003ebus), pci_dev_id(pdev));\n5597:\t\n5598:\t\tnew_bus-\u003eread = r8169_mdio_read_reg;\n5599:\t\tnew_bus-\u003ewrite = r8169_mdio_write_reg;\n5600:\t\n5601:\t\tif (tp-\u003emac_version \u003e= RTL_GIGA_MAC_VER_40) {\n5602:\t\t\tnew_bus-\u003eread_c45 = r8169_mdio_read_reg_c45;\n5603:\t\t\tnew_bus-\u003ewrite_c45 = r8169_mdio_write_reg_c45;\n5604:\t\t}\n5605:\t\n5606:\t\tret = devm_mdiobus_register(\u0026pdev-\u003edev, new_bus);\n5607:\t\tif (ret)\n5608:\t\t\treturn ret;\n5609:\t\n5610:\t\ttp-\u003ephydev = mdiobus_get_phy(new_bus, 0);\n5611:\t\tif (!tp-\u003ephydev) {\n5612:\t\t\treturn -ENODEV;\n5613:\t\t} else if (!tp-\u003ephydev-\u003edrv) {\n5614:\t\t\t/* Most chip versions fail with the genphy driver.\n5615:\t\t\t * Therefore ensure that the dedicated PHY driver is loaded.\n5616:\t\t\t */\n5617:\t\t\tdev_err(\u0026pdev-\u003edev, \"no dedicated PHY driver found for PHY ID 0x%08x, maybe realtek.ko needs to be added to initramfs?\\n\",\n5618:\t\t\t\ttp-\u003ephydev-\u003ephy_id);\n5619:\t\t\treturn -EUNATCH;\n5620:\t\t}\n5621:\t\n5622:\t\t/* PHY will be woken up in rtl_open() */\n5623:\t\tphy_suspend(tp-\u003ephydev);\n5624:\t\n5625:\t\treturn 0;\n5626:\t}\n5627:\t\n5628:\tstatic void rtl_hw_init_8168g(struct rtl8169_private *tp)\n5629:\t{\n"
} |
| 23/2 | 2026/09/23 16:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 23695 output: 34 thoughts: 417 Thoughts: **My Line of Reasoning** Okay, so `r8169` is registering an mdiobus and looking for `realtek.ko`. My initial thought is to figure out if `r8169` is even emulated in QEMU, since that's a common environment. Ah, yes, what Realtek NIC *is* emulated in QEMU? Let me remember... right! It's `rtl8139`, not `r8169`. Now, does QEMU even emulate RTL8169? Let me see... yes, I think I remember seeing the `-net nic,model=rtl8139` option. Does QEMU have `r8169` available though? Let's check the options. Even if QEMU *did* emulate it or another hypervisor did, what PHY would r8169 actually *have*? It uses a Gigabit Ethernet PHY, like an RTL8211 or the RTL8168's internal PHY. But wait, does *any* chip use an RTL8261? What *is* an RTL8261 again? Oh, right, it's a 10 Gigabit Ethernet PHY, the RTL8261C / RTL8261CE / RTL8261D. Here's an interesting thought: can USB devices somehow emulate MDIO or PHY interactions? Let me check `drivers/net/usb/asix_devices.c`. Aha! Can syzkaller emulate an ASIX USB device? YES! Syzkaller has `syz_usb_connect` and robust USB fuzzing capabilities! Now, can an ASIX USB device *respond* to MDIO reads? Let's examine what `asix_mdio_bus_read` does in `drivers/net/usb/asix_devices.c`. |
| 24/2 | 2026/09/23 16:16 | tool | grepper |
0mArgs:{
"Expression": "asix_mdio_bus_read",
"PathPrefix": "drivers/net/usb"
}Results: {
"Output": "drivers/net/usb/asix.h=232=void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val);\ndrivers/net/usb/asix.h-233-\ndrivers/net/usb/asix.h:234:int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum);\ndrivers/net/usb/asix.h-235-int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val);\n--\ndrivers/net/usb/asix_common.c=543=void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)\n--\ndrivers/net/usb/asix_common.c-548-/* MDIO read and write wrappers for phylib */\ndrivers/net/usb/asix_common.c:549:int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum)\ndrivers/net/usb/asix_common.c-550-{\n--\ndrivers/net/usb/asix_devices.c=669=static int ax88772_init_mdio(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-678-\tpriv-\u003emdio-\u003epriv = dev;\ndrivers/net/usb/asix_devices.c:679:\tpriv-\u003emdio-\u003eread = \u0026asix_mdio_bus_read;\ndrivers/net/usb/asix_devices.c-680-\tpriv-\u003emdio-\u003ewrite = \u0026asix_mdio_bus_write;\n--\ndrivers/net/usb/ax88172a.c=61=static int ax88172a_init_mdio(struct usbnet *dev)\n--\ndrivers/net/usb/ax88172a.c-72-\tpriv-\u003emdio-\u003epriv = (void *)dev;\ndrivers/net/usb/ax88172a.c:73:\tpriv-\u003emdio-\u003eread = \u0026asix_mdio_bus_read;\ndrivers/net/usb/ax88172a.c-74-\tpriv-\u003emdio-\u003ewrite = \u0026asix_mdio_bus_write;\n"
} |
| 25/2 | 2026/09/23 16:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 25163 output: 40 thoughts: 30 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Diving into the asix_mdio_bus_read Function** Alright, let's get down to brass tacks. I'm thinking I should start digging into `asix_mdio_bus_read` in `drivers/net/usb/asix_common.c`. I need to understand exactly how this bus read function is working. I'm assuming it's handling the MDIO transactions to talk to the PHY. I need to refresh myself on how the asix driver is dealing with MDIO reads, the exact sequence it's using, and whether there are any potential race conditions or locking issues that I should consider. Knowing the specifics of the hardware implementation is crucial here, I also need to verify that it is not blocking. I want to look closely at the register access patterns, error handling, and potential interactions with any other threads or interrupt contexts. I also should consider any specific asix chip quirks, to make sure it handles all variations correctly. I need to be prepared to trace it to verify. I'll need to scrutinize the function's interaction with the USB stack, too. |
| 26/2 | 2026/09/23 16:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/asix_common.c",
"FirstLine": 545,
"LineCount": 40
}Results: {
"Contents": " 545:\t\t__asix_mdio_write(netdev, phy_id, loc, val, false);\n 546:\t}\n 547:\t\n 548:\t/* MDIO read and write wrappers for phylib */\n 549:\tint asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum)\n 550:\t{\n 551:\t\tstruct usbnet *priv = bus-\u003epriv;\n 552:\t\n 553:\t\treturn __asix_mdio_read(priv-\u003enet, phy_id, regnum, false);\n 554:\t}\n 555:\t\n 556:\tint asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)\n 557:\t{\n 558:\t\tstruct usbnet *priv = bus-\u003epriv;\n 559:\t\n 560:\t\treturn __asix_mdio_write(priv-\u003enet, phy_id, regnum, val, false);\n 561:\t}\n 562:\t\n 563:\tint asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc)\n 564:\t{\n 565:\t\treturn __asix_mdio_read(netdev, phy_id, loc, true);\n 566:\t}\n 567:\t\n 568:\tvoid\n 569:\tasix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val)\n 570:\t{\n 571:\t\t__asix_mdio_write(netdev, phy_id, loc, val, true);\n 572:\t}\n 573:\t\n 574:\tvoid asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)\n 575:\t{\n 576:\t\tstruct usbnet *dev = netdev_priv(net);\n 577:\t\tu8 opt;\n 578:\t\n 579:\t\tif (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE,\n 580:\t\t\t\t 0, 0, 1, \u0026opt, 0) \u003c 0) {\n 581:\t\t\twolinfo-\u003esupported = 0;\n 582:\t\t\twolinfo-\u003ewolopts = 0;\n 583:\t\t\treturn;\n 584:\t\t}\n"
} |
| 27/2 | 2026/09/23 16:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 26158 output: 38 thoughts: 911 Thoughts: **Analyzing Potential Exploit Paths in ASIX USB Ethernet Driver** Okay, first things first, my mind immediately jumps to the probing of the ASIX device via USB. When that happens, `ax88772_init_mdio` calls `mdiobus_register`. And during that registration, it's *scanning* the bus by reading those MII registers, MII_PHYSID1 and MII_PHYSID2, using the `bus->read` method. Intriguing... but, what's changed in this patch that matters? Let's break it down. Okay, the patch impacts these files: `Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml`, `drivers/net/phy/realtek/Kconfig`, and, crucially, `drivers/net/phy/realtek/realtek_main.c`. Looking at `realtek_main.c`, there's a bunch of new `rtl822x_serdes_...` functions for SERDES control, along with LED-related functions like `rtl8261x_led_...`. These are particularly interesting. These LED functions are now part of `RTL_8261C_CG` and `RTL_8261CE_CG` driver structures. And in `rtl8261x_config_init` it's calling `rtl8261x_config_serdes_polarity(phydev)`. The question becomes, can syzkaller be used to trigger *either* `rtl8261x_config_serdes_polarity` or those LED callbacks? Let's look more closely at that SERDES polarity function. It's calling `dev_fwnode(&phydev->mdio.dev)` which means it's grabbing information from a Device Tree / ACPI firmware node. Here's the problem: on amd64, Device Tree isn't normally the go-to; it's usually ACPI. Of course, unless we're dealing with a test DTB or a setup that is using OF. Is this the avenue? Now, what about the LED callbacks that are part of the realtek driver? I need to understand *how* PHY LEDs work and determine how these new functions are used, and whether there are any places that syzkaller could reach them. So let me grep for usage of those `led_hw_control_set` or `led_brightness_set` in the PHY driver tree. |
| 28/2 | 2026/09/23 16:17 | tool | grepper |
0mArgs:{
"Expression": "led_hw_control_set|led_brightness_set",
"PathPrefix": "drivers/net/phy"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1009 lines.\nUse more precise expression if possible.\n\ndrivers/net/phy/air_an8801.c=272=static int an8801r_led_blink_set(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/air_an8801.c-332-\ndrivers/net/phy/air_an8801.c:333:static int an8801r_led_brightness_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-334-\t\t\t\t enum led_brightness value)\n--\ndrivers/net/phy/air_an8801.c=442=static int an8801r_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/air_an8801.c-452-\ndrivers/net/phy/air_an8801.c:453:static int an8801r_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-454-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_an8801.c=505=static int an8801r_led_init(struct phy_device *phydev, u8 *led_cfg)\n--\ndrivers/net/phy/air_an8801.c-554-\ndrivers/net/phy/air_an8801.c:555:\t\tret = an8801r_led_hw_control_set(phydev, led_id, led_trigger);\ndrivers/net/phy/air_an8801.c-556-\t\tif (ret)\n--\ndrivers/net/phy/air_an8801.c=1122=static struct phy_driver airoha_driver[] = {\n--\ndrivers/net/phy/air_an8801.c-1138-\t.flags\t\t\t= PHY_ALWAYS_CALL_SUSPEND,\ndrivers/net/phy/air_an8801.c:1139:\t.led_brightness_set\t= an8801r_led_brightness_set,\ndrivers/net/phy/air_an8801.c-1140-\t.led_blink_set\t\t= an8801r_led_blink_set,\ndrivers/net/phy/air_an8801.c-1141-\t.led_hw_is_supported\t= an8801r_led_hw_is_supported,\ndrivers/net/phy/air_an8801.c:1142:\t.led_hw_control_set\t= an8801r_led_hw_control_set,\ndrivers/net/phy/air_an8801.c-1143-\t.led_hw_control_get\t= an8801r_led_hw_control_get,\n--\ndrivers/net/phy/air_en8811h.c=656=static int air_led_blink_set(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/air_en8811h.c-688-\ndrivers/net/phy/air_en8811h.c:689:static int air_led_brightness_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-690-\t\t\t\t enum led_brightness value)\n--\ndrivers/net/phy/air_en8811h.c=714=static int air_led_hw_control_get(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/air_en8811h.c-726-\ndrivers/net/phy/air_en8811h.c:727:static int air_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-728-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_en8811h.c=816=static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode)\n--\ndrivers/net/phy/air_en8811h.c-858-\t\t}\ndrivers/net/phy/air_en8811h.c:859:\t\tair_led_hw_control_set(phydev, i, priv-\u003eled[i].rules);\ndrivers/net/phy/air_en8811h.c-860-\t}\n--\ndrivers/net/phy/air_en8811h.c=1576=static struct phy_driver en8811h_driver[] = {\n--\ndrivers/net/phy/air_en8811h.c-1593-\t.led_blink_set\t\t= air_led_blink_set,\ndrivers/net/phy/air_en8811h.c:1594:\t.led_brightness_set\t= air_led_brightness_set,\ndrivers/net/phy/air_en8811h.c:1595:\t.led_hw_control_set\t= air_led_hw_control_set,\ndrivers/net/phy/air_en8811h.c-1596-\t.led_hw_control_get\t= air_led_hw_control_get,\n--\ndrivers/net/phy/air_en8811h.c-1615-\t.led_blink_set\t\t= air_led_blink_set,\ndrivers/net/phy/air_en8811h.c:1616:\t.led_brightness_set\t= air_led_brightness_set,\ndrivers/net/phy/air_en8811h.c:1617:\t.led_hw_control_set\t= air_led_hw_control_set,\ndrivers/net/phy/air_en8811h.c-1618-\t.led_hw_control_get\t= air_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia.h=243=int aqr_phy_led_blink_set(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/aquantia/aquantia.h-245-\t\t\t unsigned long *delay_off);\ndrivers/net/phy/aquantia/aquantia.h:246:int aqr_phy_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/aquantia/aquantia.h-247-\t\t\t u8 index, enum led_brightness value);\n--\ndrivers/net/phy/aquantia/aquantia.h=250=int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,\ndrivers/net/phy/aquantia/aquantia.h-251-\t\t\t unsigned long *rules);\ndrivers/net/phy/aquantia/aquantia.h:252:int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/aquantia/aquantia.h-253-\t\t\t unsigned long rules);\n--\ndrivers/net/phy/aquantia/aquantia_leds.c-10-\ndrivers/net/phy/aquantia/aquantia_leds.c:11:int aqr_phy_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/aquantia/aquantia_leds.c-12-\t\t\t u8 index, enum led_brightness value)\n--\ndrivers/net/phy/aquantia/aquantia_leds.c=47=int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/aquantia/aquantia_leds.c-83-\ndrivers/net/phy/aquantia/aquantia_leds.c:84:int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/aquantia/aquantia_leds.c-85-\t\t\t unsigned long rules)\n--\ndrivers/net/phy/aquantia/aquantia_main.c=1181=static struct phy_driver aqr_driver[] = {\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1236-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1237:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1238-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1239:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1240-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1263-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1264:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1265-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1266:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1267-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1290-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1291:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1292-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1293:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1294-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1317-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1318:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1319-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1320:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1321-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1353-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1354:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1355-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1356:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1357-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1421-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1422:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1423-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1424:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1425-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1447-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1448:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1449-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1450:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1451-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1474-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1475:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1476-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1477:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1478-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1501-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1502:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1503-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1504:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1505-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1528-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1529:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1530-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1531:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1532-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/aquantia/aquantia_main.c-1554-\t.link_change_notify = aqr107_link_change_notify,\ndrivers/net/phy/aquantia/aquantia_main.c:1555:\t.led_brightness_set = aqr_phy_led_brightness_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1556-\t.led_hw_is_supported = aqr_phy_led_hw_is_supported,\ndrivers/net/phy/aquantia/aquantia_main.c:1557:\t.led_hw_control_set = aqr_phy_led_hw_control_set,\ndrivers/net/phy/aquantia/aquantia_main.c-1558-\t.led_hw_control_get = aqr_phy_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c=697=static int as21xxx_read_status(struct phy_device *phydev)\n--\ndrivers/net/phy/as21xxx.c-770-\ndrivers/net/phy/as21xxx.c:771:static int as21xxx_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/as21xxx.c-772-\t\t\t\t u8 index, enum led_brightness value)\n--\ndrivers/net/phy/as21xxx.c=803=static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/as21xxx.c-825-\ndrivers/net/phy/as21xxx.c:826:static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/as21xxx.c-827-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/as21xxx.c=946=static struct phy_driver as21xxx_drivers[] = {\n--\ndrivers/net/phy/as21xxx.c-962-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:963:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-964-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:965:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-966-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-974-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:975:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-976-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:977:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-978-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-986-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:987:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-988-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:989:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-990-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-998-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:999:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1000-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1001:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1002-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1010-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1011:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1012-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1013:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1014-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1022-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1023:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1024-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1025:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1026-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1034-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1035:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1036-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1037:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1038-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1046-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1047:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1048-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1049:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1050-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1058-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1059:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1060-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1061:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1062-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/as21xxx.c-1070-\t\t.read_status\t= as21xxx_read_status,\ndrivers/net/phy/as21xxx.c:1071:\t\t.led_brightness_set = as21xxx_led_brightness_set,\ndrivers/net/phy/as21xxx.c-1072-\t\t.led_hw_is_supported = as21xxx_led_hw_is_supported,\ndrivers/net/phy/as21xxx.c:1073:\t\t.led_hw_control_set = as21xxx_led_hw_control_set,\ndrivers/net/phy/as21xxx.c-1074-\t\t.led_hw_control_get = as21xxx_led_hw_control_get,\n--\ndrivers/net/phy/bcm-phy-lib.c=1091=EXPORT_SYMBOL_GPL(bcm_phy_wol_isr);\ndrivers/net/phy/bcm-phy-lib.c-1092-\ndrivers/net/phy/bcm-phy-lib.c:1093:int bcm_phy_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/bcm-phy-lib.c-1094-\t\t\t u8 index, enum led_brightness value)\n--\ndrivers/net/phy/bcm-phy-lib.c-1117-}\ndrivers/net/phy/bcm-phy-lib.c:1118:EXPORT_SYMBOL_GPL(bcm_phy_led_brightness_set);\ndrivers/net/phy/bcm-phy-lib.c-1119-\n--\ndrivers/net/phy/bcm-phy-lib.h=120=irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id);\ndrivers/net/phy/bcm-phy-lib.h-121-\ndrivers/net/phy/bcm-phy-lib.h:122:int bcm_phy_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/bcm-phy-lib.h-123-\t\t\t u8 index, enum led_brightness value);\n--\ndrivers/net/phy/bcm84881.c=99=static int bcm8489x_led_write(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/bcm84881.c-116-\ndrivers/net/phy/bcm84881.c:117:static int bcm8489x_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/bcm84881.c-118-\t\t\t\t u8 index, enum led_brightness value)\n--\ndrivers/net/phy/bcm84881.c=137=static int bcm8489x_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/bcm84881.c-157-\ndrivers/net/phy/bcm84881.c:158:static int bcm8489x_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/bcm84881.c-159-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/bcm84881.c=419=static struct phy_driver bcm84881_drivers[] = {\n--\ndrivers/net/phy/bcm84881.c-440-\t\t.read_status\t= bcm84881_read_status,\ndrivers/net/phy/bcm84881.c:441:\t\t.led_brightness_set = bcm8489x_led_brightness_set,\ndrivers/net/phy/bcm84881.c-442-\t\t.led_hw_is_supported = bcm8489x_led_hw_is_supported,\ndrivers/net/phy/bcm84881.c:443:\t\t.led_hw_control_set = bcm8489x_led_hw_control_set,\ndrivers/net/phy/bcm84881.c-444-\t\t.led_hw_control_get = bcm8489x_led_hw_control_get,\n--\ndrivers/net/phy/bcm84881.c-454-\t\t.read_status\t= bcm84881_read_status,\ndrivers/net/phy/bcm84881.c:455:\t\t.led_brightness_set = bcm8489x_led_brightness_set,\ndrivers/net/phy/bcm84881.c-456-\t\t.led_hw_is_supported = bcm8489x_led_hw_is_supported,\ndrivers/net/phy/bcm84881.c:457:\t\t.led_hw_control_set = bcm8489x_led_hw_control_set,\ndrivers/net/phy/bcm84881.c-458-\t\t.led_hw_control_get = bcm8489x_led_hw_control_get,\n--\ndrivers/net/phy/broadcom.c=1473=static struct phy_driver broadcom_drivers[] = {\n--\ndrivers/net/phy/broadcom.c-1514-\t.set_wol\t= bcm54xx_phy_set_wol,\ndrivers/net/phy/broadcom.c:1515:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1516-\t.disable_autonomous_eee\t= bcm54xx_disable_autonomous_eee,\n--\ndrivers/net/phy/broadcom.c-1528-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1529:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1530-}, {\n--\ndrivers/net/phy/broadcom.c-1541-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1542:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1543-\t.suspend\t= bcm54xx_suspend,\n--\ndrivers/net/phy/broadcom.c-1556-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1557:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1558-}, {\n--\ndrivers/net/phy/broadcom.c-1571-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1572:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1573-}, {\n--\ndrivers/net/phy/broadcom.c-1585-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1586:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1587-}, {\n--\ndrivers/net/phy/broadcom.c-1603-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1604:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1605-}, {\n--\ndrivers/net/phy/broadcom.c-1621-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1622:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1623-}, {\n--\ndrivers/net/phy/broadcom.c-1634-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1635:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1636-}, {\n--\ndrivers/net/phy/broadcom.c-1649-\t.resume\t\t= bcm54xx_resume,\ndrivers/net/phy/broadcom.c:1650:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1651-}, {\n--\ndrivers/net/phy/broadcom.c-1664-\t.resume\t\t= bcm54xx_resume,\ndrivers/net/phy/broadcom.c:1665:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1666-}, {\n--\ndrivers/net/phy/broadcom.c-1677-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1678:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1679-}, {\n--\ndrivers/net/phy/broadcom.c-1717-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1718:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1719-}, {\n--\ndrivers/net/phy/broadcom.c-1731-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1732:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1733-}, {\n--\ndrivers/net/phy/broadcom.c-1745-\t.link_change_notify\t= bcm54xx_link_change_notify,\ndrivers/net/phy/broadcom.c:1746:\t.led_brightness_set\t= bcm_phy_led_brightness_set,\ndrivers/net/phy/broadcom.c-1747-}, {\n--\ndrivers/net/phy/dp83822.c=1085=static int dp83822_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/dp83822.c-1096-\ndrivers/net/phy/dp83822.c:1097:static int dp83822_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/dp83822.c-1098-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/dp83822.c=1124=static int dp83822_led_hw_control_get(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/dp83822.c-1198-\t\t.led_hw_is_supported = dp83822_led_hw_is_supported,\t\\\ndrivers/net/phy/dp83822.c:1199:\t\t.led_hw_control_set = dp83822_led_hw_control_set,\t\\\ndrivers/net/phy/dp83822.c-1200-\t\t.led_hw_control_get = dp83822_led_hw_control_get,\t\\\n--\ndrivers/net/phy/dp83867.c=1070=static int\ndrivers/net/phy/dp83867.c:1071:dp83867_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/dp83867.c-1072-\t\t\t u8 index, enum led_brightness brightness)\n--\ndrivers/net/phy/dp83867.c=1129=static int dp83867_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/dp83867.c-1140-\ndrivers/net/phy/dp83867.c:1141:static int dp83867_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/dp83867.c-1142-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/dp83867.c=1268=static struct phy_driver dp83867_driver[] = {\n--\ndrivers/net/phy/dp83867.c-1296-\ndrivers/net/phy/dp83867.c:1297:\t\t.led_brightness_set = dp83867_led_brightness_set,\ndrivers/net/phy/dp83867.c-1298-\t\t.led_hw_is_supported = dp83867_led_hw_is_supported,\ndrivers/net/phy/dp83867.c:1299:\t\t.led_hw_control_set = dp83867_led_hw_control_set,\ndrivers/net/phy/dp83867.c-1300-\t\t.led_hw_control_get = dp83867_led_hw_control_get,\n--\ndrivers/net/phy/dp83td510.c=292=static int dp83td510_get_mse_snapshot(struct phy_device *phydev,\n--\ndrivers/net/phy/dp83td510.c-310-\ndrivers/net/phy/dp83td510.c:311:static int dp83td510_led_brightness_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/dp83td510.c-312-\t\t\t\t\tenum led_brightness brightness)\n--\ndrivers/net/phy/dp83td510.c=355=static int dp83td510_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/dp83td510.c-366-\ndrivers/net/phy/dp83td510.c:367:static int dp83td510_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/dp83td510.c-368-\t\t\t\t\tunsigned long rules)\n--\ndrivers/net/phy/dp83td510.c=939=static struct phy_driver dp83td510_driver[] = {\n--\ndrivers/net/phy/dp83td510.c-960-\ndrivers/net/phy/dp83td510.c:961:\t.led_brightness_set = dp83td510_led_brightness_set,\ndrivers/net/phy/dp83td510.c-962-\t.led_hw_is_supported = dp83td510_led_hw_is_supported,\ndrivers/net/phy/dp83td510.c:963:\t.led_hw_control_set = dp83td510_led_hw_control_set,\ndrivers/net/phy/dp83td510.c-964-\t.led_hw_control_get = dp83td510_led_hw_control_get,\n--\ndrivers/net/phy/intel-xway.c=375=static irqreturn_t xway_gphy_handle_interrupt(struct phy_device *phydev)\n--\ndrivers/net/phy/intel-xway.c-392-\ndrivers/net/phy/intel-xway.c:393:static int xway_gphy_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/intel-xway.c-394-\t\t\t\t\tu8 index, enum led_brightness value)\n--\ndrivers/net/phy/intel-xway.c=451=static int xway_gphy_led_hw_control_get(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/intel-xway.c-489-\ndrivers/net/phy/intel-xway.c:490:static int xway_gphy_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/intel-xway.c-491-\t\t\t\t\tunsigned long rules)\n--\ndrivers/net/phy/intel-xway.c=584=static struct phy_driver xway_gphy[] = {\n--\ndrivers/net/phy/intel-xway.c-596-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:597:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-598-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-599-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:600:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-601-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-615-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:616:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-617-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-618-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:619:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-620-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-634-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:635:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-636-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-637-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:638:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-639-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-653-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:654:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-655-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-656-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:657:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-658-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-671-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:672:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-673-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-674-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:675:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-676-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-689-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:690:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-691-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-692-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:693:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-694-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-707-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:708:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-709-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-710-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:711:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-712-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-725-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:726:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-727-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-728-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:729:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-730-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-743-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:744:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-745-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-746-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:747:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-748-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/intel-xway.c-761-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/intel-xway.c:762:\t\t.led_brightness_set = xway_gphy_led_brightness_set,\ndrivers/net/phy/intel-xway.c-763-\t\t.led_hw_is_supported = xway_gphy_led_hw_is_supported,\ndrivers/net/phy/intel-xway.c-764-\t\t.led_hw_control_get = xway_gphy_led_hw_control_get,\ndrivers/net/phy/intel-xway.c:765:\t\t.led_hw_control_set = xway_gphy_led_hw_control_set,\ndrivers/net/phy/intel-xway.c-766-\t\t.led_polarity_set = xway_gphy_led_polarity_set,\n--\ndrivers/net/phy/marvell-88q2xxx.c=1028=static int mv88q2xxx_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/marvell-88q2xxx.c-1039-\ndrivers/net/phy/marvell-88q2xxx.c:1040:static int mv88q2xxx_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/marvell-88q2xxx.c-1041-\t\t\t\t\tunsigned long rules)\n--\ndrivers/net/phy/marvell-88q2xxx.c=1102=static struct phy_driver mv88q2xxx_driver[] = {\n--\ndrivers/net/phy/marvell-88q2xxx.c-1138-\t\t.led_hw_is_supported\t= mv88q2xxx_led_hw_is_supported,\ndrivers/net/phy/marvell-88q2xxx.c:1139:\t\t.led_hw_control_set\t= mv88q2xxx_led_hw_control_set,\ndrivers/net/phy/marvell-88q2xxx.c-1140-\t\t.led_hw_control_get\t= mv88q2xxx_led_hw_control_get,\n--\ndrivers/net/phy/marvell.c=3259=static int marvell_hwmon_probe(struct phy_device *phydev)\n--\ndrivers/net/phy/marvell.c-3264-\ndrivers/net/phy/marvell.c:3265:static int m88e1318_led_brightness_set(struct phy_device *phydev,\ndrivers/net/phy/marvell.c-3266-\t\t\t\t u8 index, enum led_brightness value)\n--\ndrivers/net/phy/marvell.c=3523=static int m88e1318_led_hw_is_supported(struct phy_device *phydev, u8 index,\n--\ndrivers/net/phy/marvell.c-3540-\ndrivers/net/phy/marvell.c:3541:static int m88e1318_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/marvell.c-3542-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/marvell.c=3667=static struct phy_driver marvell_drivers[] = {\n--\ndrivers/net/phy/marvell.c-3830-\t\t.get_stats = marvell_get_stats,\ndrivers/net/phy/marvell.c:3831:\t\t.led_brightness_set = m88e1318_led_brightness_set,\ndrivers/net/phy/marvell.c-3832-\t\t.led_blink_set = m88e1318_led_blink_set,\ndrivers/net/phy/marvell.c-3833-\t\t.led_hw_is_supported = m88e1318_led_hw_is_supported,\ndrivers/net/phy/marvell.c:3834:\t\t.led_hw_control_set = m88e1318_led_hw_control_set,\ndrivers/net/phy/marvell.c-3835-\t\t.led_hw_control_get = m88e1318_led_hw_control_get,\n--\ndrivers/net/phy/marvell.c-3944-\t\t.cable_test_get_status = marvell_vct7_cable_test_get_status,\ndrivers/net/phy/marvell.c:3945:\t\t.led_brightness_set = m88e1318_led_brightness_set,\ndrivers/net/phy/marvell.c-3946-\t\t.led_blink_set = m88e1318_led_blink_set,\ndrivers/net/phy/marvell.c-3947-\t\t.led_hw_is_supported = m88e1318_led_hw_is_supported,\ndrivers/net/phy/marvell.c:3948:\t\t.led_hw_control_set = m88e1318_led_hw_control_set,\ndrivers/net/phy/marvell.c-3949-\t\t.led_hw_control_get = m88e1318_led_hw_control_get,\n--\ndrivers/net/phy/marvell.c-3976-\t\t.cable_test_get_status = marvell_vct7_cable_test_get_status,\ndrivers/net/phy/marvell.c:3977:\t\t.led_brightness_set = m88e1318_led_brightness_set,\ndrivers/net/phy/marvell.c-3978-\t\t.led_blink_set = m88e1318_led_blink_set,\ndrivers/net/phy/marvell.c-3979-\t\t.led_hw_is_supported = m88e1318_led_hw_is_supported,\n\n"
} |
| 29/2 | 2026/09/23 16:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 42654 output: 44 thoughts: 57 Thoughts: Here's my summary, as if I were thinking it: **Digging into the PHY Device Driver's LED Control** Alright, time to understand the flow for these PHY LED controls. Let's start dissecting the `phy_device.c` file. My immediate thought is to trace the execution path of the `led_hw_control_set` function. I need to figure out where those callbacks are actually *invoked* from within the driver itself. So, the first thing I'll do is reach for `grep`. I'll run it looking for both variations: `.led_hw_control_set` and also `led_hw_control_set` in the `drivers/net/phy/phy_device.c` file. This should give me a good handle on which parts of the code are actually calling the relevant function. Let's see what we get. Hopefully, it's not too convoluted. This should be a fairly standard process, but you never know when some vendor specific implementation might be involved. |
| 30/2 | 2026/09/23 16:17 | tool | grepper |
0mArgs:{
"Expression": "led_hw_control_set|led_brightness_set",
"PathPrefix": "drivers/net/phy/phy_device.c"
}Results: {
"Output": "drivers/net/phy/phy_device.c=3194=static int phy_led_set_brightness(struct led_classdev *led_cdev,\n--\ndrivers/net/phy/phy_device.c-3201-\tmutex_lock(\u0026phydev-\u003elock);\ndrivers/net/phy/phy_device.c:3202:\terr = phydev-\u003edrv-\u003eled_brightness_set(phydev, phyled-\u003eindex, value);\ndrivers/net/phy/phy_device.c-3203-\tmutex_unlock(\u0026phydev-\u003elock);\n--\ndrivers/net/phy/phy_device.c=3250=static int __maybe_unused\ndrivers/net/phy/phy_device.c:3251:phy_led_hw_control_set(struct led_classdev *led_cdev,\ndrivers/net/phy/phy_device.c-3252-\t\t unsigned long rules)\n--\ndrivers/net/phy/phy_device.c-3258-\tmutex_lock(\u0026phydev-\u003elock);\ndrivers/net/phy/phy_device.c:3259:\terr = phydev-\u003edrv-\u003eled_hw_control_set(phydev, phyled-\u003eindex, rules);\ndrivers/net/phy/phy_device.c-3260-\tmutex_unlock(\u0026phydev-\u003elock);\n--\ndrivers/net/phy/phy_device.c=3289=static int of_phy_led(struct phy_device *phydev,\n--\ndrivers/net/phy/phy_device.c-3334-\tphyled-\u003eindex = index;\ndrivers/net/phy/phy_device.c:3335:\tif (phydev-\u003edrv-\u003eled_brightness_set)\ndrivers/net/phy/phy_device.c-3336-\t\tcdev-\u003ebrightness_set_blocking = phy_led_set_brightness;\n--\ndrivers/net/phy/phy_device.c-3341-\tif (phydev-\u003edrv-\u003eled_hw_is_supported \u0026\u0026\ndrivers/net/phy/phy_device.c:3342:\t phydev-\u003edrv-\u003eled_hw_control_set \u0026\u0026\ndrivers/net/phy/phy_device.c-3343-\t phydev-\u003edrv-\u003eled_hw_control_get) {\ndrivers/net/phy/phy_device.c-3344-\t\tcdev-\u003ehw_control_is_supported = phy_led_hw_is_supported;\ndrivers/net/phy/phy_device.c:3345:\t\tcdev-\u003ehw_control_set = phy_led_hw_control_set;\ndrivers/net/phy/phy_device.c-3346-\t\tcdev-\u003ehw_control_get = phy_led_hw_control_get;\n--\ndrivers/net/phy/phy_device.c=3366=static int of_phy_leds(struct phy_device *phydev)\n--\ndrivers/net/phy/phy_device.c-3384-\t */\ndrivers/net/phy/phy_device.c:3385:\tif (!(phydev-\u003edrv-\u003eled_brightness_set ||\ndrivers/net/phy/phy_device.c-3386-\t phydev-\u003edrv-\u003eled_blink_set ||\ndrivers/net/phy/phy_device.c:3387:\t phydev-\u003edrv-\u003eled_hw_control_set)) {\ndrivers/net/phy/phy_device.c-3388-\t\tphydev_dbg(phydev, \"ignoring leds node defined with no PHY driver support\\n\");\n"
} |
| 31/2 | 2026/09/23 16:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 43867 output: 40 thoughts: 52 Thoughts: Here's my analysis of the provided information, tailored for an expert like myself: **Diving into PHY LED Handling in the Linux Kernel** Okay, so we're looking at the PHY LED handling within the network driver framework. Specifically, I'm thinking about the functions `of_phy_led` and `of_phy_leds` defined in `drivers/net/phy/phy_device.c`. My mind immediately jumps to how these likely interact with Device Tree (DT) bindings for PHYs, enabling the configuration and control of LEDs based on the PHY's presence and state. Let's quickly navigate to line 3366 in `phy_device.c`. I expect to find the core implementation of these functions or calls to their dependents. This is where the magic happens, where the DT information is parsed and translated into PHY-specific LED configurations. Depending on what I find, this could encompass parsing DT nodes, setting up GPIOs, defining LED triggers based on link status, activity, or other relevant events reported by the PHY. I'll need to look for calls to LED subsystem APIs, probably using `led_classdev` structures to abstract away from the physical LED hardware. |
| 32/2 | 2026/09/23 16:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phy_device.c",
"FirstLine": 3360,
"LineCount": 45
}Results: {
"Contents": "3360:\t\n3361:\t\tlist_add(\u0026phyled-\u003elist, \u0026phydev-\u003eleds);\n3362:\t\n3363:\t\treturn 0;\n3364:\t}\n3365:\t\n3366:\tstatic int of_phy_leds(struct phy_device *phydev)\n3367:\t{\n3368:\t\tstruct device_node *node = phydev-\u003emdio.dev.of_node;\n3369:\t\tstruct device_node *leds;\n3370:\t\tint err;\n3371:\t\n3372:\t\tif (!IS_ENABLED(CONFIG_OF_MDIO))\n3373:\t\t\treturn 0;\n3374:\t\n3375:\t\tif (!node)\n3376:\t\t\treturn 0;\n3377:\t\n3378:\t\tleds = of_get_child_by_name(node, \"leds\");\n3379:\t\tif (!leds)\n3380:\t\t\treturn 0;\n3381:\t\n3382:\t\t/* Check if the PHY driver have at least an OP to\n3383:\t\t * set the LEDs.\n3384:\t\t */\n3385:\t\tif (!(phydev-\u003edrv-\u003eled_brightness_set ||\n3386:\t\t phydev-\u003edrv-\u003eled_blink_set ||\n3387:\t\t phydev-\u003edrv-\u003eled_hw_control_set)) {\n3388:\t\t\tphydev_dbg(phydev, \"ignoring leds node defined with no PHY driver support\\n\");\n3389:\t\t\tgoto exit;\n3390:\t\t}\n3391:\t\n3392:\t\tfor_each_available_child_of_node_scoped(leds, led) {\n3393:\t\t\terr = of_phy_led(phydev, led);\n3394:\t\t\tif (err) {\n3395:\t\t\t\tof_node_put(leds);\n3396:\t\t\t\tphy_leds_unregister(phydev);\n3397:\t\t\t\treturn err;\n3398:\t\t\t}\n3399:\t\t}\n3400:\t\n3401:\texit:\n3402:\t\tof_node_put(leds);\n3403:\t\treturn 0;\n3404:\t}\n"
} |
| 33/2 | 2026/09/23 16:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 44826 output: 28 thoughts: 1836 Thoughts: **Analyzing the Reachability of Realtek RTL8261 PHY Driver Code** Okay, so I'm looking at this code and immediately see a dependency: `of_phy_leds` requires both `CONFIG_OF_MDIO` and the existence of a Device Tree node (`phydev->mdio.dev.of_node`) with a "leds" child node to register any LEDs. If that "leds" node isn't there, `of_phy_leds` does absolutely nothing. I also see that `rtl8261x_config_serdes_polarity` needs "tx-polarity" and "rx-polarity" properties in the firmware node. But wait a minute... what architecture are we talking about here? It's amd64. On amd64, Device Tree (`CONFIG_OF`) is usually not used. Even if it *is* enabled for testing, standard devices generally *don't* have an OF node. Plus, can an RTL8261 PHY even *be* instantiated on amd64 in QEMU? Let's dive deeper. Can an RTL8261 PHY even be *created* or probed? I see that it's ID matches `0x001cc898`, `0x001cc899`, and `0x001cc89a`. Is it possible this PHY *exists* in QEMU or GCE? No. QEMU doesn't emulate the RTL8261 or any other Realtek 10G PHY, and it isn't likely that it would be emulated in GCE. Could a USB gadget or `raw_gadget` somehow emulate an ASIX USB network adapter that returns one of those PHY IDs? But even if that were possible, ASIX USB adapters are usually 10/100 or 10/100/1000 adapters using clause 22 MDIO. Can ASIX do clause 45? Let's check `realtek_drvs`. Bingo, `RTL_8261C_CG` uses `phy_write_mmd`! Clause 45 / MMD. Importantly, does syzkaller have any templates, tests, or device descriptions that emulate an ASIX device with an external Realtek 10G PHY, plus a device tree node with either "leds" or "tx-polarity"? No. First off, USB devices don't have OF nodes (the `of_node` is NULL). Secondly, why would syzkaller ever be fuzzing PHY drivers meant for *physical* hardware transceivers? Let's review the "Structurally unreachable hardware" section from the instructions: *Vendor-specific PCIe switches, SmartNICs, or GPU drivers requiring physical ASIC/PCIe cards not emulated in standard QEMU*. And, *Code paths exclusive to architectures other than the target architecture*. Wait a minute, are Ethernet PHY drivers considered structurally unreachable hardware? Let's be clear about what we're talking about here. An Ethernet PHY chip is an *external* physical transceiver chip, like Marvell Alaska, Broadcom, Realtek RTL8211/8261, Aquantia, or Texas Instruments DP83xxx. These require *physical* hardware, the actual chip connected to the MDIO bus of an Ethernet MAC or an SFP module. They are NOT emulated in standard QEMU or GCE. QEMU (amd64) provides things like virtio-net-pci (no PHY), e1000/e1000e (Intel integrated MAC+PHY), rtl8139 (Realtek 10/100 with integrated transceiver), pcnet32, and ne2k_pci. None of these use phylib's `realtek_main.c`. Wait, what about `r8169`? Does QEMU emulate `r8169`? Let me look at the QEMU source code. QEMU has `hw/net/rtl8139.c` which is a PCI 0x10ec, device 0x8139. It does NOT have RTL8168 or RTL8169 *emulation*. And even if it did (or if somebody wrote one), RTL8169 is Gigabit Ethernet (RTL8211/RTL8168 PHY), NOT a 10Gbps RTL8261 PHY! RTL8261 is a 10G PHY designed for multi-gigabit/10G Ethernet switches and routers (such as RTL8261N / RTL |
| 34/2 | 2026/09/23 16:17 | tool | grepper |
0mError:no matches Args: {
"Expression": "mdio.*dummy|mdio.*fake|mdio.*mock"
}Results: {
"error": "no matches"
} |
| 35/2 | 2026/09/23 16:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 47729 output: 24 thoughts: 13 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person: **Navigating the MDIO Drivers** Alright, time to dig into the `drivers/net/mdio/` directory. That's the logical starting point for investigating anything related to Management Data Input/Output within the networking stack. I need to refresh my mental map of what's there – what specific MDIO controllers and PHY drivers are supported, and how they're structured. My initial thoughts are: I'll be looking for the typical driver layout; common MDIO bus abstraction, specific controller drivers (e.g., those for integrated MACs or external PHY controllers), and the PHY drivers themselves, which will likely handle all the specific PHY register definitions and interactions. I'm hoping to get a quick overview of the current supported hardware, the general MDIO configuration flow, and where I can start looking to see where my issue may be. |
| 36/2 | 2026/09/23 16:18 | tool | codesearch-dir-index |
0mArgs:{
"Dir": "drivers/net/mdio"
}Results: {
"Files": [
"acpi_mdio.c",
"fwnode_mdio.c",
"mdio-airoha.c",
"mdio-aspeed.c",
"mdio-bcm-iproc.c",
"mdio-bcm-unimac.c",
"mdio-bitbang.c",
"mdio-cavium.c",
"mdio-cavium.h",
"mdio-gpio.c",
"mdio-hisi-femac.c",
"mdio-i2c.c",
"mdio-ipq4019.c",
"mdio-ipq8064.c",
"mdio-moxart.c",
"mdio-mscc-miim.c",
"mdio-mux-bcm-iproc.c",
"mdio-mux-bcm6368.c",
"mdio-mux-gpio.c",
"mdio-mux-meson-g12a.c",
"mdio-mux-meson-gxl.c",
"mdio-mux-mmioreg.c",
"mdio-mux-multiplexer.c",
"mdio-mux.c",
"mdio-mvusb.c",
"mdio-octeon.c",
"mdio-pic64hpsc.c",
"mdio-realtek-rtl9300.c",
"mdio-regmap.c",
"mdio-sun4i.c",
"mdio-thunder.c",
"mdio-xgene.c",
"of_mdio.c"
],
"Subdirs": null
} |
| 37/2 | 2026/09/23 16:18 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 48367 output: 158 thoughts: 529 Thoughts: **Analysis of the Fuzzing Suitability** Okay, let's break this down. I'm looking at modifications related to the Realtek RTL8261 10Gbps Ethernet PHY. My initial assessment is that this patch *doesn't* warrant fuzzing, and I need to solidify that. First, I see the changes are confined to: documentation (specifically devicetree schema), a Kconfig dependency, and configurations for SerDes polarity and LED control. Crucially, all of these configurations are managed through Device Tree bindings. My understanding is that this PHY, the RTL8261, is *physical* hardware. It's not something emulated in the typical QEMU x86_64 or amd64 environments I usually work with, which is a key factor. This extends to the variants mentioned. I have to consider the hardware this PHY interacts with: MDIO host controllers. I realize that the target PHY is not a software driver, but interacts with actual MDIO busses. These host controllers are also *not* emulated in QEMU, so the whole chain of interaction is not possible to exercise. Therefore, the code modifications in this patch are, in essence, structurally unreachable in a fuzzing context. The RTL8261 itself is a discrete hardware component, and while its behavior is influenced by the Device Tree, the code associated with interpreting that tree and controlling the hardware is only really active when the actual physical hardware is present. My conclusion is pretty straightforward: * `WorthFuzzing` should be `false`. * `FocusSymbols` should be empty, as there's no specific code to target. * `EnableConfigs` should also be empty. * My reasoning is clear: the changes are configuration-based (DT-driven) for a hardware PHY not emulated in the standard fuzzing environments. I'm confident in this assessment. Let's move forward and set the results accordingly. |
| 38/2 | 2026/09/23 16:18 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies Device Tree bindings and adds SerDes lane polarity and LED control callbacks for Realtek RTL8261 series 10Gbps Ethernet PHYs (RTL8261C, RTL8261CE). The modified driver code interacts with physical Realtek PHY transceiver hardware via MDIO/MMD registers based on Device Tree firmware node properties (tx-polarity, rx-polarity, leds). This physical PHY hardware and its DT bindings are not present or emulated in standard virtualized environments (QEMU/GCE on amd64), making the changes structurally unreachable for fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies Device Tree bindings and adds SerDes lane polarity and LED control callbacks for Realtek RTL8261 series 10Gbps Ethernet PHYs (RTL8261C, RTL8261CE). The modified driver code interacts with physical Realtek PHY transceiver hardware via MDIO/MMD registers based on Device Tree firmware node properties (tx-polarity, rx-polarity, leds). This physical PHY hardware and its DT bindings are not present or emulated in standard virtualized environments (QEMU/GCE on amd64), making the changes structurally unreachable for fuzzing.",
"WorthFuzzing": false
} |
| 39/1 | 2026/09/23 16:18 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|