| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/04 18:29 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Wiznet W5100/W5200/W5500 SPI Ethernet driver to support a link GPIO. This is a driver for a physical SPI device that is not emulated in standard QEMU. The driver's probe function performs hardware register checks (e.g., verifying the RTR register value) that will fail without the actual hardware present, making the modified code paths unreachable in a virtualized fuzzing environment.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/04 18:29 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit b40718529dbaf9948c4fa0fa2916ed34c2bdcfc1\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Aug 4 18:29:33 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt b/Documentation/devicetree/bindings/net/wiznet,w5x00.txt\ndeleted file mode 100644\nindex e9665798c4be6..0000000000000\n--- a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-* Wiznet w5x00\n-\n-This is a standalone 10/100 MBit Ethernet controller with SPI interface.\n-\n-For each device connected to a SPI bus, define a child node within\n-the SPI master node.\n-\n-Required properties:\n-- compatible: Should be one of the following strings:\n-\t \"wiznet,w5100\"\n-\t \"wiznet,w5200\"\n-\t \"wiznet,w5500\"\n-- reg: Specify the SPI chip select the chip is wired to.\n-- interrupts: Specify the interrupt index within the interrupt controller (referred\n- to above in interrupt-parent) and interrupt type. w5x00 natively\n- generates falling edge interrupts, however, additional board logic\n- might invert the signal.\n-- pinctrl-names: List of assigned state names, see pinctrl binding documentation.\n-- pinctrl-0: List of phandles to configure the GPIO pin used as interrupt line,\n- see also generic and your platform specific pinctrl binding\n- documentation.\n-\n-Optional properties:\n-- spi-max-frequency: Maximum frequency of the SPI bus when accessing the w5500.\n- According to the w5500 datasheet, the chip allows a maximum of 80 MHz, however,\n- board designs may need to limit this value.\n-- local-mac-address: See ethernet.txt in the same directory.\n-\n-\n-Example (for Raspberry Pi with pin control stuff for GPIO irq):\n-\n-\u0026spi {\n-\tethernet@0: w5500@0 {\n-\t\tcompatible = \"wiznet,w5500\";\n-\t\treg = \u003c0\u003e;\n-\t\tpinctrl-names = \"default\";\n-\t\tpinctrl-0 = \u003c\u0026eth1_pins\u003e;\n-\t\tinterrupt-parent = \u003c\u0026gpio\u003e;\n-\t\tinterrupts = \u003c25 IRQ_TYPE_EDGE_FALLING\u003e;\n-\t\tspi-max-frequency = \u003c30000000\u003e;\n-\t};\n-};\n-\n-\u0026gpio {\n-\teth1_pins: eth1_pins {\n-\t\tbrcm,pins = \u003c25\u003e;\n-\t\tbrcm,function = \u003c0\u003e; /* in */\n-\t\tbrcm,pull = \u003c0\u003e; /* none */\n-\t};\n-};\ndiff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml b/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml\nnew file mode 100644\nindex 0000000000000..8f45a5d773fe3\n--- /dev/null\n+++ b/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml\n@@ -0,0 +1,103 @@\n+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)\n+%YAML 1.2\n+---\n+$id: http://devicetree.org/schemas/net/wiznet,w5x00.yaml#\n+$schema: http://devicetree.org/meta-schemas/core.yaml#\n+\n+title: Wiznet w5x00 SPI Ethernet Controller\n+\n+description: |\n+ This is a standalone 10/100 MBit Ethernet controller with SPI interface.\n+\n+ For each device connected to a SPI bus, define a child node within the SPI master node.\n+\n+allOf:\n+ - $ref: /schemas/net/ethernet-controller.yaml#\n+ - $ref: /schemas/spi/spi-peripheral-props.yaml#\n+\n+properties:\n+ compatible:\n+ enum:\n+ - wiznet,w5100\n+ - wiznet,w5200\n+ - wiznet,w5500\n+\n+ reg:\n+ description: Specify the SPI chip select the chip is wired to.\n+ maxItems: 1\n+ minItems: 1\n+\n+ interrupts:\n+ description:\n+ Specify the interrupt index within the interrupt controller (referred to\n+ above in interrupt-parent) and interrupt type. w5x00 natively generates\n+ falling edge interrupts, however, additional board logic might invert the\n+ signal.\n+ maxItems: 1\n+ minItems: 1\n+\n+ pinctrl-names:\n+ description:\n+ List of assigned state names, see pinctrl binding documentation.\n+ enum:\n+ - default\n+ minItems: 1\n+\n+ pinctrl-0:\n+ description:\n+ List of phandles to configure the GPIO pin used as interrupt line, see\n+ also generic and your platform specific pinctrl binding documentation.\n+ minItems: 1\n+\n+ local-mac-address: true\n+\n+ spi-max-frequency:\n+ description:\n+ Maximum frequency of the SPI bus when accessing the w5500. According to\n+ the w5500 datasheet, the chip allows a maximum of 80 MHz, however, board\n+ designs may need to limit this value.\n+ maximum: 80000000\n+\n+ link-gpios:\n+ description: A GPIO line used for the link detection interrupt.\n+ maxItems: 1\n+\n+required:\n+ - compatible\n+ - reg\n+ - interrupts\n+ - pinctrl-names\n+ - pinctrl-0\n+\n+unevaluatedProperties: false\n+\n+examples:\n+ - |\n+ /* Example (for Raspberry Pi with pin control stuff for GPIO irq) */\n+\n+ #include \u003cdt-bindings/gpio/gpio.h\u003e\n+ #include \u003cdt-bindings/interrupt-controller/irq.h\u003e\n+\n+ spi {\n+ #address-cells = \u003c1\u003e;\n+ #size-cells = \u003c0\u003e;\n+\n+ ethernet@0: w5500@0 {\n+ compatible = \"wiznet,w5500\";\n+ reg = \u003c0\u003e;\n+ pinctrl-names = \"default\";\n+ pinctrl-0 = \u003c\u0026eth1_pins\u003e;\n+ interrupt-parent = \u003c\u0026gpio\u003e;\n+ interrupts = \u003c25 IRQ_TYPE_EDGE_FALLING\u003e;\n+ spi-max-frequency = \u003c30000000\u003e;\n+ link-gpios = \u003c\u0026gpio 4 GPIO_ACTIVE_HIGH\u003e;\n+ local-mac-address = [ a0 b0 c0 d0 e0 f0 ];\n+ };\n+ };\n+\n+ \u0026gpio {\n+ eth1_pins: eth1_pins {\n+ brcm,pins = \u003c25 4\u003e;\n+ brcm,function = \u003c0 0\u003e; /* in */\n+ brcm,pull = \u003c0 0\u003e; /* none */\n+ };\ndiff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c\nindex 53d8dc642fbd6..1410a9fcfa921 100644\n--- a/drivers/net/ethernet/wiznet/w5100.c\n+++ b/drivers/net/ethernet/wiznet/w5100.c\n@@ -22,6 +22,7 @@\n #include \u003clinux/ioport.h\u003e\n #include \u003clinux/interrupt.h\u003e\n #include \u003clinux/irq.h\u003e\n+#include \u003clinux/gpio/consumer.h\u003e\n \n #include \"w5100.h\"\n \n@@ -154,6 +155,7 @@ struct w5100_priv {\n \tu16 s0_rx_buf_size;\n \n \tint irq;\n+\tstruct gpio_desc *link_gpio;\n \n \tstruct napi_struct napi;\n \tstruct net_device *ndev;\n@@ -414,6 +416,16 @@ static void w5100_get_drvinfo(struct net_device *ndev,\n \t\tsizeof(info-\u003ebus_info));\n }\n \n+static u32 w5100_get_link(struct net_device *ndev)\n+{\n+\tstruct w5100_priv *priv = netdev_priv(ndev);\n+\n+\tif (priv-\u003elink_gpio)\n+\t\treturn !!gpiod_get_value_cansleep(priv-\u003elink_gpio);\n+\n+\treturn 1;\n+}\n+\n static u32 w5100_get_msglevel(struct net_device *ndev)\n {\n \tstruct w5100_priv *priv = netdev_priv(ndev);\n@@ -616,6 +628,24 @@ static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)\n \treturn IRQ_HANDLED;\n }\n \n+static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)\n+{\n+\tstruct net_device *ndev = ndev_instance;\n+\tstruct w5100_priv *priv = netdev_priv(ndev);\n+\n+\tif (netif_running(ndev)) {\n+\t\tif (gpiod_get_value(priv-\u003elink_gpio) != 0) {\n+\t\t\tnetif_info(priv, link, ndev, \"link is up\\n\");\n+\t\t\tnetif_carrier_on(ndev);\n+\t\t} else {\n+\t\t\tnetif_info(priv, link, ndev, \"link is down\\n\");\n+\t\t\tnetif_carrier_off(ndev);\n+\t\t}\n+\t}\n+\n+\treturn IRQ_HANDLED;\n+}\n+\n static void w5100_setrx_work(struct work_struct *work)\n {\n \tstruct w5100_priv *priv = container_of(work, struct w5100_priv,\n@@ -659,6 +689,14 @@ static int w5100_open(struct net_device *ndev)\n \tw5100_hw_start(priv);\n \tnapi_enable(\u0026priv-\u003enapi);\n \tnetif_start_queue(ndev);\n+\n+\tif (priv-\u003elink_gpio) {\n+\t\tif (gpiod_get_value_cansleep(priv-\u003elink_gpio) != 0)\n+\t\t\tnetif_carrier_on(ndev);\n+\t\telse\n+\t\t\tnetif_carrier_off(ndev);\n+\t}\n+\n \treturn 0;\n }\n \n@@ -678,6 +716,7 @@ static const struct ethtool_ops w5100_ethtool_ops = {\n \t.get_drvinfo\t\t= w5100_get_drvinfo,\n \t.get_msglevel\t\t= w5100_get_msglevel,\n \t.set_msglevel\t\t= w5100_set_msglevel,\n+\t.get_link\t\t= w5100_get_link,\n \t.get_regs_len\t\t= w5100_get_regs_len,\n \t.get_regs\t\t= w5100_get_regs,\n };\n@@ -751,6 +790,13 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,\n \tpriv-\u003endev = ndev;\n \tpriv-\u003eops = ops;\n \tpriv-\u003eirq = irq;\n+\tpriv-\u003elink_gpio = devm_gpiod_get_optional(dev, \"link\", GPIOD_IN);\n+\tif (IS_ERR(priv-\u003elink_gpio)) {\n+\t\terr = dev_err_probe(dev, PTR_ERR(priv-\u003elink_gpio),\n+\t\t\t\t \"failed to get link GPIO\\n\");\n+\t\tpriv-\u003elink_gpio = NULL;\n+\t\tgoto err_register;\n+\t}\n \n \tndev-\u003enetdev_ops = \u0026w5100_netdev_ops;\n \tndev-\u003eethtool_ops = \u0026w5100_ethtool_ops;\n@@ -803,8 +849,29 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,\n \tif (err)\n \t\tgoto err_hw;\n \n+\tif (priv-\u003elink_gpio) {\n+\t\tint link_irq = gpiod_to_irq(priv-\u003elink_gpio);\n+\n+\t\tif (link_irq \u003c 0) {\n+\t\t\terr = dev_err_probe(dev, link_irq,\n+\t\t\t\t\t \"No corresponding irq for link gpio\\n\");\n+\t\t\tgoto err_gpio;\n+\t\t}\n+\n+\t\terr = devm_request_threaded_irq(dev, link_irq, NULL,\n+\t\t\t\t\t\tw5100_detect_link,\n+\t\t\t\t\t\tIRQF_TRIGGER_RISING |\n+\t\t\t\t\t\tIRQF_TRIGGER_FALLING |\n+\t\t\t\t\t\tIRQF_ONESHOT,\n+\t\t\t\t\t\t\"w5100-link\", priv-\u003endev);\n+\t\tif (err \u003c 0)\n+\t\t\tgoto err_gpio;\n+\t}\n+\n \treturn 0;\n \n+err_gpio:\n+\tfree_irq(priv-\u003eirq, ndev);\n err_hw:\n \tdestroy_workqueue(priv-\u003exfer_wq);\n err_wq:\n@@ -857,6 +924,10 @@ static int w5100_resume(struct device *dev)\n \t\tw5100_hw_start(priv);\n \n \t\tnetif_device_attach(ndev);\n+\n+\t\tif (!priv-\u003elink_gpio ||\n+\t\t gpiod_get_value_cansleep(priv-\u003elink_gpio) != 0)\n+\t\t\tnetif_carrier_on(ndev);\n \t}\n \treturn 0;\n }\n"
} |
| 2/1 | 2026/08/04 18:29 | agent | patch-evaluator |
1mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Wiznet W5100/W5200/W5500 SPI Ethernet driver to support a link GPIO. This is a driver for a physical SPI device that is not emulated in standard QEMU. The driver's probe function performs hardware register checks (e.g., verifying the RTR register value) that will fail without the actual hardware present, making the modified code paths unreachable in a virtualized fuzzing environment.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit b40718529dbaf9948c4fa0fa2916ed34c2bdcfc1
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Aug 4 18:29:33 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt b/Documentation/devicetree/bindings/net/wiznet,w5x00.txt
deleted file mode 100644
index e9665798c4be6..0000000000000
--- a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-* Wiznet w5x00
-
-This is a standalone 10/100 MBit Ethernet controller with SPI interface.
-
-For each device connected to a SPI bus, define a child node within
-the SPI master node.
-
-Required properties:
-- compatible: Should be one of the following strings:
- "wiznet,w5100"
- "wiznet,w5200"
- "wiznet,w5500"
-- reg: Specify the SPI chip select the chip is wired to.
-- interrupts: Specify the interrupt index within the interrupt controller (referred
- to above in interrupt-parent) and interrupt type. w5x00 natively
- generates falling edge interrupts, however, additional board logic
- might invert the signal.
-- pinctrl-names: List of assigned state names, see pinctrl binding documentation.
-- pinctrl-0: List of phandles to configure the GPIO pin used as interrupt line,
- see also generic and your platform specific pinctrl binding
- documentation.
-
-Optional properties:
-- spi-max-frequency: Maximum frequency of the SPI bus when accessing the w5500.
- According to the w5500 datasheet, the chip allows a maximum of 80 MHz, however,
- board designs may need to limit this value.
-- local-mac-address: See ethernet.txt in the same directory.
-
-
-Example (for Raspberry Pi with pin control stuff for GPIO irq):
-
-&spi {
- ethernet@0: w5500@0 {
- compatible = "wiznet,w5500";
- reg = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <ð1_pins>;
- interrupt-parent = <&gpio>;
- interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
- spi-max-frequency = <30000000>;
- };
-};
-
-&gpio {
- eth1_pins: eth1_pins {
- brcm,pins = <25>;
- brcm,function = <0>; /* in */
- brcm,pull = <0>; /* none */
- };
-};
diff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml b/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml
new file mode 100644
index 0000000000000..8f45a5d773fe3
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wiznet,w5x00.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/wiznet,w5x00.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Wiznet w5x00 SPI Ethernet Controller
+
+description: |
+ This is a standalone 10/100 MBit Ethernet controller with SPI interface.
+
+ For each device connected to a SPI bus, define a child node within the SPI master node.
+
+allOf:
+ - $ref: /schemas/net/ethernet-controller.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ enum:
+ - wiznet,w5100
+ - wiznet,w5200
+ - wiznet,w5500
+
+ reg:
+ description: Specify the SPI chip select the chip is wired to.
+ maxItems: 1
+ minItems: 1
+
+ interrupts:
+ description:
+ Specify the interrupt index within the interrupt controller (referred to
+ above in interrupt-parent) and interrupt type. w5x00 natively generates
+ falling edge interrupts, however, additional board logic might invert the
+ signal.
+ maxItems: 1
+ minItems: 1
+
+ pinctrl-names:
+ description:
+ List of assigned state names, see pinctrl binding documentation.
+ enum:
+ - default
+ minItems: 1
+
+ pinctrl-0:
+ description:
+ List of phandles to configure the GPIO pin used as interrupt line, see
+ also generic and your platform specific pinctrl binding documentation.
+ minItems: 1
+
+ local-mac-address: true
+
+ spi-max-frequency:
+ description:
+ Maximum frequency of the SPI bus when accessing the w5500. According to
+ the w5500 datasheet, the chip allows a maximum of 80 MHz, however, board
+ designs may need to limit this value.
+ maximum: 80000000
+
+ link-gpios:
+ description: A GPIO line used for the link detection interrupt.
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - pinctrl-names
+ - pinctrl-0
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ /* Example (for Raspberry Pi with pin control stuff for GPIO irq) */
+
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet@0: w5500@0 {
+ compatible = "wiznet,w5500";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <ð1_pins>;
+ interrupt-parent = <&gpio>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ spi-max-frequency = <30000000>;
+ link-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
+ local-mac-address = [ a0 b0 c0 d0 e0 f0 ];
+ };
+ };
+
+ &gpio {
+ eth1_pins: eth1_pins {
+ brcm,pins = <25 4>;
+ brcm,function = <0 0>; /* in */
+ brcm,pull = <0 0>; /* none */
+ };
diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c
index 53d8dc642fbd6..1410a9fcfa921 100644
--- a/drivers/net/ethernet/wiznet/w5100.c
+++ b/drivers/net/ethernet/wiznet/w5100.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/gpio/consumer.h>
#include "w5100.h"
@@ -154,6 +155,7 @@ struct w5100_priv {
u16 s0_rx_buf_size;
int irq;
+ struct gpio_desc *link_gpio;
struct napi_struct napi;
struct net_device *ndev;
@@ -414,6 +416,16 @@ static void w5100_get_drvinfo(struct net_device *ndev,
sizeof(info->bus_info));
}
+static u32 w5100_get_link(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (priv->link_gpio)
+ return !!gpiod_get_value_cansleep(priv->link_gpio);
+
+ return 1;
+}
+
static u32 w5100_get_msglevel(struct net_device *ndev)
{
struct w5100_priv *priv = netdev_priv(ndev);
@@ -616,6 +628,24 @@ static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
return IRQ_HANDLED;
}
+static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)
+{
+ struct net_device *ndev = ndev_instance;
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ if (gpiod_get_value(priv->link_gpio) != 0) {
+ netif_info(priv, link, ndev, "link is up\n");
+ netif_carrier_on(ndev);
+ } else {
+ netif_info(priv, link, ndev, "link is down\n");
+ netif_carrier_off(ndev);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static void w5100_setrx_work(struct work_struct *work)
{
struct w5100_priv *priv = container_of(work, struct w5100_priv,
@@ -659,6 +689,14 @@ static int w5100_open(struct net_device *ndev)
w5100_hw_start(priv);
napi_enable(&priv->napi);
netif_start_queue(ndev);
+
+ if (priv->link_gpio) {
+ if (gpiod_get_value_cansleep(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
+ else
+ netif_carrier_off(ndev);
+ }
+
return 0;
}
@@ -678,6 +716,7 @@ static const struct ethtool_ops w5100_ethtool_ops = {
.get_drvinfo = w5100_get_drvinfo,
.get_msglevel = w5100_get_msglevel,
.set_msglevel = w5100_set_msglevel,
+ .get_link = w5100_get_link,
.get_regs_len = w5100_get_regs_len,
.get_regs = w5100_get_regs,
};
@@ -751,6 +790,13 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
priv->ndev = ndev;
priv->ops = ops;
priv->irq = irq;
+ priv->link_gpio = devm_gpiod_get_optional(dev, "link", GPIOD_IN);
+ if (IS_ERR(priv->link_gpio)) {
+ err = dev_err_probe(dev, PTR_ERR(priv->link_gpio),
+ "failed to get link GPIO\n");
+ priv->link_gpio = NULL;
+ goto err_register;
+ }
ndev->netdev_ops = &w5100_netdev_ops;
ndev->ethtool_ops = &w5100_ethtool_ops;
@@ -803,8 +849,29 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
if (err)
goto err_hw;
+ if (priv->link_gpio) {
+ int link_irq = gpiod_to_irq(priv->link_gpio);
+
+ if (link_irq < 0) {
+ err = dev_err_probe(dev, link_irq,
+ "No corresponding irq for link gpio\n");
+ goto err_gpio;
+ }
+
+ err = devm_request_threaded_irq(dev, link_irq, NULL,
+ w5100_detect_link,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "w5100-link", priv->ndev);
+ if (err < 0)
+ goto err_gpio;
+ }
+
return 0;
+err_gpio:
+ free_irq(priv->irq, ndev);
err_hw:
destroy_workqueue(priv->xfer_wq);
err_wq:
@@ -857,6 +924,10 @@ static int w5100_resume(struct device *dev)
w5100_hw_start(priv);
netif_device_attach(ndev);
+
+ if (!priv->link_gpio ||
+ gpiod_get_value_cansleep(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
}
return 0;
}
|
| 3/2 | 2026/08/04 18:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5440 output: 19 thoughts: 248 Thoughts: **Fuzzing the Wiznet W5100 Link GPIO Patch** Okay, so we've got a patch here that adds a `link-gpios` entry to the W5100 Ethernet driver's device tree bindings. It looks like it's going to use this GPIO to monitor the link status and update the carrier state in `w5100.c`. My first thought is, is this worth fuzzing? This driver targets those Wiznet SPI Ethernet controllers – the W5100, W5200, and W5500. Now, the real question is, can we even *easily* emulate this in QEMU? Standard QEMU setups typically don't readily expose SPI Ethernet controllers without a lot of specific board emulation. SPI devices, in general, are tough to get at for fuzzing without a lot of extra work. Hmm... is there a workaround to fuzz SPI devices? I seem to recall syzkaller has some SPI support, maybe through `spidev` or something similar, but getting *specific* SPI Ethernet controller fuzzing to work is usually difficult unless it's been explicitly set up. Alright, let's see if syzkaller has any built-in support for wiznet. I'm going to run a `default_api:grepper` search and look for "wiznet" or "w5100" in the kernel source. That should tell me if there's any existing groundwork to leverage. From there, I can determine the feasibility of fuzzing this patch. |
| 4/2 | 2026/08/04 18:29 | tool | grepper |
0mArgs:{
"Expression": "w5100"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 658 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml=18=properties:\n--\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-20- enum:\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:21: - wiznet,w5100\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-22- - wiznet,w5200\n--\ndrivers/net/ethernet/wiznet/Kconfig=19=config WIZNET_W5100\n--\ndrivers/net/ethernet/wiznet/Kconfig-29-\t To compile this driver as a module, choose M here: the module\ndrivers/net/ethernet/wiznet/Kconfig:30:\t will be called w5100.\ndrivers/net/ethernet/wiznet/Kconfig-31-\n--\ndrivers/net/ethernet/wiznet/Makefile-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/ethernet/wiznet/Makefile:2:obj-$(CONFIG_WIZNET_W5100) += w5100.o w5100-spi.o\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-20-\ndrivers/net/ethernet/wiznet/w5100-spi.c:21:#include \"w5100.h\"\ndrivers/net/ethernet/wiznet/w5100-spi.c-22-\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-25-\ndrivers/net/ethernet/wiznet/w5100-spi.c:26:static int w5100_spi_read(struct net_device *ndev, u32 addr)\ndrivers/net/ethernet/wiznet/w5100-spi.c-27-{\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-37-\ndrivers/net/ethernet/wiznet/w5100-spi.c:38:static int w5100_spi_write(struct net_device *ndev, u32 addr, u8 data)\ndrivers/net/ethernet/wiznet/w5100-spi.c-39-{\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-45-\ndrivers/net/ethernet/wiznet/w5100-spi.c:46:static int w5100_spi_read16(struct net_device *ndev, u32 addr)\ndrivers/net/ethernet/wiznet/w5100-spi.c-47-{\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-50-\ndrivers/net/ethernet/wiznet/w5100-spi.c:51:\tret = w5100_spi_read(ndev, addr);\ndrivers/net/ethernet/wiznet/w5100-spi.c-52-\tif (ret \u003c 0)\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-54-\tdata = ret \u003c\u003c 8;\ndrivers/net/ethernet/wiznet/w5100-spi.c:55:\tret = w5100_spi_read(ndev, addr + 1);\ndrivers/net/ethernet/wiznet/w5100-spi.c-56-\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-59-\ndrivers/net/ethernet/wiznet/w5100-spi.c:60:static int w5100_spi_write16(struct net_device *ndev, u32 addr, u16 data)\ndrivers/net/ethernet/wiznet/w5100-spi.c-61-{\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-63-\ndrivers/net/ethernet/wiznet/w5100-spi.c:64:\tret = w5100_spi_write(ndev, addr, data \u003e\u003e 8);\ndrivers/net/ethernet/wiznet/w5100-spi.c-65-\tif (ret)\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-67-\ndrivers/net/ethernet/wiznet/w5100-spi.c:68:\treturn w5100_spi_write(ndev, addr + 1, data \u0026 0xff);\ndrivers/net/ethernet/wiznet/w5100-spi.c-69-}\ndrivers/net/ethernet/wiznet/w5100-spi.c-70-\ndrivers/net/ethernet/wiznet/w5100-spi.c:71:static int w5100_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,\ndrivers/net/ethernet/wiznet/w5100-spi.c-72-\t\t\t int len)\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-76-\tfor (i = 0; i \u003c len; i++) {\ndrivers/net/ethernet/wiznet/w5100-spi.c:77:\t\tint ret = w5100_spi_read(ndev, addr + i);\ndrivers/net/ethernet/wiznet/w5100-spi.c-78-\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-86-\ndrivers/net/ethernet/wiznet/w5100-spi.c:87:static int w5100_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,\ndrivers/net/ethernet/wiznet/w5100-spi.c-88-\t\t\t int len)\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-92-\tfor (i = 0; i \u003c len; i++) {\ndrivers/net/ethernet/wiznet/w5100-spi.c:93:\t\tint ret = w5100_spi_write(ndev, addr + i, buf[i]);\ndrivers/net/ethernet/wiznet/w5100-spi.c-94-\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-101-\ndrivers/net/ethernet/wiznet/w5100-spi.c:102:static const struct w5100_ops w5100_spi_ops = {\ndrivers/net/ethernet/wiznet/w5100-spi.c-103-\t.may_sleep = true,\ndrivers/net/ethernet/wiznet/w5100-spi.c-104-\t.chip_id = W5100,\ndrivers/net/ethernet/wiznet/w5100-spi.c:105:\t.read = w5100_spi_read,\ndrivers/net/ethernet/wiznet/w5100-spi.c:106:\t.write = w5100_spi_write,\ndrivers/net/ethernet/wiznet/w5100-spi.c:107:\t.read16 = w5100_spi_read16,\ndrivers/net/ethernet/wiznet/w5100-spi.c:108:\t.write16 = w5100_spi_write16,\ndrivers/net/ethernet/wiznet/w5100-spi.c:109:\t.readbulk = w5100_spi_readbulk,\ndrivers/net/ethernet/wiznet/w5100-spi.c:110:\t.writebulk = w5100_spi_writebulk,\ndrivers/net/ethernet/wiznet/w5100-spi.c-111-};\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c=125=static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100-spi.c-126-{\ndrivers/net/ethernet/wiznet/w5100-spi.c:127:\treturn w5100_ops_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100-spi.c-128-}\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c=213=static int w5200_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-242-\ndrivers/net/ethernet/wiznet/w5100-spi.c:243:static const struct w5100_ops w5200_ops = {\ndrivers/net/ethernet/wiznet/w5100-spi.c-244-\t.may_sleep = true,\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c=270=static struct w5500_spi_priv *w5500_spi_priv(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100-spi.c-271-{\ndrivers/net/ethernet/wiznet/w5100-spi.c:272:\treturn w5100_ops_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100-spi.c-273-}\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c=372=static int w5500_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-400-\ndrivers/net/ethernet/wiznet/w5100-spi.c:401:static const struct w5100_ops w5500_ops = {\ndrivers/net/ethernet/wiznet/w5100-spi.c-402-\t.may_sleep = true,\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-412-\ndrivers/net/ethernet/wiznet/w5100-spi.c:413:static const struct of_device_id w5100_of_match[] = {\ndrivers/net/ethernet/wiznet/w5100-spi.c:414:\t{ .compatible = \"wiznet,w5100\", .data = (const void*)W5100, },\ndrivers/net/ethernet/wiznet/w5100-spi.c-415-\t{ .compatible = \"wiznet,w5200\", .data = (const void*)W5200, },\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-418-};\ndrivers/net/ethernet/wiznet/w5100-spi.c:419:MODULE_DEVICE_TABLE(of, w5100_of_match);\ndrivers/net/ethernet/wiznet/w5100-spi.c-420-\ndrivers/net/ethernet/wiznet/w5100-spi.c:421:static int w5100_spi_probe(struct spi_device *spi)\ndrivers/net/ethernet/wiznet/w5100-spi.c-422-{\ndrivers/net/ethernet/wiznet/w5100-spi.c:423:\tconst struct w5100_ops *ops;\ndrivers/net/ethernet/wiznet/w5100-spi.c-424-\tkernel_ulong_t driver_data;\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-437-\tcase W5100:\ndrivers/net/ethernet/wiznet/w5100-spi.c:438:\t\tops = \u0026w5100_spi_ops;\ndrivers/net/ethernet/wiznet/w5100-spi.c-439-\t\tpriv_size = 0;\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-452-\ndrivers/net/ethernet/wiznet/w5100-spi.c:453:\treturn w5100_probe(\u0026spi-\u003edev, ops, priv_size, mac, spi-\u003eirq);\ndrivers/net/ethernet/wiznet/w5100-spi.c-454-}\ndrivers/net/ethernet/wiznet/w5100-spi.c-455-\ndrivers/net/ethernet/wiznet/w5100-spi.c:456:static void w5100_spi_remove(struct spi_device *spi)\ndrivers/net/ethernet/wiznet/w5100-spi.c-457-{\ndrivers/net/ethernet/wiznet/w5100-spi.c:458:\tw5100_remove(\u0026spi-\u003edev);\ndrivers/net/ethernet/wiznet/w5100-spi.c-459-}\ndrivers/net/ethernet/wiznet/w5100-spi.c-460-\ndrivers/net/ethernet/wiznet/w5100-spi.c:461:static const struct spi_device_id w5100_spi_ids[] = {\ndrivers/net/ethernet/wiznet/w5100-spi.c:462:\t{ \"w5100\", W5100 },\ndrivers/net/ethernet/wiznet/w5100-spi.c-463-\t{ \"w5200\", W5200 },\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-466-};\ndrivers/net/ethernet/wiznet/w5100-spi.c:467:MODULE_DEVICE_TABLE(spi, w5100_spi_ids);\ndrivers/net/ethernet/wiznet/w5100-spi.c-468-\ndrivers/net/ethernet/wiznet/w5100-spi.c:469:static struct spi_driver w5100_spi_driver = {\ndrivers/net/ethernet/wiznet/w5100-spi.c-470-\t.driver\t\t= {\ndrivers/net/ethernet/wiznet/w5100-spi.c:471:\t\t.name\t= \"w5100\",\ndrivers/net/ethernet/wiznet/w5100-spi.c:472:\t\t.pm\t= \u0026w5100_pm_ops,\ndrivers/net/ethernet/wiznet/w5100-spi.c:473:\t\t.of_match_table = w5100_of_match,\ndrivers/net/ethernet/wiznet/w5100-spi.c-474-\t},\ndrivers/net/ethernet/wiznet/w5100-spi.c:475:\t.probe\t\t= w5100_spi_probe,\ndrivers/net/ethernet/wiznet/w5100-spi.c:476:\t.remove\t\t= w5100_spi_remove,\ndrivers/net/ethernet/wiznet/w5100-spi.c:477:\t.id_table\t= w5100_spi_ids,\ndrivers/net/ethernet/wiznet/w5100-spi.c-478-};\ndrivers/net/ethernet/wiznet/w5100-spi.c:479:module_spi_driver(w5100_spi_driver);\ndrivers/net/ethernet/wiznet/w5100-spi.c-480-\n--\ndrivers/net/ethernet/wiznet/w5100.c-26-\ndrivers/net/ethernet/wiznet/w5100.c:27:#include \"w5100.h\"\ndrivers/net/ethernet/wiznet/w5100.c-28-\ndrivers/net/ethernet/wiznet/w5100.c:29:#define DRV_NAME\t\"w5100\"\ndrivers/net/ethernet/wiznet/w5100.c-30-#define DRV_VERSION\t\"2012-04-04\"\n--\ndrivers/net/ethernet/wiznet/w5100.c=35=MODULE_LICENSE(\"GPL\");\n--\ndrivers/net/ethernet/wiznet/w5100.c-144-\ndrivers/net/ethernet/wiznet/w5100.c:145:struct w5100_priv {\ndrivers/net/ethernet/wiznet/w5100.c:146:\tconst struct w5100_ops *ops;\ndrivers/net/ethernet/wiznet/w5100.c-147-\n--\ndrivers/net/ethernet/wiznet/w5100.c-172-\ndrivers/net/ethernet/wiznet/w5100.c:173:static int w5100_read(struct w5100_priv *priv, u32 addr)\ndrivers/net/ethernet/wiznet/w5100.c-174-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-177-\ndrivers/net/ethernet/wiznet/w5100.c:178:static int w5100_write(struct w5100_priv *priv, u32 addr, u8 data)\ndrivers/net/ethernet/wiznet/w5100.c-179-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-182-\ndrivers/net/ethernet/wiznet/w5100.c:183:static int w5100_read16(struct w5100_priv *priv, u32 addr)\ndrivers/net/ethernet/wiznet/w5100.c-184-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-187-\ndrivers/net/ethernet/wiznet/w5100.c:188:static int w5100_write16(struct w5100_priv *priv, u32 addr, u16 data)\ndrivers/net/ethernet/wiznet/w5100.c-189-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-192-\ndrivers/net/ethernet/wiznet/w5100.c:193:static int w5100_readbulk(struct w5100_priv *priv, u32 addr, u8 *buf, int len)\ndrivers/net/ethernet/wiznet/w5100.c-194-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-197-\ndrivers/net/ethernet/wiznet/w5100.c:198:static int w5100_writebulk(struct w5100_priv *priv, u32 addr, const u8 *buf,\ndrivers/net/ethernet/wiznet/w5100.c-199-\t\t\t int len)\n--\ndrivers/net/ethernet/wiznet/w5100.c-203-\ndrivers/net/ethernet/wiznet/w5100.c:204:static int w5100_readbuf(struct w5100_priv *priv, u16 offset, u8 *buf, int len)\ndrivers/net/ethernet/wiznet/w5100.c-205-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-219-\ndrivers/net/ethernet/wiznet/w5100.c:220:\tret = w5100_readbulk(priv, addr, buf, len);\ndrivers/net/ethernet/wiznet/w5100.c-221-\tif (ret || !remain)\n--\ndrivers/net/ethernet/wiznet/w5100.c-223-\ndrivers/net/ethernet/wiznet/w5100.c:224:\treturn w5100_readbulk(priv, mem_start, buf + len, remain);\ndrivers/net/ethernet/wiznet/w5100.c-225-}\ndrivers/net/ethernet/wiznet/w5100.c-226-\ndrivers/net/ethernet/wiznet/w5100.c:227:static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf,\ndrivers/net/ethernet/wiznet/w5100.c-228-\t\t\t int len)\n--\ndrivers/net/ethernet/wiznet/w5100.c-243-\ndrivers/net/ethernet/wiznet/w5100.c:244:\tret = w5100_writebulk(priv, addr, buf, len);\ndrivers/net/ethernet/wiznet/w5100.c-245-\tif (ret || !remain)\n--\ndrivers/net/ethernet/wiznet/w5100.c-247-\ndrivers/net/ethernet/wiznet/w5100.c:248:\treturn w5100_writebulk(priv, mem_start, buf + len, remain);\ndrivers/net/ethernet/wiznet/w5100.c-249-}\ndrivers/net/ethernet/wiznet/w5100.c-250-\ndrivers/net/ethernet/wiznet/w5100.c:251:static int w5100_reset(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-252-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-255-\ndrivers/net/ethernet/wiznet/w5100.c:256:\tw5100_write(priv, W5100_MR, MR_RST);\ndrivers/net/ethernet/wiznet/w5100.c-257-\tmdelay(5);\ndrivers/net/ethernet/wiznet/w5100.c:258:\tw5100_write(priv, W5100_MR, MR_PB);\ndrivers/net/ethernet/wiznet/w5100.c-259-\n--\ndrivers/net/ethernet/wiznet/w5100.c-262-\ndrivers/net/ethernet/wiznet/w5100.c:263:static int w5100_command(struct w5100_priv *priv, u16 cmd)\ndrivers/net/ethernet/wiznet/w5100.c-264-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-266-\ndrivers/net/ethernet/wiznet/w5100.c:267:\tw5100_write(priv, W5100_S0_CR(priv), cmd);\ndrivers/net/ethernet/wiznet/w5100.c-268-\n--\ndrivers/net/ethernet/wiznet/w5100.c-270-\ndrivers/net/ethernet/wiznet/w5100.c:271:\twhile (w5100_read(priv, W5100_S0_CR(priv)) != 0) {\ndrivers/net/ethernet/wiznet/w5100.c-272-\t\tif (time_after(jiffies, timeout))\n--\ndrivers/net/ethernet/wiznet/w5100.c-279-\ndrivers/net/ethernet/wiznet/w5100.c:280:static void w5100_write_macaddr(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-281-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-283-\ndrivers/net/ethernet/wiznet/w5100.c:284:\tw5100_writebulk(priv, W5100_SHAR, ndev-\u003edev_addr, ETH_ALEN);\ndrivers/net/ethernet/wiznet/w5100.c-285-}\ndrivers/net/ethernet/wiznet/w5100.c-286-\ndrivers/net/ethernet/wiznet/w5100.c:287:static void w5100_socket_intr_mask(struct w5100_priv *priv, u8 mask)\ndrivers/net/ethernet/wiznet/w5100.c-288-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-295-\ndrivers/net/ethernet/wiznet/w5100.c:296:\tw5100_write(priv, imr, mask);\ndrivers/net/ethernet/wiznet/w5100.c-297-}\ndrivers/net/ethernet/wiznet/w5100.c-298-\ndrivers/net/ethernet/wiznet/w5100.c:299:static void w5100_enable_intr(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-300-{\ndrivers/net/ethernet/wiznet/w5100.c:301:\tw5100_socket_intr_mask(priv, IR_S0);\ndrivers/net/ethernet/wiznet/w5100.c-302-}\ndrivers/net/ethernet/wiznet/w5100.c-303-\ndrivers/net/ethernet/wiznet/w5100.c:304:static void w5100_disable_intr(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-305-{\ndrivers/net/ethernet/wiznet/w5100.c:306:\tw5100_socket_intr_mask(priv, 0);\ndrivers/net/ethernet/wiznet/w5100.c-307-}\ndrivers/net/ethernet/wiznet/w5100.c-308-\ndrivers/net/ethernet/wiznet/w5100.c:309:static void w5100_memory_configure(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-310-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-313-\t */\ndrivers/net/ethernet/wiznet/w5100.c:314:\tw5100_write(priv, W5100_RMSR, 0x03);\ndrivers/net/ethernet/wiznet/w5100.c:315:\tw5100_write(priv, W5100_TMSR, 0x03);\ndrivers/net/ethernet/wiznet/w5100.c-316-}\ndrivers/net/ethernet/wiznet/w5100.c-317-\ndrivers/net/ethernet/wiznet/w5100.c:318:static void w5200_memory_configure(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-319-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-324-\t */\ndrivers/net/ethernet/wiznet/w5100.c:325:\tw5100_write(priv, W5200_Sn_RXMEM_SIZE(0), 0x10);\ndrivers/net/ethernet/wiznet/w5100.c:326:\tw5100_write(priv, W5200_Sn_TXMEM_SIZE(0), 0x10);\ndrivers/net/ethernet/wiznet/w5100.c-327-\ndrivers/net/ethernet/wiznet/w5100.c-328-\tfor (i = 1; i \u003c 8; i++) {\ndrivers/net/ethernet/wiznet/w5100.c:329:\t\tw5100_write(priv, W5200_Sn_RXMEM_SIZE(i), 0);\ndrivers/net/ethernet/wiznet/w5100.c:330:\t\tw5100_write(priv, W5200_Sn_TXMEM_SIZE(i), 0);\ndrivers/net/ethernet/wiznet/w5100.c-331-\t}\n--\ndrivers/net/ethernet/wiznet/w5100.c-333-\ndrivers/net/ethernet/wiznet/w5100.c:334:static void w5500_memory_configure(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-335-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-340-\t */\ndrivers/net/ethernet/wiznet/w5100.c:341:\tw5100_write(priv, W5500_Sn_RXMEM_SIZE(0), 0x10);\ndrivers/net/ethernet/wiznet/w5100.c:342:\tw5100_write(priv, W5500_Sn_TXMEM_SIZE(0), 0x10);\ndrivers/net/ethernet/wiznet/w5100.c-343-\ndrivers/net/ethernet/wiznet/w5100.c-344-\tfor (i = 1; i \u003c 8; i++) {\ndrivers/net/ethernet/wiznet/w5100.c:345:\t\tw5100_write(priv, W5500_Sn_RXMEM_SIZE(i), 0);\ndrivers/net/ethernet/wiznet/w5100.c:346:\t\tw5100_write(priv, W5500_Sn_TXMEM_SIZE(i), 0);\ndrivers/net/ethernet/wiznet/w5100.c-347-\t}\n--\ndrivers/net/ethernet/wiznet/w5100.c-349-\ndrivers/net/ethernet/wiznet/w5100.c:350:static int w5100_hw_reset(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-351-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-353-\ndrivers/net/ethernet/wiznet/w5100.c:354:\tw5100_reset(priv);\ndrivers/net/ethernet/wiznet/w5100.c-355-\ndrivers/net/ethernet/wiznet/w5100.c:356:\tw5100_disable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c:357:\tw5100_write_macaddr(priv);\ndrivers/net/ethernet/wiznet/w5100.c-358-\n--\ndrivers/net/ethernet/wiznet/w5100.c-360-\tcase W5100:\ndrivers/net/ethernet/wiznet/w5100.c:361:\t\tw5100_memory_configure(priv);\ndrivers/net/ethernet/wiznet/w5100.c-362-\t\trtr = W5100_RTR;\n--\ndrivers/net/ethernet/wiznet/w5100.c-375-\ndrivers/net/ethernet/wiznet/w5100.c:376:\tif (w5100_read16(priv, rtr) != RTR_DEFAULT)\ndrivers/net/ethernet/wiznet/w5100.c-377-\t\treturn -ENODEV;\n--\ndrivers/net/ethernet/wiznet/w5100.c-381-\ndrivers/net/ethernet/wiznet/w5100.c:382:static void w5100_hw_start(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-383-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-392-\ndrivers/net/ethernet/wiznet/w5100.c:393:\tw5100_write(priv, W5100_S0_MR(priv), mode);\ndrivers/net/ethernet/wiznet/w5100.c:394:\tw5100_command(priv, S0_CR_OPEN);\ndrivers/net/ethernet/wiznet/w5100.c:395:\tw5100_enable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c-396-}\ndrivers/net/ethernet/wiznet/w5100.c-397-\ndrivers/net/ethernet/wiznet/w5100.c:398:static void w5100_hw_close(struct w5100_priv *priv)\ndrivers/net/ethernet/wiznet/w5100.c-399-{\ndrivers/net/ethernet/wiznet/w5100.c:400:\tw5100_disable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c:401:\tw5100_command(priv, S0_CR_CLOSE);\ndrivers/net/ethernet/wiznet/w5100.c-402-}\n--\ndrivers/net/ethernet/wiznet/w5100.c-409-\ndrivers/net/ethernet/wiznet/w5100.c:410:static void w5100_get_drvinfo(struct net_device *ndev,\ndrivers/net/ethernet/wiznet/w5100.c-411-\t\t\t struct ethtool_drvinfo *info)\n--\ndrivers/net/ethernet/wiznet/w5100.c-418-\ndrivers/net/ethernet/wiznet/w5100.c:419:static u32 w5100_get_link(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-420-{\ndrivers/net/ethernet/wiznet/w5100.c:421:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-422-\n--\ndrivers/net/ethernet/wiznet/w5100.c-428-\ndrivers/net/ethernet/wiznet/w5100.c:429:static u32 w5100_get_msglevel(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-430-{\ndrivers/net/ethernet/wiznet/w5100.c:431:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-432-\n--\ndrivers/net/ethernet/wiznet/w5100.c-435-\ndrivers/net/ethernet/wiznet/w5100.c:436:static void w5100_set_msglevel(struct net_device *ndev, u32 value)\ndrivers/net/ethernet/wiznet/w5100.c-437-{\ndrivers/net/ethernet/wiznet/w5100.c:438:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-439-\n--\ndrivers/net/ethernet/wiznet/w5100.c-442-\ndrivers/net/ethernet/wiznet/w5100.c:443:static int w5100_get_regs_len(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-444-{\n--\ndrivers/net/ethernet/wiznet/w5100.c-447-\ndrivers/net/ethernet/wiznet/w5100.c:448:static void w5100_get_regs(struct net_device *ndev,\ndrivers/net/ethernet/wiznet/w5100.c-449-\t\t\t struct ethtool_regs *regs, void *buf)\ndrivers/net/ethernet/wiznet/w5100.c-450-{\ndrivers/net/ethernet/wiznet/w5100.c:451:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-452-\ndrivers/net/ethernet/wiznet/w5100.c-453-\tregs-\u003eversion = 1;\ndrivers/net/ethernet/wiznet/w5100.c:454:\tw5100_readbulk(priv, W5100_COMMON_REGS, buf, W5100_COMMON_REGS_LEN);\ndrivers/net/ethernet/wiznet/w5100.c-455-\tbuf += W5100_COMMON_REGS_LEN;\ndrivers/net/ethernet/wiznet/w5100.c:456:\tw5100_readbulk(priv, S0_REGS(priv), buf, W5100_S0_REGS_LEN);\ndrivers/net/ethernet/wiznet/w5100.c-457-}\ndrivers/net/ethernet/wiznet/w5100.c-458-\ndrivers/net/ethernet/wiznet/w5100.c:459:static void w5100_restart(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-460-{\ndrivers/net/ethernet/wiznet/w5100.c:461:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-462-\ndrivers/net/ethernet/wiznet/w5100.c-463-\tnetif_stop_queue(ndev);\ndrivers/net/ethernet/wiznet/w5100.c:464:\tw5100_hw_reset(priv);\ndrivers/net/ethernet/wiznet/w5100.c:465:\tw5100_hw_start(priv);\ndrivers/net/ethernet/wiznet/w5100.c-466-\tndev-\u003estats.tx_errors++;\n--\ndrivers/net/ethernet/wiznet/w5100.c-470-\ndrivers/net/ethernet/wiznet/w5100.c:471:static void w5100_restart_work(struct work_struct *work)\ndrivers/net/ethernet/wiznet/w5100.c-472-{\ndrivers/net/ethernet/wiznet/w5100.c:473:\tstruct w5100_priv *priv = container_of(work, struct w5100_priv,\ndrivers/net/ethernet/wiznet/w5100.c-474-\t\t\t\t\t restart_work);\ndrivers/net/ethernet/wiznet/w5100.c-475-\ndrivers/net/ethernet/wiznet/w5100.c:476:\tw5100_restart(priv-\u003endev);\ndrivers/net/ethernet/wiznet/w5100.c-477-}\ndrivers/net/ethernet/wiznet/w5100.c-478-\ndrivers/net/ethernet/wiznet/w5100.c:479:static void w5100_tx_timeout(struct net_device *ndev, unsigned int txqueue)\ndrivers/net/ethernet/wiznet/w5100.c-480-{\ndrivers/net/ethernet/wiznet/w5100.c:481:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-482-\n--\ndrivers/net/ethernet/wiznet/w5100.c-485-\telse\ndrivers/net/ethernet/wiznet/w5100.c:486:\t\tw5100_restart(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-487-}\ndrivers/net/ethernet/wiznet/w5100.c-488-\ndrivers/net/ethernet/wiznet/w5100.c:489:static void w5100_tx_skb(struct net_device *ndev, struct sk_buff *skb)\ndrivers/net/ethernet/wiznet/w5100.c-490-{\ndrivers/net/ethernet/wiznet/w5100.c:491:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-492-\tu16 offset;\ndrivers/net/ethernet/wiznet/w5100.c-493-\ndrivers/net/ethernet/wiznet/w5100.c:494:\toffset = w5100_read16(priv, W5100_S0_TX_WR(priv));\ndrivers/net/ethernet/wiznet/w5100.c:495:\tw5100_writebuf(priv, offset, skb-\u003edata, skb-\u003elen);\ndrivers/net/ethernet/wiznet/w5100.c:496:\tw5100_write16(priv, W5100_S0_TX_WR(priv), offset + skb-\u003elen);\ndrivers/net/ethernet/wiznet/w5100.c-497-\tndev-\u003estats.tx_bytes += skb-\u003elen;\n--\ndrivers/net/ethernet/wiznet/w5100.c-500-\ndrivers/net/ethernet/wiznet/w5100.c:501:\tw5100_command(priv, S0_CR_SEND);\ndrivers/net/ethernet/wiznet/w5100.c-502-}\ndrivers/net/ethernet/wiznet/w5100.c-503-\ndrivers/net/ethernet/wiznet/w5100.c:504:static void w5100_tx_work(struct work_struct *work)\ndrivers/net/ethernet/wiznet/w5100.c-505-{\ndrivers/net/ethernet/wiznet/w5100.c:506:\tstruct w5100_priv *priv = container_of(work, struct w5100_priv,\ndrivers/net/ethernet/wiznet/w5100.c-507-\t\t\t\t\t tx_work);\n--\ndrivers/net/ethernet/wiznet/w5100.c-513-\t\treturn;\ndrivers/net/ethernet/wiznet/w5100.c:514:\tw5100_tx_skb(priv-\u003endev, skb);\ndrivers/net/ethernet/wiznet/w5100.c-515-}\ndrivers/net/ethernet/wiznet/w5100.c-516-\ndrivers/net/ethernet/wiznet/w5100.c:517:static netdev_tx_t w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-518-{\ndrivers/net/ethernet/wiznet/w5100.c:519:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-520-\n--\ndrivers/net/ethernet/wiznet/w5100.c-527-\t} else {\ndrivers/net/ethernet/wiznet/w5100.c:528:\t\tw5100_tx_skb(ndev, skb);\ndrivers/net/ethernet/wiznet/w5100.c-529-\t}\n--\ndrivers/net/ethernet/wiznet/w5100.c-533-\ndrivers/net/ethernet/wiznet/w5100.c:534:static struct sk_buff *w5100_rx_skb(struct net_device *ndev)\ndrivers/net/ethernet/wiznet/w5100.c-535-{\ndrivers/net/ethernet/wiznet/w5100.c:536:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-537-\tstruct sk_buff *skb;\n--\ndrivers/net/ethernet/wiznet/w5100.c-540-\tu8 header[2];\ndrivers/net/ethernet/wiznet/w5100.c:541:\tu16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR(priv));\ndrivers/net/ethernet/wiznet/w5100.c-542-\n--\ndrivers/net/ethernet/wiznet/w5100.c-545-\ndrivers/net/ethernet/wiznet/w5100.c:546:\toffset = w5100_read16(priv, W5100_S0_RX_RD(priv));\ndrivers/net/ethernet/wiznet/w5100.c:547:\tw5100_readbuf(priv, offset, header, 2);\ndrivers/net/ethernet/wiznet/w5100.c-548-\trx_len = get_unaligned_be16(header) - 2;\n--\ndrivers/net/ethernet/wiznet/w5100.c-551-\tif (unlikely(!skb)) {\ndrivers/net/ethernet/wiznet/w5100.c:552:\t\tw5100_write16(priv, W5100_S0_RX_RD(priv), offset + rx_buf_len);\ndrivers/net/ethernet/wiznet/w5100.c:553:\t\tw5100_command(priv, S0_CR_RECV);\ndrivers/net/ethernet/wiznet/w5100.c-554-\t\tndev-\u003estats.rx_dropped++;\n--\ndrivers/net/ethernet/wiznet/w5100.c-558-\tskb_put(skb, rx_len);\ndrivers/net/ethernet/wiznet/w5100.c:559:\tw5100_readbuf(priv, offset + 2, skb-\u003edata, rx_len);\ndrivers/net/ethernet/wiznet/w5100.c:560:\tw5100_write16(priv, W5100_S0_RX_RD(priv), offset + 2 + rx_len);\ndrivers/net/ethernet/wiznet/w5100.c:561:\tw5100_command(priv, S0_CR_RECV);\ndrivers/net/ethernet/wiznet/w5100.c-562-\tskb-\u003eprotocol = eth_type_trans(skb, ndev);\n--\ndrivers/net/ethernet/wiznet/w5100.c-569-\ndrivers/net/ethernet/wiznet/w5100.c:570:static void w5100_rx_work(struct work_struct *work)\ndrivers/net/ethernet/wiznet/w5100.c-571-{\ndrivers/net/ethernet/wiznet/w5100.c:572:\tstruct w5100_priv *priv = container_of(work, struct w5100_priv,\ndrivers/net/ethernet/wiznet/w5100.c-573-\t\t\t\t\t rx_work);\n--\ndrivers/net/ethernet/wiznet/w5100.c-575-\ndrivers/net/ethernet/wiznet/w5100.c:576:\twhile ((skb = w5100_rx_skb(priv-\u003endev)))\ndrivers/net/ethernet/wiznet/w5100.c-577-\t\tnetif_rx(skb);\ndrivers/net/ethernet/wiznet/w5100.c-578-\ndrivers/net/ethernet/wiznet/w5100.c:579:\tw5100_enable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c-580-}\ndrivers/net/ethernet/wiznet/w5100.c-581-\ndrivers/net/ethernet/wiznet/w5100.c:582:static int w5100_napi_poll(struct napi_struct *napi, int budget)\ndrivers/net/ethernet/wiznet/w5100.c-583-{\ndrivers/net/ethernet/wiznet/w5100.c:584:\tstruct w5100_priv *priv = container_of(napi, struct w5100_priv, napi);\ndrivers/net/ethernet/wiznet/w5100.c-585-\tint rx_count;\n--\ndrivers/net/ethernet/wiznet/w5100.c-587-\tfor (rx_count = 0; rx_count \u003c budget; rx_count++) {\ndrivers/net/ethernet/wiznet/w5100.c:588:\t\tstruct sk_buff *skb = w5100_rx_skb(priv-\u003endev);\ndrivers/net/ethernet/wiznet/w5100.c-589-\n--\ndrivers/net/ethernet/wiznet/w5100.c-597-\t\tnapi_complete_done(napi, rx_count);\ndrivers/net/ethernet/wiznet/w5100.c:598:\t\tw5100_enable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c-599-\t}\n--\ndrivers/net/ethernet/wiznet/w5100.c-603-\ndrivers/net/ethernet/wiznet/w5100.c:604:static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)\ndrivers/net/ethernet/wiznet/w5100.c-605-{\ndrivers/net/ethernet/wiznet/w5100.c-606-\tstruct net_device *ndev = ndev_instance;\ndrivers/net/ethernet/wiznet/w5100.c:607:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-608-\ndrivers/net/ethernet/wiznet/w5100.c:609:\tint ir = w5100_read(priv, W5100_S0_IR(priv));\ndrivers/net/ethernet/wiznet/w5100.c-610-\tif (!ir)\ndrivers/net/ethernet/wiznet/w5100.c-611-\t\treturn IRQ_NONE;\ndrivers/net/ethernet/wiznet/w5100.c:612:\tw5100_write(priv, W5100_S0_IR(priv), ir);\ndrivers/net/ethernet/wiznet/w5100.c-613-\n--\ndrivers/net/ethernet/wiznet/w5100.c-619-\tif (ir \u0026 S0_IR_RECV) {\ndrivers/net/ethernet/wiznet/w5100.c:620:\t\tw5100_disable_intr(priv);\ndrivers/net/ethernet/wiznet/w5100.c-621-\n--\ndrivers/net/ethernet/wiznet/w5100.c-630-\ndrivers/net/ethernet/wiznet/w5100.c:631:static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)\ndrivers/net/ethernet/wiznet/w5100.c-632-{\ndrivers/net/ethernet/wiznet/w5100.c-633-\tstruct net_device *ndev = ndev_instance;\ndrivers/net/ethernet/wiznet/w5100.c:634:\tstruct w5100_priv *priv = netdev_priv(ndev);\ndrivers/net/ethernet/wiznet/w5100.c-635-\n--\ndrivers/net/ethernet/wiznet/w5100.c-648-\ndrivers/net/ethernet/wiznet/w5100.c:649:static void w5100_setrx_work(struct work_struct *work)\ndrivers/net/ethernet/wiznet/w5100.c-650-{\ndrivers/net/ethernet/wiznet/w5100.c:651:\tstruct w5100_priv *priv = container_of(work, struct w5100_priv,\ndrivers/net/ethernet/wiznet/w5100.c-652-\t\t\t\t\t setrx_work);\ndrivers/net/ethernet/wiznet/w5100.c-653-\ndrivers/net/ethernet/wiznet/w5100.c:654:\tw5100_hw_start(priv);\ndrivers/net/ethernet/wiznet/w5100.c-655-}\n\n"
} |
| 5/2 | 2026/08/04 18:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20446 output: 16 thoughts: 166 Thoughts: **Analyzing the W5100 Driver Patch** Okay, so I'm looking at this patch related to the `drivers/net/ethernet/wiznet/w5100.c` driver. This is for Wiznet W5100, W5200, and W5500 SPI Ethernet controllers, right? The patch is adding a `link_gpio` which, if I understand correctly, means it's requesting a GPIO pin, and registering an interrupt for it to monitor the link state. Makes sense. GPIO for link state is pretty standard practice. My initial thought is, will this even be hit in QEMU? These SPI devices, generally, you'd configure them through device tree overlays, or something similar. Syzkaller doesn't typically touch SPI Ethernet controllers unless there's a specific setup for them. But wait... doesn't syzkaller *have* some level of support for SPI? I vaguely recall seeing something about that. Okay, so the next step is to see if syzkaller is specifically configured to instantiate a Wiznet device in its configurations. We should check if there are any syzkaller descriptions for wiznet or SPI. That'll tell us if we're even testing this code path. |
| 6/2 | 2026/08/04 18:29 | tool | grepper |
0mArgs:{
"Expression": "wiznet"
}Results: {
"Output": "Documentation/devicetree/bindings/net/wiznet,w5x00.yaml-3----\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:4:$id: http://devicetree.org/schemas/net/wiznet,w5x00.yaml#\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-5-$schema: http://devicetree.org/meta-schemas/core.yaml#\n--\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml=18=properties:\n--\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-20- enum:\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:21: - wiznet,w5100\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:22: - wiznet,w5200\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:23: - wiznet,w5500\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-24-\n--\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml=74=examples:\n--\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-85- ethernet@0: w5500@0 {\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml:86: compatible = \"wiznet,w5500\";\nDocumentation/devicetree/bindings/net/wiznet,w5x00.yaml-87- reg = \u003c0\u003e;\n--\ndrivers/net/ethernet/Kconfig=188=source \"drivers/net/ethernet/wangxun/Kconfig\"\ndrivers/net/ethernet/Kconfig:189:source \"drivers/net/ethernet/wiznet/Kconfig\"\ndrivers/net/ethernet/Kconfig-190-source \"drivers/net/ethernet/xilinx/Kconfig\"\n--\ndrivers/net/ethernet/Makefile=101=obj-$(CONFIG_NET_VENDOR_WANGXUN) += wangxun/\ndrivers/net/ethernet/Makefile:102:obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/\ndrivers/net/ethernet/Makefile-103-obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-7- * Datasheet:\ndrivers/net/ethernet/wiznet/w5100-spi.c:8: * http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_Datasheet_v1.2.6.pdf\ndrivers/net/ethernet/wiznet/w5100-spi.c:9: * http://wiznethome.cafe24.com/wp-content/uploads/wiznethome/Chip/W5200/Documents/W5200_DS_V140E.pdf\ndrivers/net/ethernet/wiznet/w5100-spi.c-10- * http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:w5500_ds_v106e_141230.pdf\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c=413=static const struct of_device_id w5100_of_match[] = {\ndrivers/net/ethernet/wiznet/w5100-spi.c:414:\t{ .compatible = \"wiznet,w5100\", .data = (const void*)W5100, },\ndrivers/net/ethernet/wiznet/w5100-spi.c:415:\t{ .compatible = \"wiznet,w5200\", .data = (const void*)W5200, },\ndrivers/net/ethernet/wiznet/w5100-spi.c:416:\t{ .compatible = \"wiznet,w5500\", .data = (const void*)W5500, },\ndrivers/net/ethernet/wiznet/w5100-spi.c-417-\t{ },\n"
} |
| 7/2 | 2026/08/04 18:30 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22045 output: 21 thoughts: 190 Thoughts: **Analyzing the Wiznet Driver Patch for Syzkaller Integration** Okay, so this patch targets a very specific piece of hardware – a Wiznet W5100/W5200/W5500 SPI Ethernet controller. It's a real, physical SPI device, which immediately presents a challenge. I know that vanilla QEMU doesn't emulate these precisely. The big question is how to get Syzkaller to interact with this particular hardware. Syzkaller's strength is its ability to find and trigger bugs through fuzzing, but its model of how to *instantiate* hardware is key here. The core issue seems to be getting the driver to actually *see* the hardware. The goal is to reach either the `w5100_detect_link` interrupt or the `w5100_probe` function. The key dependency is a *valid* SPI device that has a `link-gpios` property. That property is the key to letting the driver know it is connected to a link to work with. Now I'm thinking... can Syzkaller leverage device tree overlays or even netlink interfaces to instantiate an SPI device? It's possible, though I'm not entirely confident. Even if we *could* create that SPI device in the simulated environment, the hardware isn't emulated. That means any SPI reads or writes would either fail outright or time out. That would prevent the driver from initializing properly anyway. I need to dive into `w5100.c` and specifically look at the `w5100_probe` function. I need to understand what hardware checks it performs. Does it do any kind of identification checks to detect if the device is actually present, or does it just assume it's there based on the device tree? Understanding that flow is key. If it's a simple, predictable sequence then there's a good chance to craft a syzkaller template to trigger the call. Otherwise, I might need to consider a more involved approach, such as using a more sophisticated emulation strategy if the hardware checks are complex. |
| 8/2 | 2026/08/04 18:30 | tool | grepper |
0mArgs:{
"Expression": "w5100_probe"
}Results: {
"Output": "drivers/net/ethernet/wiznet/w5100-spi.c=421=static int w5100_spi_probe(struct spi_device *spi)\n--\ndrivers/net/ethernet/wiznet/w5100-spi.c-452-\ndrivers/net/ethernet/wiznet/w5100-spi.c:453:\treturn w5100_probe(\u0026spi-\u003edev, ops, priv_size, mac, spi-\u003eirq);\ndrivers/net/ethernet/wiznet/w5100-spi.c-454-}\n--\ndrivers/net/ethernet/wiznet/w5100.c=739=EXPORT_SYMBOL_GPL(w5100_ops_priv);\ndrivers/net/ethernet/wiznet/w5100.c-740-\ndrivers/net/ethernet/wiznet/w5100.c:741:int w5100_probe(struct device *dev, const struct w5100_ops *ops,\ndrivers/net/ethernet/wiznet/w5100.c-742-\t\tint sizeof_ops_priv, const void *mac_addr, int irq)\n--\ndrivers/net/ethernet/wiznet/w5100.c-882-}\ndrivers/net/ethernet/wiznet/w5100.c:883:EXPORT_SYMBOL_GPL(w5100_probe);\ndrivers/net/ethernet/wiznet/w5100.c-884-\n--\ndrivers/net/ethernet/wiznet/w5100.h=29=void *w5100_ops_priv(const struct net_device *ndev);\ndrivers/net/ethernet/wiznet/w5100.h-30-\ndrivers/net/ethernet/wiznet/w5100.h:31:int w5100_probe(struct device *dev, const struct w5100_ops *ops,\ndrivers/net/ethernet/wiznet/w5100.h-32-\t\tint sizeof_ops_priv, const void *mac_addr, int irq);\n"
} |
| 9/2 | 2026/08/04 18:30 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23258 output: 46 thoughts: 21 Thoughts: Here's my take on the thought process, as if it were my own: **Investigating Hardware Initialization in `w5100_probe`** Alright, let's dive into the `w5100_probe` function. I need to understand how the system is interacting with the W5100 hardware. My gut feeling is that any thorough driver would include some kind of hardware initialization and sanity checks within the probe function. I'm hoping to find clear indicators of register reads, writes, and perhaps even some expected responses that would confirm the device's presence and basic functionality. This initial probing is crucial – it's the foundation for everything else. I'm looking for the "hello world" of this driver, the confirmation that the hardware is alive and kicking. Hopefully, it is there, so I can see what is being set up. |
| 10/2 | 2026/08/04 18:30 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/wiznet/w5100.c",
"FirstLine": 741,
"LineCount": 100
}Results: {
"Contents": " 741:\tint w5100_probe(struct device *dev, const struct w5100_ops *ops,\n 742:\t\t\tint sizeof_ops_priv, const void *mac_addr, int irq)\n 743:\t{\n 744:\t\tstruct w5100_priv *priv;\n 745:\t\tstruct net_device *ndev;\n 746:\t\tint err;\n 747:\t\tsize_t alloc_size;\n 748:\t\n 749:\t\talloc_size = sizeof(*priv);\n 750:\t\tif (sizeof_ops_priv) {\n 751:\t\t\talloc_size = ALIGN(alloc_size, NETDEV_ALIGN);\n 752:\t\t\talloc_size += sizeof_ops_priv;\n 753:\t\t}\n 754:\t\talloc_size += NETDEV_ALIGN - 1;\n 755:\t\n 756:\t\tndev = alloc_etherdev(alloc_size);\n 757:\t\tif (!ndev)\n 758:\t\t\treturn -ENOMEM;\n 759:\t\tSET_NETDEV_DEV(ndev, dev);\n 760:\t\tdev_set_drvdata(dev, ndev);\n 761:\t\tpriv = netdev_priv(ndev);\n 762:\t\n 763:\t\tswitch (ops-\u003echip_id) {\n 764:\t\tcase W5100:\n 765:\t\t\tpriv-\u003es0_regs = W5100_S0_REGS;\n 766:\t\t\tpriv-\u003es0_tx_buf = W5100_TX_MEM_START;\n 767:\t\t\tpriv-\u003es0_tx_buf_size = W5100_TX_MEM_SIZE;\n 768:\t\t\tpriv-\u003es0_rx_buf = W5100_RX_MEM_START;\n 769:\t\t\tpriv-\u003es0_rx_buf_size = W5100_RX_MEM_SIZE;\n 770:\t\t\tbreak;\n 771:\t\tcase W5200:\n 772:\t\t\tpriv-\u003es0_regs = W5200_S0_REGS;\n 773:\t\t\tpriv-\u003es0_tx_buf = W5200_TX_MEM_START;\n 774:\t\t\tpriv-\u003es0_tx_buf_size = W5200_TX_MEM_SIZE;\n 775:\t\t\tpriv-\u003es0_rx_buf = W5200_RX_MEM_START;\n 776:\t\t\tpriv-\u003es0_rx_buf_size = W5200_RX_MEM_SIZE;\n 777:\t\t\tbreak;\n 778:\t\tcase W5500:\n 779:\t\t\tpriv-\u003es0_regs = W5500_S0_REGS;\n 780:\t\t\tpriv-\u003es0_tx_buf = W5500_TX_MEM_START;\n 781:\t\t\tpriv-\u003es0_tx_buf_size = W5500_TX_MEM_SIZE;\n 782:\t\t\tpriv-\u003es0_rx_buf = W5500_RX_MEM_START;\n 783:\t\t\tpriv-\u003es0_rx_buf_size = W5500_RX_MEM_SIZE;\n 784:\t\t\tbreak;\n 785:\t\tdefault:\n 786:\t\t\terr = -EINVAL;\n 787:\t\t\tgoto err_register;\n 788:\t\t}\n 789:\t\n 790:\t\tpriv-\u003endev = ndev;\n 791:\t\tpriv-\u003eops = ops;\n 792:\t\tpriv-\u003eirq = irq;\n 793:\t\tpriv-\u003elink_gpio = devm_gpiod_get_optional(dev, \"link\", GPIOD_IN);\n 794:\t\tif (IS_ERR(priv-\u003elink_gpio)) {\n 795:\t\t\terr = dev_err_probe(dev, PTR_ERR(priv-\u003elink_gpio),\n 796:\t\t\t\t\t \"failed to get link GPIO\\n\");\n 797:\t\t\tpriv-\u003elink_gpio = NULL;\n 798:\t\t\tgoto err_register;\n 799:\t\t}\n 800:\t\n 801:\t\tndev-\u003enetdev_ops = \u0026w5100_netdev_ops;\n 802:\t\tndev-\u003eethtool_ops = \u0026w5100_ethtool_ops;\n 803:\t\tnetif_napi_add_weight(ndev, \u0026priv-\u003enapi, w5100_napi_poll, 16);\n 804:\t\n 805:\t\t/* This chip doesn't support VLAN packets with normal MTU,\n 806:\t\t * so disable VLAN for this device.\n 807:\t\t */\n 808:\t\tndev-\u003efeatures |= NETIF_F_VLAN_CHALLENGED;\n 809:\t\n 810:\t\terr = register_netdev(ndev);\n 811:\t\tif (err \u003c 0)\n 812:\t\t\tgoto err_register;\n 813:\t\n 814:\t\tpriv-\u003exfer_wq = alloc_workqueue(\"%s\", WQ_MEM_RECLAIM | WQ_PERCPU, 0,\n 815:\t\t\t\t\t\tnetdev_name(ndev));\n 816:\t\tif (!priv-\u003exfer_wq) {\n 817:\t\t\terr = -ENOMEM;\n 818:\t\t\tgoto err_wq;\n 819:\t\t}\n 820:\t\n 821:\t\tINIT_WORK(\u0026priv-\u003erx_work, w5100_rx_work);\n 822:\t\tINIT_WORK(\u0026priv-\u003etx_work, w5100_tx_work);\n 823:\t\tINIT_WORK(\u0026priv-\u003esetrx_work, w5100_setrx_work);\n 824:\t\tINIT_WORK(\u0026priv-\u003erestart_work, w5100_restart_work);\n 825:\t\n 826:\t\tif (mac_addr)\n 827:\t\t\teth_hw_addr_set(ndev, mac_addr);\n 828:\t\telse\n 829:\t\t\teth_hw_addr_random(ndev);\n 830:\t\n 831:\t\tif (priv-\u003eops-\u003einit) {\n 832:\t\t\terr = priv-\u003eops-\u003einit(priv-\u003endev);\n 833:\t\t\tif (err)\n 834:\t\t\t\tgoto err_hw;\n 835:\t\t}\n 836:\t\n 837:\t\terr = w5100_hw_reset(priv);\n 838:\t\tif (err)\n 839:\t\t\tgoto err_hw;\n 840:\t\n"
} |
| 11/2 | 2026/08/04 18:30 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 25256 output: 45 thoughts: 26 Thoughts: Here's my analysis of the provided snippet, framed as my own thought process: **Diving into the `w5100_hw_reset` Function** Okay, so the `w5100_hw_reset` function gets called during the probe process, which is interesting. It's a key part of initialization, so I should see what it's doing. Let's delve in and understand how the hardware reset is being handled here. I'm looking for the specific sequence of operations, timing considerations, and any register manipulations involved. This function's implementation will be crucial in determining how robust and reliable the overall W5100 initialization is. Hopefully there aren't any gotchas. |
| 12/2 | 2026/08/04 18:30 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/wiznet/w5100.c",
"FirstLine": 350,
"LineCount": 50
}Results: {
"Contents": " 350:\tstatic int w5100_hw_reset(struct w5100_priv *priv)\n 351:\t{\n 352:\t\tu32 rtr;\n 353:\t\n 354:\t\tw5100_reset(priv);\n 355:\t\n 356:\t\tw5100_disable_intr(priv);\n 357:\t\tw5100_write_macaddr(priv);\n 358:\t\n 359:\t\tswitch (priv-\u003eops-\u003echip_id) {\n 360:\t\tcase W5100:\n 361:\t\t\tw5100_memory_configure(priv);\n 362:\t\t\trtr = W5100_RTR;\n 363:\t\t\tbreak;\n 364:\t\tcase W5200:\n 365:\t\t\tw5200_memory_configure(priv);\n 366:\t\t\trtr = W5100_RTR;\n 367:\t\t\tbreak;\n 368:\t\tcase W5500:\n 369:\t\t\tw5500_memory_configure(priv);\n 370:\t\t\trtr = W5500_RTR;\n 371:\t\t\tbreak;\n 372:\t\tdefault:\n 373:\t\t\treturn -EINVAL;\n 374:\t\t}\n 375:\t\n 376:\t\tif (w5100_read16(priv, rtr) != RTR_DEFAULT)\n 377:\t\t\treturn -ENODEV;\n 378:\t\n 379:\t\treturn 0;\n 380:\t}\n 381:\t\n 382:\tstatic void w5100_hw_start(struct w5100_priv *priv)\n 383:\t{\n 384:\t\tu8 mode = S0_MR_MACRAW;\n 385:\t\n 386:\t\tif (!priv-\u003epromisc) {\n 387:\t\t\tif (priv-\u003eops-\u003echip_id == W5500)\n 388:\t\t\t\tmode |= W5500_S0_MR_MF;\n 389:\t\t\telse\n 390:\t\t\t\tmode |= S0_MR_MF;\n 391:\t\t}\n 392:\t\n 393:\t\tw5100_write(priv, W5100_S0_MR(priv), mode);\n 394:\t\tw5100_command(priv, S0_CR_OPEN);\n 395:\t\tw5100_enable_intr(priv);\n 396:\t}\n 397:\t\n 398:\tstatic void w5100_hw_close(struct w5100_priv *priv)\n 399:\t{\n"
} |
| 13/2 | 2026/08/04 18:30 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26224 output: 18 thoughts: 114 Thoughts: **Analyzing the W5100 Hardware Reset Function** Okay, let's break down this `w5100_hw_reset` function. It seems the core of the reset routine relies on reading a register, specifically using `w5100_read16(priv, rtr)`. It's expecting this register, probably some sort of status or control register associated with the W5100, to hold a specific value, `RTR_DEFAULT`. If the value doesn't match this expected default, the function flags a hardware failure with `-ENODEV`. Hmm, this presents a problem. Since this is a physical SPI device and, as I understand it, syzkaller doesn't emulate the specifics of the hardware, that register read is very likely to fail. My gut tells me it's probably going to return something other than `RTR_DEFAULT` – maybe zero, maybe whatever garbage the dummy SPI driver is spitting out. It's unlikely to be the correct default state, given a lack of proper initialization and emulation. But wait, what exactly *is* `RTR_DEFAULT`? I need to go and find where that is defined. That's a critical piece of information. I'm guessing this might have something to do with the *R*etry *T*ime *R*egister, or something similar, maybe? It's essential to understand the assumed initial state of the hardware in order to troubleshoot this, and to develop strategies to circumvent this expected initial value in the emulator. |
| 14/2 | 2026/08/04 18:30 | tool | grepper |
0mArgs:{
"Expression": "RTR_DEFAULT"
}Results: {
"Output": "drivers/net/ethernet/wiznet/w5100.c=35=MODULE_LICENSE(\"GPL\");\n--\ndrivers/net/ethernet/wiznet/w5100.c-89-#define W5100_RTR\t\t0x0017 /* Retry Time-value Register */\ndrivers/net/ethernet/wiznet/w5100.c:90:#define RTR_DEFAULT\t\t 2000 /* =0x07d0 (2000) */\ndrivers/net/ethernet/wiznet/w5100.c-91-\n--\ndrivers/net/ethernet/wiznet/w5100.c=350=static int w5100_hw_reset(struct w5100_priv *priv)\n--\ndrivers/net/ethernet/wiznet/w5100.c-375-\ndrivers/net/ethernet/wiznet/w5100.c:376:\tif (w5100_read16(priv, rtr) != RTR_DEFAULT)\ndrivers/net/ethernet/wiznet/w5100.c-377-\t\treturn -ENODEV;\n"
} |
| 15/2 | 2026/08/04 18:30 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26996 output: 127 thoughts: 445 Thoughts: **WorthFuzzing=False: An Analysis of the W5100 SPI Driver Patch** Okay, here's my assessment. The `RTR_DEFAULT` register is set to 2000 (0x07d0). Unless syzkaller can somehow specifically mock SPI reads to return this value during the probe, the probe itself will fail, which is the immediate issue. I know that syzkaller doesn't have a generic SPI mocking framework configurable on a per-device basis. It offers limited SPI support through `spidev` and similar, but that is intended for userspace interactions with SPI, not for emulating the hardware for a kernel driver. Essentially, syzkaller does not emulate SPI devices at all. Because of this, the `w5100_probe` call will invariably fail, meaning the new code added for IRQ requests and the `w5100_detect_link` function will never execute. The patch itself is simply adding a GPIO pin for link detection, which is hardware-specific. Based on my analysis, this falls squarely under the category of "Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware". It also aligns with the rationale of code that "require[s] physical ... hardware cards not emulated in standard QEMU". While this is SPI and not PCIe, the principle is the same. It is a very hardware-dependent patch. Now, let me double check; is there any other way this code could possibly be reached? I will quickly verify. The `w5100_probe` function is called from `w5100_spi_probe`, which is the probe function for the `w5100_spi_driver`. The driver specifically binds to SPI devices with compatible strings "wiznet,w5100", "wiznet,w5200", and "wiznet,w5500". Without physical hardware or an equivalent emulation, the probe will fail at `w5100_hw_reset`. It is a very specific hardware driver. Therefore, considering all of this, I'm confident in concluding that this patch is not worth fuzzing. I will return WorthFuzzing=false. |
| 16/2 | 2026/08/04 18:30 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the Wiznet W5100/W5200/W5500 SPI Ethernet driver to support a link GPIO. This is a driver for a physical SPI device that is not emulated in standard QEMU. The driver's probe function performs hardware register checks (e.g., verifying the RTR register value) that will fail without the actual hardware present, making the modified code paths unreachable in a virtualized fuzzing environment.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Wiznet W5100/W5200/W5500 SPI Ethernet driver to support a link GPIO. This is a driver for a physical SPI device that is not emulated in standard QEMU. The driver's probe function performs hardware register checks (e.g., verifying the RTR register value) that will fail without the actual hardware present, making the modified code paths unreachable in a virtualized fuzzing environment.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|