| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/13 00:15 | flow | patch-triage |
3mArgs:null Results: {
"EnableConfigs": [
"MARVELL_PHY",
"PHYLIB",
"NETDEVICES",
"USB_NET_DRIVERS",
"PM"
],
"FocusSymbols": [
"m88e1318_set_wol",
"marvell_probe",
"m88e1318_suspend",
"m88e1318_resume",
"m88e1510_suspend",
"m88e1510_resume",
"marvell_wol_suspend_intrs",
"marvell_wol_resume_intrs"
],
"KMSANReasoning": "The patch adds Wake-on-LAN (WoL) interrupt and power management support (suspend/resume routines and wake-irq setup) for Marvell 88E1318S and 88E1510 PHY drivers. \n\nAll stack variables (e.g. `wol_off`, `oldpage`, `ret`, `err`) are explicitly initialized before use, and no kernel memory is copied to user space or left uninitialized in heap/stack allocations. The changes primarily involve hardware register writes over MDIO and Linux device PM wakeirq configuration. Any potential issues introduced would relate to error code handling, MDIO bus communication, or PM state management, none of which involve uninitialized memory accesses or information leaks. Therefore, dedicated KMSAN fuzzing is not warranted.",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies Wake-on-LAN (WoL), interrupt masking, and suspend/resume handling for Marvell PHYs (88E1318S and 88E1510), as well as wake-irq setup in marvell_probe(). Marvell PHYs can be discovered and attached over MDIO buses exposed by emulated USB network devices (e.g., via USB Raw Gadget), making them reachable in virtualized fuzzing environments. Once registered, the modified WoL configuration and rollback logic are exercisable via ethtool ioctl/netlink, and suspend/resume paths can be tested via power management interfaces.",
"WorthFuzzing": true
} |
| 1/1 | 2026/09/13 00:15 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 087b13dfb2d69e265bbfbc7b467f39e2e7be58af\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Sep 13 00:15:11 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c\nindex f71cffa884062..70aaa09f20478 100644\n--- a/drivers/net/phy/marvell.c\n+++ b/drivers/net/phy/marvell.c\n@@ -30,6 +30,8 @@\n #include \u003clinux/ethtool_netlink.h\u003e\n #include \u003clinux/phy.h\u003e\n #include \u003clinux/phy_port.h\u003e\n+#include \u003clinux/pm_wakeirq.h\u003e\n+#include \u003clinux/property.h\u003e\n #include \u003clinux/marvell_phy.h\u003e\n #include \u003clinux/bitfield.h\u003e\n #include \u003clinux/of.h\u003e\n@@ -1902,6 +1904,61 @@ static int marvell_resume(struct phy_device *phydev)\n \treturn err;\n }\n \n+/* marvell_wol_suspend_intrs\n+ *\n+ * With WoL enabled the PHY has to stay powered to keep detecting a WoL\n+ * packet, so instead of entering low power mode, mask all interrupt\n+ * sources except the WoL event. On the 88E1318S/88E1510 the interrupt\n+ * mask (MII_M1011_IMASK) is the same register as the Copper Specific\n+ * Interrupt Enable Register (MII_88E1318S_PHY_CSIER), so writing only\n+ * the WoL event enable bit unmask just that event.\n+ */\n+static int marvell_wol_suspend_intrs(struct phy_device *phydev)\n+{\n+\tint oldpage, ret;\n+\n+\toldpage = phy_save_page(phydev);\n+\tif (oldpage \u003c 0)\n+\t\treturn oldpage;\n+\n+\tret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);\n+\tif (ret \u003c 0)\n+\t\tgoto out;\n+\n+\tret = __phy_write(phydev, MII_88E1318S_PHY_CSIER,\n+\t\t\t MII_88E1318S_PHY_CSIER_WOL_EIE);\n+out:\n+\treturn phy_restore_page(phydev, oldpage, ret);\n+}\n+\n+/* marvell_wol_resume_intrs\n+ *\n+ * marvell_config_intr() rewrites the whole MII_M1011_IMASK register\n+ * (which is MII_88E1318S_PHY_CSIER) with MII_M1011_IMASK_INIT on\n+ * resume, clearing the WoL event interrupt enable bit. Re-arm it if\n+ * WoL is still enabled so a later WoL event keeps waking the system.\n+ */\n+static int marvell_wol_resume_intrs(struct phy_device *phydev)\n+{\n+\tint oldpage, ret;\n+\n+\tif (!phydev-\u003ewol_enabled)\n+\t\treturn 0;\n+\n+\toldpage = phy_save_page(phydev);\n+\tif (oldpage \u003c 0)\n+\t\treturn oldpage;\n+\n+\tret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);\n+\tif (ret \u003c 0)\n+\t\tgoto out;\n+\n+\tret = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,\n+\t\t\t MII_88E1318S_PHY_CSIER_WOL_EIE);\n+out:\n+\treturn phy_restore_page(phydev, oldpage, ret);\n+}\n+\n /* m88e1510_resume\n *\n * The 88e1510 PHY has an erratum where the phy downshift counter is not cleared\n@@ -1934,9 +1991,25 @@ static int m88e1510_resume(struct phy_device *phydev)\n \n \t\t/* downshift enabled, with previous counter value */\n \t\terr = m88e1011_set_downshift(phydev, cnt);\n+\t\tif (err \u003c 0)\n+\t\t\treturn err;\n \t}\n \n-\treturn err;\n+\treturn marvell_wol_resume_intrs(phydev);\n+}\n+\n+/* m88e1510_suspend\n+ *\n+ * If WoL is enabled the PHY receiver has to keep running to detect a\n+ * magic packet, so keep it awake and unmask only the WoL event at the\n+ * PHY. Otherwise suspend both the fiber and copper interfaces as usual.\n+ */\n+static int m88e1510_suspend(struct phy_device *phydev)\n+{\n+\tif (phydev-\u003ewol_enabled)\n+\t\treturn marvell_wol_suspend_intrs(phydev);\n+\n+\treturn marvell_suspend(phydev);\n }\n \n static int marvell_aneg_done(struct phy_device *phydev)\n@@ -1969,8 +2042,12 @@ static void m88e1318_get_wol(struct phy_device *phydev,\n static int m88e1318_set_wol(struct phy_device *phydev,\n \t\t\t struct ethtool_wolinfo *wol)\n {\n+\tstruct device *dev = \u0026phydev-\u003emdio.dev;\n+\tbool wol_enable;\n \tint err = 0, oldpage;\n \n+\twol_enable = !!(wol-\u003ewolopts \u0026 (WAKE_MAGIC | WAKE_PHY));\n+\n \toldpage = phy_save_page(phydev);\n \tif (oldpage \u003c 0)\n \t\tgoto error;\n@@ -2075,7 +2152,49 @@ static int m88e1318_set_wol(struct phy_device *phydev,\n \t}\n \n error:\n-\treturn phy_restore_page(phydev, oldpage, err);\n+\terr = phy_restore_page(phydev, oldpage, err);\n+\tif (err \u003c 0)\n+\t\treturn err;\n+\n+\tif (device_can_wakeup(dev) \u0026\u0026 wol_enable != device_may_wakeup(dev)) {\n+\t\terr = device_set_wakeup_enable(dev, wol_enable);\n+\t\tif (err \u003c 0) {\n+\t\t\t/* Roll back the PHY WoL config if the PM state update failed */\n+\t\t\tstruct ethtool_wolinfo wol_off = { .wolopts = 0 };\n+\t\t\tint rollback_err = m88e1318_set_wol(phydev, \u0026wol_off);\n+\n+\t\t\tif (rollback_err \u003c 0)\n+\t\t\t\tphydev_err(phydev,\n+\t\t\t\t\t \"Failed to disable WoL after wakeup enable error %d\\n\",\n+\t\t\t\t\t rollback_err);\n+\t\t}\n+\t}\n+\n+\treturn err;\n+}\n+\n+/* m88e1318_suspend\n+ *\n+ * If WoL is enabled keep the PHY awake so it can detect a magic packet\n+ * while the system is asleep, unmasking only the WoL event at the PHY.\n+ * Otherwise suspend the PHY normally.\n+ */\n+static int m88e1318_suspend(struct phy_device *phydev)\n+{\n+\tif (phydev-\u003ewol_enabled)\n+\t\treturn marvell_wol_suspend_intrs(phydev);\n+\n+\treturn genphy_suspend(phydev);\n+}\n+\n+static int m88e1318_resume(struct phy_device *phydev)\n+{\n+\tint err = genphy_resume(phydev);\n+\n+\tif (err \u003c 0)\n+\t\treturn err;\n+\n+\treturn marvell_wol_resume_intrs(phydev);\n }\n \n static int marvell_get_sset_count(struct phy_device *phydev)\n@@ -3587,14 +3706,25 @@ static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index,\n \n static int marvell_probe(struct phy_device *phydev)\n {\n+\tstruct device *dev = \u0026phydev-\u003emdio.dev;\n \tstruct marvell_priv *priv;\n \n-\tpriv = devm_kzalloc(\u0026phydev-\u003emdio.dev, sizeof(*priv), GFP_KERNEL);\n+\tpriv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);\n \tif (!priv)\n \t\treturn -ENOMEM;\n \n \tphydev-\u003epriv = priv;\n \n+\tif (device_property_present(dev, \"wakeup-source\") \u0026\u0026\n+\t phy_interrupt_is_valid(phydev)) {\n+\t\tint ret = devm_pm_set_wake_irq(dev, phydev-\u003eirq);\n+\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tdevice_set_wakeup_capable(dev, true);\n+\t}\n+\n \treturn marvell_hwmon_probe(phydev);\n }\n \n@@ -3813,6 +3943,7 @@ static struct phy_driver marvell_drivers[] = {\n \t\t.phy_id_mask = MARVELL_PHY_ID_MASK,\n \t\t.name = \"Marvell 88E1318S\",\n \t\t/* PHY_GBIT_FEATURES */\n+\t\t.flags = PHY_ALWAYS_CALL_SUSPEND,\n \t\t.probe = marvell_probe,\n \t\t.config_init = m88e1318_config_init,\n \t\t.config_aneg = m88e1318_config_aneg,\n@@ -3821,8 +3952,8 @@ static struct phy_driver marvell_drivers[] = {\n \t\t.handle_interrupt = marvell_handle_interrupt,\n \t\t.get_wol = m88e1318_get_wol,\n \t\t.set_wol = m88e1318_set_wol,\n-\t\t.resume = genphy_resume,\n-\t\t.suspend = genphy_suspend,\n+\t\t.resume = m88e1318_resume,\n+\t\t.suspend = m88e1318_suspend,\n \t\t.read_page = marvell_read_page,\n \t\t.write_page = marvell_write_page,\n \t\t.get_sset_count = marvell_get_sset_count,\n@@ -3920,7 +4051,7 @@ static struct phy_driver marvell_drivers[] = {\n \t\t.name = \"Marvell 88E1510\",\n \t\t.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),\n \t\t.features = PHY_GBIT_FIBRE_FEATURES,\n-\t\t.flags = PHY_POLL_CABLE_TEST,\n+\t\t.flags = PHY_POLL_CABLE_TEST | PHY_ALWAYS_CALL_SUSPEND,\n \t\t.probe = marvell_probe,\n \t\t.config_init = m88e1510_config_init,\n \t\t.config_aneg = m88e1510_config_aneg,\n@@ -3930,7 +4061,7 @@ static struct phy_driver marvell_drivers[] = {\n \t\t.get_wol = m88e1318_get_wol,\n \t\t.set_wol = m88e1318_set_wol,\n \t\t.resume = m88e1510_resume,\n-\t\t.suspend = marvell_suspend,\n+\t\t.suspend = m88e1510_suspend,\n \t\t.read_page = marvell_read_page,\n \t\t.write_page = marvell_write_page,\n \t\t.get_sset_count = marvell_get_sset_count,\n"
} |
| 2/1 | 2026/09/13 00:15 | agent | patch-evaluator |
3mModel:core Args: null Results: {
"EnableConfigs": [
"MARVELL_PHY",
"PHYLIB",
"NETDEVICES",
"USB_NET_DRIVERS",
"PM"
],
"FocusSymbols": [
"m88e1318_set_wol",
"marvell_probe",
"m88e1318_suspend",
"m88e1318_resume",
"m88e1510_suspend",
"m88e1510_resume",
"marvell_wol_suspend_intrs",
"marvell_wol_resume_intrs"
],
"Reasoning": "The patch modifies Wake-on-LAN (WoL), interrupt masking, and suspend/resume handling for Marvell PHYs (88E1318S and 88E1510), as well as wake-irq setup in marvell_probe(). Marvell PHYs can be discovered and attached over MDIO buses exposed by emulated USB network devices (e.g., via USB Raw Gadget), making them reachable in virtualized fuzzing environments. Once registered, the modified WoL configuration and rollback logic are exercisable via ethtool ioctl/netlink, and suspend/resume paths can be tested via power management interfaces.",
"WorthFuzzing": true
}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 087b13dfb2d69e265bbfbc7b467f39e2e7be58af
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Sep 13 00:15:11 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f71cffa884062..70aaa09f20478 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -30,6 +30,8 @@
#include <linux/ethtool_netlink.h>
#include <linux/phy.h>
#include <linux/phy_port.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/property.h>
#include <linux/marvell_phy.h>
#include <linux/bitfield.h>
#include <linux/of.h>
@@ -1902,6 +1904,61 @@ static int marvell_resume(struct phy_device *phydev)
return err;
}
+/* marvell_wol_suspend_intrs
+ *
+ * With WoL enabled the PHY has to stay powered to keep detecting a WoL
+ * packet, so instead of entering low power mode, mask all interrupt
+ * sources except the WoL event. On the 88E1318S/88E1510 the interrupt
+ * mask (MII_M1011_IMASK) is the same register as the Copper Specific
+ * Interrupt Enable Register (MII_88E1318S_PHY_CSIER), so writing only
+ * the WoL event enable bit unmask just that event.
+ */
+static int marvell_wol_suspend_intrs(struct phy_device *phydev)
+{
+ int oldpage, ret;
+
+ oldpage = phy_save_page(phydev);
+ if (oldpage < 0)
+ return oldpage;
+
+ ret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
+ if (ret < 0)
+ goto out;
+
+ ret = __phy_write(phydev, MII_88E1318S_PHY_CSIER,
+ MII_88E1318S_PHY_CSIER_WOL_EIE);
+out:
+ return phy_restore_page(phydev, oldpage, ret);
+}
+
+/* marvell_wol_resume_intrs
+ *
+ * marvell_config_intr() rewrites the whole MII_M1011_IMASK register
+ * (which is MII_88E1318S_PHY_CSIER) with MII_M1011_IMASK_INIT on
+ * resume, clearing the WoL event interrupt enable bit. Re-arm it if
+ * WoL is still enabled so a later WoL event keeps waking the system.
+ */
+static int marvell_wol_resume_intrs(struct phy_device *phydev)
+{
+ int oldpage, ret;
+
+ if (!phydev->wol_enabled)
+ return 0;
+
+ oldpage = phy_save_page(phydev);
+ if (oldpage < 0)
+ return oldpage;
+
+ ret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
+ if (ret < 0)
+ goto out;
+
+ ret = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,
+ MII_88E1318S_PHY_CSIER_WOL_EIE);
+out:
+ return phy_restore_page(phydev, oldpage, ret);
+}
+
/* m88e1510_resume
*
* The 88e1510 PHY has an erratum where the phy downshift counter is not cleared
@@ -1934,9 +1991,25 @@ static int m88e1510_resume(struct phy_device *phydev)
/* downshift enabled, with previous counter value */
err = m88e1011_set_downshift(phydev, cnt);
+ if (err < 0)
+ return err;
}
- return err;
+ return marvell_wol_resume_intrs(phydev);
+}
+
+/* m88e1510_suspend
+ *
+ * If WoL is enabled the PHY receiver has to keep running to detect a
+ * magic packet, so keep it awake and unmask only the WoL event at the
+ * PHY. Otherwise suspend both the fiber and copper interfaces as usual.
+ */
+static int m88e1510_suspend(struct phy_device *phydev)
+{
+ if (phydev->wol_enabled)
+ return marvell_wol_suspend_intrs(phydev);
+
+ return marvell_suspend(phydev);
}
static int marvell_aneg_done(struct phy_device *phydev)
@@ -1969,8 +2042,12 @@ static void m88e1318_get_wol(struct phy_device *phydev,
static int m88e1318_set_wol(struct phy_device *phydev,
struct ethtool_wolinfo *wol)
{
+ struct device *dev = &phydev->mdio.dev;
+ bool wol_enable;
int err = 0, oldpage;
+ wol_enable = !!(wol->wolopts & (WAKE_MAGIC | WAKE_PHY));
+
oldpage = phy_save_page(phydev);
if (oldpage < 0)
goto error;
@@ -2075,7 +2152,49 @@ static int m88e1318_set_wol(struct phy_device *phydev,
}
error:
- return phy_restore_page(phydev, oldpage, err);
+ err = phy_restore_page(phydev, oldpage, err);
+ if (err < 0)
+ return err;
+
+ if (device_can_wakeup(dev) && wol_enable != device_may_wakeup(dev)) {
+ err = device_set_wakeup_enable(dev, wol_enable);
+ if (err < 0) {
+ /* Roll back the PHY WoL config if the PM state update failed */
+ struct ethtool_wolinfo wol_off = { .wolopts = 0 };
+ int rollback_err = m88e1318_set_wol(phydev, &wol_off);
+
+ if (rollback_err < 0)
+ phydev_err(phydev,
+ "Failed to disable WoL after wakeup enable error %d\n",
+ rollback_err);
+ }
+ }
+
+ return err;
+}
+
+/* m88e1318_suspend
+ *
+ * If WoL is enabled keep the PHY awake so it can detect a magic packet
+ * while the system is asleep, unmasking only the WoL event at the PHY.
+ * Otherwise suspend the PHY normally.
+ */
+static int m88e1318_suspend(struct phy_device *phydev)
+{
+ if (phydev->wol_enabled)
+ return marvell_wol_suspend_intrs(phydev);
+
+ return genphy_suspend(phydev);
+}
+
+static int m88e1318_resume(struct phy_device *phydev)
+{
+ int err = genphy_resume(phydev);
+
+ if (err < 0)
+ return err;
+
+ return marvell_wol_resume_intrs(phydev);
}
static int marvell_get_sset_count(struct phy_device *phydev)
@@ -3587,14 +3706,25 @@ static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index,
static int marvell_probe(struct phy_device *phydev)
{
+ struct device *dev = &phydev->mdio.dev;
struct marvell_priv *priv;
- priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
phydev->priv = priv;
+ if (device_property_present(dev, "wakeup-source") &&
+ phy_interrupt_is_valid(phydev)) {
+ int ret = devm_pm_set_wake_irq(dev, phydev->irq);
+
+ if (ret)
+ return ret;
+
+ device_set_wakeup_capable(dev, true);
+ }
+
return marvell_hwmon_probe(phydev);
}
@@ -3813,6 +3943,7 @@ static struct phy_driver marvell_drivers[] = {
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1318S",
/* PHY_GBIT_FEATURES */
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
.probe = marvell_probe,
.config_init = m88e1318_config_init,
.config_aneg = m88e1318_config_aneg,
@@ -3821,8 +3952,8 @@ static struct phy_driver marvell_drivers[] = {
.handle_interrupt = marvell_handle_interrupt,
.get_wol = m88e1318_get_wol,
.set_wol = m88e1318_set_wol,
- .resume = genphy_resume,
- .suspend = genphy_suspend,
+ .resume = m88e1318_resume,
+ .suspend = m88e1318_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -3920,7 +4051,7 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1510",
.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
.features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_POLL_CABLE_TEST,
+ .flags = PHY_POLL_CABLE_TEST | PHY_ALWAYS_CALL_SUSPEND,
.probe = marvell_probe,
.config_init = m88e1510_config_init,
.config_aneg = m88e1510_config_aneg,
@@ -3930,7 +4061,7 @@ static struct phy_driver marvell_drivers[] = {
.get_wol = m88e1318_get_wol,
.set_wol = m88e1318_set_wol,
.resume = m88e1510_resume,
- .suspend = marvell_suspend,
+ .suspend = m88e1510_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
|
| 3/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 5631 output: 21 thoughts: 385 Thoughts: **Analyzing the Marvell PHY Driver Patch** Okay, so this patch hits `drivers/net/phy/marvell.c`. Let's dig in. It looks like we're dealing with Wake-on-LAN (WoL) functionality. Specifically, it's adding `marvell_wol_suspend_intrs` and `marvell_wol_resume_intrs`. Interesting, and they've also tweaked the `m88e1510_resume`, `m88e1510_suspend`, and `m88e1318_set_wol` functions, implying existing WoL support is getting improved or refined. There are new `m88e1318_suspend` and `m88e1318_resume` functions, so that's a new PHY getting WoL capabilities. The `marvell_probe` function is being updated. It appears it will configure a wake interrupt if the "wakeup-source" device property is present *and* `phy_interrupt_is_valid(phydev)`. Smart, handling the interrupt validity check. Plus, the `marvell_drivers` tables are being modified for the "Marvell 88E1318S" and "Marvell 88E1510" PHYs. All signs point to this being about enabling and managing WoL signals. Now, the crucial question: can I even *test* this in my environment? Is `drivers/net/phy/marvell.c` reachable in QEMU or syzkaller? These Marvell PHY drivers are MDIO bus-based, meaning they are PHY drivers for the MDIO bus. Can I instantiate a Marvell PHY within QEMU without physical hardware? How are PHY devices generally bound? Can I simulate this through virtual MDIO, or mdio-gpio, a dummy MDIO, a USB Ethernet dongle with a Marvell PHY, or maybe even ethtool or netlink? This is probably a hardware-specific component. I need to figure out if it's reachable or if I'm hitting a wall here. I'm going to run grepper now to see how `MARVELL_PHY` is configured and used within the kernel. Let's see if that provides any clues about how I can actually interact with this functionality. |
| 4/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_MARVELL_PHY"
}Results: {
"Output": "arch/arm/configs/gemini_defconfig=54=CONFIG_GEMINI_ETHERNET=y\narch/arm/configs/gemini_defconfig:55:CONFIG_MARVELL_PHY=y\narch/arm/configs/gemini_defconfig-56-CONFIG_MDIO_BITBANG=y\n--\narch/arm/configs/keystone_defconfig=132=CONFIG_TI_KEYSTONE_NETCP_ETHSS=y\narch/arm/configs/keystone_defconfig:133:CONFIG_MARVELL_PHY=y\narch/arm/configs/keystone_defconfig-134-CONFIG_MICREL_PHY=y\n--\narch/arm/configs/multi_v5_defconfig=94=CONFIG_DAVICOM_PHY=y\narch/arm/configs/multi_v5_defconfig:95:CONFIG_MARVELL_PHY=y\narch/arm/configs/multi_v5_defconfig-96-CONFIG_MICREL_PHY=y\n--\narch/arm/configs/multi_v7_defconfig=288=CONFIG_ICPLUS_PHY=y\narch/arm/configs/multi_v7_defconfig:289:CONFIG_MARVELL_PHY=y\narch/arm/configs/multi_v7_defconfig-290-CONFIG_AT803X_PHY=y\n--\narch/arm/configs/mv78xx0_defconfig=55=CONFIG_MV643XX_ETH=y\narch/arm/configs/mv78xx0_defconfig-56-# CONFIG_INPUT_MOUSEDEV is not set\narch/arm/configs/mv78xx0_defconfig:57:CONFIG_MARVELL_PHY=y\narch/arm/configs/mv78xx0_defconfig-58-CONFIG_INPUT_EVDEV=y\n--\narch/arm/configs/mvebu_v5_defconfig=73=CONFIG_R8169=y\narch/arm/configs/mvebu_v5_defconfig:74:CONFIG_MARVELL_PHY=y\narch/arm/configs/mvebu_v5_defconfig-75-CONFIG_LIBERTAS=y\n--\narch/arm/configs/mvebu_v7_defconfig=65=CONFIG_SFP=y\narch/arm/configs/mvebu_v7_defconfig:66:CONFIG_MARVELL_PHY=y\narch/arm/configs/mvebu_v7_defconfig-67-CONFIG_MWIFIEX=y\n--\narch/arm/configs/orion5x_defconfig=58=CONFIG_MV643XX_ETH=y\narch/arm/configs/orion5x_defconfig:59:CONFIG_MARVELL_PHY=y\narch/arm/configs/orion5x_defconfig-60-# CONFIG_INPUT_MOUSEDEV is not set\n--\narch/arm/configs/pxa_defconfig=184=CONFIG_FIXED_PHY=m\narch/arm/configs/pxa_defconfig:185:CONFIG_MARVELL_PHY=m\narch/arm/configs/pxa_defconfig-186-CONFIG_AT803X_PHY=m\n--\narch/arm/configs/socfpga_defconfig=67=CONFIG_STMMAC_ETH=y\narch/arm/configs/socfpga_defconfig:68:CONFIG_MARVELL_PHY=y\narch/arm/configs/socfpga_defconfig-69-CONFIG_MICREL_PHY=y\n--\narch/arm64/configs/defconfig=462=CONFIG_BCM54140_PHY=m\narch/arm64/configs/defconfig:463:CONFIG_MARVELL_PHY=m\narch/arm64/configs/defconfig-464-CONFIG_MARVELL_10G_PHY=y\n--\narch/microblaze/configs/mmu_defconfig=46=CONFIG_XILINX_LL_TEMAC=y\narch/microblaze/configs/mmu_defconfig:47:CONFIG_MARVELL_PHY=y\narch/microblaze/configs/mmu_defconfig-48-# CONFIG_INPUT is not set\n--\narch/mips/configs/cavium_octeon_defconfig=95=CONFIG_BROADCOM_PHY=y\narch/mips/configs/cavium_octeon_defconfig:96:CONFIG_MARVELL_PHY=y\narch/mips/configs/cavium_octeon_defconfig-97-# CONFIG_WLAN is not set\n--\narch/mips/configs/eyeq5_defconfig=58=CONFIG_MACB=y\narch/mips/configs/eyeq5_defconfig:59:CONFIG_MARVELL_PHY=y\narch/mips/configs/eyeq5_defconfig-60-CONFIG_MICREL_PHY=y\n--\narch/mips/configs/eyeq6_defconfig=60=CONFIG_MACB=y\narch/mips/configs/eyeq6_defconfig:61:CONFIG_MARVELL_PHY=y\narch/mips/configs/eyeq6_defconfig-62-CONFIG_MICREL_PHY=y\n--\narch/mips/configs/eyeq6lplus_defconfig=59=CONFIG_MACB=y\narch/mips/configs/eyeq6lplus_defconfig:60:CONFIG_MARVELL_PHY=y\narch/mips/configs/eyeq6lplus_defconfig-61-CONFIG_MICREL_PHY=y\n--\narch/mips/configs/fuloong2e_defconfig=111=CONFIG_LXT_PHY=m\narch/mips/configs/fuloong2e_defconfig:112:CONFIG_MARVELL_PHY=m\narch/mips/configs/fuloong2e_defconfig-113-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/gpr_defconfig=157=CONFIG_LXT_PHY=m\narch/mips/configs/gpr_defconfig:158:CONFIG_MARVELL_PHY=m\narch/mips/configs/gpr_defconfig-159-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/ip22_defconfig=205=CONFIG_LXT_PHY=m\narch/mips/configs/ip22_defconfig:206:CONFIG_MARVELL_PHY=m\narch/mips/configs/ip22_defconfig-207-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/ip27_defconfig=171=CONFIG_LXT_PHY=m\narch/mips/configs/ip27_defconfig:172:CONFIG_MARVELL_PHY=m\narch/mips/configs/ip27_defconfig-173-CONFIG_NATIONAL_PHY=m\n--\narch/mips/configs/malta_defconfig=280=CONFIG_LXT_PHY=m\narch/mips/configs/malta_defconfig:281:CONFIG_MARVELL_PHY=m\narch/mips/configs/malta_defconfig-282-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/malta_kvm_defconfig=287=CONFIG_LXT_PHY=m\narch/mips/configs/malta_kvm_defconfig:288:CONFIG_MARVELL_PHY=m\narch/mips/configs/malta_kvm_defconfig-289-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/maltaup_xpa_defconfig=286=CONFIG_LXT_PHY=m\narch/mips/configs/maltaup_xpa_defconfig:287:CONFIG_MARVELL_PHY=m\narch/mips/configs/maltaup_xpa_defconfig-288-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/mtx1_defconfig=271=CONFIG_LXT_PHY=m\narch/mips/configs/mtx1_defconfig:272:CONFIG_MARVELL_PHY=m\narch/mips/configs/mtx1_defconfig-273-CONFIG_QSEMI_PHY=m\n--\narch/mips/configs/rm200_defconfig=225=CONFIG_LXT_PHY=m\narch/mips/configs/rm200_defconfig:226:CONFIG_MARVELL_PHY=m\narch/mips/configs/rm200_defconfig-227-CONFIG_QSEMI_PHY=m\n--\narch/nios2/configs/10m50_defconfig=47=CONFIG_ALTERA_TSE=y\narch/nios2/configs/10m50_defconfig:48:CONFIG_MARVELL_PHY=y\narch/nios2/configs/10m50_defconfig-49-# CONFIG_WLAN is not set\n--\narch/nios2/configs/3c120_defconfig=50=CONFIG_ALTERA_TSE=y\narch/nios2/configs/3c120_defconfig:51:CONFIG_MARVELL_PHY=y\narch/nios2/configs/3c120_defconfig-52-# CONFIG_WLAN is not set\n--\narch/parisc/configs/generic-64bit_defconfig=139=CONFIG_LSI_ET1011C_PHY=m\narch/parisc/configs/generic-64bit_defconfig:140:CONFIG_MARVELL_PHY=m\narch/parisc/configs/generic-64bit_defconfig-141-CONFIG_NATIONAL_PHY=m\n--\narch/powerpc/configs/52xx/motionpro_defconfig=48=CONFIG_LXT_PHY=y\narch/powerpc/configs/52xx/motionpro_defconfig:49:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/52xx/motionpro_defconfig-50-CONFIG_QSEMI_PHY=y\n--\narch/powerpc/configs/83xx/kmeter1_defconfig=42=CONFIG_UCC_GETH=y\narch/powerpc/configs/83xx/kmeter1_defconfig:43:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/83xx/kmeter1_defconfig-44-CONFIG_PPP=y\n--\narch/powerpc/configs/83xx/mpc837x_rdb_defconfig=38=CONFIG_GIANFAR=y\narch/powerpc/configs/83xx/mpc837x_rdb_defconfig:39:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/83xx/mpc837x_rdb_defconfig-40-CONFIG_INPUT_FF_MEMLESS=m\n--\narch/powerpc/configs/85xx-hw.config=55=CONFIG_INPUT_FF_MEMLESS=m\n--\narch/powerpc/configs/85xx-hw.config-58-# CONFIG_INPUT_MOUSE is not set\narch/powerpc/configs/85xx-hw.config:59:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/85xx-hw.config-60-CONFIG_MDIO_BUS_MUX_GPIO=y\n--\narch/powerpc/configs/85xx/ksi8560_defconfig=40=CONFIG_GIANFAR=y\narch/powerpc/configs/85xx/ksi8560_defconfig:41:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/85xx/ksi8560_defconfig-42-# CONFIG_INPUT_KEYBOARD is not set\n--\narch/powerpc/configs/85xx/ppa8548_defconfig=33=CONFIG_GIANFAR=y\narch/powerpc/configs/85xx/ppa8548_defconfig:34:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/85xx/ppa8548_defconfig-35-CONFIG_SERIAL_8250=y\n--\narch/powerpc/configs/85xx/socrates_defconfig=43=CONFIG_GIANFAR=y\narch/powerpc/configs/85xx/socrates_defconfig:44:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/85xx/socrates_defconfig-45-CONFIG_INPUT_EVDEV=y\n--\narch/powerpc/configs/85xx/stx_gp3_defconfig=39=CONFIG_GIANFAR=y\narch/powerpc/configs/85xx/stx_gp3_defconfig:40:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/85xx/stx_gp3_defconfig-41-CONFIG_INPUT_JOYDEV=m\n--\narch/powerpc/configs/mpc512x_defconfig=63=CONFIG_LXT_PHY=y\narch/powerpc/configs/mpc512x_defconfig:64:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/mpc512x_defconfig-65-CONFIG_NATIONAL_PHY=y\n--\narch/powerpc/configs/mpc83xx_defconfig=56=CONFIG_ICPLUS_PHY=y\narch/powerpc/configs/mpc83xx_defconfig:57:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/mpc83xx_defconfig-58-CONFIG_VITESSE_PHY=y\n--\narch/powerpc/configs/pasemi_defconfig=84=CONFIG_PASEMI_MAC=y\narch/powerpc/configs/pasemi_defconfig:85:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/pasemi_defconfig-86-CONFIG_INPUT_JOYDEV=y\n--\narch/powerpc/configs/ppc64_defconfig=226=CONFIG_BROADCOM_PHY=m\narch/powerpc/configs/ppc64_defconfig:227:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/ppc64_defconfig-228-CONFIG_PPP=m\n--\narch/powerpc/configs/ppc64e_defconfig=104=CONFIG_BROADCOM_PHY=m\narch/powerpc/configs/ppc64e_defconfig:105:CONFIG_MARVELL_PHY=y\narch/powerpc/configs/ppc64e_defconfig-106-CONFIG_PPP=m\n--\narch/powerpc/configs/ppc6xx_defconfig=464=CONFIG_LXT_PHY=m\narch/powerpc/configs/ppc6xx_defconfig:465:CONFIG_MARVELL_PHY=m\narch/powerpc/configs/ppc6xx_defconfig-466-CONFIG_QSEMI_PHY=m\n--\narch/sh/configs/titan_defconfig=162=CONFIG_PHYLIB=m\narch/sh/configs/titan_defconfig:163:CONFIG_MARVELL_PHY=m\narch/sh/configs/titan_defconfig-164-CONFIG_DAVICOM_PHY=m\n--\narch/sh/configs/urquell_defconfig=60=CONFIG_PHYLIB=y\narch/sh/configs/urquell_defconfig:61:CONFIG_MARVELL_PHY=y\narch/sh/configs/urquell_defconfig-62-CONFIG_NET_ETHERNET=y\n--\narch/xtensa/configs/audio_kc705_defconfig=64=CONFIG_NETDEVICES=y\n--\narch/xtensa/configs/audio_kc705_defconfig-76-# CONFIG_NET_VENDOR_WIZNET is not set\narch/xtensa/configs/audio_kc705_defconfig:77:CONFIG_MARVELL_PHY=y\narch/xtensa/configs/audio_kc705_defconfig-78-# CONFIG_WLAN is not set\n--\narch/xtensa/configs/generic_kc705_defconfig=62=CONFIG_NETDEVICES=y\n--\narch/xtensa/configs/generic_kc705_defconfig-74-# CONFIG_NET_VENDOR_WIZNET is not set\narch/xtensa/configs/generic_kc705_defconfig:75:CONFIG_MARVELL_PHY=y\narch/xtensa/configs/generic_kc705_defconfig-76-# CONFIG_WLAN is not set\n--\narch/xtensa/configs/nommu_kc705_defconfig=66=CONFIG_NETDEVICES=y\n--\narch/xtensa/configs/nommu_kc705_defconfig-76-# CONFIG_NET_VENDOR_WIZNET is not set\narch/xtensa/configs/nommu_kc705_defconfig:77:CONFIG_MARVELL_PHY=y\narch/xtensa/configs/nommu_kc705_defconfig-78-# CONFIG_WLAN is not set\n--\narch/xtensa/configs/smp_lx200_defconfig=66=CONFIG_NETDEVICES=y\n--\narch/xtensa/configs/smp_lx200_defconfig-78-# CONFIG_NET_VENDOR_WIZNET is not set\narch/xtensa/configs/smp_lx200_defconfig:79:CONFIG_MARVELL_PHY=y\narch/xtensa/configs/smp_lx200_defconfig-80-# CONFIG_WLAN is not set\n--\narch/xtensa/configs/xip_kc705_defconfig=56=CONFIG_NETDEVICES=y\n--\narch/xtensa/configs/xip_kc705_defconfig-68-# CONFIG_NET_VENDOR_WIZNET is not set\narch/xtensa/configs/xip_kc705_defconfig:69:CONFIG_MARVELL_PHY=y\narch/xtensa/configs/xip_kc705_defconfig-70-# CONFIG_WLAN is not set\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c=1551=mv643xx_eth_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1562-\tif (err == -EOPNOTSUPP)\ndrivers/net/ethernet/marvell/mv643xx_eth.c:1563:\t\tnetdev_info(dev, \"The PHY does not support set_wol, was CONFIG_MARVELL_PHY enabled?\\n\");\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1564-\treturn err;\n--\ndrivers/net/phy/Makefile=71=obj-$(CONFIG_MARVELL_10G_PHY)\t+= marvell10g.o\ndrivers/net/phy/Makefile:72:obj-$(CONFIG_MARVELL_PHY)\t+= marvell.o\ndrivers/net/phy/Makefile-73-obj-$(CONFIG_MARVELL_88Q2XXX_PHY)\t+= marvell-88q2xxx.o\n--\ndrivers/net/phy/phylink.c=3990=static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)\n--\ndrivers/net/phy/phylink.c-3996-\t\t\t phydev_name(phy), (unsigned long)phy-\u003ephy_id);\ndrivers/net/phy/phylink.c:3997:\t\tphylink_err(pl, \"Drivers which handle known common cases: CONFIG_BCM84881_PHY, CONFIG_MARVELL_PHY\\n\");\ndrivers/net/phy/phylink.c-3998-\t\treturn -EINVAL;\n"
} |
| 5/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11506 output: 34 thoughts: 21 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Investigating MARVELL_PHY Configuration** Okay, let's dive into the kernel configuration, specifically the `drivers/net/phy/Kconfig` file. I need to understand how the `MARVELL_PHY` option is handled and what dependencies or implications it has. I'm essentially tracing the configuration path for Marvell PHY support. I'm looking for the relevant `config` option, of course. I’ll be examining its default value, help text, and importantly, any dependencies it might have on other features or hardware configurations. I'm especially interested in looking for any potential conflicts it might introduce. I'll need to know whether it's tied to any specific Marvell hardware revisions or SoCs and whether there are any conditional statements or tristate settings. This will give me the information I need to understand whether I can enable or disable this option reliably, depending on a specific Marvell-based setup. |
| 6/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "config MARVELL_PHY",
"PathPrefix": "drivers/net/phy/Kconfig"
}Results: {
"Output": "drivers/net/phy/Kconfig=273=config LSI_ET1011C_PHY\n--\ndrivers/net/phy/Kconfig-277-\ndrivers/net/phy/Kconfig:278:config MARVELL_PHY\ndrivers/net/phy/Kconfig-279-\ttristate \"Marvell Alaska PHYs\"\n"
} |
| 7/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11873 output: 36 thoughts: 21 Thoughts: Here's a summary of my thought process, as requested: **Navigating the PHY Configuration Space** Okay, time to dive into the kernel's PHY configuration. I need to refresh my memory on some specific options. Let's start by looking at `drivers/net/phy/Kconfig`, specifically around line 278. That section likely covers the crucial aspects of configuring the Physical Layer Transceivers, and I know from experience that's where the heart of the PHY driver options are defined. This should give me a good baseline for understanding the present options and any dependencies they might have. It's the standard first step when needing a broader picture. |
| 8/2 | 2026/09/13 00:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/Kconfig",
"FirstLine": 275,
"LineCount": 20
}Results: {
"Contents": " 275:\t\thelp\n 276:\t\t Supports the LSI ET1011C PHY.\n 277:\t\n 278:\tconfig MARVELL_PHY\n 279:\t\ttristate \"Marvell Alaska PHYs\"\n 280:\t\thelp\n 281:\t\t Currently has a driver for the 88E1XXX\n 282:\t\n 283:\tconfig MARVELL_10G_PHY\n 284:\t\ttristate \"Marvell Alaska 10Gbit PHYs\"\n 285:\t\thelp\n 286:\t\t Support for the Marvell Alaska MV88X3310 and compatible PHYs.\n 287:\t\n 288:\tconfig MARVELL_88Q2XXX_PHY\n 289:\t\ttristate \"Marvell 88Q2XXX PHY\"\n 290:\t\tdepends on HWMON || HWMON=n\n 291:\t\thelp\n 292:\t\t Support for the Marvell 88Q2XXX 100/1000BASE-T1 Automotive Ethernet\n 293:\t\t PHYs.\n 294:\t\n"
} |
| 9/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 12382 output: 28 thoughts: 404 Thoughts: **My Line of Inquiry: MARVELL_PHY and QEMU Reachability** Okay, so I'm thinking about this `MARVELL_PHY` driver. It's supposed to be architecture and bus-agnostic, which is great. But my immediate question is: how does a specific MDIO or PHY device *actually* get created and connected to this driver? Let's take a look at the standard way PHY devices are handled in Linux. A key point arises: can these PHY devices even *exist* in a QEMU environment? Can I create them there? I'm getting that nagging feeling that the answer might be no, especially given the fuzzing context. Ah, here it is, the instructions again remind me: "REACHABILITY IS THE PRIMARY GATE." If the code's execution is structurally impossible within standard virtual environments, it's out. Vendor-specific hardware like PCIe switches, SmartNICs, or GPU drivers are explicitly mentioned as examples of code that's not reachable without the physical hardware, which isn't emulated in QEMU. That's a good reminder. So the million-dollar question: can a Marvell PHY with an ID like 88E1318S or 88E1510 *ever* be instantiated in a QEMU environment, especially targeting an amd64 architecture? Or are we going to need some sort of software-emulated device to achieve this? Can any software emulated device in QEMU or virtual bus instantiate a Marvell PHY? I need to figure out if there's any way to create an MDIO bus or PHY device in a virtual environment. Now, I need to start searching for information on MDIO bus creation from user-space or whether virtual MDIO buses are even possible. |
| 10/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "mdio_bus",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 2175 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/microchip/ksz9477.c=321=static int ksz9477_pcs_create(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz9477.c-332-\ndrivers/net/dsa/microchip/ksz9477.c:333:\tbus-\u003ename = \"ksz_pcs_mdio_bus\";\ndrivers/net/dsa/microchip/ksz9477.c-334-\tsnprintf(bus-\u003eid, MII_BUS_ID_SIZE, \"%s-pcs\",\n--\ndrivers/net/dsa/microchip/ksz_common.c=2160=int ksz_parent_mdio_read(struct mii_bus *bus, int addr, int regnum)\n--\ndrivers/net/dsa/microchip/ksz_common.c-2163-\ndrivers/net/dsa/microchip/ksz_common.c:2164:\treturn mdiobus_read_nested(dev-\u003eparent_mdio_bus, addr, regnum);\ndrivers/net/dsa/microchip/ksz_common.c-2165-}\n--\ndrivers/net/dsa/microchip/ksz_common.c=2180=int ksz_parent_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)\n--\ndrivers/net/dsa/microchip/ksz_common.c-2183-\ndrivers/net/dsa/microchip/ksz_common.c:2184:\treturn mdiobus_write_nested(dev-\u003eparent_mdio_bus, addr, regnum, val);\ndrivers/net/dsa/microchip/ksz_common.c-2185-}\n--\ndrivers/net/dsa/microchip/ksz_common.c=2356=int ksz_mdio_register(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz_common.c-2382-\ndrivers/net/dsa/microchip/ksz_common.c:2383:\t\tdev-\u003eparent_mdio_bus = parent_bus;\ndrivers/net/dsa/microchip/ksz_common.c-2384-\t}\n--\ndrivers/net/dsa/microchip/ksz_common.h=206=struct ksz_device {\n--\ndrivers/net/dsa/microchip/ksz_common.h-258-\t/**\ndrivers/net/dsa/microchip/ksz_common.h:259:\t * @parent_mdio_bus: Pointer to the external MDIO bus controller.\ndrivers/net/dsa/microchip/ksz_common.h-260-\t *\n--\ndrivers/net/dsa/microchip/ksz_common.h-265-\t */\ndrivers/net/dsa/microchip/ksz_common.h:266:\tstruct mii_bus *parent_mdio_bus;\ndrivers/net/dsa/microchip/ksz_common.h-267-\n--\ndrivers/net/dsa/microchip/lan937x_main.c=143=static int lan937x_create_phy_addr_map(struct ksz_device *dev, bool side_mdio)\n--\ndrivers/net/dsa/microchip/lan937x_main.c-210-/**\ndrivers/net/dsa/microchip/lan937x_main.c:211: * lan937x_mdio_bus_preinit - Pre-initialize MDIO bus for accessing PHYs.\ndrivers/net/dsa/microchip/lan937x_main.c-212- * @dev: Pointer to device structure.\n--\ndrivers/net/dsa/microchip/lan937x_main.c-226- */\ndrivers/net/dsa/microchip/lan937x_main.c:227:static int lan937x_mdio_bus_preinit(struct ksz_device *dev, bool side_mdio)\ndrivers/net/dsa/microchip/lan937x_main.c-228-{\n--\ndrivers/net/dsa/microchip/lan937x_main.c=685=static int lan937x_mdio_register(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/lan937x_main.c-711-\ndrivers/net/dsa/microchip/lan937x_main.c:712:\t\tdev-\u003eparent_mdio_bus = parent_bus;\ndrivers/net/dsa/microchip/lan937x_main.c-713-\t}\n--\ndrivers/net/dsa/microchip/lan937x_main.c-720-\ndrivers/net/dsa/microchip/lan937x_main.c:721:\tret = lan937x_mdio_bus_preinit(dev, !!parent_bus);\ndrivers/net/dsa/microchip/lan937x_main.c-722-\tif (ret)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=126=int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-132-\ndrivers/net/dsa/mv88e6xxx/chip.c:133:struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)\ndrivers/net/dsa/mv88e6xxx/chip.c-134-{\ndrivers/net/dsa/mv88e6xxx/chip.c:135:\tstruct mv88e6xxx_mdio_bus *mdio_bus;\ndrivers/net/dsa/mv88e6xxx/chip.c-136-\ndrivers/net/dsa/mv88e6xxx/chip.c:137:\tmdio_bus = list_first_entry_or_null(\u0026chip-\u003emdios,\ndrivers/net/dsa/mv88e6xxx/chip.c:138:\t\t\t\t\t struct mv88e6xxx_mdio_bus, list);\ndrivers/net/dsa/mv88e6xxx/chip.c:139:\tif (!mdio_bus)\ndrivers/net/dsa/mv88e6xxx/chip.c-140-\t\treturn NULL;\ndrivers/net/dsa/mv88e6xxx/chip.c-141-\ndrivers/net/dsa/mv88e6xxx/chip.c:142:\treturn mdio_bus-\u003ebus;\ndrivers/net/dsa/mv88e6xxx/chip.c-143-}\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3765=static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)\ndrivers/net/dsa/mv88e6xxx/chip.c-3766-{\ndrivers/net/dsa/mv88e6xxx/chip.c:3767:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:3768:\tstruct mv88e6xxx_chip *chip = mdio_bus-\u003echip;\ndrivers/net/dsa/mv88e6xxx/chip.c-3769-\tu16 prod_id;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3791=static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3793-{\ndrivers/net/dsa/mv88e6xxx/chip.c:3794:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:3795:\tstruct mv88e6xxx_chip *chip = mdio_bus-\u003echip;\ndrivers/net/dsa/mv88e6xxx/chip.c-3796-\tu16 val;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3809=static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)\ndrivers/net/dsa/mv88e6xxx/chip.c-3810-{\ndrivers/net/dsa/mv88e6xxx/chip.c:3811:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:3812:\tstruct mv88e6xxx_chip *chip = mdio_bus-\u003echip;\ndrivers/net/dsa/mv88e6xxx/chip.c-3813-\tint err;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3825=static int mv88e6xxx_mdio_write_c45(struct mii_bus *bus, int phy, int devad,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3827-{\ndrivers/net/dsa/mv88e6xxx/chip.c:3828:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:3829:\tstruct mv88e6xxx_chip *chip = mdio_bus-\u003echip;\ndrivers/net/dsa/mv88e6xxx/chip.c-3830-\tint err;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3842=static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3846-\tstatic int index;\ndrivers/net/dsa/mv88e6xxx/chip.c:3847:\tstruct mv88e6xxx_mdio_bus *mdio_bus;\ndrivers/net/dsa/mv88e6xxx/chip.c-3848-\tstruct mii_bus *bus;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3862-\ndrivers/net/dsa/mv88e6xxx/chip.c:3863:\tbus = mdiobus_alloc_size(sizeof(*mdio_bus));\ndrivers/net/dsa/mv88e6xxx/chip.c-3864-\tif (!bus)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3866-\ndrivers/net/dsa/mv88e6xxx/chip.c:3867:\tmdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:3868:\tmdio_bus-\u003ebus = bus;\ndrivers/net/dsa/mv88e6xxx/chip.c:3869:\tmdio_bus-\u003echip = chip;\ndrivers/net/dsa/mv88e6xxx/chip.c:3870:\tINIT_LIST_HEAD(\u0026mdio_bus-\u003elist);\ndrivers/net/dsa/mv88e6xxx/chip.c:3871:\tmdio_bus-\u003eexternal = external;\ndrivers/net/dsa/mv88e6xxx/chip.c-3872-\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3903-\tif (external)\ndrivers/net/dsa/mv88e6xxx/chip.c:3904:\t\tlist_add_tail(\u0026mdio_bus-\u003elist, \u0026chip-\u003emdios);\ndrivers/net/dsa/mv88e6xxx/chip.c-3905-\telse\ndrivers/net/dsa/mv88e6xxx/chip.c:3906:\t\tlist_add(\u0026mdio_bus-\u003elist, \u0026chip-\u003emdios);\ndrivers/net/dsa/mv88e6xxx/chip.c-3907-\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3915=static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3917-{\ndrivers/net/dsa/mv88e6xxx/chip.c:3918:\tstruct mv88e6xxx_mdio_bus *mdio_bus, *p;\ndrivers/net/dsa/mv88e6xxx/chip.c-3919-\tstruct mii_bus *bus;\ndrivers/net/dsa/mv88e6xxx/chip.c-3920-\ndrivers/net/dsa/mv88e6xxx/chip.c:3921:\tlist_for_each_entry_safe(mdio_bus, p, \u0026chip-\u003emdios, list) {\ndrivers/net/dsa/mv88e6xxx/chip.c:3922:\t\tbus = mdio_bus-\u003ebus;\ndrivers/net/dsa/mv88e6xxx/chip.c-3923-\ndrivers/net/dsa/mv88e6xxx/chip.c:3924:\t\tif (!mdio_bus-\u003eexternal)\ndrivers/net/dsa/mv88e6xxx/chip.c-3925-\t\t\tmv88e6xxx_g2_irq_mdio_free(chip, bus);\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3988=static int mv88e6xxx_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3999-\tchip-\u003eds = ds;\ndrivers/net/dsa/mv88e6xxx/chip.c:4000:\tds-\u003euser_mii_bus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/chip.c-4001-\n--\ndrivers/net/dsa/mv88e6xxx/chip.h=488=struct mv88e6xxx_bus_ops {\n--\ndrivers/net/dsa/mv88e6xxx/chip.h-493-\ndrivers/net/dsa/mv88e6xxx/chip.h:494:struct mv88e6xxx_mdio_bus {\ndrivers/net/dsa/mv88e6xxx/chip.h-495-\tstruct mii_bus *bus;\n--\ndrivers/net/dsa/mv88e6xxx/chip.h=873=int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,\ndrivers/net/dsa/mv88e6xxx/chip.h-874-\t\t int bit, int val);\ndrivers/net/dsa/mv88e6xxx/chip.h:875:struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);\ndrivers/net/dsa/mv88e6xxx/chip.h-876-\n--\ndrivers/net/dsa/mv88e6xxx/global2.c=787=int mv88e6xxx_g2_smi_phy_read_c22(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/global2.c-790-{\ndrivers/net/dsa/mv88e6xxx/global2.c:791:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/global2.c:792:\tbool external = mdio_bus-\u003eexternal;\ndrivers/net/dsa/mv88e6xxx/global2.c-793-\n--\ndrivers/net/dsa/mv88e6xxx/global2.c=798=int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/global2.c-801-{\ndrivers/net/dsa/mv88e6xxx/global2.c:802:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/global2.c:803:\tbool external = mdio_bus-\u003eexternal;\ndrivers/net/dsa/mv88e6xxx/global2.c-804-\n--\ndrivers/net/dsa/mv88e6xxx/global2.c=809=int mv88e6xxx_g2_smi_phy_write_c22(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/global2.c-812-{\ndrivers/net/dsa/mv88e6xxx/global2.c:813:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/global2.c:814:\tbool external = mdio_bus-\u003eexternal;\ndrivers/net/dsa/mv88e6xxx/global2.c-815-\n--\ndrivers/net/dsa/mv88e6xxx/global2.c=820=int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/global2.c-823-{\ndrivers/net/dsa/mv88e6xxx/global2.c:824:\tstruct mv88e6xxx_mdio_bus *mdio_bus = bus-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/global2.c:825:\tbool external = mdio_bus-\u003eexternal;\ndrivers/net/dsa/mv88e6xxx/global2.c-826-\n--\ndrivers/net/dsa/mv88e6xxx/pcs-6352.c=324=static int mv88e6352_pcs_init(struct mv88e6xxx_chip *chip, int port)\n--\ndrivers/net/dsa/mv88e6xxx/pcs-6352.c-336-\tirq = mv88e6xxx_serdes_irq_mapping(chip, port);\ndrivers/net/dsa/mv88e6xxx/pcs-6352.c:337:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/pcs-6352.c-338-\tdev = chip-\u003edev;\n--\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c=549=static int mv88e6390_pcs_init(struct mv88e6xxx_chip *chip, int port)\n--\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c-559-\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c:560:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c-561-\tdev = chip-\u003edev;\n--\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c=927=static int mv88e6393x_pcs_init(struct mv88e6xxx_chip *chip, int port)\n--\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c-937-\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c:938:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/pcs-639x.c-939-\tdev = chip-\u003edev;\n--\ndrivers/net/dsa/mv88e6xxx/phy.c=28=int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy, int reg, u16 *val)\n--\ndrivers/net/dsa/mv88e6xxx/phy.c-32-\ndrivers/net/dsa/mv88e6xxx/phy.c:33:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/phy.c-34-\tif (!bus)\n--\ndrivers/net/dsa/mv88e6xxx/phy.c=43=int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy, int reg, u16 val)\n--\ndrivers/net/dsa/mv88e6xxx/phy.c-47-\ndrivers/net/dsa/mv88e6xxx/phy.c:48:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/phy.c-49-\tif (!bus)\n--\ndrivers/net/dsa/mv88e6xxx/phy.c=58=int mv88e6xxx_phy_read_c45(struct mv88e6xxx_chip *chip, int phy, int devad,\n--\ndrivers/net/dsa/mv88e6xxx/phy.c-63-\ndrivers/net/dsa/mv88e6xxx/phy.c:64:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/phy.c-65-\tif (!bus)\n--\ndrivers/net/dsa/mv88e6xxx/phy.c=74=int mv88e6xxx_phy_write_c45(struct mv88e6xxx_chip *chip, int phy, int devad,\n--\ndrivers/net/dsa/mv88e6xxx/phy.c-79-\ndrivers/net/dsa/mv88e6xxx/phy.c:80:\tbus = mv88e6xxx_default_mdio_bus(chip);\ndrivers/net/dsa/mv88e6xxx/phy.c-81-\tif (!bus)\n--\ndrivers/net/dsa/netc/netc_main.c=133=static int netc_port_get_info_from_dt(struct netc_port *np,\n--\ndrivers/net/dsa/netc/netc_main.c-148-\ndrivers/net/dsa/netc/netc_main.c:149:static int netc_port_create_emdio_bus(struct netc_port *np,\ndrivers/net/dsa/netc/netc_main.c-150-\t\t\t\t struct device_node *node)\n--\ndrivers/net/dsa/netc/netc_main.c-189-\ndrivers/net/dsa/netc/netc_main.c:190:static int netc_port_create_mdio_bus(struct netc_port *np,\ndrivers/net/dsa/netc/netc_main.c-191-\t\t\t\t struct device_node *node)\n--\ndrivers/net/dsa/netc/netc_main.c-197-\tif (mdio_node) {\ndrivers/net/dsa/netc/netc_main.c:198:\t\terr = netc_port_create_emdio_bus(np, mdio_node);\ndrivers/net/dsa/netc/netc_main.c-199-\t\tof_node_put(mdio_node);\n--\ndrivers/net/dsa/netc/netc_main.c=241=static int netc_init_all_ports(struct netc_switch *priv)\n--\ndrivers/net/dsa/netc/netc_main.c-283-\t\tif (dsa_port_is_user(dp)) {\ndrivers/net/dsa/netc/netc_main.c:284:\t\t\terr = netc_port_create_mdio_bus(np, dp-\u003edn);\ndrivers/net/dsa/netc/netc_main.c-285-\t\t\tif (err) {\n--\ndrivers/net/dsa/ocelot/felix.c=1517=static int felix_init_structs(struct felix *felix, int num_phys_ports)\n--\ndrivers/net/dsa/ocelot/felix.c-1602-\ndrivers/net/dsa/ocelot/felix.c:1603:\tif (felix-\u003einfo-\u003emdio_bus_alloc) {\ndrivers/net/dsa/ocelot/felix.c:1604:\t\terr = felix-\u003einfo-\u003emdio_bus_alloc(ocelot);\ndrivers/net/dsa/ocelot/felix.c-1605-\t\tif (err \u003c 0)\n--\ndrivers/net/dsa/ocelot/felix.c=1696=static int felix_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/ocelot/felix.c-1768-out_mdiobus_free:\ndrivers/net/dsa/ocelot/felix.c:1769:\tif (felix-\u003einfo-\u003emdio_bus_free)\ndrivers/net/dsa/ocelot/felix.c:1770:\t\tfelix-\u003einfo-\u003emdio_bus_free(ocelot);\ndrivers/net/dsa/ocelot/felix.c-1771-\n--\ndrivers/net/dsa/ocelot/felix.c=1775=static void felix_teardown(struct dsa_switch *ds)\n--\ndrivers/net/dsa/ocelot/felix.c-1792-\ndrivers/net/dsa/ocelot/felix.c:1793:\tif (felix-\u003einfo-\u003emdio_bus_free)\ndrivers/net/dsa/ocelot/felix.c:1794:\t\tfelix-\u003einfo-\u003emdio_bus_free(ocelot);\ndrivers/net/dsa/ocelot/felix.c-1795-}\n--\ndrivers/net/dsa/ocelot/felix.h=22=struct felix_info {\n--\ndrivers/net/dsa/ocelot/felix.h-55-\ndrivers/net/dsa/ocelot/felix.h:56:\tint\t(*mdio_bus_alloc)(struct ocelot *ocelot);\ndrivers/net/dsa/ocelot/felix.h:57:\tvoid\t(*mdio_bus_free)(struct ocelot *ocelot);\ndrivers/net/dsa/ocelot/felix.h-58-\tint\t(*port_setup_tc)(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c=951=static void vsc9959_wm_stat(u32 val, u32 *inuse, u32 *maxuse)\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c-956-\ndrivers/net/dsa/ocelot/felix_vsc9959.c:957:static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)\ndrivers/net/dsa/ocelot/felix_vsc9959.c-958-{\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c-1044-\ndrivers/net/dsa/ocelot/felix_vsc9959.c:1045:static void vsc9959_mdio_bus_free(struct ocelot *ocelot)\ndrivers/net/dsa/ocelot/felix_vsc9959.c-1046-{\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c=2659=static const struct felix_info felix_info_vsc9959 = {\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c-2675-\t.ptp_caps\t\t= \u0026vsc9959_ptp_caps,\ndrivers/net/dsa/ocelot/felix_vsc9959.c:2676:\t.mdio_bus_alloc\t\t= vsc9959_mdio_bus_alloc,\ndrivers/net/dsa/ocelot/felix_vsc9959.c:2677:\t.mdio_bus_free\t\t= vsc9959_mdio_bus_free,\ndrivers/net/dsa/ocelot/felix_vsc9959.c-2678-\t.port_modes\t\t= vsc9959_port_modes,\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c=869=static const struct ocelot_ops vsc9953_ops = {\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c-877-\ndrivers/net/dsa/ocelot/seville_vsc9953.c:878:static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)\ndrivers/net/dsa/ocelot/seville_vsc9953.c-879-{\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c-934-\ndrivers/net/dsa/ocelot/seville_vsc9953.c:935:static void vsc9953_mdio_bus_free(struct ocelot *ocelot)\ndrivers/net/dsa/ocelot/seville_vsc9953.c-936-{\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c=950=static const struct felix_info seville_info_vsc9953 = {\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c-964-\t.num_ports\t\t= VSC9953_NUM_PORTS,\ndrivers/net/dsa/ocelot/seville_vsc9953.c:965:\t.mdio_bus_alloc\t\t= vsc9953_mdio_bus_alloc,\ndrivers/net/dsa/ocelot/seville_vsc9953.c:966:\t.mdio_bus_free\t\t= vsc9953_mdio_bus_free,\ndrivers/net/dsa/ocelot/seville_vsc9953.c-967-\t.port_modes\t\t= vsc9953_port_modes,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=793=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:794:qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)\ndrivers/net/dsa/qca/qca8k-8xxx.c-795-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=816=qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-840-\ndrivers/net/dsa/qca/qca8k-8xxx.c:841:\tret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-842-\t\t\t\t QCA8K_MDIO_MASTER_BUSY);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=854=qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-877-\ndrivers/net/dsa/qca/qca8k-8xxx.c:878:\tret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-879-\t\t\t\t QCA8K_MDIO_MASTER_BUSY);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=947=qca8k_mdio_register(struct qca8k_priv *priv)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-964-\ndrivers/net/dsa/qca/qca8k-8xxx.c:965:\tpriv-\u003einternal_mdio_bus = bus;\ndrivers/net/dsa/qca/qca8k-8xxx.c-966-\tbus-\u003epriv = (void *)priv;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=994=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:995:qca8k_setup_mdio_bus(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-996-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1843=qca8k_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1860-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1861:\tret = qca8k_setup_mdio_bus(priv);\ndrivers/net/dsa/qca/qca8k-8xxx.c-1862-\tif (ret)\n--\ndrivers/net/dsa/qca/qca8k-leds.c=365=qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)\n--\ndrivers/net/dsa/qca/qca8k-leds.c-431-\t\tinit_data.devicename = kasprintf(GFP_KERNEL, \"%s:0%d\",\ndrivers/net/dsa/qca/qca8k-leds.c:432:\t\t\t\t\t\t priv-\u003einternal_mdio_bus ?\ndrivers/net/dsa/qca/qca8k-leds.c:433:\t\t\t\t\t\t priv-\u003einternal_mdio_bus-\u003eid : priv-\u003ebus-\u003eid,\ndrivers/net/dsa/qca/qca8k-leds.c-434-\t\t\t\t\t\t port_num);\n--\ndrivers/net/dsa/qca/qca8k.h=445=struct qca8k_priv {\n--\ndrivers/net/dsa/qca/qca8k.h-458-\tstruct mii_bus *bus;\ndrivers/net/dsa/qca/qca8k.h:459:\tstruct mii_bus *internal_mdio_bus;\ndrivers/net/dsa/qca/qca8k.h-460-\tstruct dsa_switch *ds;\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c=521=static int vsc73xx_detect(struct vsc73xx *vsc)\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-604-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:605:static int vsc73xx_mdio_busy_check(struct vsc73xx *vsc)\ndrivers/net/dsa/vitesse-vsc73xx-core.c-606-{\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c=621=static int vsc73xx_phy_read(struct dsa_switch *ds, int phy, int regnum)\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-627-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:628:\tret = vsc73xx_mdio_busy_check(vsc);\ndrivers/net/dsa/vitesse-vsc73xx-core.c-629-\tif (ret)\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-640-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:641:\tret = vsc73xx_mdio_busy_check(vsc);\ndrivers/net/dsa/vitesse-vsc73xx-core.c-642-\tif (ret)\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c=662=static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum,\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-668-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:669:\tret = vsc73xx_mdio_busy_check(vsc);\ndrivers/net/dsa/vitesse-vsc73xx-core.c-670-\tif (ret)\n--\ndrivers/net/ethernet/apm/xgene-v2/main.h=51=struct xge_pdata {\n--\ndrivers/net/ethernet/apm/xgene-v2/main.h-56-\tchar irq_name[IRQ_ID_SIZE];\ndrivers/net/ethernet/apm/xgene-v2/main.h:57:\tstruct mii_bus *mdio_bus;\ndrivers/net/ethernet/apm/xgene-v2/main.h-58-\tstruct net_device *ndev;\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c=84=void xge_mdio_remove(struct net_device *ndev)\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-86-\tstruct xge_pdata *pdata = netdev_priv(ndev);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:87:\tstruct mii_bus *mdio_bus = pdata-\u003emdio_bus;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-88-\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-91-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:92:\tif (mdio_bus-\u003estate == MDIOBUS_REGISTERED)\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:93:\t\tmdiobus_unregister(mdio_bus);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-94-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:95:\tmdiobus_free(mdio_bus);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-96-}\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c=98=int xge_mdio_config(struct net_device *ndev)\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-101-\tstruct device *dev = \u0026pdata-\u003epdev-\u003edev;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:102:\tstruct mii_bus *mdio_bus;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-103-\tstruct phy_device *phydev;\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-105-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:106:\tmdio_bus = mdiobus_alloc();\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:107:\tif (!mdio_bus)\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-108-\t\treturn -ENOMEM;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-109-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:110:\tmdio_bus-\u003ename = \"APM X-Gene Ethernet (v2) MDIO Bus\";\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:111:\tmdio_bus-\u003eread = xge_mdio_read;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:112:\tmdio_bus-\u003ewrite = xge_mdio_write;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:113:\tmdio_bus-\u003epriv = pdata;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:114:\tmdio_bus-\u003eparent = dev;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:115:\tsnprintf(mdio_bus-\u003eid, MII_BUS_ID_SIZE, \"%s-mii\", dev_name(dev));\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:116:\tpdata-\u003emdio_bus = mdio_bus;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-117-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:118:\tmdio_bus-\u003ephy_mask = 0x1;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:119:\tret = mdiobus_register(mdio_bus);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-120-\tif (ret)\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-122-\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:123:\tphydev = phy_find_first(mdio_bus);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-124-\tif (!phydev) {\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c=939=int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-941-\tstruct net_device *ndev = pdata-\u003endev;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:942:\tstruct mii_bus *mdio_bus;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-943-\tint ret;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-944-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:945:\tmdio_bus = mdiobus_alloc();\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:946:\tif (!mdio_bus)\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-947-\t\treturn -ENOMEM;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-948-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:949:\tmdio_bus-\u003ename = \"APM X-Gene MDIO bus\";\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:950:\tmdio_bus-\u003eread = xgene_mdio_rgmii_read;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:951:\tmdio_bus-\u003ewrite = xgene_mdio_rgmii_write;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:952:\tsnprintf(mdio_bus-\u003eid, MII_BUS_ID_SIZE, \"%s-%s\", \"xgene-mii\",\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-953-\t\t ndev-\u003ename);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-954-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:955:\tmdio_bus-\u003epriv = (void __force *)pdata-\u003emcx_mac_addr;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:956:\tmdio_bus-\u003eparent = \u0026pdata-\u003epdev-\u003edev;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-957-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:958:\tret = xgene_mdiobus_register(pdata, mdio_bus);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-959-\tif (ret) {\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-960-\t\tnetdev_err(ndev, \"Failed to register MDIO bus\\n\");\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:961:\t\tmdiobus_free(mdio_bus);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-962-\t\treturn ret;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-963-\t}\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:964:\tpdata-\u003emdio_bus = mdio_bus;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-965-\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c=981=void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-987-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:988:\tmdiobus_unregister(pdata-\u003emdio_bus);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:989:\tmdiobus_free(pdata-\u003emdio_bus);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:990:\tpdata-\u003emdio_bus = NULL;\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-991-}\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_main.h=184=struct xgene_enet_pdata {\ndrivers/net/ethernet/apm/xgene/xgene_enet_main.h-185-\tstruct net_device *ndev;\ndrivers/net/ethernet/apm/xgene/xgene_enet_main.h:186:\tstruct mii_bus *mdio_bus;\ndrivers/net/ethernet/apm/xgene/xgene_enet_main.h-187-\tint phy_speed;\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-11-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:12:bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw)\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-13-{\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-16-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:17:\terr = readx_poll_timeout_atomic(hw_atl_mdio_busy_get, aq_hw,\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-18-\t\t\t\t\tval, val == 0U, 10U, 100000U);\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c=26=u16 aq_mdio_read_word(struct aq_hw_s *aq_hw, u16 mmd, u16 addr)\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-38-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:39:\taq_mdio_busy_wait(aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-40-\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-46-\t/* Read result. */\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:47:\taq_mdio_busy_wait(aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-48-\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c=52=void aq_mdio_write_word(struct aq_hw_s *aq_hw, u16 mmd, u16 addr, u16 data)\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-64-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:65:\taq_mdio_busy_wait(aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-66-\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-74-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c:75:\taq_mdio_busy_wait(aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.c-76-}\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.h-19-\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.h:20:bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/aq_phy.h-21-\n--\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c=1886=u32 hw_atl_glb_mdio_iface5_get(struct aq_hw_s *aq_hw)\n--\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c-1890-\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c:1891:u32 hw_atl_mdio_busy_get(struct aq_hw_s *aq_hw)\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c-1892-{\n--\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h=871=u32 hw_atl_glb_mdio_iface5_get(struct aq_hw_s *hw);\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h-872-\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h:873:u32 hw_atl_mdio_busy_get(struct aq_hw_s *aq_hw);\ndrivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h-874-\n--\ndrivers/net/ethernet/arc/emac.h=100=struct buffer_state {\n--\ndrivers/net/ethernet/arc/emac.h-105-\n\n"
} |
| 11/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 27019 output: 46 thoughts: 60 Thoughts: **Investigating Marvell Alaska PHY Usage in the Kernel** Okay, time to dig in. I need to understand which devices are leveraging Marvell Alaska PHYs. My immediate thought is to look for those specific PHY IDs within the kernel source code. Specifically, I'll search for `MARVELL_PHY_ID_88E1318S` and `MARVELL_PHY_ID_88E1510`. That should give me a good starting point to identify the relevant drivers and the systems where these PHYs are being deployed. |
| 12/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "MARVELL_PHY_ID_88E1318S|MARVELL_PHY_ID_88E1510"
}Results: {
"Output": "drivers/net/phy/marvell.c=845=static void marvell_config_led(struct phy_device *phydev)\n--\ndrivers/net/phy/marvell.c-852-\tcase MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):\ndrivers/net/phy/marvell.c:853:\tcase MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):\ndrivers/net/phy/marvell.c-854-\t\tdef_config = MII_88E1121_PHY_LED_DEF;\n--\ndrivers/net/phy/marvell.c-860-\t */\ndrivers/net/phy/marvell.c:861:\tcase MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):\ndrivers/net/phy/marvell.c-862-\t\tif (phydev-\u003edev_flags \u0026 MARVELL_PHY_LED0_LINK_LED1_ACTIVE)\n--\ndrivers/net/phy/marvell.c=3797=static struct phy_driver marvell_drivers[] = {\n--\ndrivers/net/phy/marvell.c-3941-\t{\ndrivers/net/phy/marvell.c:3942:\t\t.phy_id = MARVELL_PHY_ID_88E1318S,\ndrivers/net/phy/marvell.c-3943-\t\t.phy_id_mask = MARVELL_PHY_ID_MASK,\n--\ndrivers/net/phy/marvell.c-4048-\t{\ndrivers/net/phy/marvell.c:4049:\t\t.phy_id = MARVELL_PHY_ID_88E1510,\ndrivers/net/phy/marvell.c-4050-\t\t.phy_id_mask = MARVELL_PHY_ID_MASK,\n--\ndrivers/net/phy/marvell.c=4310=static const struct mdio_device_id __maybe_unused marvell_tbl[] = {\n--\ndrivers/net/phy/marvell.c-4320-\t{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },\ndrivers/net/phy/marvell.c:4321:\t{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },\ndrivers/net/phy/marvell.c-4322-\t{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },\ndrivers/net/phy/marvell.c:4323:\t{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },\ndrivers/net/phy/marvell.c-4324-\t{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },\n--\ninclude/linux/marvell_phy.h-17-#define MARVELL_PHY_ID_88E1240\t\t0x01410e30\ninclude/linux/marvell_phy.h:18:#define MARVELL_PHY_ID_88E1318S\t\t0x01410e90\ninclude/linux/marvell_phy.h-19-#define MARVELL_PHY_ID_88E1340S\t\t0x01410dc0\ninclude/linux/marvell_phy.h-20-#define MARVELL_PHY_ID_88E1116R\t\t0x01410e40\ninclude/linux/marvell_phy.h:21:#define MARVELL_PHY_ID_88E1510\t\t0x01410dd0\ninclude/linux/marvell_phy.h-22-#define MARVELL_PHY_ID_88E1540\t\t0x01410eb0\n"
} |
| 13/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 28266 output: 27 thoughts: 288 Thoughts: **My Current Investigative Path** Okay, so I'm trying to track down how these specific Marvell PHY IDs, `MARVELL_PHY_ID_88E1318S` and `MARVELL_PHY_ID_88E1510`, are handled within the system. My first thought is to just search directly for driver matches or devices registered with those IDs. But, I need to understand the mechanism. Wait, right, how are these PHYs actually discovered on the MDIO bus? I need to refresh my memory on that. *Ah yes*, when an MDIO bus is initially registered using `mdiobus_register`, it iterates through all possible PHY addresses (0-31), attempting to read the `MII_PHYSID1` and `MII_PHYSID2` registers. From this it gets the `phy_id`, a 32-bit identifier. Then the `phy_device_create` function is used, and `phy_device_register` adds the device to the `mdio_bus_type`. Finally, the kernel matches the discovered device against available `phy_driver` instances in the bus, and then calls the `probe` function. Now the real question: can I create an MDIO bus or PHY devices from userspace, or even through syzkaller? That would be incredibly useful for testing. I need to figure out if it's possible to create and emulate an MDIO bus from userspace. Specifically, I wonder if there's any way to do it via USB. Perhaps through a raw-gadget, dummy_hcd, usbnet, or asix driver scenario, any of those USB Ethernet adapters which may have an associated MDIO bus or use a Marvell PHY. I will need to look into this more deeply. |
| 14/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "mdio",
"PathPrefix": "drivers/net/usb"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1105 lines.\nUse more precise expression if possible.\n\ndrivers/net/usb/aqc111.c=266=static int aqc111_get_link_ksettings(struct net_device *net,\n--\ndrivers/net/usb/aqc111.c-290-\ndrivers/net/usb/aqc111.c:291:\telk-\u003ebase.mdio_support = 0x00; /*Not supported*/\ndrivers/net/usb/aqc111.c-292-\n--\ndrivers/net/usb/asix.h=178=struct asix_common_private {\n--\ndrivers/net/usb/asix.h-184-\tstruct asix_rx_fixup_info rx_fixup_info;\ndrivers/net/usb/asix.h:185:\tstruct mii_bus *mdio;\ndrivers/net/usb/asix.h-186-\tstruct phy_device *phydev;\n--\ndrivers/net/usb/asix.h=229=void asix_set_multicast(struct net_device *net);\ndrivers/net/usb/asix.h-230-\ndrivers/net/usb/asix.h:231:int asix_mdio_read(struct net_device *netdev, int phy_id, int loc);\ndrivers/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);\ndrivers/net/usb/asix.h-236-\ndrivers/net/usb/asix.h:237:int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc);\ndrivers/net/usb/asix.h:238:void asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc,\ndrivers/net/usb/asix.h-239-\t\t\t int val);\n--\ndrivers/net/usb/asix_common.c=441=void asix_set_multicast(struct net_device *net)\n--\ndrivers/net/usb/asix_common.c-479-\ndrivers/net/usb/asix_common.c:480:static int __asix_mdio_read(struct net_device *netdev, int phy_id, int loc,\ndrivers/net/usb/asix_common.c-481-\t\t\t bool in_pm)\n--\ndrivers/net/usb/asix_common.c-503-\ndrivers/net/usb/asix_common.c:504:\tnetdev_dbg(dev-\u003enet, \"asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\\n\",\ndrivers/net/usb/asix_common.c-505-\t\t\tphy_id, loc, le16_to_cpu(res));\n--\ndrivers/net/usb/asix_common.c-509-\ndrivers/net/usb/asix_common.c:510:int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)\ndrivers/net/usb/asix_common.c-511-{\ndrivers/net/usb/asix_common.c:512:\treturn __asix_mdio_read(netdev, phy_id, loc, false);\ndrivers/net/usb/asix_common.c-513-}\ndrivers/net/usb/asix_common.c-514-\ndrivers/net/usb/asix_common.c:515:static int __asix_mdio_write(struct net_device *netdev, int phy_id, int loc,\ndrivers/net/usb/asix_common.c-516-\t\t\t int val, bool in_pm)\n--\ndrivers/net/usb/asix_common.c-521-\ndrivers/net/usb/asix_common.c:522:\tnetdev_dbg(dev-\u003enet, \"asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\\n\",\ndrivers/net/usb/asix_common.c-523-\t\t\tphy_id, loc, val);\n--\ndrivers/net/usb/asix_common.c-542-\ndrivers/net/usb/asix_common.c:543:void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)\ndrivers/net/usb/asix_common.c-544-{\ndrivers/net/usb/asix_common.c:545:\t__asix_mdio_write(netdev, phy_id, loc, val, false);\ndrivers/net/usb/asix_common.c-546-}\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_common.c-552-\ndrivers/net/usb/asix_common.c:553:\treturn __asix_mdio_read(priv-\u003enet, phy_id, regnum, false);\ndrivers/net/usb/asix_common.c-554-}\ndrivers/net/usb/asix_common.c-555-\ndrivers/net/usb/asix_common.c:556:int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)\ndrivers/net/usb/asix_common.c-557-{\n--\ndrivers/net/usb/asix_common.c-559-\ndrivers/net/usb/asix_common.c:560:\treturn __asix_mdio_write(priv-\u003enet, phy_id, regnum, val, false);\ndrivers/net/usb/asix_common.c-561-}\ndrivers/net/usb/asix_common.c-562-\ndrivers/net/usb/asix_common.c:563:int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc)\ndrivers/net/usb/asix_common.c-564-{\ndrivers/net/usb/asix_common.c:565:\treturn __asix_mdio_read(netdev, phy_id, loc, true);\ndrivers/net/usb/asix_common.c-566-}\n--\ndrivers/net/usb/asix_common.c=568=void\ndrivers/net/usb/asix_common.c:569:asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val)\ndrivers/net/usb/asix_common.c-570-{\ndrivers/net/usb/asix_common.c:571:\t__asix_mdio_write(netdev, phy_id, loc, val, true);\ndrivers/net/usb/asix_common.c-572-}\n--\ndrivers/net/usb/asix_devices.c=70=static u32 asix_get_phyid(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-77-\tfor (i = 0; i \u003c 100; i++) {\ndrivers/net/usb/asix_devices.c:78:\t\tphy_reg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id, MII_PHYSID1);\ndrivers/net/usb/asix_devices.c-79-\t\tif (phy_reg \u003c 0)\n--\ndrivers/net/usb/asix_devices.c-90-\ndrivers/net/usb/asix_devices.c:91:\tphy_reg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id, MII_PHYSID2);\ndrivers/net/usb/asix_devices.c-92-\tif (phy_reg \u003c 0)\n--\ndrivers/net/usb/asix_devices.c=190=static void asix_phy_reset(struct usbnet *dev, unsigned int reset_bits)\n--\ndrivers/net/usb/asix_devices.c-193-\ndrivers/net/usb/asix_devices.c:194:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_BMCR, reset_bits);\ndrivers/net/usb/asix_devices.c-195-\n--\ndrivers/net/usb/asix_devices.c-200-\twhile (timeout--) {\ndrivers/net/usb/asix_devices.c:201:\t\tif (asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id, MII_BMCR)\ndrivers/net/usb/asix_devices.c-202-\t\t\t\t\t\t\t\u0026 BMCR_RESET)\n--\ndrivers/net/usb/asix_devices.c=212=static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/asix_devices.c-248-\tdev-\u003emii.dev = dev-\u003enet;\ndrivers/net/usb/asix_devices.c:249:\tdev-\u003emii.mdio_read = asix_mdio_read;\ndrivers/net/usb/asix_devices.c:250:\tdev-\u003emii.mdio_write = asix_mdio_write;\ndrivers/net/usb/asix_devices.c-251-\tdev-\u003emii.phy_id_mask = 0x3f;\n--\ndrivers/net/usb/asix_devices.c-263-\tasix_phy_reset(dev, BMCR_RESET);\ndrivers/net/usb/asix_devices.c:264:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_ADVERTISE,\ndrivers/net/usb/asix_devices.c-265-\t\tADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);\n--\ndrivers/net/usb/asix_devices.c=362=static int ax88772_hw_reset(struct usbnet *dev, int in_pm)\n--\ndrivers/net/usb/asix_devices.c-406-\ndrivers/net/usb/asix_devices.c:407:\tif (in_pm \u0026\u0026 (!asix_mdio_read_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-408-\t\t\t\t\t MII_PHYSID1))){\n--\ndrivers/net/usb/asix_devices.c=456=static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)\n--\ndrivers/net/usb/asix_devices.c-496-\ndrivers/net/usb/asix_devices.c:497:\tif (in_pm \u0026\u0026 (!asix_mdio_read_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-498-\t\t\t\t\t MII_PHYSID1))) {\n--\ndrivers/net/usb/asix_devices.c-512-\t\t/* Check if the PHY registers have default settings */\ndrivers/net/usb/asix_devices.c:513:\t\tphy14h = asix_mdio_read_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-514-\t\t\t\t\t AX88772A_PHY14H);\ndrivers/net/usb/asix_devices.c:515:\t\tphy15h = asix_mdio_read_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-516-\t\t\t\t\t AX88772A_PHY15H);\ndrivers/net/usb/asix_devices.c:517:\t\tphy16h = asix_mdio_read_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-518-\t\t\t\t\t AX88772A_PHY16H);\n--\ndrivers/net/usb/asix_devices.c-525-\t\tif (phy14h != AX88772A_PHY14H_DEFAULT)\ndrivers/net/usb/asix_devices.c:526:\t\t\tasix_mdio_write_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-527-\t\t\t\t\t AX88772A_PHY14H,\n--\ndrivers/net/usb/asix_devices.c-529-\t\tif (phy15h != AX88772A_PHY15H_DEFAULT)\ndrivers/net/usb/asix_devices.c:530:\t\t\tasix_mdio_write_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-531-\t\t\t\t\t AX88772A_PHY15H,\n--\ndrivers/net/usb/asix_devices.c-533-\t\tif (phy16h != AX88772A_PHY16H_DEFAULT)\ndrivers/net/usb/asix_devices.c:534:\t\t\tasix_mdio_write_nopm(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-535-\t\t\t\t\t AX88772A_PHY16H,\n--\ndrivers/net/usb/asix_devices.c=658=static int asix_resume(struct usb_interface *intf)\n--\ndrivers/net/usb/asix_devices.c-668-\ndrivers/net/usb/asix_devices.c:669:static int ax88772_init_mdio(struct usbnet *dev)\ndrivers/net/usb/asix_devices.c-670-{\n--\ndrivers/net/usb/asix_devices.c-673-\ndrivers/net/usb/asix_devices.c:674:\tpriv-\u003emdio = mdiobus_alloc();\ndrivers/net/usb/asix_devices.c:675:\tif (!priv-\u003emdio)\ndrivers/net/usb/asix_devices.c-676-\t\treturn -ENOMEM;\ndrivers/net/usb/asix_devices.c-677-\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;\ndrivers/net/usb/asix_devices.c:681:\tpriv-\u003emdio-\u003ename = \"Asix MDIO Bus\";\ndrivers/net/usb/asix_devices.c:682:\tpriv-\u003emdio-\u003ephy_mask = ~(BIT(priv-\u003ephy_addr \u0026 0x1f) | BIT(AX_EMBD_PHY_ADDR));\ndrivers/net/usb/asix_devices.c-683-\t/* mii bus name is usb-\u003cusb bus number\u003e-\u003cusb device number\u003e */\ndrivers/net/usb/asix_devices.c:684:\tsnprintf(priv-\u003emdio-\u003eid, MII_BUS_ID_SIZE, \"usb-%03d:%03d\",\ndrivers/net/usb/asix_devices.c-685-\t\t dev-\u003eudev-\u003ebus-\u003ebusnum, dev-\u003eudev-\u003edevnum);\ndrivers/net/usb/asix_devices.c-686-\ndrivers/net/usb/asix_devices.c:687:\tret = mdiobus_register(priv-\u003emdio);\ndrivers/net/usb/asix_devices.c-688-\tif (ret) {\ndrivers/net/usb/asix_devices.c-689-\t\tnetdev_err(dev-\u003enet, \"Could not register MDIO bus (err %d)\\n\", ret);\ndrivers/net/usb/asix_devices.c:690:\t\tmdiobus_free(priv-\u003emdio);\ndrivers/net/usb/asix_devices.c:691:\t\tpriv-\u003emdio = NULL;\ndrivers/net/usb/asix_devices.c-692-\t}\n--\ndrivers/net/usb/asix_devices.c-696-\ndrivers/net/usb/asix_devices.c:697:static void ax88772_mdio_unregister(struct asix_common_private *priv)\ndrivers/net/usb/asix_devices.c-698-{\ndrivers/net/usb/asix_devices.c:699:\tmdiobus_unregister(priv-\u003emdio);\ndrivers/net/usb/asix_devices.c:700:\tmdiobus_free(priv-\u003emdio);\ndrivers/net/usb/asix_devices.c-701-}\n--\ndrivers/net/usb/asix_devices.c=703=static int ax88772_init_phy(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-707-\ndrivers/net/usb/asix_devices.c:708:\tpriv-\u003ephydev = mdiobus_get_phy(priv-\u003emdio, priv-\u003ephy_addr);\ndrivers/net/usb/asix_devices.c-709-\tif (!priv-\u003ephydev) {\n--\ndrivers/net/usb/asix_devices.c-731-\t */\ndrivers/net/usb/asix_devices.c:732:\tpriv-\u003ephydev_int = mdiobus_get_phy(priv-\u003emdio, AX_EMBD_PHY_ADDR);\ndrivers/net/usb/asix_devices.c-733-\tif (!priv-\u003ephydev_int) {\n--\ndrivers/net/usb/asix_devices.c=829=static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/asix_devices.c-916-\ndrivers/net/usb/asix_devices.c:917:\tret = ax88772_init_mdio(dev);\ndrivers/net/usb/asix_devices.c-918-\tif (ret)\ndrivers/net/usb/asix_devices.c:919:\t\tgoto mdio_err;\ndrivers/net/usb/asix_devices.c-920-\n--\ndrivers/net/usb/asix_devices.c-940-phylink_err:\ndrivers/net/usb/asix_devices.c:941:\tax88772_mdio_unregister(priv);\ndrivers/net/usb/asix_devices.c:942:mdio_err:\ndrivers/net/usb/asix_devices.c-943-\treturn ret;\n--\ndrivers/net/usb/asix_devices.c=955=static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/asix_devices.c-962-\tphylink_destroy(priv-\u003ephylink);\ndrivers/net/usb/asix_devices.c:963:\tax88772_mdio_unregister(priv);\ndrivers/net/usb/asix_devices.c-964-\tasix_rx_fixup_common_free(dev-\u003edriver_priv);\n--\ndrivers/net/usb/asix_devices.c=990=static int marvell_phy_init(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-996-\ndrivers/net/usb/asix_devices.c:997:\treg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id, MII_MARVELL_STATUS);\ndrivers/net/usb/asix_devices.c-998-\tnetdev_dbg(dev-\u003enet, \"MII_MARVELL_STATUS = 0x%04x\\n\", reg);\ndrivers/net/usb/asix_devices.c-999-\ndrivers/net/usb/asix_devices.c:1000:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_MARVELL_CTRL,\ndrivers/net/usb/asix_devices.c-1001-\t\t\tMARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);\n--\ndrivers/net/usb/asix_devices.c-1003-\tif (data-\u003eledmode) {\ndrivers/net/usb/asix_devices.c:1004:\t\treg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-1005-\t\t\tMII_MARVELL_LED_CTRL);\n--\ndrivers/net/usb/asix_devices.c-1009-\t\treg |= (1 + 0x0100);\ndrivers/net/usb/asix_devices.c:1010:\t\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-1011-\t\t\tMII_MARVELL_LED_CTRL, reg);\ndrivers/net/usb/asix_devices.c-1012-\ndrivers/net/usb/asix_devices.c:1013:\t\treg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id,\ndrivers/net/usb/asix_devices.c-1014-\t\t\tMII_MARVELL_LED_CTRL);\n--\ndrivers/net/usb/asix_devices.c=1021=static int rtl8211cl_phy_init(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-1026-\ndrivers/net/usb/asix_devices.c:1027:\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x1f, 0x0005);\ndrivers/net/usb/asix_devices.c:1028:\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x0c, 0);\ndrivers/net/usb/asix_devices.c:1029:\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x01,\ndrivers/net/usb/asix_devices.c:1030:\t\tasix_mdio_read (dev-\u003enet, dev-\u003emii.phy_id, 0x01) | 0x0080);\ndrivers/net/usb/asix_devices.c:1031:\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x1f, 0);\ndrivers/net/usb/asix_devices.c-1032-\ndrivers/net/usb/asix_devices.c-1033-\tif (data-\u003eledmode == 12) {\ndrivers/net/usb/asix_devices.c:1034:\t\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x1f, 0x0002);\ndrivers/net/usb/asix_devices.c:1035:\t\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x1a, 0x00cb);\ndrivers/net/usb/asix_devices.c:1036:\t\tasix_mdio_write (dev-\u003enet, dev-\u003emii.phy_id, 0x1f, 0);\ndrivers/net/usb/asix_devices.c-1037-\t}\n--\ndrivers/net/usb/asix_devices.c=1042=static int marvell_led_status(struct usbnet *dev, u16 speed)\ndrivers/net/usb/asix_devices.c-1043-{\ndrivers/net/usb/asix_devices.c:1044:\tu16 reg = asix_mdio_read(dev-\u003enet, dev-\u003emii.phy_id, MARVELL_LED_MANUAL);\ndrivers/net/usb/asix_devices.c-1045-\n--\ndrivers/net/usb/asix_devices.c-1062-\tnetdev_dbg(dev-\u003enet, \"marvell_led_status() writing 0x%04x\\n\", reg);\ndrivers/net/usb/asix_devices.c:1063:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MARVELL_LED_MANUAL, reg);\ndrivers/net/usb/asix_devices.c-1064-\n--\ndrivers/net/usb/asix_devices.c=1068=static int ax88178_reset(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-1141-\tasix_phy_reset(dev, BMCR_RESET | BMCR_ANENABLE);\ndrivers/net/usb/asix_devices.c:1142:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_ADVERTISE,\ndrivers/net/usb/asix_devices.c-1143-\t\t\tADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);\ndrivers/net/usb/asix_devices.c:1144:\tasix_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_CTRL1000,\ndrivers/net/usb/asix_devices.c-1145-\t\t\tADVERTISE_1000FULL);\n--\ndrivers/net/usb/asix_devices.c=1271=static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/asix_devices.c-1290-\tdev-\u003emii.dev = dev-\u003enet;\ndrivers/net/usb/asix_devices.c:1291:\tdev-\u003emii.mdio_read = asix_mdio_read;\ndrivers/net/usb/asix_devices.c:1292:\tdev-\u003emii.mdio_write = asix_mdio_write;\ndrivers/net/usb/asix_devices.c-1293-\tdev-\u003emii.phy_id_mask = 0x1f;\n--\ndrivers/net/usb/ax88172a.c=18=struct ax88172a_private {\ndrivers/net/usb/ax88172a.c:19:\tstruct mii_bus *mdio;\ndrivers/net/usb/ax88172a.c-20-\tstruct phy_device *phydev;\n--\ndrivers/net/usb/ax88172a.c=55=static void ax88172a_status(struct usbnet *dev, struct urb *urb)\n--\ndrivers/net/usb/ax88172a.c-60-/* use phylib infrastructure */\ndrivers/net/usb/ax88172a.c:61:static int ax88172a_init_mdio(struct usbnet *dev)\ndrivers/net/usb/ax88172a.c-62-{\n--\ndrivers/net/usb/ax88172a.c-65-\ndrivers/net/usb/ax88172a.c:66:\tpriv-\u003emdio = mdiobus_alloc();\ndrivers/net/usb/ax88172a.c:67:\tif (!priv-\u003emdio) {\ndrivers/net/usb/ax88172a.c-68-\t\tnetdev_err(dev-\u003enet, \"Could not allocate MDIO bus\\n\");\n--\ndrivers/net/usb/ax88172a.c-71-\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;\ndrivers/net/usb/ax88172a.c:75:\tpriv-\u003emdio-\u003ename = \"Asix MDIO Bus\";\ndrivers/net/usb/ax88172a.c-76-\t/* mii bus name is usb-\u003cusb bus number\u003e-\u003cusb device number\u003e */\ndrivers/net/usb/ax88172a.c:77:\tsnprintf(priv-\u003emdio-\u003eid, MII_BUS_ID_SIZE, \"usb-%03d:%03d\",\ndrivers/net/usb/ax88172a.c-78-\t\t dev-\u003eudev-\u003ebus-\u003ebusnum, dev-\u003eudev-\u003edevnum);\ndrivers/net/usb/ax88172a.c-79-\ndrivers/net/usb/ax88172a.c:80:\tret = mdiobus_register(priv-\u003emdio);\ndrivers/net/usb/ax88172a.c-81-\tif (ret) {\n--\ndrivers/net/usb/ax88172a.c-85-\ndrivers/net/usb/ax88172a.c:86:\tnetdev_info(dev-\u003enet, \"registered mdio bus %s\\n\", priv-\u003emdio-\u003eid);\ndrivers/net/usb/ax88172a.c-87-\treturn 0;\n--\ndrivers/net/usb/ax88172a.c-89-mfree:\ndrivers/net/usb/ax88172a.c:90:\tmdiobus_free(priv-\u003emdio);\ndrivers/net/usb/ax88172a.c-91-\treturn ret;\n--\ndrivers/net/usb/ax88172a.c-93-\ndrivers/net/usb/ax88172a.c:94:static void ax88172a_remove_mdio(struct usbnet *dev)\ndrivers/net/usb/ax88172a.c-95-{\n--\ndrivers/net/usb/ax88172a.c-97-\ndrivers/net/usb/ax88172a.c:98:\tnetdev_info(dev-\u003enet, \"deregistering mdio bus %s\\n\", priv-\u003emdio-\u003eid);\ndrivers/net/usb/ax88172a.c:99:\tmdiobus_unregister(priv-\u003emdio);\ndrivers/net/usb/ax88172a.c:100:\tmdiobus_free(priv-\u003emdio);\ndrivers/net/usb/ax88172a.c-101-}\n--\ndrivers/net/usb/ax88172a.c=158=static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/ax88172a.c-225-\t/* init MDIO bus */\ndrivers/net/usb/ax88172a.c:226:\tret = ax88172a_init_mdio(dev);\ndrivers/net/usb/ax88172a.c-227-\tif (ret)\n--\ndrivers/net/usb/ax88172a.c=253=static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/ax88172a.c-256-\ndrivers/net/usb/ax88172a.c:257:\tax88172a_remove_mdio(dev);\ndrivers/net/usb/ax88172a.c-258-\tkfree(priv);\n--\ndrivers/net/usb/ax88172a.c=261=static int ax88172a_reset(struct usbnet *dev)\n--\ndrivers/net/usb/ax88172a.c-311-\tsnprintf(priv-\u003ephy_name, sizeof(priv-\u003ephy_name), PHY_ID_FMT,\ndrivers/net/usb/ax88172a.c:312:\t\t priv-\u003emdio-\u003eid, priv-\u003ephy_addr);\ndrivers/net/usb/ax88172a.c-313-\n--\ndrivers/net/usb/ax88179_178a.c-13-#include \u003clinux/usb/usbnet.h\u003e\ndrivers/net/usb/ax88179_178a.c:14:#include \u003cuapi/linux/mdio.h\u003e\ndrivers/net/usb/ax88179_178a.c:15:#include \u003clinux/mdio.h\u003e\ndrivers/net/usb/ax88179_178a.c-16-\n--\ndrivers/net/usb/ax88179_178a.c=314=static void ax88179_status(struct usbnet *dev, struct urb *urb)\n--\ndrivers/net/usb/ax88179_178a.c-333-\ndrivers/net/usb/ax88179_178a.c:334:static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc)\ndrivers/net/usb/ax88179_178a.c-335-{\n--\ndrivers/net/usb/ax88179_178a.c-342-\ndrivers/net/usb/ax88179_178a.c:343:static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,\ndrivers/net/usb/ax88179_178a.c-344-\t\t\t int val)\n--\ndrivers/net/usb/ax88179_178a.c=1281=static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/ax88179_178a.c-1302-\tdev-\u003emii.dev = dev-\u003enet;\ndrivers/net/usb/ax88179_178a.c:1303:\tdev-\u003emii.mdio_read = ax88179_mdio_read;\ndrivers/net/usb/ax88179_178a.c:1304:\tdev-\u003emii.mdio_write = ax88179_mdio_write;\ndrivers/net/usb/ax88179_178a.c-1305-\tdev-\u003emii.phy_id_mask = 0xff;\n--\ndrivers/net/usb/ch9200.c=137=static int control_write(struct usbnet *dev, unsigned char request,\n--\ndrivers/net/usb/ch9200.c-176-\ndrivers/net/usb/ch9200.c:177:static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)\ndrivers/net/usb/ch9200.c-178-{\n--\ndrivers/net/usb/ch9200.c-196-\ndrivers/net/usb/ch9200.c:197:static void ch9200_mdio_write(struct net_device *netdev,\ndrivers/net/usb/ch9200.c-198-\t\t\t int phy_id, int loc, int val)\n--\ndrivers/net/usb/ch9200.c=338=static int ch9200_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/ch9200.c-348-\tdev-\u003emii.dev = dev-\u003enet;\ndrivers/net/usb/ch9200.c:349:\tdev-\u003emii.mdio_read = ch9200_mdio_read;\ndrivers/net/usb/ch9200.c:350:\tdev-\u003emii.mdio_write = ch9200_mdio_write;\ndrivers/net/usb/ch9200.c-351-\tdev-\u003emii.reg_num_mask = 0x1f;\n--\ndrivers/net/usb/dm9601.c=201=static int dm9601_get_eeprom(struct net_device *net,\n--\ndrivers/net/usb/dm9601.c-219-\ndrivers/net/usb/dm9601.c:220:static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)\ndrivers/net/usb/dm9601.c-221-{\n--\ndrivers/net/usb/dm9601.c-238-\tnetdev_dbg(dev-\u003enet,\ndrivers/net/usb/dm9601.c:239:\t\t \"dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\\n\",\ndrivers/net/usb/dm9601.c-240-\t\t phy_id, loc, le16_to_cpu(res));\n--\ndrivers/net/usb/dm9601.c-244-\ndrivers/net/usb/dm9601.c:245:static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,\ndrivers/net/usb/dm9601.c-246-\t\t\t int val)\n--\ndrivers/net/usb/dm9601.c-255-\ndrivers/net/usb/dm9601.c:256:\tnetdev_dbg(dev-\u003enet, \"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\\n\",\ndrivers/net/usb/dm9601.c-257-\t\t phy_id, loc, val);\n--\ndrivers/net/usb/dm9601.c=338=static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/dm9601.c-358-\tdev-\u003emii.dev = dev-\u003enet;\ndrivers/net/usb/dm9601.c:359:\tdev-\u003emii.mdio_read = dm9601_mdio_read;\ndrivers/net/usb/dm9601.c:360:\tdev-\u003emii.mdio_write = dm9601_mdio_write;\ndrivers/net/usb/dm9601.c-361-\tdev-\u003emii.phy_id_mask = 0x1f;\n--\ndrivers/net/usb/dm9601.c-411-\ndrivers/net/usb/dm9601.c:412:\tdm9601_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_BMCR, BMCR_RESET);\ndrivers/net/usb/dm9601.c:413:\tdm9601_mdio_write(dev-\u003enet, dev-\u003emii.phy_id, MII_ADVERTISE,\ndrivers/net/usb/dm9601.c-414-\t\t\t ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);\n--\ndrivers/net/usb/lan78xx.c-19-#include \u003clinux/ipv6.h\u003e\ndrivers/net/usb/lan78xx.c:20:#include \u003clinux/mdio.h\u003e\ndrivers/net/usb/lan78xx.c-21-#include \u003clinux/phy.h\u003e\n--\ndrivers/net/usb/lan78xx.c-29-#include \u003clinux/microchipphy.h\u003e\ndrivers/net/usb/lan78xx.c:30:#include \u003clinux/of_mdio.h\u003e\ndrivers/net/usb/lan78xx.c-31-#include \u003clinux/of_net.h\u003e\n--\ndrivers/net/usb/lan78xx.c=413=struct lan78xx_net {\n--\ndrivers/net/usb/lan78xx.c-441-\tstruct mutex\t\tdev_mutex; /* serialise open/stop wrt suspend/resume */\ndrivers/net/usb/lan78xx.c:442:\tstruct mutex\t\tmdiobus_mutex; /* for MDIO bus access */\ndrivers/net/usb/lan78xx.c-443-\tunsigned int\t\tpipe_in, pipe_out, pipe_intr;\n--\ndrivers/net/usb/lan78xx.c-458-\tu32\t\t\tchiprev;\ndrivers/net/usb/lan78xx.c:459:\tstruct mii_bus\t\t*mdiobus;\ndrivers/net/usb/lan78xx.c-460-\tphy_interface_t\t\tinterface;\n--\ndrivers/net/usb/lan78xx.c=946=static int lan78xx_flush_rx_fifo(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-950-\ndrivers/net/usb/lan78xx.c:951:/* Loop until the read is completed with timeout called with mdiobus_mutex held */\ndrivers/net/usb/lan78xx.c:952:static int lan78xx_mdiobus_wait_not_busy(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-953-{\n--\ndrivers/net/usb/lan78xx.c=1582=static int lan78xx_mac_reset(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-1587-\ndrivers/net/usb/lan78xx.c:1588:\tmutex_lock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-1589-\n--\ndrivers/net/usb/lan78xx.c-1593-\t */\ndrivers/net/usb/lan78xx.c:1594:\tret = lan78xx_mdiobus_wait_not_busy(dev);\ndrivers/net/usb/lan78xx.c-1595-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-1622-exit_unlock:\ndrivers/net/usb/lan78xx.c:1623:\tmutex_unlock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-1624-\n--\ndrivers/net/usb/lan78xx.c=1944=static int lan78xx_init_mac_address(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2011-/* MDIO read and write wrappers for phylib */\ndrivers/net/usb/lan78xx.c:2012:static int lan78xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)\ndrivers/net/usb/lan78xx.c-2013-{\n--\ndrivers/net/usb/lan78xx.c-2021-\ndrivers/net/usb/lan78xx.c:2022:\tmutex_lock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-2023-\ndrivers/net/usb/lan78xx.c-2024-\t/* confirm MII not busy */\ndrivers/net/usb/lan78xx.c:2025:\tret = lan78xx_mdiobus_wait_not_busy(dev);\ndrivers/net/usb/lan78xx.c-2026-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-2034-\ndrivers/net/usb/lan78xx.c:2035:\tret = lan78xx_mdiobus_wait_not_busy(dev);\ndrivers/net/usb/lan78xx.c-2036-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-2045-done:\ndrivers/net/usb/lan78xx.c:2046:\tmutex_unlock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-2047-\tusb_autopm_put_interface(dev-\u003eintf);\n--\ndrivers/net/usb/lan78xx.c-2051-\ndrivers/net/usb/lan78xx.c:2052:static int lan78xx_mdiobus_write(struct mii_bus *bus, int phy_id, int idx,\ndrivers/net/usb/lan78xx.c-2053-\t\t\t\t u16 regval)\n--\ndrivers/net/usb/lan78xx.c-2062-\ndrivers/net/usb/lan78xx.c:2063:\tmutex_lock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-2064-\ndrivers/net/usb/lan78xx.c-2065-\t/* confirm MII not busy */\ndrivers/net/usb/lan78xx.c:2066:\tret = lan78xx_mdiobus_wait_not_busy(dev);\ndrivers/net/usb/lan78xx.c-2067-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-2080-\ndrivers/net/usb/lan78xx.c:2081:\tret = lan78xx_mdiobus_wait_not_busy(dev);\ndrivers/net/usb/lan78xx.c-2082-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-2085-done:\ndrivers/net/usb/lan78xx.c:2086:\tmutex_unlock(\u0026dev-\u003emdiobus_mutex);\ndrivers/net/usb/lan78xx.c-2087-\tusb_autopm_put_interface(dev-\u003eintf);\n--\ndrivers/net/usb/lan78xx.c-2090-\ndrivers/net/usb/lan78xx.c:2091:static int lan78xx_mdio_init(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-2092-{\n--\ndrivers/net/usb/lan78xx.c-2095-\ndrivers/net/usb/lan78xx.c:2096:\tdev-\u003emdiobus = mdiobus_alloc();\ndrivers/net/usb/lan78xx.c:2097:\tif (!dev-\u003emdiobus) {\ndrivers/net/usb/lan78xx.c-2098-\t\tnetdev_err(dev-\u003enet, \"can't allocate MDIO bus\\n\");\n--\ndrivers/net/usb/lan78xx.c-2101-\ndrivers/net/usb/lan78xx.c:2102:\tdev-\u003emdiobus-\u003epriv = (void *)dev;\ndrivers/net/usb/lan78xx.c:2103:\tdev-\u003emdiobus-\u003eread = lan78xx_mdiobus_read;\ndrivers/net/usb/lan78xx.c:2104:\tdev-\u003emdiobus-\u003ewrite = lan78xx_mdiobus_write;\ndrivers/net/usb/lan78xx.c:2105:\tdev-\u003emdiobus-\u003ename = \"lan78xx-mdiobus\";\ndrivers/net/usb/lan78xx.c:2106:\tdev-\u003emdiobus-\u003eparent = \u0026dev-\u003eudev-\u003edev;\ndrivers/net/usb/lan78xx.c-2107-\ndrivers/net/usb/lan78xx.c:2108:\tsnprintf(dev-\u003emdiobus-\u003eid, MII_BUS_ID_SIZE, \"usb-%03d:%03d\",\ndrivers/net/usb/lan78xx.c-2109-\t\t dev-\u003eudev-\u003ebus-\u003ebusnum, dev-\u003eudev-\u003edevnum);\n--\ndrivers/net/usb/lan78xx.c-2114-\t\t/* set to internal PHY id */\ndrivers/net/usb/lan78xx.c:2115:\t\tdev-\u003emdiobus-\u003ephy_mask = ~(1 \u003c\u003c 1);\ndrivers/net/usb/lan78xx.c-2116-\t\tbreak;\n--\ndrivers/net/usb/lan78xx.c-2120-\ndrivers/net/usb/lan78xx.c:2121:\tnode = of_get_child_by_name(dev-\u003eudev-\u003edev.of_node, \"mdio\");\n\n"
} |
| 15/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41832 output: 33 thoughts: 141 Thoughts: **MDIO Bus Initialization: A Deep Dive** Okay, so I'm seeing a pattern here. `ax88772_init_mdio`, `ax88172a_init_mdio`, and `lan78xx_mdio_init`—they're all screaming the same thing at me: MDIO bus initialization. I know that when a USB gadget, or even something more sophisticated like syzkaller fuzzing with raw-gadget/dummy_hcd, connects one of these devices (AX88772, AX88172A, or LAN78xx), an MDIO bus is registered using `mdiobus_register`. The real question, of course, is *what* does `mdiobus_register` actually *do*? I need to check the implementation in `drivers/net/phy/mdio_bus.c`. Time to dig into the kernel source and see what's happening under the hood. It's the only way to be sure what's going on and if there's any potential here for... well, anything interesting. |
| 16/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "int __mdiobus_register",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=525=static bool mdiobus_prevent_c45_scan(struct mii_bus *bus)\n--\ndrivers/net/phy/mdio_bus_provider.c-552- */\ndrivers/net/phy/mdio_bus_provider.c:553:int __mdiobus_register(struct mii_bus *bus, struct module *owner)\ndrivers/net/phy/mdio_bus_provider.c-554-{\n"
} |
| 17/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 42386 output: 42 thoughts: 27 Thoughts: Here's a summary of my thought process, as if I were the one thinking it: **Diving into the MDIO Bus Provider Code** Alright, time to dig into this. I'm going to pull up `drivers/net/phy/mdio_bus_provider.c` and zero in on line 553. I'm expecting to find something interesting there related to the overall MDIO bus provider functionality. I'm hoping to get a clearer picture of how it's handling... well, something. Could be a specific PHY register, error handling, bus access logic, or perhaps even an interrupt context consideration. Let's see what line 553 holds. I’ll be looking for clues in the surrounding code as well to build a more complete understanding. |
| 18/2 | 2026/09/13 00:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 550,
"LineCount": 60
}Results: {
"Contents": " 550:\t *\n 551:\t * Returns 0 on success or \u003c 0 on error.\n 552:\t */\n 553:\tint __mdiobus_register(struct mii_bus *bus, struct module *owner)\n 554:\t{\n 555:\t\tstruct mdio_device *mdiodev;\n 556:\t\tstruct gpio_desc *gpiod;\n 557:\t\tbool prevent_c45_scan;\n 558:\t\tint i, err;\n 559:\t\n 560:\t\tif (!bus || !bus-\u003ename)\n 561:\t\t\treturn -EINVAL;\n 562:\t\n 563:\t\t/* An access method always needs both read and write operations */\n 564:\t\tif (!!bus-\u003eread != !!bus-\u003ewrite || !!bus-\u003eread_c45 != !!bus-\u003ewrite_c45)\n 565:\t\t\treturn -EINVAL;\n 566:\t\n 567:\t\t/* At least one method is mandatory */\n 568:\t\tif (!bus-\u003eread \u0026\u0026 !bus-\u003eread_c45)\n 569:\t\t\treturn -EINVAL;\n 570:\t\n 571:\t\tif (bus-\u003eparent \u0026\u0026 bus-\u003eparent-\u003eof_node)\n 572:\t\t\tfwnode_set_flag(\u0026bus-\u003eparent-\u003eof_node-\u003efwnode,\n 573:\t\t\t\t\tFWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD);\n 574:\t\n 575:\t\tWARN(bus-\u003estate != MDIOBUS_ALLOCATED \u0026\u0026\n 576:\t\t bus-\u003estate != MDIOBUS_UNREGISTERED,\n 577:\t\t \"%s: not in ALLOCATED or UNREGISTERED state\\n\", bus-\u003eid);\n 578:\t\n 579:\t\tbus-\u003eowner = owner;\n 580:\t\tbus-\u003edev.parent = bus-\u003eparent;\n 581:\t\tbus-\u003edev.class = \u0026mdio_bus_class;\n 582:\t\tbus-\u003edev.groups = NULL;\n 583:\t\tdev_set_name(\u0026bus-\u003edev, \"%s\", bus-\u003eid);\n 584:\t\n 585:\t\t/* If the bus state is allocated, we're registering a fresh bus\n 586:\t\t * that may have a fwnode associated with it. Grab a reference\n 587:\t\t * to the fwnode. This will be dropped when the bus is released.\n 588:\t\t * If the bus was set to unregistered, it means that the bus was\n 589:\t\t * previously registered, and we've already grabbed a reference.\n 590:\t\t */\n 591:\t\tif (bus-\u003estate == MDIOBUS_ALLOCATED)\n 592:\t\t\tfwnode_handle_get(dev_fwnode(\u0026bus-\u003edev));\n 593:\t\n 594:\t\t/* We need to set state to MDIOBUS_UNREGISTERED to correctly release\n 595:\t\t * the device in mdiobus_free()\n 596:\t\t *\n 597:\t\t * State will be updated later in this function in case of success\n 598:\t\t */\n 599:\t\tbus-\u003estate = MDIOBUS_UNREGISTERED;\n 600:\t\n 601:\t\terr = device_register(\u0026bus-\u003edev);\n 602:\t\tif (err) {\n 603:\t\t\tpr_err(\"mii_bus %s failed to register\\n\", bus-\u003eid);\n 604:\t\t\treturn -EINVAL;\n 605:\t\t}\n 606:\t\n 607:\t\tmutex_init(\u0026bus-\u003emdio_lock);\n 608:\t\tmutex_init(\u0026bus-\u003eshared_lock);\n 609:\t\n"
} |
| 19/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 43588 output: 42 thoughts: 15 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Diving Deeper into `__mdiobus_register`** Alright, so I've just seen a reference to `__mdiobus_register`. My initial thought is, "Let's dig in and understand this more fully." This isn't just a casual glance; I want to see *how* it's implemented. I'm assuming, of course, that this isn't simply a wrapper, but the actual core registration function for an MDIO bus. I’m thinking there is more functionality here, or perhaps it is part of a larger architecture for a specific driver model. My instincts tell me that there's a good chance this is where the low-level interactions with the underlying hardware, or the platform’s MDIO controller, are handled. I need to understand the implications of this registration: what data structures are being populated, what callbacks are being established, and where does it hook into the broader MDIO framework or potentially the device tree integration? I’m preparing to analyze the code for any potential concurrency issues or race conditions that might arise with multiple MDIO buses. Time to roll up my sleeves and get into the nitty gritty. |
| 20/2 | 2026/09/13 00:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 610,
"LineCount": 50
}Results: {
"Contents": " 610:\t\t/* assert bus level PHY GPIO reset */\n 611:\t\tgpiod = devm_gpiod_get_optional(\u0026bus-\u003edev, \"reset\", GPIOD_OUT_HIGH);\n 612:\t\tif (IS_ERR(gpiod)) {\n 613:\t\t\terr = dev_err_probe(\u0026bus-\u003edev, PTR_ERR(gpiod),\n 614:\t\t\t\t\t \"mii_bus %s couldn't get reset GPIO\\n\",\n 615:\t\t\t\t\t bus-\u003eid);\n 616:\t\t\tdevice_del(\u0026bus-\u003edev);\n 617:\t\t\treturn err;\n 618:\t\t} else\tif (gpiod) {\n 619:\t\t\tbus-\u003ereset_gpiod = gpiod;\n 620:\t\t\tfsleep(bus-\u003ereset_delay_us);\n 621:\t\t\tgpiod_set_value_cansleep(gpiod, 0);\n 622:\t\t\tif (bus-\u003ereset_post_delay_us \u003e 0)\n 623:\t\t\t\tfsleep(bus-\u003ereset_post_delay_us);\n 624:\t\t}\n 625:\t\n 626:\t\tif (bus-\u003ereset) {\n 627:\t\t\terr = bus-\u003ereset(bus);\n 628:\t\t\tif (err)\n 629:\t\t\t\tgoto error_reset_gpiod;\n 630:\t\t}\n 631:\t\n 632:\t\tif (bus-\u003eread) {\n 633:\t\t\terr = mdiobus_scan_bus_c22(bus);\n 634:\t\t\tif (err)\n 635:\t\t\t\tgoto error;\n 636:\t\t}\n 637:\t\n 638:\t\tprevent_c45_scan = mdiobus_prevent_c45_scan(bus);\n 639:\t\n 640:\t\tif (!prevent_c45_scan \u0026\u0026 bus-\u003eread_c45) {\n 641:\t\t\terr = mdiobus_scan_bus_c45(bus);\n 642:\t\t\tif (err)\n 643:\t\t\t\tgoto error;\n 644:\t\t}\n 645:\t\n 646:\t\tbus-\u003estate = MDIOBUS_REGISTERED;\n 647:\t\tdev_dbg(\u0026bus-\u003edev, \"probed\\n\");\n 648:\t\treturn 0;\n 649:\t\n 650:\terror:\n 651:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 652:\t\t\tmdiodev = bus-\u003emdio_map[i];\n 653:\t\t\tif (!mdiodev)\n 654:\t\t\t\tcontinue;\n 655:\t\n 656:\t\t\tmdiodev-\u003edevice_remove(mdiodev);\n 657:\t\t\tmdiodev-\u003edevice_free(mdiodev);\n 658:\t\t}\n 659:\terror_reset_gpiod:\n"
} |
| 21/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 44686 output: 43 thoughts: 395 Thoughts: **My Line of Reasoning** Okay, so I'm thinking about how `mdiobus_scan_bus_c22` works. Essentially, it uses `bus->read` to scan addresses on the MDIO bus. In the context of these specific USB ethernet adapters – the ax88772, ax88172a, and lan78xx – that `bus->read` operation translates to sending USB control packets to the device. The interesting part is that when syzkaller, acting as a USB device through raw-gadget/dummy_hcd, gets these control transfers, it's returning the PHY ID it chooses! This got me thinking... If the device returns a specific Marvell PHY ID like `MARVELL_PHY_ID_88E1318S` (0x01410e90) or `MARVELL_PHY_ID_88E1510` (0x01410dd0) when the system reads MII_PHYSID1 and MII_PHYSID2, then the Marvell PHY driver will bind to it. This begs the question: can USB ethernet *actually* emulate a Marvell PHY and trigger the Marvell driver to bind? I'll check the `drivers/net/usb/asix_devices.c` file, specifically around line 990, for any clues. Aha, I see something promising: `static int marvell_phy_init(struct usbnet *dev)`. Wait, it seems the AX88178 *actually* has Marvell PHY support! This is key! I'll look deeper into the file. I see the function `asix_mdio_read` being called to read the Marvell status. Okay, now let's take a step back and check whether AX88772, AX88172A, or LAN78xx actually uses phylib and probes the PHY via phylib. I'll focus on the `ax88172a.c` file specifically now. I'll read through `drivers/net/usb/ax88172a.c` now to determine this. |
| 22/2 | 2026/09/13 00:15 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/ax88172a.c",
"FirstLine": 210,
"LineCount": 50
}Results: {
"Contents": " 210:\t\tret = asix_read_phy_addr(dev, priv-\u003euse_embdphy);\n 211:\t\tif (ret \u003c 0)\n 212:\t\t\tgoto free;\n 213:\t\n 214:\t\tpriv-\u003ephy_addr = ret;\n 215:\t\n 216:\t\tax88172a_reset_phy(dev, priv-\u003euse_embdphy);\n 217:\t\n 218:\t\t/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */\n 219:\t\tif (dev-\u003edriver_info-\u003eflags \u0026 FLAG_FRAMING_AX) {\n 220:\t\t\t/* hard_mtu is still the default - the device does not support\n 221:\t\t\t jumbo eth frames */\n 222:\t\t\tdev-\u003erx_urb_size = 2048;\n 223:\t\t}\n 224:\t\n 225:\t\t/* init MDIO bus */\n 226:\t\tret = ax88172a_init_mdio(dev);\n 227:\t\tif (ret)\n 228:\t\t\tgoto free;\n 229:\t\n 230:\t\treturn 0;\n 231:\t\n 232:\tfree:\n 233:\t\tkfree(priv);\n 234:\t\treturn ret;\n 235:\t}\n 236:\t\n 237:\tstatic int ax88172a_stop(struct usbnet *dev)\n 238:\t{\n 239:\t\tstruct ax88172a_private *priv = dev-\u003edriver_priv;\n 240:\t\n 241:\t\tnetdev_dbg(dev-\u003enet, \"Stopping interface\\n\");\n 242:\t\n 243:\t\tif (priv-\u003ephydev) {\n 244:\t\t\tnetdev_info(dev-\u003enet, \"Disconnecting from phy %s\\n\",\n 245:\t\t\t\t priv-\u003ephy_name);\n 246:\t\t\tphy_stop(priv-\u003ephydev);\n 247:\t\t\tphy_disconnect(priv-\u003ephydev);\n 248:\t\t}\n 249:\t\n 250:\t\treturn 0;\n 251:\t}\n 252:\t\n 253:\tstatic void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)\n 254:\t{\n 255:\t\tstruct ax88172a_private *priv = dev-\u003edriver_priv;\n 256:\t\n 257:\t\tax88172a_remove_mdio(dev);\n 258:\t\tkfree(priv);\n 259:\t}\n"
} |
| 23/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 46320 output: 37 thoughts: 230 Thoughts: **Analyzing the Initialization of the Asix Ethernet Driver's MDIO Bus** Okay, let's dissect this `ax88172a_init_mdio` function. First, I see the typical MDIO bus setup. It's associating the device context (`dev`) with the MDIO structure (`priv->mdio`), assigning the read and write functions (`asix_mdio_bus_read`, `asix_mdio_bus_write`), and giving it a descriptive name. The `snprintf` call constructing the ID is standard, using the USB bus and device numbers – that's clean. Now, the crucial part: `mdiobus_register(priv->mdio)`. That's where the MDIO bus comes alive. I know this registers the bus with the system, and that's usually where the hardware discovery and enumeration kick in. Let's see... Ah, right, that call will lead us straight to `mdiobus_scan_bus_c22(bus)`. Time to dig into that function and understand the specifics of how it actually identifies and configures the PHYs on this bus. That's the heart of the initialization. |
| 24/2 | 2026/09/13 00:15 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_scan_bus_c22",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=477=static struct phy_device *mdiobus_scan_c45(struct mii_bus *bus, int addr)\n--\ndrivers/net/phy/mdio_bus_provider.c-481-\ndrivers/net/phy/mdio_bus_provider.c:482:static int mdiobus_scan_bus_c22(struct mii_bus *bus)\ndrivers/net/phy/mdio_bus_provider.c-483-{\n--\ndrivers/net/phy/mdio_bus_provider.c=553=int __mdiobus_register(struct mii_bus *bus, struct module *owner)\n--\ndrivers/net/phy/mdio_bus_provider.c-632-\tif (bus-\u003eread) {\ndrivers/net/phy/mdio_bus_provider.c:633:\t\terr = mdiobus_scan_bus_c22(bus);\ndrivers/net/phy/mdio_bus_provider.c-634-\t\tif (err)\n"
} |
| 25/2 | 2026/09/13 00:15 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 47119 output: 42 thoughts: 26 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing the MDIO Bus Provider Code** Alright, let's dive in. The task at hand is to understand how this `mdio_bus_provider.c` interacts, and my current focus is on line 482. Given that it's within the `drivers/net/phy/` directory, I'm expecting this section to be involved with the MDIO bus driver, which is responsible for managing the communication to PHYs (Physical Layer Transceivers) via the MDIO interface. Now, let's take a look to see what's happening at that specific line. I am anticipating a function call or a variable assignment, most likely related to either reading/writing to PHY registers or configuring the MDIO bus itself. Hopefully, there is enough context to easily figure out the exact purpose of the line. Let's get to the code. |
| 26/2 | 2026/09/13 00:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 480,
"LineCount": 40
}Results: {
"Contents": " 480:\t}\n 481:\t\n 482:\tstatic int mdiobus_scan_bus_c22(struct mii_bus *bus)\n 483:\t{\n 484:\t\tint i;\n 485:\t\n 486:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 487:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 488:\t\t\t\tstruct phy_device *phydev;\n 489:\t\n 490:\t\t\t\tphydev = mdiobus_scan_c22(bus, i);\n 491:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 492:\t\t\t\t\treturn PTR_ERR(phydev);\n 493:\t\t\t}\n 494:\t\t}\n 495:\t\treturn 0;\n 496:\t}\n 497:\t\n 498:\tstatic int mdiobus_scan_bus_c45(struct mii_bus *bus)\n 499:\t{\n 500:\t\tint i;\n 501:\t\n 502:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 503:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 504:\t\t\t\tstruct phy_device *phydev;\n 505:\t\n 506:\t\t\t\t/* Don't scan C45 if we already have a C22 device */\n 507:\t\t\t\tif (bus-\u003emdio_map[i])\n 508:\t\t\t\t\tcontinue;\n 509:\t\n 510:\t\t\t\tphydev = mdiobus_scan_c45(bus, i);\n 511:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 512:\t\t\t\t\treturn PTR_ERR(phydev);\n 513:\t\t\t}\n 514:\t\t}\n 515:\t\treturn 0;\n 516:\t}\n 517:\t\n 518:\t/* There are some C22 PHYs which do bad things when where is a C45\n 519:\t * transaction on the bus, like accepting a read themselves, and\n"
} |
| 27/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 47995 output: 35 thoughts: 16 Thoughts: Okay, here's my summary, presented as a first-person account, assuming I'm an expert in the field: **Deconstructing `mdiobus_scan_c22`** Alright, let's dive into this `mdiobus_scan_c22` function. My initial thought is to immediately start visualizing the MDIO bus scanning process. I'm expecting this function to be the core of the C22 clause-based PHY address detection on this specific MDIO bus. I'll need to rapidly recall my understanding of the MDIO protocol, particularly the nuances of C22 registers and how they differ from C45. I’m guessing it will involve sending out a series of read and possibly write commands to specific addresses within the MDIO space, checking for valid responses that indicate the presence of PHY devices. I'm probably anticipating things like: iterating through the potential physical addresses, typically starting from 0 and going up to a maximum defined by the specification or the hardware. There will likely be a specific method to determine if a PHY is present. This might involve attempting to read a known register and checking for a valid value, or possibly even looking for a specific ID in a standard register. I'm ready to dig into the function's internal structure; I hope the code is well-commented and easy to navigate. I'll be particularly interested in any error handling and robustness checks, as MDIO buses can be notoriously sensitive to timing and potential hardware glitches. I’ll be comparing it to the equivalent C45 code I know so well. This will be an interesting exercise. |
| 28/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_scan_c22",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=408=static struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr, bool c45)\n--\ndrivers/net/phy/mdio_bus_provider.c-447-/**\ndrivers/net/phy/mdio_bus_provider.c:448: * mdiobus_scan_c22 - scan one address on a bus for C22 MDIO devices.\ndrivers/net/phy/mdio_bus_provider.c-449- * @bus: mii_bus to scan\n--\ndrivers/net/phy/mdio_bus_provider.c-458- */\ndrivers/net/phy/mdio_bus_provider.c:459:struct phy_device *mdiobus_scan_c22(struct mii_bus *bus, int addr)\ndrivers/net/phy/mdio_bus_provider.c-460-{\n--\ndrivers/net/phy/mdio_bus_provider.c-462-}\ndrivers/net/phy/mdio_bus_provider.c:463:EXPORT_SYMBOL(mdiobus_scan_c22);\ndrivers/net/phy/mdio_bus_provider.c-464-\n--\ndrivers/net/phy/mdio_bus_provider.c=482=static int mdiobus_scan_bus_c22(struct mii_bus *bus)\n--\ndrivers/net/phy/mdio_bus_provider.c-489-\ndrivers/net/phy/mdio_bus_provider.c:490:\t\t\tphydev = mdiobus_scan_c22(bus, i);\ndrivers/net/phy/mdio_bus_provider.c-491-\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n"
} |
| 29/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 48858 output: 42 thoughts: 30 Thoughts: Here's my take on the thought process, as requested: **Diving into the MDIO Bus Provider Code** Alright, time to get my hands dirty. I need to understand what's happening with the MDIO bus provider, so I'm going to zero in on lines 408 through 460 in `drivers/net/phy/mdio_bus_provider.c`. This specific section should be key to whatever I'm investigating. I expect it probably has to do with how the driver interacts with the hardware, maybe probing for PHYs, registering them, or dealing with communication errors. Given the function's naming convention, there could be some lower-level details as well. I'll need to pay close attention to the data structures involved, the error handling, and any synchronization mechanisms used. Let's see what gems are hidden in there. |
| 30/2 | 2026/09/13 00:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 408,
"LineCount": 55
}Results: {
"Contents": " 408:\tstatic struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr, bool c45)\n 409:\t{\n 410:\t\tstruct phy_device *phydev = ERR_PTR(-ENODEV);\n 411:\t\tstruct fwnode_handle *fwnode;\n 412:\t\tchar node_name[16];\n 413:\t\tint err;\n 414:\t\n 415:\t\tphydev = get_phy_device(bus, addr, c45);\n 416:\t\tif (IS_ERR(phydev))\n 417:\t\t\treturn phydev;\n 418:\t\n 419:\t#if IS_ENABLED(CONFIG_OF_MDIO)\n 420:\t\t/* For DT, see if the auto-probed phy has a corresponding child\n 421:\t\t * in the bus node, and set the of_node pointer in this case.\n 422:\t\t */\n 423:\t\tof_mdiobus_link_mdiodev(bus, \u0026phydev-\u003emdio);\n 424:\t#endif\n 425:\t\n 426:\t\t/* Search for a swnode for the phy in the swnode hierarchy of the bus.\n 427:\t\t * If there is no swnode for the phy provided, just ignore it.\n 428:\t\t */\n 429:\t\tif (dev_fwnode(\u0026bus-\u003edev) \u0026\u0026 !dev_fwnode(\u0026phydev-\u003emdio.dev)) {\n 430:\t\t\tsnprintf(node_name, sizeof(node_name), \"ethernet-phy@%d\",\n 431:\t\t\t\t addr);\n 432:\t\t\tfwnode = fwnode_get_named_child_node(dev_fwnode(\u0026bus-\u003edev),\n 433:\t\t\t\t\t\t\t node_name);\n 434:\t\t\tif (fwnode)\n 435:\t\t\t\tdevice_set_node(\u0026phydev-\u003emdio.dev, fwnode);\n 436:\t\t}\n 437:\t\n 438:\t\terr = phy_device_register(phydev);\n 439:\t\tif (err) {\n 440:\t\t\tphy_device_free(phydev);\n 441:\t\t\treturn ERR_PTR(-ENODEV);\n 442:\t\t}\n 443:\t\n 444:\t\treturn phydev;\n 445:\t}\n 446:\t\n 447:\t/**\n 448:\t * mdiobus_scan_c22 - scan one address on a bus for C22 MDIO devices.\n 449:\t * @bus: mii_bus to scan\n 450:\t * @addr: address on bus to scan\n 451:\t *\n 452:\t * This function scans one address on the MDIO bus, looking for\n 453:\t * devices which can be identified using a vendor/product ID in\n 454:\t * registers 2 and 3. Not all MDIO devices have such registers, but\n 455:\t * PHY devices typically do. Hence this function assumes anything\n 456:\t * found is a PHY, or can be treated as a PHY. Other MDIO devices,\n 457:\t * such as switches, will probably not be found during the scan.\n 458:\t */\n 459:\tstruct phy_device *mdiobus_scan_c22(struct mii_bus *bus, int addr)\n 460:\t{\n 461:\t\treturn mdiobus_scan(bus, addr, false);\n 462:\t}\n"
} |
| 31/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 50044 output: 29 thoughts: 252 Thoughts: **My Mental Trace Through PHY Device Registration** Okay, so I'm tracing how a PHY device gets set up, right? `get_phy_device` is the starting point – it's reading those MII registers and then calling `phy_device_create`. That makes sense. After that, `phy_device_register` triggers `device_add` on `phydev->mdio.dev`. And that device’s bus is the `mdio_bus_type`. This is key. Now, here's where things get interesting. When `device_add` is invoked, it's matching that `mdio_bus_type` against registered drivers. Bingo! It finds the `marvell_drivers`! That means `marvell_probe` gets called. Perfect, that's the driver I was looking for. But wait, I need to zoom out a bit. I need to make sure I'm not missing anything. Let me think, are we *only* dealing with direct MII/MDIO connections here? Are there PCI ethernet cards or virtual devices that are leveraging PHYs in some indirect way? This needs to be considered. And now that I'm thinking about it, what about QEMU? Are there any PCI network devices that *inside* QEMU that use phylib or mdio? I need to know where these devices originate. Okay, now let's also remember syzkaller. Even without PCI, syzkaller supports USB emulation - the `raw-gadget` and `dummy_hcd` stuff. Ah, yes. I remember! USB devices like the AX88772, AX88172A, or LAN78xx - they register an `mii_bus` and scan it! That's another pathway I need to keep in mind. Finally, I can't forget about the purely software-based devices. What about dummy or mock MDIO buses, or even `netdevsim`? Does `netdevsim` *have* an MDIO bus or PHY emulation? I need to check the `drivers/net/netdevsim/` directory. Gotta make sure I've got the whole picture of potential PHY interactions. |
| 32/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "phy",
"PathPrefix": "drivers/net/netdevsim/"
}Results: {
"Output": "drivers/net/netdevsim/dev.c=1380=static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,\n--\ndrivers/net/netdevsim/dev.c-1399-\t\tattrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;\ndrivers/net/netdevsim/dev.c:1400:\t\tattrs.phys.port_number = port_index + 1;\ndrivers/net/netdevsim/dev.c-1401-\t} else {\n--\ndrivers/net/netdevsim/netdevsim.h=320=struct nsim_dev {\n--\ndrivers/net/netdevsim/netdevsim.h-339-\tstruct mutex progs_list_lock;\ndrivers/net/netdevsim/netdevsim.h:340:\tstruct netdev_phys_item_id switch_id;\ndrivers/net/netdevsim/netdevsim.h-341-\tstruct list_head port_list;\n"
} |
| 33/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 51076 output: 19 thoughts: 80 Thoughts: **Investigating MDIO Bus Instantiation in Netdevsim Context** Okay, so I'm thinking about how Netdevsim handles MDIO interactions, and the first thing that pops into my head is that it *doesn't* seem to leverage phylib. Interesting. That simplifies some aspects, but raises others. Now, I need to figure out how the MDIO bus itself is constructed. Are we looking at `mdio-gpio` or `mdio-bitbang` as potential candidates? My gut tells me `mdio-gpio` might be a good starting point, but then I'm wondering: Can `mdio-gpio` even be instantiated directly? It's a platform driver, so that implies it relies on platform data. This prompts a broader question: Can *any* driver dynamically create an MDIO bus? Or is it always a static, pre-defined entity? That's the core of the problem, really. To get a handle on this, the next step is crystal clear. I need to dive into the kernel source and meticulously trace all the callers of `mdiobus_register`. This should reveal the range of drivers that are capable of constructing and registering an MDIO bus, giving me a solid understanding of how it *could* be accomplished within Netdevsim. Time to get my hands dirty. |
| 34/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_register"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1138 lines.\nUse more precise expression if possible.\n\nDocumentation/driver-api/driver-model/devres.rst=349=MDIO\n--\nDocumentation/driver-api/driver-model/devres.rst-351- devm_mdiobus_alloc_size()\nDocumentation/driver-api/driver-model/devres.rst:352: devm_mdiobus_register()\nDocumentation/driver-api/driver-model/devres.rst:353: devm_of_mdiobus_register()\nDocumentation/driver-api/driver-model/devres.rst-354-\n--\nDocumentation/firmware-guide/acpi/dsd/motorcomm-yt8xxx-phy.rst=12=device (the same objects that are registered via\nDocumentation/firmware-guide/acpi/dsd/motorcomm-yt8xxx-phy.rst:13:``fwnode_mdiobus_register_phy()``). MAC-side connection properties such as\nDocumentation/firmware-guide/acpi/dsd/motorcomm-yt8xxx-phy.rst-14-``phy-handle`` and ``phy-mode`` are documented in [acpi-mdio-phy]_.\n--\nDocumentation/firmware-guide/acpi/dsd/phy.rst=7=The PHYs on an MDIO bus [phy] are probed and registered using\nDocumentation/firmware-guide/acpi/dsd/phy.rst:8:fwnode_mdiobus_register_phy().\nDocumentation/firmware-guide/acpi/dsd/phy.rst-9-\n--\nDocumentation/networking/phy.rst=40=registered as a distinct device.\n--\nDocumentation/networking/phy.rst-56- driver needs, setup the mii_bus structure, and register with the PAL using\nDocumentation/networking/phy.rst:57: mdiobus_register. Similarly, there's a remove function to undo all of\nDocumentation/networking/phy.rst-58- that (use mdiobus_unregister).\n--\narch/powerpc/platforms/82xx/ep8248e.c=109=static int ep8248e_mdio_probe(struct platform_device *ofdev)\n--\narch/powerpc/platforms/82xx/ep8248e.c-132-\narch/powerpc/platforms/82xx/ep8248e.c:133:\tret = of_mdiobus_register(bus, ofdev-\u003edev.of_node);\narch/powerpc/platforms/82xx/ep8248e.c-134-\tif (ret)\n--\narch/powerpc/platforms/pasemi/gpio_mdio.c=207=static int gpio_mdio_probe(struct platform_device *ofdev)\n--\narch/powerpc/platforms/pasemi/gpio_mdio.c-243-\narch/powerpc/platforms/pasemi/gpio_mdio.c:244:\terr = of_mdiobus_register(new_bus, np);\narch/powerpc/platforms/pasemi/gpio_mdio.c-245-\n--\ndrivers/net/dsa/bcm_sf2.c=607=static int bcm_sf2_mdio_register(struct dsa_switch *ds)\n--\ndrivers/net/dsa/bcm_sf2.c-683-\ndrivers/net/dsa/bcm_sf2.c:684:\terr = mdiobus_register(priv-\u003euser_mii_bus);\ndrivers/net/dsa/bcm_sf2.c-685-\tif (err)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=187=static int gswip_mdio(struct gswip_priv *priv)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-213-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:214:\terr = devm_of_mdiobus_register(dev, bus, mdio_np);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-215-\n--\ndrivers/net/dsa/microchip/ksz9477.c=321=static int ksz9477_pcs_create(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz9477.c-341-\ndrivers/net/dsa/microchip/ksz9477.c:342:\tret = devm_mdiobus_register(dev-\u003edev, bus);\ndrivers/net/dsa/microchip/ksz9477.c-343-\tif (ret)\n--\ndrivers/net/dsa/microchip/ksz_common.c=2356=int ksz_mdio_register(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz_common.c-2427-\ndrivers/net/dsa/microchip/ksz_common.c:2428:\tret = devm_of_mdiobus_register(ds-\u003edev, bus, mdio_np);\ndrivers/net/dsa/microchip/ksz_common.c-2429-\tif (ret) {\n--\ndrivers/net/dsa/microchip/lan937x_main.c=685=static int lan937x_mdio_register(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/lan937x_main.c-755-\ndrivers/net/dsa/microchip/lan937x_main.c:756:\tret = devm_of_mdiobus_register(ds-\u003edev, bus, mdio_np);\ndrivers/net/dsa/microchip/lan937x_main.c-757-\tif (ret)\n--\ndrivers/net/dsa/motorcomm/chip.c=389=yt921x_mbus_int_init(struct yt921x_priv *priv, struct device_node *mnp)\n--\ndrivers/net/dsa/motorcomm/chip.c-406-\ndrivers/net/dsa/motorcomm/chip.c:407:\tres = devm_of_mdiobus_register(dev, mbus, mnp);\ndrivers/net/dsa/motorcomm/chip.c-408-\tif (res)\n--\ndrivers/net/dsa/motorcomm/chip.c=520=yt921x_mbus_ext_init(struct yt921x_priv *priv, struct device_node *mnp)\n--\ndrivers/net/dsa/motorcomm/chip.c-537-\ndrivers/net/dsa/motorcomm/chip.c:538:\tres = devm_of_mdiobus_register(dev, mbus, mnp);\ndrivers/net/dsa/motorcomm/chip.c-539-\tif (res)\n--\ndrivers/net/dsa/mt7530.c=2337=mt7530_setup_mdio(struct mt7530_priv *priv)\n--\ndrivers/net/dsa/mt7530.c-2372-\ndrivers/net/dsa/mt7530.c:2373:\tret = devm_of_mdiobus_register(dev, bus, mnp);\ndrivers/net/dsa/mt7530.c-2374-\tif (ret) {\n--\ndrivers/net/dsa/mt7628.c=242=static int mt7628_setup_internal_mdio(struct dsa_switch *ds)\n--\ndrivers/net/dsa/mt7628.c-261-\ndrivers/net/dsa/mt7628.c:262:\treturn devm_mdiobus_register(dev, bus);\ndrivers/net/dsa/mt7628.c-263-}\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=3842=static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3895-\ndrivers/net/dsa/mv88e6xxx/chip.c:3896:\terr = of_mdiobus_register(bus, np);\ndrivers/net/dsa/mv88e6xxx/chip.c-3897-\tif (err) {\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c=267=static int mxl862xx_setup_mdio(struct dsa_switch *ds)\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c-292-\ndrivers/net/dsa/mxl862xx/mxl862xx.c:293:\tret = devm_of_mdiobus_register(dev, bus, mdio_np);\ndrivers/net/dsa/mxl862xx/mxl862xx.c-294-\tof_node_put(mdio_np);\n--\ndrivers/net/dsa/netc/netc_main.c=149=static int netc_port_create_emdio_bus(struct netc_port *np,\n--\ndrivers/net/dsa/netc/netc_main.c-179-\ndrivers/net/dsa/netc/netc_main.c:180:\terr = devm_of_mdiobus_register(dev, bus, node);\ndrivers/net/dsa/netc/netc_main.c-181-\tif (err)\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c=957=static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)\n--\ndrivers/net/dsa/ocelot/felix_vsc9959.c-1013-\t/* Needed in order to initialize the bus mutex lock */\ndrivers/net/dsa/ocelot/felix_vsc9959.c:1014:\trc = mdiobus_register(bus);\ndrivers/net/dsa/ocelot/felix_vsc9959.c-1015-\tif (rc \u003c 0) {\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c=878=static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)\n--\ndrivers/net/dsa/ocelot/seville_vsc9953.c-903-\t/* Needed in order to initialize the bus mutex lock */\ndrivers/net/dsa/ocelot/seville_vsc9953.c:904:\trc = devm_of_mdiobus_register(dev, bus, NULL);\ndrivers/net/dsa/ocelot/seville_vsc9953.c-905-\tif (rc \u003c 0) {\n--\ndrivers/net/dsa/qca/ar9331.c=357=static int ar9331_sw_mbus_init(struct ar9331_sw_priv *priv)\n--\ndrivers/net/dsa/qca/ar9331.c-381-\ndrivers/net/dsa/qca/ar9331.c:382:\tret = devm_of_mdiobus_register(dev, mbus, mnp);\ndrivers/net/dsa/qca/ar9331.c-383-\tof_node_put(mnp);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=947=qca8k_mdio_register(struct qca8k_priv *priv)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-986-\ndrivers/net/dsa/qca/qca8k-8xxx.c:987:\tret = devm_of_mdiobus_register(dev, bus, mdio);\ndrivers/net/dsa/qca/qca8k-8xxx.c-988-\n--\ndrivers/net/dsa/realtek/rtl83xx.c=75=int rtl83xx_setup_user_mdio(struct dsa_switch *ds)\n--\ndrivers/net/dsa/realtek/rtl83xx.c-100-\ndrivers/net/dsa/realtek/rtl83xx.c:101:\tret = devm_of_mdiobus_register(priv-\u003edev, bus, mdio_np);\ndrivers/net/dsa/realtek/rtl83xx.c-102-\tif (ret) {\n--\ndrivers/net/dsa/rzn1_a5psw.c=1117=static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)\n--\ndrivers/net/dsa/rzn1_a5psw.c-1143-\ndrivers/net/dsa/rzn1_a5psw.c:1144:\treturn devm_of_mdiobus_register(dev, bus, node);\ndrivers/net/dsa/rzn1_a5psw.c-1145-}\n--\ndrivers/net/dsa/sja1105/sja1105.h=307=void sja1105_frame_memory_partitioning(struct sja1105_private *priv);\n--\ndrivers/net/dsa/sja1105/sja1105.h-309-/* From sja1105_mdio.c */\ndrivers/net/dsa/sja1105/sja1105.h:310:int sja1105_mdiobus_register(struct dsa_switch *ds);\ndrivers/net/dsa/sja1105/sja1105.h-311-void sja1105_mdiobus_unregister(struct dsa_switch *ds);\n--\ndrivers/net/dsa/sja1105/sja1105_main.c=3026=static int sja1105_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/sja1105/sja1105_main.c-3067-\ndrivers/net/dsa/sja1105/sja1105_main.c:3068:\trc = sja1105_mdiobus_register(ds);\ndrivers/net/dsa/sja1105/sja1105_main.c-3069-\tif (rc \u003c 0) {\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c=258=static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c-287-\ndrivers/net/dsa/sja1105/sja1105_mdio.c:288:\trc = of_mdiobus_register(bus, np);\ndrivers/net/dsa/sja1105/sja1105_mdio.c-289-\tif (rc) {\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c=312=static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c-343-\ndrivers/net/dsa/sja1105/sja1105_mdio.c:344:\trc = of_mdiobus_register(bus, np);\ndrivers/net/dsa/sja1105/sja1105_mdio.c-345-\tif (rc) {\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c=368=static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c-395-\ndrivers/net/dsa/sja1105/sja1105_mdio.c:396:\trc = mdiobus_register(bus);\ndrivers/net/dsa/sja1105/sja1105_mdio.c-397-\tif (rc) {\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c=439=static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)\n--\ndrivers/net/dsa/sja1105/sja1105_mdio.c-458-\ndrivers/net/dsa/sja1105/sja1105_mdio.c:459:int sja1105_mdiobus_register(struct dsa_switch *ds)\ndrivers/net/dsa/sja1105/sja1105_mdio.c-460-{\n--\ndrivers/net/ethernet/8390/ax88796.c=459=static int ax_mii_init(struct net_device *dev)\n--\ndrivers/net/ethernet/8390/ax88796.c-478-\ndrivers/net/ethernet/8390/ax88796.c:479:\terr = mdiobus_register(ax-\u003emii_bus);\ndrivers/net/ethernet/8390/ax88796.c-480-\tif (err)\n--\ndrivers/net/ethernet/actions/owl-emac.c=1321=static int owl_emac_mdio_init(struct net_device *netdev)\n--\ndrivers/net/ethernet/actions/owl-emac.c-1345-\ndrivers/net/ethernet/actions/owl-emac.c:1346:\tret = devm_of_mdiobus_register(dev, priv-\u003emii, mdio_node);\ndrivers/net/ethernet/actions/owl-emac.c-1347-\n--\ndrivers/net/ethernet/adi/adin1110.c=509=static int adin1110_register_mdiobus(struct adin1110_priv *priv,\n--\ndrivers/net/ethernet/adi/adin1110.c-529-\ndrivers/net/ethernet/adi/adin1110.c:530:\tret = devm_mdiobus_register(dev, mii_bus);\ndrivers/net/ethernet/adi/adin1110.c-531-\tif (ret)\n--\ndrivers/net/ethernet/adi/adin1140.c=617=static int adin1140_mdio_register(struct adin1140_priv *priv,\n--\ndrivers/net/ethernet/adi/adin1140.c-636-\ndrivers/net/ethernet/adi/adin1140.c:637:\treturn devm_mdiobus_register(\u0026spidev-\u003edev, priv-\u003emdiobus);\ndrivers/net/ethernet/adi/adin1140.c-638-}\n--\ndrivers/net/ethernet/aeroflex/greth.c=1290=static int greth_mdio_init(struct greth_private *greth)\n--\ndrivers/net/ethernet/aeroflex/greth.c-1306-\ndrivers/net/ethernet/aeroflex/greth.c:1307:\tret = mdiobus_register(greth-\u003emdio);\ndrivers/net/ethernet/aeroflex/greth.c-1308-\tif (ret) {\n--\ndrivers/net/ethernet/agere/et131x.c=3931=static int et131x_pci_setup(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/agere/et131x.c-4026-\ndrivers/net/ethernet/agere/et131x.c:4027:\trc = mdiobus_register(adapter-\u003emii_bus);\ndrivers/net/ethernet/agere/et131x.c-4028-\tif (rc \u003c 0) {\n--\ndrivers/net/ethernet/altera/altera_tse_main.c=121=static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)\n--\ndrivers/net/ethernet/altera/altera_tse_main.c-157-\ndrivers/net/ethernet/altera/altera_tse_main.c:158:\tret = of_mdiobus_register(mdio, mdio_node);\ndrivers/net/ethernet/altera/altera_tse_main.c-159-\tif (ret != 0) {\n--\ndrivers/net/ethernet/amd/au1000_eth.c=1061=static int au1000_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/amd/au1000_eth.c-1221-\ndrivers/net/ethernet/amd/au1000_eth.c:1222:\terr = mdiobus_register(aup-\u003emii_bus);\ndrivers/net/ethernet/amd/au1000_eth.c-1223-\tif (err) {\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c=3428=static int xgbe_phy_init(struct xgbe_prv_data *pdata)\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-3717-\tsnprintf(mii-\u003eid, sizeof(mii-\u003eid), \"%s\", dev_name(pdata-\u003edev));\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c:3718:\tret = mdiobus_register(mii);\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-3719-\tif (ret) {\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c:3720:\t\tdev_err(pdata-\u003edev, \"mdiobus_register failed\\n\");\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-3721-\t\treturn ret;\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c=98=int xge_mdio_config(struct net_device *ndev)\n--\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-118-\tmdio_bus-\u003ephy_mask = 0x1;\ndrivers/net/ethernet/apm/xgene-v2/mdio.c:119:\tret = mdiobus_register(mdio_bus);\ndrivers/net/ethernet/apm/xgene-v2/mdio.c-120-\tif (ret)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c=837=int xgene_enet_phy_connect(struct net_device *ndev)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-887-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:888:static int xgene_mdiobus_register(struct xgene_enet_pdata *pdata,\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-889-\t\t\t\t struct mii_bus *mdio)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-912-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:913:\t\tret = of_mdiobus_register(mdio, mdio_np);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-914-\t\tof_node_put(mdio_np);\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-921-\t/* Register the MDIO bus */\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:922:\tret = mdiobus_register(mdio);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-923-\tif (ret)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c=939=int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)\n--\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-957-\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c:958:\tret = xgene_mdiobus_register(pdata, mdio_bus);\ndrivers/net/ethernet/apm/xgene/xgene_enet_hw.c-959-\tif (ret) {\n--\ndrivers/net/ethernet/arc/emac_mdio.c=131=int arc_mdio_probe(struct arc_emac_priv *priv)\n--\ndrivers/net/ethernet/arc/emac_mdio.c-172-\ndrivers/net/ethernet/arc/emac_mdio.c:173:\terror = of_mdiobus_register(bus, mdio_node);\ndrivers/net/ethernet/arc/emac_mdio.c-174-\tof_node_put(mdio_node);\n--\ndrivers/net/ethernet/asix/ax88796c_main.c=966=static int ax88796c_probe(struct spi_device *spi)\n--\ndrivers/net/ethernet/asix/ax88796c_main.c-1010-\ndrivers/net/ethernet/asix/ax88796c_main.c:1011:\tret = devm_mdiobus_register(\u0026spi-\u003edev, ax_local-\u003emdiobus);\ndrivers/net/ethernet/asix/ax88796c_main.c-1012-\tif (ret \u003c 0) {\n--\ndrivers/net/ethernet/atheros/ag71xx.c=687=static int ag71xx_mdio_probe(struct ag71xx *ag)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-727-\tmnp = of_get_child_by_name(np, \"mdio\");\ndrivers/net/ethernet/atheros/ag71xx.c:728:\terr = devm_of_mdiobus_register(dev, mii_bus, mnp);\ndrivers/net/ethernet/atheros/ag71xx.c-729-\tof_node_put(mnp);\n--\ndrivers/net/ethernet/broadcom/b44.c=2234=static int b44_register_phy_one(struct b44 *bp)\n--\ndrivers/net/ethernet/broadcom/b44.c-2259-\ndrivers/net/ethernet/broadcom/b44.c:2260:\terr = mdiobus_register(mii_bus);\ndrivers/net/ethernet/broadcom/b44.c-2261-\tif (err) {\n--\ndrivers/net/ethernet/broadcom/bcm63xx_enet.c=1713=static int bcm_enet_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/broadcom/bcm63xx_enet.c-1829-\ndrivers/net/ethernet/broadcom/bcm63xx_enet.c:1830:\t\tret = mdiobus_register(bus);\ndrivers/net/ethernet/broadcom/bcm63xx_enet.c-1831-\t\tif (ret) {\n--\ndrivers/net/ethernet/broadcom/bgmac-bcma-mdio.c=211=struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac)\n--\ndrivers/net/ethernet/broadcom/bgmac-bcma-mdio.c-235-\ndrivers/net/ethernet/broadcom/bgmac-bcma-mdio.c:236:\terr = of_mdiobus_register(mii_bus, np);\ndrivers/net/ethernet/broadcom/bgmac-bcma-mdio.c-237-\tof_node_put(np);\n--\ndrivers/net/ethernet/broadcom/genet/bcmmii.c=193=int bcmgenet_mii_config(struct net_device *dev, bool init)\n--\ndrivers/net/ethernet/broadcom/genet/bcmmii.c-233-\t\tphy_name = \"external RvMII\";\ndrivers/net/ethernet/broadcom/genet/bcmmii.c:234:\t\t/* of_mdiobus_register took care of reading the 'max-speed'\ndrivers/net/ethernet/broadcom/genet/bcmmii.c-235-\t\t * PHY property for us, effectively limiting the PHY supported\n--\ndrivers/net/ethernet/broadcom/sb1250-mac.c=2157=static int sbmac_init(struct platform_device *pldev, long long base)\n--\ndrivers/net/ethernet/broadcom/sb1250-mac.c-2227-\t */\ndrivers/net/ethernet/broadcom/sb1250-mac.c:2228:\terr = mdiobus_register(sc-\u003emii_bus);\ndrivers/net/ethernet/broadcom/sb1250-mac.c-2229-\tif (err) {\n--\ndrivers/net/ethernet/broadcom/tg3.c=1505=static int tg3_mdio_init(struct tg3 *tp)\n--\ndrivers/net/ethernet/broadcom/tg3.c-1557-\ndrivers/net/ethernet/broadcom/tg3.c:1558:\ti = mdiobus_register(tp-\u003emdio_bus);\ndrivers/net/ethernet/broadcom/tg3.c-1559-\tif (i) {\n--\ndrivers/net/ethernet/cadence/macb_main.c=1023=static int macb_mii_probe(struct net_device *netdev)\n--\ndrivers/net/ethernet/cadence/macb_main.c-1096-\ndrivers/net/ethernet/cadence/macb_main.c:1097:static int macb_mdiobus_register(struct macb *bp, struct device_node *mdio_np)\ndrivers/net/ethernet/cadence/macb_main.c-1098-{\n--\ndrivers/net/ethernet/cadence/macb_main.c-1104-\tif (mdio_np)\ndrivers/net/ethernet/cadence/macb_main.c:1105:\t\treturn of_mdiobus_register(bp-\u003emii_bus, mdio_np);\ndrivers/net/ethernet/cadence/macb_main.c-1106-\n--\ndrivers/net/ethernet/cadence/macb_main.c-1118-\ndrivers/net/ethernet/cadence/macb_main.c:1119:\t\t\treturn of_mdiobus_register(bp-\u003emii_bus, np);\ndrivers/net/ethernet/cadence/macb_main.c-1120-\t\t}\ndrivers/net/ethernet/cadence/macb_main.c-1121-\ndrivers/net/ethernet/cadence/macb_main.c:1122:\treturn mdiobus_register(bp-\u003emii_bus);\ndrivers/net/ethernet/cadence/macb_main.c-1123-}\n--\ndrivers/net/ethernet/cadence/macb_main.c=1125=static int macb_mii_init(struct macb *bp)\n--\ndrivers/net/ethernet/cadence/macb_main.c-1158-\ndrivers/net/ethernet/cadence/macb_main.c:1159:\terr = macb_mdiobus_register(bp, mdio_np);\ndrivers/net/ethernet/cadence/macb_main.c-1160-\tif (err)\n--\ndrivers/net/ethernet/davicom/dm9051.c=1107=static int dm9051_mdio_register(struct board_info *db)\n--\ndrivers/net/ethernet/davicom/dm9051.c-1124-\ndrivers/net/ethernet/davicom/dm9051.c:1125:\tret = devm_mdiobus_register(\u0026spi-\u003edev, db-\u003emdiobus);\ndrivers/net/ethernet/davicom/dm9051.c-1126-\tif (ret)\n--\ndrivers/net/ethernet/engleder/tsnep_main.c=2423=static int tsnep_mdio_init(struct tsnep_adapter *adapter)\n--\ndrivers/net/ethernet/engleder/tsnep_main.c-2454-\ndrivers/net/ethernet/engleder/tsnep_main.c:2455:\tretval = of_mdiobus_register(adapter-\u003emdiobus, np);\ndrivers/net/ethernet/engleder/tsnep_main.c-2456-\n--\ndrivers/net/ethernet/ethoc.c=1024=static int ethoc_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/ethoc.c-1207-\ndrivers/net/ethernet/ethoc.c:1208:\tret = mdiobus_register(priv-\u003emdio);\ndrivers/net/ethernet/ethoc.c-1209-\tif (ret) {\n--\ndrivers/net/ethernet/faraday/ftgmac100.c=1734=static int ftgmac100_setup_mdio(struct net_device *netdev)\n--\ndrivers/net/ethernet/faraday/ftgmac100.c-1769-\ndrivers/net/ethernet/faraday/ftgmac100.c:1770:\terr = devm_of_mdiobus_register(priv-\u003edev, priv-\u003emii_bus, mdio_np);\ndrivers/net/ethernet/faraday/ftgmac100.c-1771-\tof_node_put(mdio_np);\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c=36=static int enetc_pci_mdio_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c-90-\ndrivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c:91:\terr = of_mdiobus_register(bus, dev-\u003eof_node);\ndrivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c-92-\tif (err)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c=266=static int enetc_mdio_probe(struct enetc_pf *pf, struct device_node *np)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-292-\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c:293:\terr = of_mdiobus_register(bus, np);\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-294-\tif (err)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c=308=static int enetc_imdio_create(struct enetc_pf *pf)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-342-\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c:343:\terr = mdiobus_register(bus);\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-344-\tif (err) {\n--\ndrivers/net/ethernet/freescale/fec_main.c=3042=static int fec_enet_mii_init(struct platform_device *pdev)\n--\ndrivers/net/ethernet/freescale/fec_main.c-3160-\ndrivers/net/ethernet/freescale/fec_main.c:3161:\terr = of_mdiobus_register(fep-\u003emii_bus, node);\ndrivers/net/ethernet/freescale/fec_main.c-3162-\tif (err)\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx_phy.c=65=static int mpc52xx_fec_mdio_probe(struct platform_device *of)\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx_phy.c-105-\ndrivers/net/ethernet/freescale/fec_mpc52xx_phy.c:106:\terr = of_mdiobus_register(bus, np);\ndrivers/net/ethernet/freescale/fec_mpc52xx_phy.c-107-\tif (err)\n--\ndrivers/net/ethernet/freescale/fs_enet/mii-bitbang.c=149=static int fs_enet_mdio_probe(struct platform_device *ofdev)\n--\ndrivers/net/ethernet/freescale/fs_enet/mii-bitbang.c-175-\ndrivers/net/ethernet/freescale/fs_enet/mii-bitbang.c:176:\tret = of_mdiobus_register(new_bus, ofdev-\u003edev.of_node);\ndrivers/net/ethernet/freescale/fs_enet/mii-bitbang.c-177-\tif (ret)\n--\ndrivers/net/ethernet/freescale/fs_enet/mii-fec.c=97=static int fs_enet_mdio_probe(struct platform_device *ofdev)\n--\ndrivers/net/ethernet/freescale/fs_enet/mii-fec.c-166-\ndrivers/net/ethernet/freescale/fs_enet/mii-fec.c:167:\tret = of_mdiobus_register(new_bus, ofdev-\u003edev.of_node);\ndrivers/net/ethernet/freescale/fs_enet/mii-fec.c-168-\tif (ret)\n--\ndrivers/net/ethernet/freescale/fsl_pq_mdio.c=409=static int fsl_pq_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/freescale/fsl_pq_mdio.c-493-\ndrivers/net/ethernet/freescale/fsl_pq_mdio.c:494:\terr = of_mdiobus_register(new_bus, np);\ndrivers/net/ethernet/freescale/fsl_pq_mdio.c-495-\tif (err) {\n--\ndrivers/net/ethernet/freescale/xgmac_mdio.c=371=static int xgmac_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/freescale/xgmac_mdio.c-426-\tif (is_of_node(fwnode))\ndrivers/net/ethernet/freescale/xgmac_mdio.c:427:\t\tret = of_mdiobus_register(bus, to_of_node(fwnode));\ndrivers/net/ethernet/freescale/xgmac_mdio.c-428-\telse if (is_acpi_node(fwnode))\ndrivers/net/ethernet/freescale/xgmac_mdio.c:429:\t\tret = acpi_mdiobus_register(bus, fwnode);\ndrivers/net/ethernet/freescale/xgmac_mdio.c-430-\telse\n--\ndrivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c=266=int hbg_mdio_init(struct hbg_priv *priv)\n--\ndrivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c-291-\ndrivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c:292:\tret = devm_mdiobus_register(dev, mdio_bus);\ndrivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c-293-\tif (ret)\n--\ndrivers/net/ethernet/hisilicon/hix5hd2_gmac.c=1094=static int hix5hd2_dev_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/hisilicon/hix5hd2_gmac.c-1185-\ndrivers/net/ethernet/hisilicon/hix5hd2_gmac.c:1186:\tret = of_mdiobus_register(bus, node);\ndrivers/net/ethernet/hisilicon/hix5hd2_gmac.c-1187-\tif (ret)\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c=123=int hclge_mac_mdio_config(struct hclge_dev *hdev)\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c-154-\tmdio_bus-\u003ephy_mask = ~(1U \u003c\u003c mac-\u003ephy_addr);\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c:155:\tret = mdiobus_register(mdio_bus);\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c-156-\tif (ret) {\n--\ndrivers/net/ethernet/hisilicon/hns_mdio.c=495=static int hns_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/hisilicon/hns_mdio.c-583-\ndrivers/net/ethernet/hisilicon/hns_mdio.c:584:\t\tret = of_mdiobus_register(new_bus, pdev-\u003edev.of_node);\ndrivers/net/ethernet/hisilicon/hns_mdio.c-585-\t} else if (is_acpi_node(pdev-\u003edev.fwnode)) {\n--\ndrivers/net/ethernet/hisilicon/hns_mdio.c-592-\t\t/* Register the MDIO bus */\ndrivers/net/ethernet/hisilicon/hns_mdio.c:593:\t\tret = mdiobus_register(new_bus);\ndrivers/net/ethernet/hisilicon/hns_mdio.c-594-\t} else {\n--\ndrivers/net/ethernet/ibm/emac/core.c=2560=static int emac_dt_mdio_probe(struct emac_instance *dev)\n--\ndrivers/net/ethernet/ibm/emac/core.c-2584-\tsnprintf(bus-\u003eid, MII_BUS_ID_SIZE, \"%s\", dev-\u003eofdev-\u003ename);\ndrivers/net/ethernet/ibm/emac/core.c:2585:\tres = devm_of_mdiobus_register(\u0026dev-\u003eofdev-\u003edev, bus, mii_np);\ndrivers/net/ethernet/ibm/emac/core.c-2586-\tif (res) {\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_phy.c=1026=int ixgbe_mii_bus_init(struct ixgbe_hw *hw)\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_phy.c-1088-\tadapter-\u003emii_bus = bus;\ndrivers/net/ethernet/intel/ixgbe/ixgbe_phy.c:1089:\treturn mdiobus_register(bus);\ndrivers/net/ethernet/intel/ixgbe/ixgbe_phy.c-1090-}\n--\ndrivers/net/ethernet/lantiq_etop.c=385=ltq_etop_mdio_init(struct net_device *dev)\n--\ndrivers/net/ethernet/lantiq_etop.c-402-\t\t priv-\u003epdev-\u003ename, priv-\u003epdev-\u003eid);\ndrivers/net/ethernet/lantiq_etop.c:403:\tif (mdiobus_register(priv-\u003emii_bus)) {\ndrivers/net/ethernet/lantiq_etop.c-404-\t\terr = -ENXIO;\n--\ndrivers/net/ethernet/marvell/mvmdio.c=283=static int orion_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/marvell/mvmdio.c-381-\t/* For the platforms not supporting DT/ACPI fall-back\ndrivers/net/ethernet/marvell/mvmdio.c:382:\t * to mdiobus_register via of_mdiobus_register.\ndrivers/net/ethernet/marvell/mvmdio.c-383-\t */\ndrivers/net/ethernet/marvell/mvmdio.c-384-\tif (is_acpi_node(pdev-\u003edev.fwnode))\ndrivers/net/ethernet/marvell/mvmdio.c:385:\t\tret = acpi_mdiobus_register(bus, pdev-\u003edev.fwnode);\ndrivers/net/ethernet/marvell/mvmdio.c-386-\telse\ndrivers/net/ethernet/marvell/mvmdio.c:387:\t\tret = of_mdiobus_register(bus, pdev-\u003edev.of_node);\ndrivers/net/ethernet/marvell/mvmdio.c-388-\tif (ret \u003c 0) {\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c=1387=static int pxa168_eth_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c-1504-\tpep-\u003esmi_bus-\u003ephy_mask = 0xffffffff;\ndrivers/net/ethernet/marvell/pxa168_eth.c:1505:\terr = mdiobus_register(pep-\u003esmi_bus);\ndrivers/net/ethernet/marvell/pxa168_eth.c-1506-\tif (err)\n--\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c=998=static int mtk_mdio_init(struct mtk_eth *eth)\n--\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c-1037-\tdev_dbg(eth-\u003edev, \"MDC is running on %d Hz\\n\", MDC_MAX_FREQ / eth-\u003emdc_divider);\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c:1038:\tret = of_mdiobus_register(eth-\u003emii_bus, mii_np);\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c-1039-\n--\ndrivers/net/ethernet/mediatek/mtk_star_emac.c=1422=static int mtk_star_mdio_init(struct net_device *ndev)\n--\ndrivers/net/ethernet/mediatek/mtk_star_emac.c-1447-\ndrivers/net/ethernet/mediatek/mtk_star_emac.c:1448:\tret = devm_of_mdiobus_register(dev, priv-\u003emii, mdio_node);\ndrivers/net/ethernet/mediatek/mtk_star_emac.c-1449-\n--\ndrivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c=287=int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)\n--\ndrivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c-332-\ndrivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c:333:\tret = mdiobus_register(priv-\u003emdiobus);\ndrivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c-334-\tif (ret)\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_mdio.c=253=int fbnic_mdiobus_create(struct fbnic_dev *fbd)\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_mdio.c-272-\n\n"
} |
| 35/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64316 output: 24 thoughts: 27 Thoughts: Here's my summary, as though I'm thinking through this process: **Diving into the MDIO Drivers** Okay, so I need to understand the MDIO interface at the driver level. Let's see... the logical place to start is the `drivers/net/mdio/` directory. That's where all the MDIO driver code should reside, right? I'll browse that directory and start building a mental map of what's implemented there, which drivers are present, and how they handle the MDIO protocol. I'm looking for a solid overview. |
| 36/2 | 2026/09/13 00:16 | 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/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64892 output: 35 thoughts: 29 Thoughts: Here's my take on the thought process, as requested: **Diving into `mdio-mvusb.c`** Alright, let's get down to brass tacks. The task at hand involves examining `mdio-mvusb.c`. My initial thought is, "Okay, `mdio-mvusb.c`... what *is* this file?" It's clear that it relates to MDIO (Media Independent Interface) functionality, likely interacting with a Marvell USB device based on the naming convention. Now the question is what functionality this is involved with. It needs some investigation. |
| 38/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "usb",
"PathPrefix": "drivers/net/mdio/mdio-mvusb.c"
}Results: {
"Output": "drivers/net/mdio/mdio-mvusb.c-6-#include \u003clinux/phy.h\u003e\ndrivers/net/mdio/mdio-mvusb.c:7:#include \u003clinux/usb.h\u003e\ndrivers/net/mdio/mdio-mvusb.c-8-\n--\ndrivers/net/mdio/mdio-mvusb.c-10-\ndrivers/net/mdio/mdio-mvusb.c:11:static const struct usb_device_id mvusb_mdio_table[] = {\ndrivers/net/mdio/mdio-mvusb.c-12-\t{ USB_DEVICE(USB_MARVELL_VID, 0x1fa4) },\n--\ndrivers/net/mdio/mdio-mvusb.c-15-};\ndrivers/net/mdio/mdio-mvusb.c:16:MODULE_DEVICE_TABLE(usb, mvusb_mdio_table);\ndrivers/net/mdio/mdio-mvusb.c-17-\ndrivers/net/mdio/mdio-mvusb.c=18=enum {\n--\ndrivers/net/mdio/mdio-mvusb.c-24-\ndrivers/net/mdio/mdio-mvusb.c:25:struct mvusb_mdio {\ndrivers/net/mdio/mdio-mvusb.c:26:\tstruct usb_device *udev;\ndrivers/net/mdio/mdio-mvusb.c-27-\tstruct mii_bus *mdio;\n--\ndrivers/net/mdio/mdio-mvusb.c-31-\ndrivers/net/mdio/mdio-mvusb.c:32:static int mvusb_mdio_read(struct mii_bus *mdio, int dev, int reg)\ndrivers/net/mdio/mdio-mvusb.c-33-{\ndrivers/net/mdio/mdio-mvusb.c:34:\tstruct mvusb_mdio *mvusb = mdio-\u003epriv;\ndrivers/net/mdio/mdio-mvusb.c-35-\tint err, alen;\ndrivers/net/mdio/mdio-mvusb.c-36-\ndrivers/net/mdio/mdio-mvusb.c:37:\tmvusb-\u003ebuf[MVUSB_CMD_ADDR] = cpu_to_le16(0xa400 | (dev \u003c\u003c 5) | reg);\ndrivers/net/mdio/mdio-mvusb.c-38-\ndrivers/net/mdio/mdio-mvusb.c:39:\terr = usb_bulk_msg(mvusb-\u003eudev, usb_sndbulkpipe(mvusb-\u003eudev, 2),\ndrivers/net/mdio/mdio-mvusb.c:40:\t\t\t mvusb-\u003ebuf, 6, \u0026alen, 100);\ndrivers/net/mdio/mdio-mvusb.c-41-\tif (err)\n--\ndrivers/net/mdio/mdio-mvusb.c-43-\ndrivers/net/mdio/mdio-mvusb.c:44:\terr = usb_bulk_msg(mvusb-\u003eudev, usb_rcvbulkpipe(mvusb-\u003eudev, 6),\ndrivers/net/mdio/mdio-mvusb.c:45:\t\t\t \u0026mvusb-\u003ebuf[MVUSB_CMD_VAL], 2, \u0026alen, 100);\ndrivers/net/mdio/mdio-mvusb.c-46-\tif (err)\n--\ndrivers/net/mdio/mdio-mvusb.c-48-\ndrivers/net/mdio/mdio-mvusb.c:49:\treturn le16_to_cpu(mvusb-\u003ebuf[MVUSB_CMD_VAL]);\ndrivers/net/mdio/mdio-mvusb.c-50-}\ndrivers/net/mdio/mdio-mvusb.c-51-\ndrivers/net/mdio/mdio-mvusb.c:52:static int mvusb_mdio_write(struct mii_bus *mdio, int dev, int reg, u16 val)\ndrivers/net/mdio/mdio-mvusb.c-53-{\ndrivers/net/mdio/mdio-mvusb.c:54:\tstruct mvusb_mdio *mvusb = mdio-\u003epriv;\ndrivers/net/mdio/mdio-mvusb.c-55-\tint alen;\ndrivers/net/mdio/mdio-mvusb.c-56-\ndrivers/net/mdio/mdio-mvusb.c:57:\tmvusb-\u003ebuf[MVUSB_CMD_ADDR] = cpu_to_le16(0x8000 | (dev \u003c\u003c 5) | reg);\ndrivers/net/mdio/mdio-mvusb.c:58:\tmvusb-\u003ebuf[MVUSB_CMD_VAL] = cpu_to_le16(val);\ndrivers/net/mdio/mdio-mvusb.c-59-\ndrivers/net/mdio/mdio-mvusb.c:60:\treturn usb_bulk_msg(mvusb-\u003eudev, usb_sndbulkpipe(mvusb-\u003eudev, 2),\ndrivers/net/mdio/mdio-mvusb.c:61:\t\t\t mvusb-\u003ebuf, 8, \u0026alen, 100);\ndrivers/net/mdio/mdio-mvusb.c-62-}\ndrivers/net/mdio/mdio-mvusb.c-63-\ndrivers/net/mdio/mdio-mvusb.c:64:static int mvusb_mdio_probe(struct usb_interface *interface,\ndrivers/net/mdio/mdio-mvusb.c:65:\t\t\t const struct usb_device_id *id)\ndrivers/net/mdio/mdio-mvusb.c-66-{\ndrivers/net/mdio/mdio-mvusb.c-67-\tstruct device *dev = \u0026interface-\u003edev;\ndrivers/net/mdio/mdio-mvusb.c:68:\tstruct mvusb_mdio *mvusb;\ndrivers/net/mdio/mdio-mvusb.c-69-\tstruct mii_bus *mdio;\ndrivers/net/mdio/mdio-mvusb.c-70-\ndrivers/net/mdio/mdio-mvusb.c:71:\tmdio = devm_mdiobus_alloc_size(dev, sizeof(*mvusb));\ndrivers/net/mdio/mdio-mvusb.c-72-\tif (!mdio)\n--\ndrivers/net/mdio/mdio-mvusb.c-74-\ndrivers/net/mdio/mdio-mvusb.c:75:\tmvusb = mdio-\u003epriv;\ndrivers/net/mdio/mdio-mvusb.c:76:\tmvusb-\u003emdio = mdio;\ndrivers/net/mdio/mdio-mvusb.c:77:\tmvusb-\u003eudev = interface_to_usbdev(interface);\ndrivers/net/mdio/mdio-mvusb.c-78-\ndrivers/net/mdio/mdio-mvusb.c-79-\t/* Reversed from USB PCAPs, no idea what these mean. */\ndrivers/net/mdio/mdio-mvusb.c:80:\tmvusb-\u003ebuf[MVUSB_CMD_PREAMBLE0] = cpu_to_le16(0xe800);\ndrivers/net/mdio/mdio-mvusb.c:81:\tmvusb-\u003ebuf[MVUSB_CMD_PREAMBLE1] = cpu_to_le16(0x0001);\ndrivers/net/mdio/mdio-mvusb.c-82-\ndrivers/net/mdio/mdio-mvusb.c:83:\tsnprintf(mdio-\u003eid, MII_BUS_ID_SIZE, \"mvusb-%s\", dev_name(dev));\ndrivers/net/mdio/mdio-mvusb.c-84-\tmdio-\u003ename = mdio-\u003eid;\ndrivers/net/mdio/mdio-mvusb.c-85-\tmdio-\u003eparent = dev;\ndrivers/net/mdio/mdio-mvusb.c:86:\tmdio-\u003eread = mvusb_mdio_read;\ndrivers/net/mdio/mdio-mvusb.c:87:\tmdio-\u003ewrite = mvusb_mdio_write;\ndrivers/net/mdio/mdio-mvusb.c-88-\ndrivers/net/mdio/mdio-mvusb.c:89:\tusb_set_intfdata(interface, mvusb);\ndrivers/net/mdio/mdio-mvusb.c-90-\n--\ndrivers/net/mdio/mdio-mvusb.c-93-\ndrivers/net/mdio/mdio-mvusb.c:94:static void mvusb_mdio_disconnect(struct usb_interface *interface)\ndrivers/net/mdio/mdio-mvusb.c-95-{\ndrivers/net/mdio/mdio-mvusb.c:96:\tstruct mvusb_mdio *mvusb = usb_get_intfdata(interface);\ndrivers/net/mdio/mdio-mvusb.c-97-\ndrivers/net/mdio/mdio-mvusb.c:98:\tmdiobus_unregister(mvusb-\u003emdio);\ndrivers/net/mdio/mdio-mvusb.c:99:\tusb_set_intfdata(interface, NULL);\ndrivers/net/mdio/mdio-mvusb.c-100-}\ndrivers/net/mdio/mdio-mvusb.c-101-\ndrivers/net/mdio/mdio-mvusb.c:102:static struct usb_driver mvusb_mdio_driver = {\ndrivers/net/mdio/mdio-mvusb.c:103:\t.name = \"mvusb_mdio\",\ndrivers/net/mdio/mdio-mvusb.c:104:\t.id_table = mvusb_mdio_table,\ndrivers/net/mdio/mdio-mvusb.c:105:\t.probe = mvusb_mdio_probe,\ndrivers/net/mdio/mdio-mvusb.c:106:\t.disconnect = mvusb_mdio_disconnect,\ndrivers/net/mdio/mdio-mvusb.c-107-};\ndrivers/net/mdio/mdio-mvusb.c-108-\ndrivers/net/mdio/mdio-mvusb.c:109:module_usb_driver(mvusb_mdio_driver);\ndrivers/net/mdio/mdio-mvusb.c-110-\n"
} |
| 39/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 67721 output: 41 thoughts: 60 Thoughts: Here's my take on those thoughts: **Analyzing the `mdio-mvusb.c` Driver** Okay, so I'm looking at `mdio-mvusb.c`. This is intriguing – a USB driver that's *directly* registering an MDIO bus. That's a clever approach, bypassing the usual layering I'm used to. I wonder what the probe function, `mvusb_mdio_probe`, does exactly. Let me quickly jump to lines 90-93 in `mdio-mvusb.c` to see what initializations and calls are made, specifically within that important probe routine, to get the MDIO bus up and running via USB. I bet there are some interesting memory-mapped register accesses or USB-specific control transfers involved. I want to see how they're handling the hardware interaction. |
| 40/2 | 2026/09/13 00:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/mdio/mdio-mvusb.c",
"FirstLine": 85,
"LineCount": 20
}Results: {
"Contents": " 85:\t\tmdio-\u003eparent = dev;\n 86:\t\tmdio-\u003eread = mvusb_mdio_read;\n 87:\t\tmdio-\u003ewrite = mvusb_mdio_write;\n 88:\t\n 89:\t\tusb_set_intfdata(interface, mvusb);\n 90:\t\n 91:\t\treturn of_mdiobus_register(mdio, dev-\u003eof_node);\n 92:\t}\n 93:\t\n 94:\tstatic void mvusb_mdio_disconnect(struct usb_interface *interface)\n 95:\t{\n 96:\t\tstruct mvusb_mdio *mvusb = usb_get_intfdata(interface);\n 97:\t\n 98:\t\tmdiobus_unregister(mvusb-\u003emdio);\n 99:\t\tusb_set_intfdata(interface, NULL);\n 100:\t}\n 101:\t\n 102:\tstatic struct usb_driver mvusb_mdio_driver = {\n 103:\t\t.name = \"mvusb_mdio\",\n 104:\t\t.id_table = mvusb_mdio_table,\n"
} |
| 41/2 | 2026/09/13 00:16 | llm | patch-evaluator-compressor |
0mModel:gemini-3.8-flash Args: null Results: null Reply: ### 1. Summary of Approaches and Results
- **Patch Inspection**:
- Target file: `drivers/net/phy/marvell.c`.
- Modification details: Adds Wake-on-LAN (WoL) suspend/resume interrupt handlers (`marvell_wol_suspend_intrs`, `marvell_wol_resume_intrs`), adjusts `m88e1510_resume` and `m88e1510_suspend`, adds `m88e1318_suspend` and `m88e1318_resume`, modifies `m88e1318_set_wol` to manage wakeup enable state (`device_set_wakeup_enable`) with rollback handling, updates `marvell_probe` to configure wake IRQ via `devm_pm_set_wake_irq` if `wakeup-source` property is set and `phy_interrupt_is_valid(phydev)`, and sets `PHY_ALWAYS_CALL_SUSPEND` on `Marvell 88E1318S` and `Marvell 88E1510` driver definitions.
- Changes target PHY IDs `MARVELL_PHY_ID_88E1318S` (`0x01410e90`) and `MARVELL_PHY_ID_88E1510` (`0x01410dd0`).
- **Kconfig and Architecture Analysis**:
- Searched defconfigs and `drivers/net/phy/Kconfig`.
- Config symbol: `CONFIG_MARVELL_PHY` (tristate "Marvell Alaska PHYs").
- `CONFIG_MARVELL_PHY` has no strict architecture dependency; depends on phylib / networking.
- **Reachability Evaluation (Virtual Environment / QEMU / Syzkaller)**:
- Investigated whether MDIO PHY drivers can be reached/probed via virtual buses without physical hardware.
- Checked USB ethernet drivers (`drivers/net/usb/`) to determine if USB devices (emulatable via `raw-gadget` or `dummy_hcd`) instantiate an MDIO bus scanned via phylib.
- Found that `asix_devices.c` (`AX88772`), `ax88172a.c` (`AX88172A`), and `lan78xx.c` allocate and register an MDIO bus via `mdiobus_register()`.
- In `__mdiobus_register()` (`drivers/net/phy/mdio_bus_provider.c`), `mdiobus_scan_bus_c22()` queries each unmasked PHY address (0–31) using `bus->read()` (which maps to USB control transfers handled by the USB gadget/emulated device).
- A USB gadget responding to MII register reads for `MII_PHYSID1` and `MII_PHYSID2` with `MARVELL_PHY_ID_88E1318S` or `MARVELL_PHY_ID_88E1510` can trigger device discovery, phylib device creation, and driver binding to `marvell_drivers` in `marvell.c`.
### 2. Hypotheses and Active Lines of Investigation
- **Active Hypothesis 1**: Can `drivers/net/phy/marvell.c` be instantiated and exercised in QEMU/syzkaller?
- Even if physical ethernet boards using Marvell PHYs are not present in standard amd64 QEMU VMs, MDIO bus scanning from USB ethernet adapters (or virtual netdev/phylink) can bind `marvell_drivers` if the device reports Marvell PHY IDs.
- However, need to evaluate whether the specific modified code (`m88e1318_set_wol`, `marvell_probe`, `m88e1510_suspend`, `m88e1510_resume`, `m88e1318_suspend`, `m88e1318_resume`) is considered reachable under fuzzing criteria, or if Marvell PHY is considered dedicated physical hardware that standard fuzzing cannot effectively target.
- Need to check if `marvell_probe` requires specific device tree nodes / properties (`wakeup-source`) and interrupt lines, or if ethtool netlink/ioctl (`ETHTOOL_SWOL`) can invoke `m88e1318_set_wol`.
- Need to determine whether the patch warrants fuzzing (`WorthFuzzing=true` vs `WorthFuzzing=false`) based on reachability rules regarding physical transceivers / hardware drivers vs reachable USB / netlink interfaces.
- **Active Hypothesis 2**: ETHTOOL WoL invocation:
- Ethtool `SIOCETHTOOL` / Netlink `ETHTOOL_MSG_WOL_SET` invokes `phy_ethtool_set_wol()`, which calls `phydev->drv->set_wol(phydev, wol)`.
- If a netdev is attached to the Marvell PHY, userspace can call `ethtool -s ethX wol g` to reach `m88e1318_set_wol()`.
### 3. Critical Code Snippets, Symbols, and Configs
- **Config**:
- `MARVELL_PHY`
- Relevant parents: `NETDEVICES`, `PHYLIB`, `USB_NET_DRIVERS`, `USB_NET_AX88172A`, `USB_NET_AX8817X`, `USB_NET_LAN78XX`
- **Modified Functions in `drivers/net/phy/marvell.c`**:
- `marvell_wol_suspend_intrs(struct phy_device *phydev)`
- `marvell_wol_resume_intrs(struct phy_device *phydev)`
- `m88e1510_resume(struct phy_device *phydev)`
- `m88e1510_suspend(struct phy_device *phydev)`
- `m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)`
- `m88e1318_suspend(struct phy_device *phydev)`
- `m88e1318_resume(struct phy_device *phydev)`
- `marvell_probe(struct phy_device *phydev)`
- **Key Constants & Identifiers**:
- `MARVELL_PHY_ID_88E1318S` = `0x01410e90`
- `MARVELL_PHY_ID_88E1510` = `0x01410dd0`
- `MII_88E1318S_PHY_CSIER` / `MII_88E1318S_PHY_CSIER_WOL_EIE`
- `MII_MARVELL_COPPER_PAGE`
- `PHY_ALWAYS_CALL_SUSPEND`
- **Key Callers / Hooks**:
- Probe: `phy_probe` -> `marvell_probe`
- WoL: `phy_ethtool_set_wol` -> `m88e1318_set_wol`
- PM suspend/resume: `mdio_bus_phy_suspend` / `mdio_bus_phy_resume` -> `m88e1318_suspend` / `m88e1318_resume`, `m88e1510_suspend` / `m88e1510_resume`
### 4. Watchouts & Pitfalls
- Avoid infinite search loops checking generic MDIO drivers across tree.
- Assess whether syzkaller actually emulates USB MDIO PHY devices in real corpus (syzkaller has USB fuzzing descriptors for various CDC/ethernet adapters, but whether it probes specific MDIO transceivers is edge case).
- Weigh Section 2 ("Structurally unreachable hardware" vs Section 3 "Reachable Drivers and Protocols: Drivers accessible via virtual buses").
- Ensure `set-results` tool format adheres strictly to schema (JSON with `worth_fuzzing`, `reason`, `focus_symbols`, `enable_configs`).Tokens: input: 48905 output: 1902 thoughts: 0 |
| 42/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 27361 output: 31 thoughts: 0 |
| 43/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_register",
"PathPrefix": "drivers/net/usb/"
}Results: {
"Output": "drivers/net/usb/asix_devices.c=669=static int ax88772_init_mdio(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-686-\ndrivers/net/usb/asix_devices.c:687:\tret = mdiobus_register(priv-\u003emdio);\ndrivers/net/usb/asix_devices.c-688-\tif (ret) {\n--\ndrivers/net/usb/ax88172a.c=61=static int ax88172a_init_mdio(struct usbnet *dev)\n--\ndrivers/net/usb/ax88172a.c-79-\ndrivers/net/usb/ax88172a.c:80:\tret = mdiobus_register(priv-\u003emdio);\ndrivers/net/usb/ax88172a.c-81-\tif (ret) {\n--\ndrivers/net/usb/lan78xx.c=2091=static int lan78xx_mdio_init(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2121-\tnode = of_get_child_by_name(dev-\u003eudev-\u003edev.of_node, \"mdio\");\ndrivers/net/usb/lan78xx.c:2122:\tret = of_mdiobus_register(dev-\u003emdiobus, node);\ndrivers/net/usb/lan78xx.c-2123-\tof_node_put(node);\n--\ndrivers/net/usb/smsc95xx.c=1147=static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)\n--\ndrivers/net/usb/smsc95xx.c-1241-\ndrivers/net/usb/smsc95xx.c:1242:\tret = mdiobus_register(pdata-\u003emdiobus);\ndrivers/net/usb/smsc95xx.c-1243-\tif (ret) {\n"
} |
| 44/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 27930 output: 40 thoughts: 133 Thoughts: **Investigating USB Ethernet Driver Registration** Okay, so I'm trying to trace the MDIO bus registration for these USB Ethernet drivers. Specifically, I know that `drivers/net/usb/asix_devices.c`, `drivers/net/usb/ax88172a.c`, and `drivers/net/usb/smsc95xx.c` all call `mdiobus_register()`. My next step is to examine one of these to understand *how* they're registering the bus, and, crucially, when PHY probing happens. I suspect there will be driver-specific initialization routines involved. Let's start with `drivers/net/usb/asix_devices.c`, and I'll jump right to around line 669 to see what the core setup looks like. |
| 45/2 | 2026/09/13 00:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/asix_devices.c",
"FirstLine": 660,
"LineCount": 40
}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 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"
} |
| 46/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 28952 output: 37 thoughts: 59 Thoughts: Here's my summary, as if I were thinking it: **Examining the MDIO Bus Initialization** Okay, let's dive into this `ax88772_init_mdio` function. Right, first thing I see is the `mdiobus_register(priv->mdio)` call. That's the core of getting the Media Independent Interface (MII) bus set up, which is what I'd expect. So, it's registering the bus with the system. Now, let's get a handle on the specifics of this registration process. I'll need to know where I can find the data on the structure `priv->mdio`. Let's take a look under the hood at `__mdiobus_register()`. I'm curious to see exactly what this function is doing behind the scenes during registration. |
| 47/2 | 2026/09/13 00:16 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_scan_bus_c22",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=477=static struct phy_device *mdiobus_scan_c45(struct mii_bus *bus, int addr)\n--\ndrivers/net/phy/mdio_bus_provider.c-481-\ndrivers/net/phy/mdio_bus_provider.c:482:static int mdiobus_scan_bus_c22(struct mii_bus *bus)\ndrivers/net/phy/mdio_bus_provider.c-483-{\n--\ndrivers/net/phy/mdio_bus_provider.c=553=int __mdiobus_register(struct mii_bus *bus, struct module *owner)\n--\ndrivers/net/phy/mdio_bus_provider.c-632-\tif (bus-\u003eread) {\ndrivers/net/phy/mdio_bus_provider.c:633:\t\terr = mdiobus_scan_bus_c22(bus);\ndrivers/net/phy/mdio_bus_provider.c-634-\t\tif (err)\n"
} |
| 48/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 29509 output: 42 thoughts: 76 Thoughts: Here's my analysis of what's happening, from my perspective: **Diving into the MDIO Bus Registration Process** Okay, so `__mdiobus_register` has been called, and now we're moving into the `mdiobus_scan_bus_c22(bus)` function. My interest is piqued here, because this is where the actual bus scanning should happen. Let's see what the implementation is actually doing under the hood. Let me go take a look at the code. I'll check `drivers/net/phy/mdio_bus_provider.c`, and specifically, line 482 and around there. I'm expecting this to be where the crucial work of identifying connected PHYs on the C22 MDIO bus is executed. Let's get to the bottom of this! |
| 49/2 | 2026/09/13 00:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 480,
"LineCount": 40
}Results: {
"Contents": " 480:\t}\n 481:\t\n 482:\tstatic int mdiobus_scan_bus_c22(struct mii_bus *bus)\n 483:\t{\n 484:\t\tint i;\n 485:\t\n 486:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 487:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 488:\t\t\t\tstruct phy_device *phydev;\n 489:\t\n 490:\t\t\t\tphydev = mdiobus_scan_c22(bus, i);\n 491:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 492:\t\t\t\t\treturn PTR_ERR(phydev);\n 493:\t\t\t}\n 494:\t\t}\n 495:\t\treturn 0;\n 496:\t}\n 497:\t\n 498:\tstatic int mdiobus_scan_bus_c45(struct mii_bus *bus)\n 499:\t{\n 500:\t\tint i;\n 501:\t\n 502:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 503:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 504:\t\t\t\tstruct phy_device *phydev;\n 505:\t\n 506:\t\t\t\t/* Don't scan C45 if we already have a C22 device */\n 507:\t\t\t\tif (bus-\u003emdio_map[i])\n 508:\t\t\t\t\tcontinue;\n 509:\t\n 510:\t\t\t\tphydev = mdiobus_scan_c45(bus, i);\n 511:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 512:\t\t\t\t\treturn PTR_ERR(phydev);\n 513:\t\t\t}\n 514:\t\t}\n 515:\t\treturn 0;\n 516:\t}\n 517:\t\n 518:\t/* There are some C22 PHYs which do bad things when where is a C45\n 519:\t * transaction on the bus, like accepting a read themselves, and\n"
} |
| 50/2 | 2026/09/13 00:16 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30415 output: 32 thoughts: 214 Thoughts: **My MDIO Bus Scan Process** Okay, so I'm looking at this `mdiobus_scan_c22` function, and it seems like it's the core of how we discover PHY devices on the MDIO bus. My first step is a call to `get_phy_device`, which is the workhorse here. Let me delve into `get_phy_device` and figure out what it's doing. Right, so `get_phy_device` starts by actually reading the PHY ID registers, specifically MII_PHYSID1 and MII_PHYSID2, from the MDIO bus itself. It does this through a bus read operation, utilizing the `bus->read` method. If it gets valid IDs back from the bus, the function then goes ahead and instantiates a `phy_device` structure. It's cleverly setting the `phy_id` field by combining the high and low parts of the ID. A simple left shift and bitwise OR is all it takes. Then, and this is key, it calls `phy_device_register`. `phy_device_register`, it turns out, is the registration function that actually hooks the PHY device into the system. This calls `device_register` on the `phydev->mdio.dev` member. This is the registration step that brings the new PHY device into the device tree. This registration triggers device matching on the `mdio_bus_type`. Makes sense, we need to match it against drivers. Now, I need to see what's happening during this device matching process, particularly inside `mdio_bus_match`. That's where the magic probably happens in terms of driver association. I need to understand this to make sure the right drivers are being loaded for the discovered PHYs. |
| 51/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "mdio_bus_match",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=238=const struct class mdio_bus_class = {\n--\ndrivers/net/phy/mdio_bus_provider.c-244-/**\ndrivers/net/phy/mdio_bus_provider.c:245: * mdio_bus_match - determine if given MDIO driver supports the given\ndrivers/net/phy/mdio_bus_provider.c-246- *\t\t MDIO device\n--\ndrivers/net/phy/mdio_bus_provider.c-254- */\ndrivers/net/phy/mdio_bus_provider.c:255:static int mdio_bus_match(struct device *dev, const struct device_driver *drv)\ndrivers/net/phy/mdio_bus_provider.c-256-{\n--\ndrivers/net/phy/mdio_bus_provider.c=300=const struct bus_type mdio_bus_type = {\n--\ndrivers/net/phy/mdio_bus_provider.c-302-\t.dev_groups\t= mdio_bus_device_statistics_groups,\ndrivers/net/phy/mdio_bus_provider.c:303:\t.match\t\t= mdio_bus_match,\ndrivers/net/phy/mdio_bus_provider.c-304-\t.uevent\t\t= mdio_uevent,\n"
} |
| 52/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 31395 output: 30 thoughts: 90 Thoughts: Here's my analysis of what's happening, keeping in mind my expertise: **MDIO Bus Matching and PHY Driver Probe** Okay, so I'm looking at how the MDIO bus is matching PHY drivers to specific devices. It seems like the core of the matching process lies within the `mdio_bus_match` function. The key comparison is this: `(phydrv->phy_id & phydrv->phy_id_mask) == (phydev->phy_id & phydrv->phy_id_mask)`. This is a classic bitmasking approach, and I immediately recognize it. It's using a mask (`phy_id_mask`) to identify a range or specific bits within the PHY ID, allowing for flexible matching beyond an exact ID. That's good design – supports various PHY revisions and implementations of the same base PHY ID. Once a match is found, the driver's `probe` function, likely `phy_probe()`, is triggered. I need to dig into `phy_probe()` in `phy_device.c` to fully understand the next steps. I'm going to look there to see how the PHY is initialized, configured, and integrated with the rest of the network stack. This initial matching is the first hurdle. If that isn't working as expected, there's no reason to look at further debugging. |
| 53/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "phy_probe\\(",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/broadcom.c=1150=static int bcm54xx_phy_set_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/broadcom.c-1169-\ndrivers/net/phy/broadcom.c:1170:static int bcm54xx_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/broadcom.c-1171-{\n--\ndrivers/net/phy/intel-xway.c=287=static int xway_gphy_config_init(struct phy_device *phydev)\n--\ndrivers/net/phy/intel-xway.c-315-\ndrivers/net/phy/intel-xway.c:316:static int xway_gphy_probe(struct phy_device *phydev)\ndrivers/net/phy/intel-xway.c-317-{\n--\ndrivers/net/phy/mediatek/mtk-2p5ge.c=314=static int mt798x_2p5ge_phy_led_hw_control_set(struct phy_device *phydev,\n--\ndrivers/net/phy/mediatek/mtk-2p5ge.c-322-\ndrivers/net/phy/mediatek/mtk-2p5ge.c:323:static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/mediatek/mtk-2p5ge.c-324-{\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c=1332=static int mt7988_phy_probe_shared(struct phy_device *phydev)\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1372-\ndrivers/net/phy/mediatek/mtk-ge-soc.c:1373:static int mt7988_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1374-{\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1413-\ndrivers/net/phy/mediatek/mtk-ge-soc.c:1414:static int mt7981_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1415-{\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1429-\ndrivers/net/phy/mediatek/mtk-ge-soc.c:1430:static int an7581_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1431-{\n--\ndrivers/net/phy/mediatek/mtk-ge.c=37=static void mtk_gephy_config_init(struct phy_device *phydev)\n--\ndrivers/net/phy/mediatek/mtk-ge.c-64-\ndrivers/net/phy/mediatek/mtk-ge.c:65:static int mt7530_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/mediatek/mtk-ge.c-66-{\n--\ndrivers/net/phy/mediatek/mtk-ge.c=77=static int mt7530_phy_config_init(struct phy_device *phydev)\n--\ndrivers/net/phy/mediatek/mtk-ge.c-84-\t * -\u003econfig_init after a PHY reset, with the register back at its\ndrivers/net/phy/mediatek/mtk-ge.c:85:\t * EEE-advertising hardware default, and phy_probe() zeroes\ndrivers/net/phy/mediatek/mtk-ge.c-86-\t * eee_disabled_modes (of_set_phy_eee_broken()) after -\u003eprobe already\n--\ndrivers/net/phy/micrel.c=2754=static int ksz8061_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/micrel.c-2758-\ndrivers/net/phy/micrel.c:2759:static int kszphy_probe(struct phy_device *phydev)\ndrivers/net/phy/micrel.c-2760-{\n--\ndrivers/net/phy/micrel.c=6040=static int lan8841_probe(struct phy_device *phydev)\n--\ndrivers/net/phy/micrel.c-6045-\ndrivers/net/phy/micrel.c:6046:\terr = kszphy_probe(phydev);\ndrivers/net/phy/micrel.c-6047-\tif (err)\n--\ndrivers/net/phy/phy_device.c=3735=EXPORT_SYMBOL_GPL(fwnode_get_phy_node);\n--\ndrivers/net/phy/phy_device.c-3742- */\ndrivers/net/phy/phy_device.c:3743:static int phy_probe(struct device *dev)\ndrivers/net/phy/phy_device.c-3744-{\n--\ndrivers/net/phy/smsc.c=656=EXPORT_SYMBOL_GPL(smsc_phy_set_tunable);\ndrivers/net/phy/smsc.c-657-\ndrivers/net/phy/smsc.c:658:int smsc_phy_probe(struct phy_device *phydev)\ndrivers/net/phy/smsc.c-659-{\n"
} |
| 54/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 33235 output: 40 thoughts: 23 Thoughts: Here's a summary of my thought process, as requested: **Diving into `phy_probe`** Okay, let's get down to brass tacks. I need to understand how the PHYs are being initialized and managed within the Linux kernel, specifically within the network stack. My immediate focus is the `phy_probe` function. I know it's located in `drivers/net/phy/phy_device.c`, so I'll navigate there. I'm already anticipating that this function likely serves as the critical entry point for the probing and attachment of Physical Layer devices. I'm keen to dissect its execution path and identify how it interacts with the broader framework, like the MDIO bus and the driver model. I'm particularly interested in how it handles different PHY types, the resource allocation, and the overall device lifecycle management. This should give me a solid handle on the inner workings. |
| 55/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phy_device.c",
"FirstLine": 3740,
"LineCount": 80
}Results: {
"Contents": "3740:\t *\n3741:\t * Take care of setting up the phy_device structure, set the state to READY.\n3742:\t */\n3743:\tstatic int phy_probe(struct device *dev)\n3744:\t{\n3745:\t\tstruct phy_device *phydev = to_phy_device(dev);\n3746:\t\tstruct device_driver *drv = phydev-\u003emdio.dev.driver;\n3747:\t\tstruct phy_driver *phydrv = to_phy_driver(drv);\n3748:\t\tint err = 0;\n3749:\t\n3750:\t\tphydev-\u003edrv = phydrv;\n3751:\t\n3752:\t\t/* Disable the interrupt if the PHY doesn't support it\n3753:\t\t * but the interrupt is still a valid one\n3754:\t\t */\n3755:\t\tif (!phy_drv_supports_irq(phydrv) \u0026\u0026 phy_interrupt_is_valid(phydev))\n3756:\t\t\tphydev-\u003eirq = PHY_POLL;\n3757:\t\n3758:\t\tif (phydrv-\u003eflags \u0026 PHY_IS_INTERNAL)\n3759:\t\t\tphydev-\u003eis_internal = true;\n3760:\t\n3761:\t\t/* Deassert the reset signal */\n3762:\t\tphy_device_reset(phydev, 0);\n3763:\t\n3764:\t\tif (phydev-\u003edrv-\u003eprobe) {\n3765:\t\t\terr = phydev-\u003edrv-\u003eprobe(phydev);\n3766:\t\t\tif (err)\n3767:\t\t\t\tgoto out_reset;\n3768:\t\t}\n3769:\t\n3770:\t\tphy_disable_interrupts(phydev);\n3771:\t\n3772:\t\t/* Start out supporting everything. Eventually,\n3773:\t\t * a controller will attach, and may modify one\n3774:\t\t * or both of these values\n3775:\t\t */\n3776:\t\tif (phydrv-\u003efeatures) {\n3777:\t\t\tlinkmode_copy(phydev-\u003esupported, phydrv-\u003efeatures);\n3778:\t\t\tgenphy_c45_read_eee_abilities(phydev);\n3779:\t\t}\n3780:\t\telse if (phydrv-\u003eget_features)\n3781:\t\t\terr = phydrv-\u003eget_features(phydev);\n3782:\t\telse if (phydev-\u003eis_c45)\n3783:\t\t\terr = genphy_c45_pma_read_abilities(phydev);\n3784:\t\telse\n3785:\t\t\terr = genphy_read_abilities(phydev);\n3786:\t\n3787:\t\tif (err)\n3788:\t\t\tgoto out_remove;\n3789:\t\n3790:\t\tif (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,\n3791:\t\t\t\t phydev-\u003esupported))\n3792:\t\t\tphydev-\u003eautoneg = 0;\n3793:\t\n3794:\t\tif (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,\n3795:\t\t\t\t phydev-\u003esupported))\n3796:\t\t\tphydev-\u003eis_gigabit_capable = 1;\n3797:\t\tif (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,\n3798:\t\t\t\t phydev-\u003esupported))\n3799:\t\t\tphydev-\u003eis_gigabit_capable = 1;\n3800:\t\n3801:\t\tof_set_phy_supported(phydev);\n3802:\t\n3803:\t\terr = phy_setup_ports(phydev);\n3804:\t\tif (err)\n3805:\t\t\tgoto out_remove;\n3806:\t\n3807:\t\tphy_advertise_supported(phydev);\n3808:\t\n3809:\t\t/* Get PHY default EEE advertising modes and handle them as potentially\n3810:\t\t * safe initial configuration.\n3811:\t\t */\n3812:\t\terr = genphy_c45_read_eee_adv(phydev, phydev-\u003eadvertising_eee);\n3813:\t\tif (err)\n3814:\t\t\tgoto out_sfp_release;\n3815:\t\n3816:\t\t/* Get the EEE modes we want to prohibit. */\n3817:\t\tof_set_phy_eee_broken(phydev);\n3818:\t\n3819:\t\t/* Some PHYs may advertise, by default, not support EEE modes. So,\n"
} |
| 56/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 34717 output: 28 thoughts: 626 Thoughts: **Analyzing the PHY Device Patch** Okay, let's break this down. First, `phy_probe()` calls the driver's probe function – `phydev->drv->probe(phydev)`. My focus is on the `marvell_probe` function specifically. This patch seems to be introducing or modifying some power management or Wake-on-LAN functionality within the Marvell PHY driver. Looking at `marvell_probe`, it's allocating a `marvell_priv` structure using `devm_kzalloc`. This is standard practice for managing private data associated with the device. If allocation fails, it returns an error; nothing surprising there. The `phydev->priv = priv` assignment associates the private structure with the PHY device. The interesting part is the "wakeup-source" property check. If this property is present in the device tree *and* the PHY interrupt is valid, it calls `devm_pm_set_wake_irq()`, essentially enabling the PHY to wake the system from a low-power state. It also sets the device as capable of wakeup with `device_set_wakeup_capable()`. Finally, it calls `marvell_hwmon_probe()`, which I'll assume handles hardware monitoring specific to this driver. Now, what did the patch *modify*? Let's see... it touches these functions: `marvell_wol_suspend_intrs`, `marvell_wol_resume_intrs`, `m88e1510_resume`, `m88e1510_suspend`, `m88e1318_set_wol`, `m88e1318_suspend`, `m88e1318_resume`, and the `marvell_probe` function itself, which we already looked at. It also changes the `marvell_drivers[]` structure, defining the behavior of specific Marvell PHYs. Specifically, I see changes for "Marvell 88E1318S" and "Marvell 88E1510". The 88E1318S now has `.flags = PHY_ALWAYS_CALL_SUSPEND` and `suspend` and `resume` pointers defined. The 88E1510 gets `PHY_POLL_CABLE_TEST | PHY_ALWAYS_CALL_SUSPEND` as well as its own `suspend` and `resume` pointers. The `PHY_ALWAYS_CALL_SUSPEND` flag is immediately interesting – it implies that these PHYs' suspend and resume functions should *always* be called, regardless of the system's power state. This, combined with the other function calls, leads me to believe the patch is primarily focused on making these Marvell PHYs correctly support suspend and resume, particularly with WoL. `PHY_POLL_CABLE_TEST` sounds like it’s related to cable diagnostics, which could be useful during resume. Finally, I need to understand when suspend and resume are actually *called*. I'll need to look at how the PHY framework manages those functions. I’ll run a grep for `->suspend`, `mdio_bus_phy_suspend`, or `phy_suspend` in the surrounding code to determine how the framework actually orchestrates the suspend/resume flow. |
| 57/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "phy_suspend",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 856 lines.\nUse more precise expression if possible.\n\ndrivers/net/ethernet/broadcom/bcmsysport.c=2708=static int __maybe_unused bcm_sysport_suspend(struct device *d)\n--\ndrivers/net/ethernet/broadcom/bcmsysport.c-2722-\ndrivers/net/ethernet/broadcom/bcmsysport.c:2723:\tphy_suspend(dev-\u003ephydev);\ndrivers/net/ethernet/broadcom/bcmsysport.c-2724-\n--\ndrivers/net/ethernet/hisilicon/hns/hns_ethtool.c=257=static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)\n--\ndrivers/net/ethernet/hisilicon/hns/hns_ethtool.c-274-\ndrivers/net/ethernet/hisilicon/hns/hns_ethtool.c:275:\t\terr = phy_suspend(phy_dev);\ndrivers/net/ethernet/hisilicon/hns/hns_ethtool.c-276-\t}\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c=5598=static int hclge_enable_phy_loopback(struct hclge_dev *hdev,\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c-5603-\tif (!phydev-\u003esuspended) {\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c:5604:\t\tret = phy_suspend(phydev);\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c-5605-\t\tif (ret)\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c=5616=static int hclge_disable_phy_loopback(struct hclge_dev *hdev,\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c-5624-\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c:5625:\treturn phy_suspend(phydev);\ndrivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c-5626-}\n--\ndrivers/net/ethernet/realtek/r8169_main.c=1317=static void rtl_sfp_reset(struct rtl8169_private *tp)\n--\ndrivers/net/ethernet/realtek/r8169_main.c-1325- */\ndrivers/net/ethernet/realtek/r8169_main.c:1326:static void rtl8168g_phy_suspend_quirk(struct rtl8169_private *tp, int value)\ndrivers/net/ethernet/realtek/r8169_main.c-1327-{\n--\ndrivers/net/ethernet/realtek/r8169_main.c=1340=static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value)\n--\ndrivers/net/ethernet/realtek/r8169_main.c-1350-\tif (tp-\u003eocp_base == OCP_STD_PHY_BASE \u0026\u0026 reg == MII_BMCR)\ndrivers/net/ethernet/realtek/r8169_main.c:1351:\t\trtl8168g_phy_suspend_quirk(tp, value);\ndrivers/net/ethernet/realtek/r8169_main.c-1352-\n--\ndrivers/net/ethernet/realtek/r8169_main.c=5571=static int r8169_mdio_register(struct rtl8169_private *tp)\n--\ndrivers/net/ethernet/realtek/r8169_main.c-5622-\t/* PHY will be woken up in rtl_open() */\ndrivers/net/ethernet/realtek/r8169_main.c:5623:\tphy_suspend(tp-\u003ephydev);\ndrivers/net/ethernet/realtek/r8169_main.c-5624-\n--\ndrivers/net/phy/adin.c=1010=static struct phy_driver adin_driver[] = {\n--\ndrivers/net/phy/adin.c-1027-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/adin.c:1028:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/adin.c-1029-\t\t.read_mmd\t= adin_read_mmd,\n--\ndrivers/net/phy/adin.c-1050-\t\t.resume\t\t= genphy_resume,\ndrivers/net/phy/adin.c:1051:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/adin.c-1052-\t\t.read_mmd\t= adin_read_mmd,\n--\ndrivers/net/phy/air_an8801.c=1060=static int an8801r_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/air_an8801.c-1085-\tif (!phydev-\u003ewol_enabled)\ndrivers/net/phy/air_an8801.c:1086:\t\treturn genphy_suspend(phydev);\ndrivers/net/phy/air_an8801.c-1087-\n--\ndrivers/net/phy/air_en8811h.c=1559=static int en8811h_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/air_en8811h.c-1562-\ndrivers/net/phy/air_en8811h.c:1563:\treturn genphy_suspend(phydev);\ndrivers/net/phy/air_en8811h.c-1564-}\n--\ndrivers/net/phy/ax88796b.c=97=static struct phy_driver asix_driver[] = {\n--\ndrivers/net/phy/ax88796b.c-102-\t.read_status\t= asix_ax88772a_read_status,\ndrivers/net/phy/ax88796b.c:103:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/ax88796b.c-104-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/ax88796b.c-110-\t.flags\t\t= PHY_IS_INTERNAL,\ndrivers/net/phy/ax88796b.c:111:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/ax88796b.c-112-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/ax88796b_rust.rs=80= fn suspend(dev: \u0026mut phy::Device) -\u003e Result {\ndrivers/net/phy/ax88796b_rust.rs:81: dev.genphy_suspend()\ndrivers/net/phy/ax88796b_rust.rs-82- }\n--\ndrivers/net/phy/ax88796b_rust.rs=110= fn suspend(dev: \u0026mut phy::Device) -\u003e Result {\ndrivers/net/phy/ax88796b_rust.rs:111: dev.genphy_suspend()\ndrivers/net/phy/ax88796b_rust.rs-112- }\n--\ndrivers/net/phy/bcm-cygnus.c=252=static struct phy_driver bcm_cygnus_phy_driver[] = {\n--\ndrivers/net/phy/bcm-cygnus.c-260-\t.handle_interrupt = bcm_phy_handle_interrupt,\ndrivers/net/phy/bcm-cygnus.c:261:\t.suspend = genphy_suspend,\ndrivers/net/phy/bcm-cygnus.c-262-\t.resume = bcm_cygnus_resume,\n--\ndrivers/net/phy/bcm-cygnus.c-269-\t.config_init\t= bcm_omega_config_init,\ndrivers/net/phy/bcm-cygnus.c:270:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/bcm-cygnus.c-271-\t.resume\t\t= bcm_omega_resume,\n--\ndrivers/net/phy/bcm54140.c=865=static struct phy_driver bcm54140_drivers[] = {\n--\ndrivers/net/phy/bcm54140.c-875-\t\t.probe\t\t= bcm54140_probe,\ndrivers/net/phy/bcm54140.c:876:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/bcm54140.c-877-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/bcm7xxx.c=810=static int bcm7xxx_28nm_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/bcm7xxx.c-817-\ndrivers/net/phy/bcm7xxx.c:818:\treturn genphy_suspend(phydev);\ndrivers/net/phy/bcm7xxx.c-819-}\n--\ndrivers/net/phy/broadcom.c=1466=static struct phy_driver broadcom_drivers[] = {\n--\ndrivers/net/phy/broadcom.c-1561-\t.handle_interrupt = bcm_phy_handle_interrupt,\ndrivers/net/phy/broadcom.c:1562:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/broadcom.c-1563-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/dap8211r.c=196=static struct phy_driver dap8211r_driver[] = {\n--\ndrivers/net/phy/dap8211r.c-204-\t\t.config_aneg\t= genphy_config_aneg,\ndrivers/net/phy/dap8211r.c:205:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/dap8211r.c-206-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/dp83822.c=1033=static int dp83822_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83822.c-1039-\tif (!(value \u0026 DP83822_WOL_EN))\ndrivers/net/phy/dp83822.c:1040:\t\tgenphy_suspend(phydev);\ndrivers/net/phy/dp83822.c-1041-\n--\ndrivers/net/phy/dp83848.c=136=MODULE_DEVICE_TABLE(mdio, dp83848_tbl);\n--\ndrivers/net/phy/dp83848.c-146-\t\t.config_init\t= _config_init,\t\t\t\\\ndrivers/net/phy/dp83848.c:147:\t\t.suspend\t= genphy_suspend,\t\t\\\ndrivers/net/phy/dp83848.c-148-\t\t.resume\t\t= genphy_resume,\t\t\\\n--\ndrivers/net/phy/dp83867.c=698=static int dp83867_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83867.c-705-\ndrivers/net/phy/dp83867.c:706:\treturn genphy_suspend(phydev);\ndrivers/net/phy/dp83867.c-707-}\n--\ndrivers/net/phy/dp83869.c=898=static int dp83869_phy_reset(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83869.c-929-\t.set_wol\t= dp83869_set_wol,\t\t\t\\\ndrivers/net/phy/dp83869.c:930:\t.suspend\t= genphy_suspend,\t\t\t\\\ndrivers/net/phy/dp83869.c-931-\t.resume\t\t= genphy_resume,\t\t\t\\\n--\ndrivers/net/phy/dp83tc811.c=365=static int dp83811_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83tc811.c-371-\tif (!(value \u0026 DP83811_WOL_EN))\ndrivers/net/phy/dp83tc811.c:372:\t\tgenphy_suspend(phydev);\ndrivers/net/phy/dp83tc811.c-373-\n--\ndrivers/net/phy/dp83td510.c=939=static struct phy_driver dp83td510_driver[] = {\n--\ndrivers/net/phy/dp83td510.c-966-\ndrivers/net/phy/dp83td510.c:967:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/dp83td510.c-968-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/dp83tg720.c=644=static struct phy_driver dp83tg720_driver[] = {\n--\ndrivers/net/phy/dp83tg720.c-664-\ndrivers/net/phy/dp83tg720.c:665:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/dp83tg720.c-666-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/icplus.c=575=static struct phy_driver icplus_driver[] = {\n--\ndrivers/net/phy/icplus.c-582-\t.read_status\t= ip175c_read_status,\ndrivers/net/phy/icplus.c:583:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/icplus.c-584-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/icplus.c-590-\t.soft_reset\t= genphy_soft_reset,\ndrivers/net/phy/icplus.c:591:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/icplus.c-592-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/icplus.c-604-\t.soft_reset\t= genphy_soft_reset,\ndrivers/net/phy/icplus.c:605:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/icplus.c-606-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/icplus.c-621-\t.get_stats\t= ip101g_get_stats,\ndrivers/net/phy/icplus.c:622:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/icplus.c-623-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c=584=static struct phy_driver xway_gphy[] = {\n--\ndrivers/net/phy/intel-xway.c-594-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:595:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-596-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-613-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:614:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-615-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-632-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:633:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-634-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-651-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:652:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-653-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-669-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:670:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-671-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-687-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:688:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-689-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-705-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:706:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-707-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-723-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:724:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-725-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-741-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:742:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-743-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/intel-xway.c-759-\t\t.config_intr\t= xway_gphy_config_intr,\ndrivers/net/phy/intel-xway.c:760:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/intel-xway.c-761-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/lxt.c=308=static struct phy_driver lxt97x_driver[] = {\n--\ndrivers/net/phy/lxt.c-323-\t.handle_interrupt = lxt971_handle_interrupt,\ndrivers/net/phy/lxt.c:324:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/lxt.c-325-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/lxt.c-334-\t.read_status\t= lxt973a2_read_status,\ndrivers/net/phy/lxt.c:335:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/lxt.c-336-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/lxt.c-344-\t.config_aneg\t= lxt973_config_aneg,\ndrivers/net/phy/lxt.c:345:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/lxt.c-346-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/marvell.c=1842=static int marvell_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/marvell.c-1853-\t\t/* With the page set, use the generic suspend */\ndrivers/net/phy/marvell.c:1854:\t\terr = genphy_suspend(phydev);\ndrivers/net/phy/marvell.c-1855-\t\tif (err \u003c 0)\n--\ndrivers/net/phy/marvell.c-1864-\t/* With the page set, use the generic suspend */\ndrivers/net/phy/marvell.c:1865:\treturn genphy_suspend(phydev);\ndrivers/net/phy/marvell.c-1866-\n--\ndrivers/net/phy/marvell.c=2182=static int m88e1318_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/marvell.c-2186-\ndrivers/net/phy/marvell.c:2187:\treturn genphy_suspend(phydev);\ndrivers/net/phy/marvell.c-2188-}\n--\ndrivers/net/phy/marvell.c=3797=static struct phy_driver marvell_drivers[] = {\n--\ndrivers/net/phy/marvell.c-3808-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3809:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3810-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3825-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3826:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3827-\t\t.cable_test_start = m88e3082_vct_cable_test_start,\n--\ndrivers/net/phy/marvell.c-3842-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3843:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3844-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3866-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3867:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3868-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3891-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3892:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3893-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3911-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3912:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3913-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3931-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3932:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3933-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-3979-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:3980:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-3981-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4001-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4002:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4003-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4019-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4020:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4021-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4038-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4039:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4040-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4096-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4097:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4098-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4127-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4128:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4129-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4156-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4157:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4158-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4173-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4174:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4175-\t\t.get_sset_count = marvell_get_sset_count_simple,\n--\ndrivers/net/phy/marvell.c-4192-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4193:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4194-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4218-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4219:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4220-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4244-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4245:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4246-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4269-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4270:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4271-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/marvell.c-4291-\t\t.resume = genphy_resume,\ndrivers/net/phy/marvell.c:4292:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/marvell.c-4293-\t\t.read_page = marvell_read_page,\n--\ndrivers/net/phy/mediatek/mtk-2p5ge.c=379=static struct phy_driver mtk_2p5gephy_driver[] = {\n--\ndrivers/net/phy/mediatek/mtk-2p5ge.c-388-\t\t.get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,\ndrivers/net/phy/mediatek/mtk-2p5ge.c:389:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/mediatek/mtk-2p5ge.c-390-\t\t.resume = genphy_resume,\n--\ndrivers/net/phy/mediatek/mtk-fe-soc.c=30=static struct phy_driver mtk_soc_fe_phy_driver[] = {\n--\ndrivers/net/phy/mediatek/mtk-fe-soc.c-36-\t\t.write_page\t= mt7628_phy_write_page,\ndrivers/net/phy/mediatek/mtk-fe-soc.c:37:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/mediatek/mtk-fe-soc.c-38-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c=1495=static struct phy_driver mtk_socphy_driver[] = {\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1502-\t\t.probe\t\t= mt7981_phy_probe,\ndrivers/net/phy/mediatek/mtk-ge-soc.c:1503:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1504-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1519-\t\t.probe\t\t= mt7988_phy_probe,\ndrivers/net/phy/mediatek/mtk-ge-soc.c:1520:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/mediatek/mtk-ge-soc.c-1521-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/mediatek/mtk-ge.c=127=static struct phy_driver mtk_gephy_driver[] = {\n--\ndrivers/net/phy/mediatek/mtk-ge.c-137-\t\t.handle_interrupt = genphy_handle_interrupt_no_ack,\ndrivers/net/phy/mediatek/mtk-ge.c:138:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/mediatek/mtk-ge.c-139-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/mediatek/mtk-ge.c-151-\t\t.handle_interrupt = genphy_handle_interrupt_no_ack,\ndrivers/net/phy/mediatek/mtk-ge.c:152:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/mediatek/mtk-ge.c-153-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/meson-gxl.c=187=static struct phy_driver meson_gxl_phy[] = {\n--\ndrivers/net/phy/meson-gxl.c-197-\t\t.handle_interrupt = smsc_phy_handle_interrupt,\ndrivers/net/phy/meson-gxl.c:198:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/meson-gxl.c-199-\t\t.resume = genphy_resume,\n--\ndrivers/net/phy/meson-gxl.c-216-\ndrivers/net/phy/meson-gxl.c:217:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/meson-gxl.c-218-\t\t.resume = genphy_resume,\n--\ndrivers/net/phy/micrel.c=2591=static int kszphy_generic_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/micrel.c-2594-\ndrivers/net/phy/micrel.c:2595:\tret = genphy_suspend(phydev);\ndrivers/net/phy/micrel.c-2596-\tif (ret)\n--\ndrivers/net/phy/micrel.c-2603-\ndrivers/net/phy/micrel.c:2604:static int kszphy_suspend(struct phy_device *phydev)\ndrivers/net/phy/micrel.c-2605-{\n--\ndrivers/net/phy/micrel.c=2754=static int ksz8061_suspend(struct phy_device *phydev)\ndrivers/net/phy/micrel.c-2755-{\ndrivers/net/phy/micrel.c:2756:\treturn kszphy_suspend(phydev);\ndrivers/net/phy/micrel.c-2757-}\n--\ndrivers/net/phy/micrel.c=6693=static int lan9645x_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/micrel.c-6715-\ndrivers/net/phy/micrel.c:6716:\treturn genphy_suspend(phydev);\ndrivers/net/phy/micrel.c-6717-}\n--\ndrivers/net/phy/micrel.c=6781=static struct phy_driver ksphy_driver[] = {\n--\ndrivers/net/phy/micrel.c-6790-\t.handle_interrupt = kszphy_handle_interrupt,\ndrivers/net/phy/micrel.c:6791:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6792-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6805-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6806:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6807-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6820-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6821:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6822-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6849-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6850:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6851-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6863-\t.match_phy_device = ksz8051_match_phy_device,\ndrivers/net/phy/micrel.c:6864:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6865-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6878-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6879:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6880-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6896-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6897:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6898-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6925-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6926:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6927-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6944-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6945:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-6946-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-6961-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:6962:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/micrel.c-6963-\t.resume\t\t= kszphy_resume,\n--\ndrivers/net/phy/micrel.c-7049-\t.get_stats\t= kszphy_get_stats,\ndrivers/net/phy/micrel.c:7050:\t.suspend\t= kszphy_suspend,\ndrivers/net/phy/micrel.c-7051-\t.resume\t\t= ksz9131_resume,\n--\ndrivers/net/phy/micrel.c-7062-\t.read_status\t= ksz8873mll_read_status,\ndrivers/net/phy/micrel.c:7063:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/micrel.c-7064-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/micrel.c-7073-\t.read_status\t= ksz886x_read_status,\ndrivers/net/phy/micrel.c:7074:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/micrel.c-7075-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/micrel.c-7084-\t.set_tunable\t= ksz8795_set_tunable,\ndrivers/net/phy/micrel.c:7085:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/micrel.c-7086-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/micrel.c-7096-\t.handle_interrupt = kszphy_handle_interrupt,\ndrivers/net/phy/micrel.c:7097:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/micrel.c-7098-\t.resume\t\t= ksz9477_resume,\n--\ndrivers/net/phy/microchip.c=42=static int lan88xx_suspend(struct phy_device *phydev)\n--\ndrivers/net/phy/microchip.c-47-\tif (!priv-\u003ewolopts)\ndrivers/net/phy/microchip.c:48:\t\tgenphy_suspend(phydev);\ndrivers/net/phy/microchip.c-49-\n--\ndrivers/net/phy/microchip.c=546=static struct phy_driver microchip_phy_driver[] = {\n--\ndrivers/net/phy/microchip.c-582-\t.name\t\t= \"Microchip LAN937x TX\",\ndrivers/net/phy/microchip.c:583:\t.suspend\t= genphy_suspend,\ndrivers/net/phy/microchip.c-584-\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/microchip_t1.c=2106=static struct phy_driver microchip_t1_phy_driver[] = {\n--\ndrivers/net/phy/microchip_t1.c-2114-\t\t.handle_interrupt = lan87xx_handle_interrupt,\ndrivers/net/phy/microchip_t1.c:2115:\t\t.suspend = genphy_suspend,\ndrivers/net/phy/microchip_t1.c-2116-\t\t.resume = genphy_resume,\n--\ndrivers/net/phy/microchip_t1.c-2131-\t\t.handle_interrupt = lan87xx_handle_interrupt,\ndrivers/net/phy/microchip_t1.c:2132:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/microchip_t1.c-2133-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/microchip_t1.c-2151-\t\t.get_strings = lan887x_get_strings,\ndrivers/net/phy/microchip_t1.c:2152:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/microchip_t1.c-2153-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/motorcomm.c=3107=static struct phy_driver motorcomm_phy_drvs[] = {\n--\ndrivers/net/phy/motorcomm.c-3111-\t\t.config_init\t= yt8511_config_init,\ndrivers/net/phy/motorcomm.c:3112:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/motorcomm.c-3113-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/motorcomm.c-3141-\t\t.config_init\t= yt8522_config_init,\ndrivers/net/phy/motorcomm.c:3142:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/motorcomm.c-3143-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/motorcomm.c-3149-\t\t.config_init\t= yt8531_config_init,\ndrivers/net/phy/motorcomm.c:3150:\t\t.suspend\t= genphy_suspend,\ndrivers/net/phy/motorcomm.c-3151-\t\t.resume\t\t= genphy_resume,\n--\ndrivers/net/phy/mscc/mscc_main.c=2548=static struct phy_driver vsc85xx_driver[] = {\n--\ndrivers/net/phy/mscc/mscc_main.c-2559-\t.config_intr\t= \u0026vsc85xx_config_intr,\ndrivers/net/phy/mscc/mscc_main.c:2560:\t.suspend\t= \u0026genphy_suspend,\ndrivers/net/phy/mscc/mscc_main.c-2561-\t.resume\t\t= \u0026genphy_resume,\n\n"
} |
| 58/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 47436 output: 29 thoughts: 54 Thoughts: **Investigating the Wake-on-LAN Function Call** Okay, so I need to trace the execution of `m88e1318_set_wol()`. First things first, let's figure out where this function is even being called. Given that it's related to Wake-on-LAN, I'll start by searching within the common PHY driver areas. I'll search for `set_wol` within the `drivers/net/phy/phy.c` and `phy_device.c` source files. Those seem like the most likely candidates to contain the code that's initializing or controlling the PHY's Wake-on-LAN capabilities. Time to dig in and see what the call graph looks like. |
| 59/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "set_wol",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/air_an8801.c=680=static void an8801r_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/air_an8801.c-707-\ndrivers/net/phy/air_an8801.c:708:static int an8801r_set_wol(struct phy_device *phydev,\ndrivers/net/phy/air_an8801.c-709-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/air_an8801.c=1122=static struct phy_driver airoha_driver[] = {\n--\ndrivers/net/phy/air_an8801.c-1133-\t.handle_interrupt\t= an8801r_handle_interrupt,\ndrivers/net/phy/air_an8801.c:1134:\t.set_wol\t\t= an8801r_set_wol,\ndrivers/net/phy/air_an8801.c-1135-\t.get_wol\t\t= an8801r_get_wol,\n--\ndrivers/net/phy/bcm-phy-lib.c=875=EXPORT_SYMBOL_GPL(bcm_phy_cable_test_get_status_rdb);\n--\ndrivers/net/phy/bcm-phy-lib.c-882-\ndrivers/net/phy/bcm-phy-lib.c:883:int bcm_phy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)\ndrivers/net/phy/bcm-phy-lib.c-884-{\n--\ndrivers/net/phy/bcm-phy-lib.c-1030-}\ndrivers/net/phy/bcm-phy-lib.c:1031:EXPORT_SYMBOL_GPL(bcm_phy_set_wol);\ndrivers/net/phy/bcm-phy-lib.c-1032-\n--\ndrivers/net/phy/bcm-phy-lib.h=113=static inline void bcm_ptp_stop(struct bcm_ptp_private *priv)\n--\ndrivers/net/phy/bcm-phy-lib.h-117-\ndrivers/net/phy/bcm-phy-lib.h:118:int bcm_phy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);\ndrivers/net/phy/bcm-phy-lib.h-119-void bcm_phy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);\n--\ndrivers/net/phy/broadcom.c=1134=static void bcm54xx_phy_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/broadcom.c-1149-\ndrivers/net/phy/broadcom.c:1150:static int bcm54xx_phy_set_wol(struct phy_device *phydev,\ndrivers/net/phy/broadcom.c-1151-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/broadcom.c-1162-\ndrivers/net/phy/broadcom.c:1163:\tret = bcm_phy_set_wol(phydev, wol);\ndrivers/net/phy/broadcom.c-1164-\tif (ret \u003c 0)\n--\ndrivers/net/phy/broadcom.c=1466=static struct phy_driver broadcom_drivers[] = {\n--\ndrivers/net/phy/broadcom.c-1506-\t.get_wol\t= bcm54xx_phy_get_wol,\ndrivers/net/phy/broadcom.c:1507:\t.set_wol\t= bcm54xx_phy_set_wol,\ndrivers/net/phy/broadcom.c-1508-\t.led_brightness_set\t= bcm_phy_led_brightness_set,\n--\ndrivers/net/phy/dp83822.c=214=static int dp83822_config_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/dp83822.c-275-\ndrivers/net/phy/dp83822.c:276:static int dp83822_set_wol(struct phy_device *phydev,\ndrivers/net/phy/dp83822.c-277-\t\t\t struct ethtool_wolinfo *wol)\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-1192-\t\t.get_wol = dp83822_get_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c:1193:\t\t.set_wol = dp83822_set_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c-1194-\t\t.config_intr = dp83822_config_intr,\t\t\\\n--\ndrivers/net/phy/dp83822.c-1212-\t\t.get_wol = dp83822_get_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c:1213:\t\t.set_wol = dp83822_set_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c-1214-\t\t.config_intr = dp83822_config_intr,\t\t\\\n--\ndrivers/net/phy/dp83822.c-1228-\t\t.get_wol = dp83822_get_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c:1229:\t\t.set_wol = dp83822_set_wol,\t\t\t\\\ndrivers/net/phy/dp83822.c-1230-\t\t.config_intr = dp83822_config_intr,\t\t\\\n--\ndrivers/net/phy/dp83867.c=201=static int dp83867_ack_interrupt(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83867.c-210-\ndrivers/net/phy/dp83867.c:211:static int dp83867_set_wol(struct phy_device *phydev,\ndrivers/net/phy/dp83867.c-212-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/dp83867.c=1183=static struct phy_driver dp83867_driver[] = {\n--\ndrivers/net/phy/dp83867.c-1199-\t\t.get_wol\t= dp83867_get_wol,\ndrivers/net/phy/dp83867.c:1200:\t\t.set_wol\t= dp83867_set_wol,\ndrivers/net/phy/dp83867.c-1201-\n--\ndrivers/net/phy/dp83869.c=235=static irqreturn_t dp83869_handle_interrupt(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83869.c-258-\ndrivers/net/phy/dp83869.c:259:static int dp83869_set_wol(struct phy_device *phydev,\ndrivers/net/phy/dp83869.c-260-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/dp83869.c=898=static int dp83869_phy_reset(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83869.c-928-\t.get_wol\t= dp83869_get_wol,\t\t\t\\\ndrivers/net/phy/dp83869.c:929:\t.set_wol\t= dp83869_set_wol,\t\t\t\\\ndrivers/net/phy/dp83869.c-930-\t.suspend\t= genphy_suspend,\t\t\t\\\n--\ndrivers/net/phy/dp83tc811.c=78=static int dp83811_ack_interrupt(struct phy_device *phydev)\n--\ndrivers/net/phy/dp83tc811.c-96-\ndrivers/net/phy/dp83tc811.c:97:static int dp83811_set_wol(struct phy_device *phydev,\ndrivers/net/phy/dp83tc811.c-98-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/dp83tc811.c=387=static struct phy_driver dp83811_driver[] = {\n--\ndrivers/net/phy/dp83tc811.c-397-\t\t.get_wol = dp83811_get_wol,\ndrivers/net/phy/dp83tc811.c:398:\t\t.set_wol = dp83811_set_wol,\ndrivers/net/phy/dp83tc811.c-399-\t\t.config_intr = dp83811_config_intr,\n--\ndrivers/net/phy/marvell.c=2022=static void m88e1318_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/marvell.c-2041-\ndrivers/net/phy/marvell.c:2042:static int m88e1318_set_wol(struct phy_device *phydev,\ndrivers/net/phy/marvell.c-2043-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/marvell.c-2163-\t\t\tstruct ethtool_wolinfo wol_off = { .wolopts = 0 };\ndrivers/net/phy/marvell.c:2164:\t\t\tint rollback_err = m88e1318_set_wol(phydev, \u0026wol_off);\ndrivers/net/phy/marvell.c-2165-\n--\ndrivers/net/phy/marvell.c=3797=static struct phy_driver marvell_drivers[] = {\n--\ndrivers/net/phy/marvell.c-3953-\t\t.get_wol = m88e1318_get_wol,\ndrivers/net/phy/marvell.c:3954:\t\t.set_wol = m88e1318_set_wol,\ndrivers/net/phy/marvell.c-3955-\t\t.resume = m88e1318_resume,\n--\ndrivers/net/phy/marvell.c-4061-\t\t.get_wol = m88e1318_get_wol,\ndrivers/net/phy/marvell.c:4062:\t\t.set_wol = m88e1318_set_wol,\ndrivers/net/phy/marvell.c-4063-\t\t.resume = m88e1510_resume,\n--\ndrivers/net/phy/marvell10g.c=1314=static void mv3110_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/marvell10g.c-1329-\ndrivers/net/phy/marvell10g.c:1330:static int mv3110_set_wol(struct phy_device *phydev,\ndrivers/net/phy/marvell10g.c-1331-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/marvell10g.c=1388=static struct phy_driver mv3310_drivers[] = {\n--\ndrivers/net/phy/marvell10g.c-1407-\t\t.get_wol\t= mv3110_get_wol,\ndrivers/net/phy/marvell10g.c:1408:\t\t.set_wol\t= mv3110_set_wol,\ndrivers/net/phy/marvell10g.c-1409-\t\t.attach_mii_port = mv3310_attach_mii_port,\n--\ndrivers/net/phy/marvell10g.c-1450-\t\t.get_wol\t= mv3110_get_wol,\ndrivers/net/phy/marvell10g.c:1451:\t\t.set_wol\t= mv3110_set_wol,\ndrivers/net/phy/marvell10g.c-1452-\t\t.attach_mii_port = mv3310_attach_mii_port,\n--\ndrivers/net/phy/microchip.c=309=static void lan88xx_remove(struct phy_device *phydev)\n--\ndrivers/net/phy/microchip.c-317-\ndrivers/net/phy/microchip.c:318:static int lan88xx_set_wol(struct phy_device *phydev,\ndrivers/net/phy/microchip.c-319-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/microchip.c=546=static struct phy_driver microchip_phy_driver[] = {\n--\ndrivers/net/phy/microchip.c-573-\t.resume\t\t= genphy_resume,\ndrivers/net/phy/microchip.c:574:\t.set_wol\t= lan88xx_set_wol,\ndrivers/net/phy/microchip.c-575-\t.read_page\t= lan88xx_read_page,\n--\ndrivers/net/phy/motorcomm.c=537=static void ytphy_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/motorcomm.c-553-/**\ndrivers/net/phy/motorcomm.c:554: * ytphy_set_wol() - turn wake-on-lan on or off\ndrivers/net/phy/motorcomm.c-555- * @phydev: a pointer to a \u0026struct phy_device\n--\ndrivers/net/phy/motorcomm.c-563- */\ndrivers/net/phy/motorcomm.c:564:static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)\ndrivers/net/phy/motorcomm.c-565-{\n--\ndrivers/net/phy/motorcomm.c-635-\ndrivers/net/phy/motorcomm.c:636:static int yt8531_set_wol(struct phy_device *phydev,\ndrivers/net/phy/motorcomm.c-637-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/motorcomm.c=3107=static struct phy_driver motorcomm_phy_drvs[] = {\n--\ndrivers/net/phy/motorcomm.c-3124-\t\t.get_wol\t= ytphy_get_wol,\ndrivers/net/phy/motorcomm.c:3125:\t\t.set_wol\t= ytphy_set_wol,\ndrivers/net/phy/motorcomm.c-3126-\t\t.config_aneg\t= yt8521_config_aneg,\n--\ndrivers/net/phy/motorcomm.c-3152-\t\t.get_wol\t= ytphy_get_wol,\ndrivers/net/phy/motorcomm.c:3153:\t\t.set_wol\t= yt8531_set_wol,\ndrivers/net/phy/motorcomm.c-3154-\t\t.link_change_notify = yt8531_link_change_notify,\n--\ndrivers/net/phy/motorcomm.c-3166-\t\t.get_wol\t= ytphy_get_wol,\ndrivers/net/phy/motorcomm.c:3167:\t\t.set_wol\t= ytphy_set_wol,\ndrivers/net/phy/motorcomm.c-3168-\t\t.config_aneg\t= yt8521_config_aneg,\n--\ndrivers/net/phy/motorcomm.c-3182-\t\t.get_wol\t\t= ytphy_get_wol,\ndrivers/net/phy/motorcomm.c:3183:\t\t.set_wol\t\t= ytphy_set_wol,\ndrivers/net/phy/motorcomm.c-3184-\t\t.config_aneg\t\t= genphy_config_aneg,\n--\ndrivers/net/phy/mscc/mscc_main.c=2548=static struct phy_driver vsc85xx_driver[] = {\n--\ndrivers/net/phy/mscc/mscc_main.c-2562-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2563:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2564-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2590-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2591:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2592-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2619-\t.probe\t\t= \u0026vsc8574_probe,\ndrivers/net/phy/mscc/mscc_main.c:2620:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2621-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2648-\t.probe\t\t= \u0026vsc8514_probe,\ndrivers/net/phy/mscc/mscc_main.c:2649:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2650-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2678-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2679:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2680-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2706-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2707:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2708-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2734-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2735:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2736-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2762-\t.probe\t\t= \u0026vsc85xx_probe,\ndrivers/net/phy/mscc/mscc_main.c:2763:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2764-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2790-\t.probe\t\t= \u0026vsc8574_probe,\ndrivers/net/phy/mscc/mscc_main.c:2791:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2792-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2849-\t.probe\t\t= \u0026vsc8584_probe,\ndrivers/net/phy/mscc/mscc_main.c:2850:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2851-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mscc/mscc_main.c-2881-\t.probe\t\t= \u0026vsc8584_probe,\ndrivers/net/phy/mscc/mscc_main.c:2882:\t.set_wol\t= \u0026vsc85xx_wol_set,\ndrivers/net/phy/mscc/mscc_main.c-2883-\t.get_wol\t= \u0026vsc85xx_wol_get,\n--\ndrivers/net/phy/mxl-86110.c=338=static void mxl86110_get_wol(struct phy_device *phydev,\n--\ndrivers/net/phy/mxl-86110.c-350-/**\ndrivers/net/phy/mxl-86110.c:351: * mxl86110_set_wol() - enable/disable wake-on-lan\ndrivers/net/phy/mxl-86110.c-352- * @phydev: pointer to the phy_device\n--\ndrivers/net/phy/mxl-86110.c-358- */\ndrivers/net/phy/mxl-86110.c:359:static int mxl86110_set_wol(struct phy_device *phydev,\ndrivers/net/phy/mxl-86110.c-360-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/mxl-86110.c=936=static struct phy_driver mxl_phy_drvs[] = {\n--\ndrivers/net/phy/mxl-86110.c-944-\t\t.get_wol\t\t= mxl86110_get_wol,\ndrivers/net/phy/mxl-86110.c:945:\t\t.set_wol\t\t= mxl86110_set_wol,\ndrivers/net/phy/mxl-86110.c-946-\t\t.led_brightness_set\t= mxl86110_led_brightness_set,\n--\ndrivers/net/phy/mxl-86110.c-956-\t\t.get_wol\t\t= mxl86110_get_wol,\ndrivers/net/phy/mxl-86110.c:957:\t\t.set_wol\t\t= mxl86110_set_wol,\ndrivers/net/phy/mxl-86110.c-958-\t\t.inband_caps\t\t= mxl86111_inband_caps,\n--\ndrivers/net/phy/mxl-gpy.c=708=static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)\n--\ndrivers/net/phy/mxl-gpy.c-746-\ndrivers/net/phy/mxl-gpy.c:747:static int gpy_set_wol(struct phy_device *phydev,\ndrivers/net/phy/mxl-gpy.c-748-\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/mxl-gpy.c=1102=static struct phy_driver gpy_drivers[] = {\n--\ndrivers/net/phy/mxl-gpy.c-1117-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1118:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1119-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1144-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1145:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1146-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1170-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1171:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1172-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1197-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1198:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1199-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1223-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1224:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1225-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1250-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1251:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1252-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1276-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1277:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1278-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1303-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1304:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1305-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1329-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1330:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1331-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1355-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1356:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1357-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1376-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1377:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1378-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1397-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1398:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1399-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1418-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1419:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1420-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1442-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1443:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1444-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/mxl-gpy.c-1466-\t\t.handle_interrupt = gpy_handle_interrupt,\ndrivers/net/phy/mxl-gpy.c:1467:\t\t.set_wol\t= gpy_set_wol,\ndrivers/net/phy/mxl-gpy.c-1468-\t\t.get_wol\t= gpy_get_wol,\n--\ndrivers/net/phy/phy.c=2019=EXPORT_SYMBOL(phy_ethtool_set_eee);\n--\ndrivers/net/phy/phy.c-2021-/**\ndrivers/net/phy/phy.c:2022: * phy_ethtool_set_wol - Configure Wake On LAN\ndrivers/net/phy/phy.c-2023- *\n--\ndrivers/net/phy/phy.c-2026- */\ndrivers/net/phy/phy.c:2027:int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)\ndrivers/net/phy/phy.c-2028-{\n--\ndrivers/net/phy/phy.c-2030-\ndrivers/net/phy/phy.c:2031:\tif (phydev-\u003edrv \u0026\u0026 phydev-\u003edrv-\u003eset_wol) {\ndrivers/net/phy/phy.c-2032-\t\tmutex_lock(\u0026phydev-\u003elock);\ndrivers/net/phy/phy.c:2033:\t\tret = phydev-\u003edrv-\u003eset_wol(phydev, wol);\ndrivers/net/phy/phy.c-2034-\t\tmutex_unlock(\u0026phydev-\u003elock);\n--\ndrivers/net/phy/phy.c-2040-}\ndrivers/net/phy/phy.c:2041:EXPORT_SYMBOL(phy_ethtool_set_wol);\ndrivers/net/phy/phy.c-2042-\n--\ndrivers/net/phy/phylink.c=2710=static bool phylink_phy_pm_speed_ctrl(struct phylink *pl)\n--\ndrivers/net/phy/phylink.c-2730- * Note: when phylink managed Wake-on-Lan is in use, @mac_wol is ignored.\ndrivers/net/phy/phylink.c:2731: * (struct phylink_mac_ops.mac_set_wol populated.)\ndrivers/net/phy/phylink.c-2732- */\n--\ndrivers/net/phy/phylink.c=2874=EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol);\n--\ndrivers/net/phy/phylink.c-2876-/**\ndrivers/net/phy/phylink.c:2877: * phylink_ethtool_set_wol() - set wake on lan parameters\ndrivers/net/phy/phylink.c-2878- * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\n--\ndrivers/net/phy/phylink.c-2886- */\ndrivers/net/phy/phylink.c:2887:int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)\ndrivers/net/phy/phylink.c-2888-{\n--\ndrivers/net/phy/phylink.c-2899-\t\tif (phylink_phy_supports_wol(pl, pl-\u003ephydev)) {\ndrivers/net/phy/phylink.c:2900:\t\t\tret = phy_ethtool_set_wol(pl-\u003ephydev, wol);\ndrivers/net/phy/phylink.c-2901-\t\t\tif (ret != 0 \u0026\u0026 ret != -EOPNOTSUPP)\n--\ndrivers/net/phy/phylink.c-2928-\t\tif (pl-\u003ephydev)\ndrivers/net/phy/phylink.c:2929:\t\t\tret = phy_ethtool_set_wol(pl-\u003ephydev, wol);\ndrivers/net/phy/phylink.c-2930-\t}\n--\ndrivers/net/phy/phylink.c-2933-}\ndrivers/net/phy/phylink.c:2934:EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol);\ndrivers/net/phy/phylink.c-2935-\n--\ndrivers/net/phy/qcom/at803x.c=1113=static struct phy_driver at803x_driver[] = {\n--\ndrivers/net/phy/qcom/at803x.c-1122-\t.soft_reset\t\t= genphy_soft_reset,\ndrivers/net/phy/qcom/at803x.c:1123:\t.set_wol\t\t= at803x_set_wol,\ndrivers/net/phy/qcom/at803x.c-1124-\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/at803x.c-1142-\t.link_change_notify\t= at803x_link_change_notify,\ndrivers/net/phy/qcom/at803x.c:1143:\t.set_wol\t\t= at803x_set_wol,\ndrivers/net/phy/qcom/at803x.c-1144-\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/at803x.c-1158-\t.soft_reset\t\t= genphy_soft_reset,\ndrivers/net/phy/qcom/at803x.c:1159:\t.set_wol\t\t= at8031_set_wol,\ndrivers/net/phy/qcom/at803x.c-1160-\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/qca807x.c=791=static struct phy_driver qca807x_drivers[] = {\n--\ndrivers/net/phy/qcom/qca807x.c-810-\t\t.get_phy_stats\t\t= qca807x_get_phy_stats,\ndrivers/net/phy/qcom/qca807x.c:811:\t\t.set_wol\t\t= at8031_set_wol,\ndrivers/net/phy/qcom/qca807x.c-812-\t\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/qca807x.c-838-\t\t.get_phy_stats\t\t= qca807x_get_phy_stats,\ndrivers/net/phy/qcom/qca807x.c:839:\t\t.set_wol\t\t= at8031_set_wol,\ndrivers/net/phy/qcom/qca807x.c-840-\t\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/qca808x.c=646=static struct phy_driver qca808x_driver[] = {\n--\ndrivers/net/phy/qcom/qca808x.c-656-\t.set_tunable\t\t= at803x_set_tunable,\ndrivers/net/phy/qcom/qca808x.c:657:\t.set_wol\t\t= at8031_set_wol,\ndrivers/net/phy/qcom/qca808x.c-658-\t.get_wol\t\t= at803x_get_wol,\n--\ndrivers/net/phy/qcom/qcom-phy-lib.c=57=EXPORT_SYMBOL_GPL(at803x_debug_reg_write);\ndrivers/net/phy/qcom/qcom-phy-lib.c-58-\ndrivers/net/phy/qcom/qcom-phy-lib.c:59:int at803x_set_wol(struct phy_device *phydev,\ndrivers/net/phy/qcom/qcom-phy-lib.c-60-\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/qcom/qcom-phy-lib.c-115-}\ndrivers/net/phy/qcom/qcom-phy-lib.c:116:EXPORT_SYMBOL_GPL(at803x_set_wol);\ndrivers/net/phy/qcom/qcom-phy-lib.c-117-\ndrivers/net/phy/qcom/qcom-phy-lib.c:118:int at8031_set_wol(struct phy_device *phydev,\ndrivers/net/phy/qcom/qcom-phy-lib.c-119-\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/qcom/qcom-phy-lib.c-123-\t/* First setup MAC address and enable WOL interrupt */\ndrivers/net/phy/qcom/qcom-phy-lib.c:124:\tret = at803x_set_wol(phydev, wol);\ndrivers/net/phy/qcom/qcom-phy-lib.c-125-\tif (ret)\n--\ndrivers/net/phy/qcom/qcom-phy-lib.c-140-}\ndrivers/net/phy/qcom/qcom-phy-lib.c:141:EXPORT_SYMBOL_GPL(at8031_set_wol);\ndrivers/net/phy/qcom/qcom-phy-lib.c-142-\n--\ndrivers/net/phy/qcom/qcom.h=236=int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data);\ndrivers/net/phy/qcom/qcom.h:237:int at803x_set_wol(struct phy_device *phydev,\ndrivers/net/phy/qcom/qcom.h-238-\t\t struct ethtool_wolinfo *wol);\ndrivers/net/phy/qcom/qcom.h:239:int at8031_set_wol(struct phy_device *phydev,\ndrivers/net/phy/qcom/qcom.h-240-\t\t struct ethtool_wolinfo *wol);\n--\ndrivers/net/phy/realtek/realtek_main.c=957=static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/realtek/realtek_main.c-978-\ndrivers/net/phy/realtek/realtek_main.c:979:static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)\ndrivers/net/phy/realtek/realtek_main.c-980-{\n--\ndrivers/net/phy/realtek/realtek_main.c=3046=static struct phy_driver realtek_drvs[] = {\n--\ndrivers/net/phy/realtek/realtek_main.c-3126-\t\t.handle_interrupt = rtl8211f_handle_interrupt,\ndrivers/net/phy/realtek/realtek_main.c:3127:\t\t.set_wol\t= rtl8211f_set_wol,\ndrivers/net/phy/realtek/realtek_main.c-3128-\t\t.get_wol\t= rtl8211f_get_wol,\n--\ndrivers/net/phy/smsc.c=377=static int lan874x_chk_wol_pattern(const u8 pattern[], const u16 *mask,\n--\ndrivers/net/phy/smsc.c-413-\ndrivers/net/phy/smsc.c:414:static int lan874x_set_wol_pattern(struct phy_device *phydev, u16 val,\ndrivers/net/phy/smsc.c-415-\t\t\t\t const u8 data[], u8 datalen,\n--\ndrivers/net/phy/smsc.c-452-\ndrivers/net/phy/smsc.c:453:static int lan874x_set_wol(struct phy_device *phydev,\ndrivers/net/phy/smsc.c-454-\t\t\t struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/smsc.c-510-\t\tval = 12 | MII_LAN874X_PHY_WOL_FILTER_BCSTEN;\ndrivers/net/phy/smsc.c:511:\t\trc = lan874x_set_wol_pattern(phydev, val, data, datalen, mask,\ndrivers/net/phy/smsc.c-512-\t\t\t\t\t 2);\n--\ndrivers/net/phy/smsc.c-520-\t\tval = MII_LAN874X_PHY_WOL_FILTER_MCASTTEN;\ndrivers/net/phy/smsc.c:521:\t\trc = lan874x_set_wol_pattern(phydev, val, data, 0, NULL, 0);\ndrivers/net/phy/smsc.c-522-\t\tif (rc \u003c 0)\n--\ndrivers/net/phy/smsc.c=687=static struct phy_driver smsc_phy_driver[] = {\n--\ndrivers/net/phy/smsc.c-838-\t/* WoL */\ndrivers/net/phy/smsc.c:839:\t.set_wol\t= lan874x_set_wol,\ndrivers/net/phy/smsc.c-840-\t.get_wol\t= lan874x_get_wol,\n--\ndrivers/net/phy/smsc.c-875-\t/* WoL */\ndrivers/net/phy/smsc.c:876:\t.set_wol\t= lan874x_set_wol,\ndrivers/net/phy/smsc.c-877-\t.get_wol\t= lan874x_get_wol,\n"
} |
| 60/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 59055 output: 23 thoughts: 61 Thoughts: **Investigating the Wake-on-LAN Configuration** Okay, so `phy_ethtool_set_wol` is the function that gets the ball rolling for Wake-on-LAN configuration. Seems pretty straightforward: it calls `phydev->drv->set_wol(phydev, wol)`. That makes sense - the PHY driver has its own specific implementation. But I need to understand the calling context to see *why* this is being invoked. Where is this `phy_ethtool_set_wol` function actually being called from? Time to whip out the grep tool and find all the instances of `phy_ethtool_set_wol`. That should give me the larger picture. |
| 61/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "phy_ethtool_set_wol"
}Results: {
"Output": "Documentation/networking/sfp-phylink.rst=74=this documentation.\n--\nDocumentation/networking/sfp-phylink.rst-127- - phylink_ethtool_get_wol(priv-\u003ephylink, wol)\nDocumentation/networking/sfp-phylink.rst:128: * - phy_ethtool_set_wol(phydev, wol)\nDocumentation/networking/sfp-phylink.rst-129- - phylink_ethtool_set_wol(priv-\u003ephylink, wol)\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c=194=static int bcmasp_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-202-\tif (dev-\u003ephydev) {\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c:203:\t\tret = phy_ethtool_set_wol(dev-\u003ephydev, wol);\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-204-\t\tif (ret != -EOPNOTSUPP \u0026\u0026 wol-\u003ewolopts)\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet_wol.c=72=int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet_wol.c-79-\tif (dev-\u003ephydev) {\ndrivers/net/ethernet/broadcom/genet/bcmgenet_wol.c:80:\t\tret = phy_ethtool_set_wol(dev-\u003ephydev, wol);\ndrivers/net/ethernet/broadcom/genet/bcmgenet_wol.c-81-\t\tif (ret != -EOPNOTSUPP \u0026\u0026 wol-\u003ewolopts)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_ethtool.c=1235=static int enetc_set_wol(struct net_device *dev,\n--\ndrivers/net/ethernet/freescale/enetc/enetc_ethtool.c-1242-\ndrivers/net/ethernet/freescale/enetc/enetc_ethtool.c:1243:\tret = phy_ethtool_set_wol(dev-\u003ephydev, wol);\ndrivers/net/ethernet/freescale/enetc/enetc_ethtool.c-1244-\tif (!ret)\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c=1551=mv643xx_eth_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1557-\ndrivers/net/ethernet/marvell/mv643xx_eth.c:1558:\terr = phy_ethtool_set_wol(dev-\u003ephydev, wol);\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1559-\t/* Given that mv643xx_eth works without the marvell-specific PHY driver,\n--\ndrivers/net/ethernet/socionext/sni_ave.c=428=static int __ave_ethtool_set_wol(struct net_device *ndev,\n--\ndrivers/net/ethernet/socionext/sni_ave.c-434-\ndrivers/net/ethernet/socionext/sni_ave.c:435:\treturn phy_ethtool_set_wol(ndev-\u003ephydev, wol);\ndrivers/net/ethernet/socionext/sni_ave.c-436-}\n--\ndrivers/net/ethernet/ti/cpsw_ethtool.c=339=int cpsw_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)\n--\ndrivers/net/ethernet/ti/cpsw_ethtool.c-345-\tif (cpsw-\u003eslaves[slave_no].phy)\ndrivers/net/ethernet/ti/cpsw_ethtool.c:346:\t\treturn phy_ethtool_set_wol(cpsw-\u003eslaves[slave_no].phy, wol);\ndrivers/net/ethernet/ti/cpsw_ethtool.c-347-\telse\n--\ndrivers/net/phy/phy.c=2019=EXPORT_SYMBOL(phy_ethtool_set_eee);\n--\ndrivers/net/phy/phy.c-2021-/**\ndrivers/net/phy/phy.c:2022: * phy_ethtool_set_wol - Configure Wake On LAN\ndrivers/net/phy/phy.c-2023- *\n--\ndrivers/net/phy/phy.c-2026- */\ndrivers/net/phy/phy.c:2027:int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)\ndrivers/net/phy/phy.c-2028-{\n--\ndrivers/net/phy/phy.c-2040-}\ndrivers/net/phy/phy.c:2041:EXPORT_SYMBOL(phy_ethtool_set_wol);\ndrivers/net/phy/phy.c-2042-\n--\ndrivers/net/phy/phylink.c=2887=int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)\n--\ndrivers/net/phy/phylink.c-2899-\t\tif (phylink_phy_supports_wol(pl, pl-\u003ephydev)) {\ndrivers/net/phy/phylink.c:2900:\t\t\tret = phy_ethtool_set_wol(pl-\u003ephydev, wol);\ndrivers/net/phy/phylink.c-2901-\t\t\tif (ret != 0 \u0026\u0026 ret != -EOPNOTSUPP)\n--\ndrivers/net/phy/phylink.c-2928-\t\tif (pl-\u003ephydev)\ndrivers/net/phy/phylink.c:2929:\t\t\tret = phy_ethtool_set_wol(pl-\u003ephydev, wol);\ndrivers/net/phy/phylink.c-2930-\t}\n--\ndrivers/net/usb/lan78xx.c=1788=static int lan78xx_set_wol(struct net_device *netdev,\n--\ndrivers/net/usb/lan78xx.c-1807-\ndrivers/net/usb/lan78xx.c:1808:\tret = phy_ethtool_set_wol(netdev-\u003ephydev, wol);\ndrivers/net/usb/lan78xx.c-1809-\n--\ninclude/linux/phy.h=2453=int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_keee *data);\ninclude/linux/phy.h:2454:int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);\ninclude/linux/phy.h-2455-void phy_ethtool_get_wol(struct phy_device *phydev,\n"
} |
| 62/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 61155 output: 35 thoughts: 102 Thoughts: **Investigating the LAN78xx Wake-on-LAN Implementation** Okay, let's dive into this `lan78xx.c` driver code. Specifically, I need to understand how the Wake-on-LAN (WoL) functionality is implemented. Alright, `drivers/net/usb/lan78xx.c` it is. Now, I see that the function `lan78xx_set_wol()` takes care of setting the WoL configuration. Interesting, and it looks like it's calling `phy_ethtool_set_wol()` with the network device's PHY device. But hang on a second... how exactly *is* the PHY device attached in the context of this LAN78xx driver? That's the crucial piece of the puzzle I need to understand. Let's head back to the `lan78xx.c` code to trace how that PHY connection is established. I need to understand the whole picture here. |
| 63/2 | 2026/09/13 00:17 | tool | grepper |
0mError:no matches Args: {
"Expression": "phy_connect",
"PathPrefix": "drivers/net/usb/lan78xx.c"
}Results: {
"error": "no matches"
} |
| 64/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 61513 output: 34 thoughts: 16 Thoughts: Here's my thought process, as it went down: **Investigating the LAN78xx Driver** Okay, so I need to find something related to "phy" within the `lan78xx.c` file. This likely points to the PHY (Physical Layer) component of the LAN78xx ethernet controller. That's a good starting point, as it could be related to various PHY-specific configurations, initialization, or even error handling. Let's get to it. Time to run a quick `grep phy lan78xx.c` to see what comes back. I wonder what I'll find? |
| 65/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "phy_",
"PathPrefix": "drivers/net/usb/lan78xx.c"
}Results: {
"Output": "drivers/net/usb/lan78xx.c=413=struct lan78xx_net {\n--\ndrivers/net/usb/lan78xx.c-459-\tstruct mii_bus\t\t*mdiobus;\ndrivers/net/usb/lan78xx.c:460:\tphy_interface_t\t\tinterface;\ndrivers/net/usb/lan78xx.c-461-\n--\ndrivers/net/usb/lan78xx.c=1582=static int lan78xx_mac_reset(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-1628-/**\ndrivers/net/usb/lan78xx.c:1629: * lan78xx_phy_int_ack - Acknowledge PHY interrupt\ndrivers/net/usb/lan78xx.c-1630- * @dev: pointer to the LAN78xx device structure\n--\ndrivers/net/usb/lan78xx.c-1636- */\ndrivers/net/usb/lan78xx.c:1637:static int lan78xx_phy_int_ack(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-1638-{\n--\ndrivers/net/usb/lan78xx.c=1788=static int lan78xx_set_wol(struct net_device *netdev,\n--\ndrivers/net/usb/lan78xx.c-1807-\ndrivers/net/usb/lan78xx.c:1808:\tret = phy_ethtool_set_wol(netdev-\u003ephydev, wol);\ndrivers/net/usb/lan78xx.c-1809-\n--\ndrivers/net/usb/lan78xx.c=1918=static const struct ethtool_ops lan78xx_ethtool_ops = {\ndrivers/net/usb/lan78xx.c-1919-\t.get_link\t= ethtool_op_get_link,\ndrivers/net/usb/lan78xx.c:1920:\t.nway_reset\t= phy_ethtool_nway_reset,\ndrivers/net/usb/lan78xx.c-1921-\t.get_drvinfo\t= lan78xx_get_drvinfo,\n--\ndrivers/net/usb/lan78xx.c=1944=static int lan78xx_init_mac_address(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2011-/* MDIO read and write wrappers for phylib */\ndrivers/net/usb/lan78xx.c:2012:static int lan78xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)\ndrivers/net/usb/lan78xx.c-2013-{\n--\ndrivers/net/usb/lan78xx.c-2029-\t/* set the address, index \u0026 direction (read from PHY) */\ndrivers/net/usb/lan78xx.c:2030:\taddr = mii_access(phy_id, idx, MII_READ);\ndrivers/net/usb/lan78xx.c-2031-\tret = lan78xx_write_reg(dev, MII_ACC, addr);\n--\ndrivers/net/usb/lan78xx.c-2051-\ndrivers/net/usb/lan78xx.c:2052:static int lan78xx_mdiobus_write(struct mii_bus *bus, int phy_id, int idx,\ndrivers/net/usb/lan78xx.c-2053-\t\t\t\t u16 regval)\n--\ndrivers/net/usb/lan78xx.c-2075-\t/* set the address, index \u0026 direction (write to PHY) */\ndrivers/net/usb/lan78xx.c:2076:\taddr = mii_access(phy_id, idx, MII_WRITE);\ndrivers/net/usb/lan78xx.c-2077-\tret = lan78xx_write_reg(dev, MII_ACC, addr);\n--\ndrivers/net/usb/lan78xx.c=2091=static int lan78xx_mdio_init(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2114-\t\t/* set to internal PHY id */\ndrivers/net/usb/lan78xx.c:2115:\t\tdev-\u003emdiobus-\u003ephy_mask = ~(1 \u003c\u003c 1);\ndrivers/net/usb/lan78xx.c-2116-\t\tbreak;\n--\ndrivers/net/usb/lan78xx.c=2306=static void lan78xx_mac_link_down(struct phylink_config *config,\ndrivers/net/usb/lan78xx.c:2307:\t\t\t\t unsigned int mode, phy_interface_t interface)\ndrivers/net/usb/lan78xx.c-2308-{\n--\ndrivers/net/usb/lan78xx.c=2477=static void lan78xx_mac_link_up(struct phylink_config *config,\ndrivers/net/usb/lan78xx.c:2478:\t\t\t\tstruct phy_device *phy,\ndrivers/net/usb/lan78xx.c:2479:\t\t\t\tunsigned int mode, phy_interface_t interface,\ndrivers/net/usb/lan78xx.c-2480-\t\t\t\tint speed, int duplex,\n--\ndrivers/net/usb/lan78xx.c=2626=static int lan78xx_set_fixed_link(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2648- */\ndrivers/net/usb/lan78xx.c:2649:static struct phy_device *lan78xx_get_phy(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-2650-{\ndrivers/net/usb/lan78xx.c:2651:\tstruct phy_device *phydev;\ndrivers/net/usb/lan78xx.c-2652-\ndrivers/net/usb/lan78xx.c-2653-\t/* Attempt to locate a PHY on the MDIO bus */\ndrivers/net/usb/lan78xx.c:2654:\tphydev = phy_find_first(dev-\u003emdiobus);\ndrivers/net/usb/lan78xx.c-2655-\n--\ndrivers/net/usb/lan78xx.c=2769=static int lan78xx_configure_leds_from_dt(struct lan78xx_net *dev,\ndrivers/net/usb/lan78xx.c:2770:\t\t\t\t\t struct phy_device *phydev)\ndrivers/net/usb/lan78xx.c-2771-{\n--\ndrivers/net/usb/lan78xx.c=2799=static int lan78xx_phylink_setup(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2830-\tif (dev-\u003echipid == ID_REV_CHIP_ID_7801_)\ndrivers/net/usb/lan78xx.c:2831:\t\tphy_interface_set_rgmii(pc-\u003esupported_interfaces);\ndrivers/net/usb/lan78xx.c-2832-\telse\n--\ndrivers/net/usb/lan78xx.c-2848-\ndrivers/net/usb/lan78xx.c:2849:static void lan78xx_phy_uninit(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-2850-{\n--\ndrivers/net/usb/lan78xx.c-2857-\ndrivers/net/usb/lan78xx.c:2858:static int lan78xx_phy_init(struct lan78xx_net *dev)\ndrivers/net/usb/lan78xx.c-2859-{\ndrivers/net/usb/lan78xx.c:2860:\tstruct phy_device *phydev;\ndrivers/net/usb/lan78xx.c-2861-\tint ret;\n--\ndrivers/net/usb/lan78xx.c-2915-phylink_uninit:\ndrivers/net/usb/lan78xx.c:2916:\tlan78xx_phy_uninit(dev);\ndrivers/net/usb/lan78xx.c-2917-\n--\ndrivers/net/usb/lan78xx.c=4448=static void lan78xx_delayedwork(struct work_struct *work)\n--\ndrivers/net/usb/lan78xx.c-4498-\t\tclear_bit(EVENT_PHY_INT_ACK, \u0026dev-\u003eflags);\ndrivers/net/usb/lan78xx.c:4499:\t\tret = lan78xx_phy_int_ack(dev);\ndrivers/net/usb/lan78xx.c-4500-\t\tif (ret)\n--\ndrivers/net/usb/lan78xx.c=4632=static const struct net_device_ops lan78xx_netdev_ops = {\n--\ndrivers/net/usb/lan78xx.c-4639-\t.ndo_validate_addr\t= eth_validate_addr,\ndrivers/net/usb/lan78xx.c:4640:\t.ndo_eth_ioctl\t\t= phy_do_ioctl_running,\ndrivers/net/usb/lan78xx.c-4641-\t.ndo_set_rx_mode\t= lan78xx_set_multicast,\n--\ndrivers/net/usb/lan78xx.c=4655=static int lan78xx_probe(struct usb_interface *intf,\n--\ndrivers/net/usb/lan78xx.c-4785-\ndrivers/net/usb/lan78xx.c:4786:\tret = lan78xx_phy_init(dev);\ndrivers/net/usb/lan78xx.c-4787-\tif (ret \u003c 0)\n--\ndrivers/net/usb/lan78xx.c-4792-\t\tnetif_err(dev, probe, netdev, \"couldn't register the device\\n\");\ndrivers/net/usb/lan78xx.c:4793:\t\tgoto phy_uninit;\ndrivers/net/usb/lan78xx.c-4794-\t}\n--\ndrivers/net/usb/lan78xx.c-4807-\ndrivers/net/usb/lan78xx.c:4808:phy_uninit:\ndrivers/net/usb/lan78xx.c:4809:\tlan78xx_phy_uninit(dev);\ndrivers/net/usb/lan78xx.c-4810-free_urbs:\n"
} |
| 66/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64501 output: 41 thoughts: 44 Thoughts: Here's my summary, as if I were thinking it: **Digging into the LAN78xx Driver Initialization** Okay, so I'm diving into the `lan78xx_probe` function. The first thing that catches my eye is the call to `lan78xx_phy_init(dev)`. That's where the PHY initialization happens, so let's zoom in on that function. I need to understand how the PHY is being brought up to properly diagnose what might be happening with this device. It's a key piece of the puzzle. Gotta see if it's being properly configured or if something's going wrong during that setup phase. |
| 67/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/lan78xx.c",
"FirstLine": 2855,
"LineCount": 45
}Results: {
"Contents": "2855:\t\t}\n2856:\t}\n2857:\t\n2858:\tstatic int lan78xx_phy_init(struct lan78xx_net *dev)\n2859:\t{\n2860:\t\tstruct phy_device *phydev;\n2861:\t\tint ret;\n2862:\t\n2863:\t\tphydev = lan78xx_get_phy(dev);\n2864:\t\t/* phydev can be NULL if no PHY is found and the chip is LAN7801,\n2865:\t\t * which will use a fixed link later.\n2866:\t\t * If an error occurs, return the error code immediately.\n2867:\t\t */\n2868:\t\tif (IS_ERR(phydev))\n2869:\t\t\treturn PTR_ERR(phydev);\n2870:\t\n2871:\t\tret = lan78xx_phylink_setup(dev);\n2872:\t\tif (ret \u003c 0)\n2873:\t\t\treturn ret;\n2874:\t\n2875:\t\tret = lan78xx_mac_prepare_for_phy(dev);\n2876:\t\tif (ret \u003c 0)\n2877:\t\t\tgoto phylink_uninit;\n2878:\t\n2879:\t\t/* If no PHY is found, set up a fixed link. It is very specific to\n2880:\t\t * the LAN7801 and is used in special cases like EVB-KSZ9897-1 where\n2881:\t\t * LAN7801 acts as a USB-to-Ethernet interface to a switch without\n2882:\t\t * a visible PHY.\n2883:\t\t */\n2884:\t\tif (!phydev) {\n2885:\t\t\tret = lan78xx_set_fixed_link(dev);\n2886:\t\t\tif (ret \u003c 0)\n2887:\t\t\t\tgoto phylink_uninit;\n2888:\t\n2889:\t\t\t/* No PHY found, so set up a fixed link and return early.\n2890:\t\t\t * No need to configure PHY IRQ or attach to phylink.\n2891:\t\t\t */\n2892:\t\t\treturn 0;\n2893:\t\t}\n2894:\t\n2895:\t\t/* if phyirq is not set, use polling mode in phylib */\n2896:\t\tif (dev-\u003edomain_data.phyirq \u003e 0)\n2897:\t\t\tphydev-\u003eirq = dev-\u003edomain_data.phyirq;\n2898:\t\telse\n2899:\t\t\tphydev-\u003eirq = PHY_POLL;\n"
} |
| 68/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 65421 output: 41 thoughts: 140 Thoughts: **My Initial Thoughts on the `lan78xx_get_phy` Function** Okay, hold on a second. Let me zero in on this `lan78xx_get_phy` function. I see that it's designed to locate a PHY device. Specifically, it uses `phy_find_first` on `dev->mdiobus`. That's standard practice, but a question pops up immediately: Where does the `lan78xx` driver populate `dev->mdiobus`? I need to trace back where that member of the structure is assigned. Ah, of course! It's likely within the MDIO initialization. Let me just take a look at `lan78xx_mdio_init` to confirm my suspicion... |
| 69/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/usb/lan78xx.c",
"FirstLine": 2090,
"LineCount": 40
}Results: {
"Contents": "2090:\t\n2091:\tstatic int lan78xx_mdio_init(struct lan78xx_net *dev)\n2092:\t{\n2093:\t\tstruct device_node *node;\n2094:\t\tint ret;\n2095:\t\n2096:\t\tdev-\u003emdiobus = mdiobus_alloc();\n2097:\t\tif (!dev-\u003emdiobus) {\n2098:\t\t\tnetdev_err(dev-\u003enet, \"can't allocate MDIO bus\\n\");\n2099:\t\t\treturn -ENOMEM;\n2100:\t\t}\n2101:\t\n2102:\t\tdev-\u003emdiobus-\u003epriv = (void *)dev;\n2103:\t\tdev-\u003emdiobus-\u003eread = lan78xx_mdiobus_read;\n2104:\t\tdev-\u003emdiobus-\u003ewrite = lan78xx_mdiobus_write;\n2105:\t\tdev-\u003emdiobus-\u003ename = \"lan78xx-mdiobus\";\n2106:\t\tdev-\u003emdiobus-\u003eparent = \u0026dev-\u003eudev-\u003edev;\n2107:\t\n2108:\t\tsnprintf(dev-\u003emdiobus-\u003eid, MII_BUS_ID_SIZE, \"usb-%03d:%03d\",\n2109:\t\t\t dev-\u003eudev-\u003ebus-\u003ebusnum, dev-\u003eudev-\u003edevnum);\n2110:\t\n2111:\t\tswitch (dev-\u003echipid) {\n2112:\t\tcase ID_REV_CHIP_ID_7800_:\n2113:\t\tcase ID_REV_CHIP_ID_7850_:\n2114:\t\t\t/* set to internal PHY id */\n2115:\t\t\tdev-\u003emdiobus-\u003ephy_mask = ~(1 \u003c\u003c 1);\n2116:\t\t\tbreak;\n2117:\t\tcase ID_REV_CHIP_ID_7801_:\n2118:\t\t\tbreak;\n2119:\t\t}\n2120:\t\n2121:\t\tnode = of_get_child_by_name(dev-\u003eudev-\u003edev.of_node, \"mdio\");\n2122:\t\tret = of_mdiobus_register(dev-\u003emdiobus, node);\n2123:\t\tof_node_put(node);\n2124:\t\tif (ret) {\n2125:\t\t\tnetdev_err(dev-\u003enet, \"can't register MDIO bus\\n\");\n2126:\t\t\tgoto exit1;\n2127:\t\t}\n2128:\t\n2129:\t\tnetdev_dbg(dev-\u003enet, \"registered mdiobus bus %s\\n\", dev-\u003emdiobus-\u003eid);\n"
} |
| 70/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 66459 output: 34 thoughts: 55 Thoughts: **Analyzing the MDIO Bus Registration Process** Okay, let's dive into this `of_mdiobus_register` function. My initial focus is what happens when the `node` argument is NULL. Given my understanding of device-tree usage, or rather, the lack thereof in this specific context, that's essentially the default condition. So, in this scenario, I need to understand the implications of calling `of_mdiobus_register(dev->mdiobus, NULL)`. It's a crucial point to understand the registration behavior when device tree is not in play, so let's see where that goes! |
| 71/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "of_mdiobus_register",
"PathPrefix": "drivers/net/mdio/"
}Results: {
"Output": "drivers/net/mdio/mdio-airoha.c=203=static int airoha_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-airoha.c-250-\ndrivers/net/mdio/mdio-airoha.c:251:\tret = devm_of_mdiobus_register(dev, bus, dev-\u003eof_node);\ndrivers/net/mdio/mdio-airoha.c-252-\tif (ret) {\n--\ndrivers/net/mdio/mdio-aspeed.c=146=static int aspeed_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-aspeed.c-174-\ndrivers/net/mdio/mdio-aspeed.c:175:\trc = of_mdiobus_register(bus, pdev-\u003edev.of_node);\ndrivers/net/mdio/mdio-aspeed.c-176-\tif (rc) {\n--\ndrivers/net/mdio/mdio-bcm-iproc.c=122=static int iproc_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-bcm-iproc.c-153-\ndrivers/net/mdio/mdio-bcm-iproc.c:154:\trc = of_mdiobus_register(bus, pdev-\u003edev.of_node);\ndrivers/net/mdio/mdio-bcm-iproc.c-155-\tif (rc) {\n--\ndrivers/net/mdio/mdio-bcm-unimac.c=237=static int unimac_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-bcm-unimac.c-301-\ndrivers/net/mdio/mdio-bcm-unimac.c:302:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-bcm-unimac.c-303-\tif (ret) {\n--\ndrivers/net/mdio/mdio-gpio.c=157=static int mdio_gpio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-gpio.c-184-\ndrivers/net/mdio/mdio-gpio.c:185:\tret = of_mdiobus_register(new_bus, pdev-\u003edev.of_node);\ndrivers/net/mdio/mdio-gpio.c-186-\tif (ret)\n--\ndrivers/net/mdio/mdio-hisi-femac.c=72=static int hisi_femac_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-hisi-femac.c-105-\ndrivers/net/mdio/mdio-hisi-femac.c:106:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-hisi-femac.c-107-\tif (ret)\n--\ndrivers/net/mdio/mdio-ipq4019.c=326=static int ipq4019_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-ipq4019.c-369-\ndrivers/net/mdio/mdio-ipq4019.c:370:\tret = of_mdiobus_register(bus, pdev-\u003edev.of_node);\ndrivers/net/mdio/mdio-ipq4019.c-371-\tif (ret) {\n--\ndrivers/net/mdio/mdio-ipq8064.c=110=ipq8064_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-ipq8064.c-141-\ndrivers/net/mdio/mdio-ipq8064.c:142:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-ipq8064.c-143-\tif (ret)\n--\ndrivers/net/mdio/mdio-moxart.c=110=static int moxart_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-moxart.c-128-\t/* Setting PHY_MAC_INTERRUPT here even if it has no effect,\ndrivers/net/mdio/mdio-moxart.c:129:\t * of_mdiobus_register() sets these PHY_POLL.\ndrivers/net/mdio/mdio-moxart.c-130-\t * Ideally, the interrupt from MAC controller could be used to\n--\ndrivers/net/mdio/mdio-moxart.c-144-\ndrivers/net/mdio/mdio-moxart.c:145:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-moxart.c-146-\tif (ret \u003c 0)\n--\ndrivers/net/mdio/mdio-mscc-miim.c=270=static int mscc_miim_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-mscc-miim.c-330-\ndrivers/net/mdio/mdio-mscc-miim.c:331:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-mscc-miim.c-332-\tif (ret \u003c 0) {\n--\ndrivers/net/mdio/mdio-mux.c=139=int mdio_mux_init(struct device *dev,\n--\ndrivers/net/mdio/mdio-mux.c-224-\t\t\tcb-\u003emii_bus-\u003ewrite_c45 = mdio_mux_write_c45;\ndrivers/net/mdio/mdio-mux.c:225:\t\tr = of_mdiobus_register(cb-\u003emii_bus, child_bus_node);\ndrivers/net/mdio/mdio-mux.c-226-\t\tif (r) {\n--\ndrivers/net/mdio/mdio-mvusb.c=64=static int mvusb_mdio_probe(struct usb_interface *interface,\n--\ndrivers/net/mdio/mdio-mvusb.c-90-\ndrivers/net/mdio/mdio-mvusb.c:91:\treturn of_mdiobus_register(mdio, dev-\u003eof_node);\ndrivers/net/mdio/mdio-mvusb.c-92-}\n--\ndrivers/net/mdio/mdio-octeon.c=16=static int octeon_mdiobus_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-octeon.c-50-\ndrivers/net/mdio/mdio-octeon.c:51:\terr = of_mdiobus_register(bus-\u003emii_bus, pdev-\u003edev.of_node);\ndrivers/net/mdio/mdio-octeon.c-52-\tif (err)\n--\ndrivers/net/mdio/mdio-pic64hpsc.c=117=static int pic64hpsc_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-pic64hpsc.c-163-\ndrivers/net/mdio/mdio-pic64hpsc.c:164:\tret = devm_of_mdiobus_register(dev, bus, np);\ndrivers/net/mdio/mdio-pic64hpsc.c-165-\tif (ret) {\n--\ndrivers/net/mdio/mdio-realtek-rtl9300.c=833=static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv,\n--\ndrivers/net/mdio/mdio-realtek-rtl9300.c-867-\ndrivers/net/mdio/mdio-realtek-rtl9300.c:868:\terr = devm_of_mdiobus_register(dev, bus, to_of_node(node));\ndrivers/net/mdio/mdio-realtek-rtl9300.c-869-\tif (err)\n--\ndrivers/net/mdio/mdio-sun4i.c=90=static int sun4i_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-sun4i.c-128-\ndrivers/net/mdio/mdio-sun4i.c:129:\tret = of_mdiobus_register(bus, np);\ndrivers/net/mdio/mdio-sun4i.c-130-\tif (ret \u003c 0)\n--\ndrivers/net/mdio/mdio-thunder.c=22=static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/mdio/mdio-thunder.c-99-\ndrivers/net/mdio/mdio-thunder.c:100:\t\terr = of_mdiobus_register(bus-\u003emii_bus, node);\ndrivers/net/mdio/mdio-thunder.c-101-\t\tif (err)\ndrivers/net/mdio/mdio-thunder.c:102:\t\t\tdev_err(\u0026pdev-\u003edev, \"of_mdiobus_register failed\\n\");\ndrivers/net/mdio/mdio-thunder.c-103-\n--\ndrivers/net/mdio/mdio-xgene.c=327=static int xgene_mdio_probe(struct platform_device *pdev)\n--\ndrivers/net/mdio/mdio-xgene.c-392-\tif (dev-\u003eof_node) {\ndrivers/net/mdio/mdio-xgene.c:393:\t\tret = of_mdiobus_register(mdio_bus, dev-\u003eof_node);\ndrivers/net/mdio/mdio-xgene.c-394-\t} else {\n--\ndrivers/net/mdio/of_mdio.c=44=EXPORT_SYMBOL(of_mdiobus_phy_device_register);\ndrivers/net/mdio/of_mdio.c-45-\ndrivers/net/mdio/of_mdio.c:46:static int of_mdiobus_register_phy(struct mii_bus *mdio,\ndrivers/net/mdio/of_mdio.c-47-\t\t\t\t struct device_node *child, u32 addr)\n--\ndrivers/net/mdio/of_mdio.c-51-\ndrivers/net/mdio/of_mdio.c:52:static int of_mdiobus_register_device(struct mii_bus *mdio,\ndrivers/net/mdio/of_mdio.c-53-\t\t\t\t struct device_node *child, u32 addr)\n--\ndrivers/net/mdio/of_mdio.c=139=static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np,\n--\ndrivers/net/mdio/of_mdio.c-167-\t\tif (of_mdiobus_child_is_phy(child))\ndrivers/net/mdio/of_mdio.c:168:\t\t\trc = of_mdiobus_register_phy(mdio, child, addr);\ndrivers/net/mdio/of_mdio.c-169-\t\telse\ndrivers/net/mdio/of_mdio.c:170:\t\t\trc = of_mdiobus_register_device(mdio, child, addr);\ndrivers/net/mdio/of_mdio.c-171-\n--\ndrivers/net/mdio/of_mdio.c-186-/**\ndrivers/net/mdio/of_mdio.c:187: * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree\ndrivers/net/mdio/of_mdio.c-188- * @mdio: pointer to mii_bus structure\n--\ndrivers/net/mdio/of_mdio.c-194- */\ndrivers/net/mdio/of_mdio.c:195:int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,\ndrivers/net/mdio/of_mdio.c-196-\t\t\t struct module *owner)\n--\ndrivers/net/mdio/of_mdio.c-254-\t\t\t\t */\ndrivers/net/mdio/of_mdio.c:255:\t\t\t\trc = of_mdiobus_register_phy(mdio, child, addr);\ndrivers/net/mdio/of_mdio.c-256-\t\t\t\tif (!rc)\n--\ndrivers/net/mdio/of_mdio.c-271-}\ndrivers/net/mdio/of_mdio.c:272:EXPORT_SYMBOL(__of_mdiobus_register);\ndrivers/net/mdio/of_mdio.c-273-\n"
} |
| 72/2 | 2026/09/13 00:17 | llm | patch-evaluator-compressor |
0mModel:gemini-3.8-flash Args: null Results: null Reply: ### 1. Summary of Approaches and Results
- **Patch Inspection**:
- Target file: `drivers/net/phy/marvell.c`.
- Patch changes:
- Added helper `marvell_wol_suspend_intrs(struct phy_device *phydev)`: masks interrupts except WoL (`MII_88E1318S_PHY_CSIER_WOL_EIE`) on page `MII_MARVELL_COPPER_PAGE`.
- Added helper `marvell_wol_resume_intrs(struct phy_device *phydev)`: re-enables WoL event interrupt enable bit if `phydev->wol_enabled`.
- Modified `m88e1510_resume(struct phy_device *phydev)`: calls `marvell_wol_resume_intrs(phydev)` instead of returning `err` directly.
- Added `m88e1510_suspend(struct phy_device *phydev)`: if `phydev->wol_enabled`, calls `marvell_wol_suspend_intrs(phydev)`; otherwise falls back to `marvell_suspend(phydev)`.
- Modified `m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)`: evaluates `wol_enable = !!(wol->wolopts & (WAKE_MAGIC | WAKE_PHY))`, updates `device_set_wakeup_enable(dev, wol_enable)` when `device_can_wakeup(dev)`, and performs rollback to disable WoL if PM wakeup enable fails.
- Added `m88e1318_suspend(struct phy_device *phydev)` and `m88e1318_resume(struct phy_device *phydev)` calling `marvell_wol_suspend_intrs`/`marvell_wol_resume_intrs`.
- Modified `marvell_probe(struct phy_device *phydev)`: checks `device_property_present(dev, "wakeup-source") && phy_interrupt_is_valid(phydev)`; if true, registers `devm_pm_set_wake_irq(dev, phydev->irq)` and sets `device_set_wakeup_capable(dev, true)`.
- Updated driver definitions for "Marvell 88E1318S" and "Marvell 88E1510": set `PHY_ALWAYS_CALL_SUSPEND` flag, pointed `.suspend` and `.resume` callbacks to the new functions.
- **Kconfig and Subsystem Analysis**:
- Driver config: `CONFIG_MARVELL_PHY` in `drivers/net/phy/Kconfig`.
- Architecture: Not arch-specific (`depends on PHYLIB`).
- **Reachability and Device Model Tracing**:
- Analyzed MDIO bus registration and PHY discovery path (`__mdiobus_register` -> `mdiobus_scan_bus_c22` -> `mdiobus_scan_c22` -> `mdiobus_scan` -> `get_phy_device` -> `phy_device_register` -> `device_add` -> `mdio_bus_match` -> `phy_probe` -> `marvell_probe`).
- Investigated potential virtual/emulated buses capable of instantiating an MDIO bus and discovering Marvell PHYs in standard QEMU/syzkaller environments:
- `drivers/net/usb/asix_devices.c` (`ax88772_init_mdio`), `drivers/net/usb/ax88172a.c` (`ax88172a_init_mdio`), `drivers/net/usb/smsc95xx.c`, and `drivers/net/mdio/mdio-mvusb.c`.
- USB Ethernet devices emulated via `raw-gadget` / `dummy_hcd` register an MDIO bus and scan addresses 0–31 via C22 read operations (`MII_PHYSID1`, `MII_PHYSID2`).
- If emulated USB device returns Marvell IDs (`MARVELL_PHY_ID_88E1318S` or `MARVELL_PHY_ID_88E1510`), the kernel binds `marvell.c` and calls `marvell_probe`.
- Once attached to netdev, WoL settings can be manipulated from userspace via ethtool ioctl (`SIOCETHTOOL` / `ETHTOOL_SWOL`) or Netlink (`ETHTOOL_MSG_WOL_SET`), triggering `phy_ethtool_set_wol` -> `m88e1318_set_wol`.
- PM suspend/resume paths can be exercised via PM callbacks / driver suspend.
### 2. Current Hypotheses and Active Lines of Investigation
- **Hypothesis 1: Reachability classification (Virtual Bus vs Physical Transceiver)**:
- While Marvell PHYs are physical transceivers usually soldered on boards, the driver interfaces directly with MDIO bus abstraction.
- MDIO buses are exposed and scanned by virtual/emulated USB network adapters (e.g., ASIX, SMSC, USB-MDIO bridges) reachable via Syzkaller's USB gadget emulation.
- Userspace ethtool interfaces (`ethtool -s <dev> wol ...`) directly reach `m88e1318_set_wol`.
- Need to evaluate whether this qualifies under Section 3 ("Reachable Drivers and Protocols: Drivers accessible via virtual buses (virtio, USB gadget...)") or Section 2 ("Structurally unreachable hardware"). If reachable through USB gadget MII emulation + ethtool, `WorthFuzzing=true`.
- **Hypothesis 2: Evaluation of changes for fuzzing value**:
- The patch introduces complex state rollback logic in `m88e1318_set_wol` (recursive call to `m88e1318_set_wol(phydev, &wol_off)` on failure).
- Modifies probe logic to configure PM wake IRQ (`devm_pm_set_wake_irq`), interacting with PM runtime / wakeirq subsystem.
- Changes suspend/resume paths for two PHY drivers with `PHY_ALWAYS_CALL_SUSPEND`.
### 3. Critical Files, Symbols, and Configs
- **Files**:
- `drivers/net/phy/marvell.c`
- `drivers/net/phy/mdio_bus_provider.c`
- `drivers/net/phy/phy_device.c`
- **Focus Symbols**:
- `m88e1318_set_wol`
- `marvell_probe`
- `m88e1318_suspend`
- `m88e1318_resume`
- `m88e1510_suspend`
- `m88e1510_resume`
- `marvell_wol_suspend_intrs`
- `marvell_wol_resume_intrs`
- **Enable Configs**:
- `MARVELL_PHY`
- `PHYLIB`
- `MDIO_DEVICE`
- `PM`
- `USB_NET_DRIVERS`
- `USB_NET_AX88172A`
- `USB_NET_AX8817X`
### 4. Watchouts & Potential Loops
- Avoid repeatedly grepping for generic callers of `phy_suspend` or `mdiobus_register` across the whole kernel tree; MDIO registration mechanisms and PHY probing flows are already determined.
- Proceed directly to completing the final evaluation and calling `set-results` with determined parameters.Tokens: input: 48215 output: 1782 thoughts: 0 |
| 73/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 29608 output: 41 thoughts: 0 |
| 74/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/mdio/of_mdio.c",
"FirstLine": 220,
"LineCount": 55
}Results: {
"Contents": " 220:\t\n 221:\t\t/* Register the MDIO bus */\n 222:\t\trc = __mdiobus_register(mdio, owner);\n 223:\t\tif (rc)\n 224:\t\t\treturn rc;\n 225:\t\n 226:\t\t/* Loop over the child nodes and register a phy_device for each phy */\n 227:\t\trc = __of_mdiobus_parse_phys(mdio, np, \u0026scanphys);\n 228:\t\tif (rc)\n 229:\t\t\tgoto unregister;\n 230:\t\n 231:\t\tif (!scanphys)\n 232:\t\t\treturn 0;\n 233:\t\n 234:\t\t/* auto scan for PHYs with empty reg property */\n 235:\t\tfor_each_available_child_of_node(np, child) {\n 236:\t\t\t/* Skip PHYs with reg property set or ethernet-phy-package node */\n 237:\t\t\tif (of_property_present(child, \"reg\") ||\n 238:\t\t\t of_node_name_eq(child, \"ethernet-phy-package\"))\n 239:\t\t\t\tcontinue;\n 240:\t\n 241:\t\t\tfor (addr = 0; addr \u003c PHY_MAX_ADDR; addr++) {\n 242:\t\t\t\t/* skip already registered PHYs */\n 243:\t\t\t\tif (mdiobus_is_registered_device(mdio, addr))\n 244:\t\t\t\t\tcontinue;\n 245:\t\n 246:\t\t\t\t/* be noisy to encourage people to set reg property */\n 247:\t\t\t\tdev_info(\u0026mdio-\u003edev, \"scan phy %pOFn at address %i\\n\",\n 248:\t\t\t\t\t child, addr);\n 249:\t\n 250:\t\t\t\tif (of_mdiobus_child_is_phy(child)) {\n 251:\t\t\t\t\t/* -ENODEV is the return code that PHYLIB has\n 252:\t\t\t\t\t * standardized on to indicate that bus\n 253:\t\t\t\t\t * scanning should continue.\n 254:\t\t\t\t\t */\n 255:\t\t\t\t\trc = of_mdiobus_register_phy(mdio, child, addr);\n 256:\t\t\t\t\tif (!rc)\n 257:\t\t\t\t\t\tbreak;\n 258:\t\t\t\t\tif (rc != -ENODEV)\n 259:\t\t\t\t\t\tgoto put_unregister;\n 260:\t\t\t\t}\n 261:\t\t\t}\n 262:\t\t}\n 263:\t\n 264:\t\treturn 0;\n 265:\t\n 266:\tput_unregister:\n 267:\t\tof_node_put(child);\n 268:\tunregister:\n 269:\t\tmdiobus_unregister(mdio);\n 270:\t\treturn rc;\n 271:\t}\n 272:\tEXPORT_SYMBOL(__of_mdiobus_register);\n 273:\t\n 274:\t/**\n"
} |
| 75/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30420 output: 33 thoughts: 86 Thoughts: **Tracing the MDIO Bus Registration Process** Okay, so I'm digging into how the MDIO bus registration works, specifically focusing on the `__mdiobus_register` function and the potential scenario where the device tree node pointer (`np`) is null. Or maybe just `mdiobus_register`. Right, let's start by looking at where this function is called. The trace begins in `of_mdio.c`, and I see the call: `rc = __mdiobus_register(mdio, owner);`. Now, I'm heading over to `drivers/net/phy/mdio_bus.c` to examine the implementation of `__mdiobus_register`. This will be the key to understanding the registration flow, the handling of the null device tree node (if applicable), and any associated initialization or configuration steps. I'll be looking closely at the logic within `__mdiobus_register` to see how it branches and what happens under these conditions. I also might jump to `mdiobus_register` to check on how the argument gets passed to `__mdiobus_register`. |
| 76/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "int __mdiobus_register",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=525=static bool mdiobus_prevent_c45_scan(struct mii_bus *bus)\n--\ndrivers/net/phy/mdio_bus_provider.c-552- */\ndrivers/net/phy/mdio_bus_provider.c:553:int __mdiobus_register(struct mii_bus *bus, struct module *owner)\ndrivers/net/phy/mdio_bus_provider.c-554-{\n"
} |
| 77/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30918 output: 42 thoughts: 27 Thoughts: Here's a summary of my thought process, as if I were the one thinking it: **Diving into the MDIO Bus Provider Code** Alright, time to dig into this. I'm going to pull up `drivers/net/phy/mdio_bus_provider.c` and zero in on line 553. I'm expecting to find something interesting there related to the overall MDIO bus provider functionality. I'm hoping to get a clearer picture of how it's handling... well, something. Could be a specific PHY register, error handling, bus access logic, or perhaps even an interrupt context consideration. Let's see what line 553 holds. I’ll be looking for clues in the surrounding code as well to build a more complete understanding. |
| 78/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 550,
"LineCount": 60
}Results: {
"Contents": " 550:\t *\n 551:\t * Returns 0 on success or \u003c 0 on error.\n 552:\t */\n 553:\tint __mdiobus_register(struct mii_bus *bus, struct module *owner)\n 554:\t{\n 555:\t\tstruct mdio_device *mdiodev;\n 556:\t\tstruct gpio_desc *gpiod;\n 557:\t\tbool prevent_c45_scan;\n 558:\t\tint i, err;\n 559:\t\n 560:\t\tif (!bus || !bus-\u003ename)\n 561:\t\t\treturn -EINVAL;\n 562:\t\n 563:\t\t/* An access method always needs both read and write operations */\n 564:\t\tif (!!bus-\u003eread != !!bus-\u003ewrite || !!bus-\u003eread_c45 != !!bus-\u003ewrite_c45)\n 565:\t\t\treturn -EINVAL;\n 566:\t\n 567:\t\t/* At least one method is mandatory */\n 568:\t\tif (!bus-\u003eread \u0026\u0026 !bus-\u003eread_c45)\n 569:\t\t\treturn -EINVAL;\n 570:\t\n 571:\t\tif (bus-\u003eparent \u0026\u0026 bus-\u003eparent-\u003eof_node)\n 572:\t\t\tfwnode_set_flag(\u0026bus-\u003eparent-\u003eof_node-\u003efwnode,\n 573:\t\t\t\t\tFWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD);\n 574:\t\n 575:\t\tWARN(bus-\u003estate != MDIOBUS_ALLOCATED \u0026\u0026\n 576:\t\t bus-\u003estate != MDIOBUS_UNREGISTERED,\n 577:\t\t \"%s: not in ALLOCATED or UNREGISTERED state\\n\", bus-\u003eid);\n 578:\t\n 579:\t\tbus-\u003eowner = owner;\n 580:\t\tbus-\u003edev.parent = bus-\u003eparent;\n 581:\t\tbus-\u003edev.class = \u0026mdio_bus_class;\n 582:\t\tbus-\u003edev.groups = NULL;\n 583:\t\tdev_set_name(\u0026bus-\u003edev, \"%s\", bus-\u003eid);\n 584:\t\n 585:\t\t/* If the bus state is allocated, we're registering a fresh bus\n 586:\t\t * that may have a fwnode associated with it. Grab a reference\n 587:\t\t * to the fwnode. This will be dropped when the bus is released.\n 588:\t\t * If the bus was set to unregistered, it means that the bus was\n 589:\t\t * previously registered, and we've already grabbed a reference.\n 590:\t\t */\n 591:\t\tif (bus-\u003estate == MDIOBUS_ALLOCATED)\n 592:\t\t\tfwnode_handle_get(dev_fwnode(\u0026bus-\u003edev));\n 593:\t\n 594:\t\t/* We need to set state to MDIOBUS_UNREGISTERED to correctly release\n 595:\t\t * the device in mdiobus_free()\n 596:\t\t *\n 597:\t\t * State will be updated later in this function in case of success\n 598:\t\t */\n 599:\t\tbus-\u003estate = MDIOBUS_UNREGISTERED;\n 600:\t\n 601:\t\terr = device_register(\u0026bus-\u003edev);\n 602:\t\tif (err) {\n 603:\t\t\tpr_err(\"mii_bus %s failed to register\\n\", bus-\u003eid);\n 604:\t\t\treturn -EINVAL;\n 605:\t\t}\n 606:\t\n 607:\t\tmutex_init(\u0026bus-\u003emdio_lock);\n 608:\t\tmutex_init(\u0026bus-\u003eshared_lock);\n 609:\t\n"
} |
| 79/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 32120 output: 42 thoughts: 32 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Diving Deeper into `__mdiobus_register`** Okay, so we're looking at the implementation of `__mdiobus_register`, specifically in `drivers/net/phy/mdio_bus_provider.c`. I need to fully grasp the nuances of this function. Let's dig into the rest of the code within that file. I'm going to pay close attention to the data structures involved and how they interact, as well as any synchronization mechanisms used. I'll need to consider how this core function impacts the overall MDIO bus management and how it relates to the PHY device registration. This is crucial for understanding how the device drivers correctly interface with the MDIO bus. |
| 80/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 610,
"LineCount": 60
}Results: {
"Contents": " 610:\t\t/* assert bus level PHY GPIO reset */\n 611:\t\tgpiod = devm_gpiod_get_optional(\u0026bus-\u003edev, \"reset\", GPIOD_OUT_HIGH);\n 612:\t\tif (IS_ERR(gpiod)) {\n 613:\t\t\terr = dev_err_probe(\u0026bus-\u003edev, PTR_ERR(gpiod),\n 614:\t\t\t\t\t \"mii_bus %s couldn't get reset GPIO\\n\",\n 615:\t\t\t\t\t bus-\u003eid);\n 616:\t\t\tdevice_del(\u0026bus-\u003edev);\n 617:\t\t\treturn err;\n 618:\t\t} else\tif (gpiod) {\n 619:\t\t\tbus-\u003ereset_gpiod = gpiod;\n 620:\t\t\tfsleep(bus-\u003ereset_delay_us);\n 621:\t\t\tgpiod_set_value_cansleep(gpiod, 0);\n 622:\t\t\tif (bus-\u003ereset_post_delay_us \u003e 0)\n 623:\t\t\t\tfsleep(bus-\u003ereset_post_delay_us);\n 624:\t\t}\n 625:\t\n 626:\t\tif (bus-\u003ereset) {\n 627:\t\t\terr = bus-\u003ereset(bus);\n 628:\t\t\tif (err)\n 629:\t\t\t\tgoto error_reset_gpiod;\n 630:\t\t}\n 631:\t\n 632:\t\tif (bus-\u003eread) {\n 633:\t\t\terr = mdiobus_scan_bus_c22(bus);\n 634:\t\t\tif (err)\n 635:\t\t\t\tgoto error;\n 636:\t\t}\n 637:\t\n 638:\t\tprevent_c45_scan = mdiobus_prevent_c45_scan(bus);\n 639:\t\n 640:\t\tif (!prevent_c45_scan \u0026\u0026 bus-\u003eread_c45) {\n 641:\t\t\terr = mdiobus_scan_bus_c45(bus);\n 642:\t\t\tif (err)\n 643:\t\t\t\tgoto error;\n 644:\t\t}\n 645:\t\n 646:\t\tbus-\u003estate = MDIOBUS_REGISTERED;\n 647:\t\tdev_dbg(\u0026bus-\u003edev, \"probed\\n\");\n 648:\t\treturn 0;\n 649:\t\n 650:\terror:\n 651:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 652:\t\t\tmdiodev = bus-\u003emdio_map[i];\n 653:\t\t\tif (!mdiodev)\n 654:\t\t\t\tcontinue;\n 655:\t\n 656:\t\t\tmdiodev-\u003edevice_remove(mdiodev);\n 657:\t\t\tmdiodev-\u003edevice_free(mdiodev);\n 658:\t\t}\n 659:\terror_reset_gpiod:\n 660:\t\t/* Put PHYs in RESET to save power */\n 661:\t\tif (bus-\u003ereset_gpiod)\n 662:\t\t\tgpiod_set_value_cansleep(bus-\u003ereset_gpiod, 1);\n 663:\t\n 664:\t\tdevice_del(\u0026bus-\u003edev);\n 665:\t\treturn err;\n 666:\t}\n 667:\tEXPORT_SYMBOL(__mdiobus_register);\n 668:\t\n 669:\tvoid mdiobus_unregister(struct mii_bus *bus)\n"
} |
| 81/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 33281 output: 37 thoughts: 150 Thoughts: **My Analysis of MDIO Bus Scanning** Okay, let's break this down. My focus right now is on understanding how this `mdiobus_scan_bus_c22(bus)` function works, particularly when it gets called. It seems that whenever an MDIO bus gets registered via `__mdiobus_register`, or when `of_mdiobus_register` is invoked without a device tree node, this `mdiobus_scan_bus_c22` function is triggered. I see examples of this behavior in various USB Ethernet drivers, things like `lan78xx`, `ax88172a`, `ax88772`, and even in the `mvusb` driver, which means it is scanning from a USB interface. So, when the MDIO bus is registered in these cases, the system, specifically this function, goes through a scan of addresses. The key thing here is the address range: it's scanning from 0 all the way up to `PHY_MAX_ADDR`, which is typically 31. This is a common method, and I need to investigate what occurs within this function, what are the implications of the address range being scanned, and how this relates to the PHY devices on that bus. I should probably check that function's implementation next. |
| 82/2 | 2026/09/13 00:17 | tool | grepper |
0mArgs:{
"Expression": "mdiobus_scan_bus_c22",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "drivers/net/phy/mdio_bus_provider.c=477=static struct phy_device *mdiobus_scan_c45(struct mii_bus *bus, int addr)\n--\ndrivers/net/phy/mdio_bus_provider.c-481-\ndrivers/net/phy/mdio_bus_provider.c:482:static int mdiobus_scan_bus_c22(struct mii_bus *bus)\ndrivers/net/phy/mdio_bus_provider.c-483-{\n--\ndrivers/net/phy/mdio_bus_provider.c=553=int __mdiobus_register(struct mii_bus *bus, struct module *owner)\n--\ndrivers/net/phy/mdio_bus_provider.c-632-\tif (bus-\u003eread) {\ndrivers/net/phy/mdio_bus_provider.c:633:\t\terr = mdiobus_scan_bus_c22(bus);\ndrivers/net/phy/mdio_bus_provider.c-634-\t\tif (err)\n"
} |
| 83/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 34026 output: 42 thoughts: 30 Thoughts: Here's my take on the specified lines of `drivers/net/phy/mdio_bus_provider.c`, thinking through it as an expert would: **Dissecting the MDIO Bus Provider Code (Lines 480-520)** Okay, so I'm diving into this section of the MDIO bus provider code. Lines 480 to 520, huh? Let's see what's happening... My initial guess is that we're likely dealing with either the core MDIO bus registration/deregistration, or perhaps some sort of bus probing or device detection routine within the driver. Given the context of a PHY driver, it's probably related to how the driver interfaces with the MDIO bus to talk to the physical layer devices. Let's assume the code is dealing with the MDIO bus structure itself. It could be managing things like mutexes or spinlocks to protect concurrent access to the bus from multiple PHYs. Or, perhaps it's involved with initializing or de-initializing the bus's resources, like memory allocation for MDIO transaction buffers, or registering the bus with the kernel. I'd expect to see some calls to `devm_kzalloc` or similar memory management functions, if this is the case. I'll be looking for calls to kernel functions that interact with the MDIO bus core, functions like `mdiobus_register`, `mdiobus_unregister`, or potentially some lower-level functions that directly manipulate the MDIO bus registers through a platform-specific interface (like I2C or SPI). I anticipate some error handling using `return` statements and `pr_err` calls to log failures in a manner that's consistent with a robust device driver. The overall goal is to handle the specifics of the driver and connect the PHY with the MDIO bus. Based on where this code is in the driver, it might also contain the logic for implementing custom MDIO bus probing, or handling certain PHY devices that might require specific initialization sequences. If that's the case, I would expect a section of the code dealing with device ID checks and possibly a call to another routine dealing with a known PHY. The details should tell me a lot about the bus's operational constraints and how it interfaces with PHY devices. Let's see what the implementation truly does. |
| 84/2 | 2026/09/13 00:17 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/mdio_bus_provider.c",
"FirstLine": 480,
"LineCount": 45
}Results: {
"Contents": " 480:\t}\n 481:\t\n 482:\tstatic int mdiobus_scan_bus_c22(struct mii_bus *bus)\n 483:\t{\n 484:\t\tint i;\n 485:\t\n 486:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 487:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 488:\t\t\t\tstruct phy_device *phydev;\n 489:\t\n 490:\t\t\t\tphydev = mdiobus_scan_c22(bus, i);\n 491:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 492:\t\t\t\t\treturn PTR_ERR(phydev);\n 493:\t\t\t}\n 494:\t\t}\n 495:\t\treturn 0;\n 496:\t}\n 497:\t\n 498:\tstatic int mdiobus_scan_bus_c45(struct mii_bus *bus)\n 499:\t{\n 500:\t\tint i;\n 501:\t\n 502:\t\tfor (i = 0; i \u003c PHY_MAX_ADDR; i++) {\n 503:\t\t\tif ((bus-\u003ephy_mask \u0026 BIT(i)) == 0) {\n 504:\t\t\t\tstruct phy_device *phydev;\n 505:\t\n 506:\t\t\t\t/* Don't scan C45 if we already have a C22 device */\n 507:\t\t\t\tif (bus-\u003emdio_map[i])\n 508:\t\t\t\t\tcontinue;\n 509:\t\n 510:\t\t\t\tphydev = mdiobus_scan_c45(bus, i);\n 511:\t\t\t\tif (IS_ERR(phydev) \u0026\u0026 (PTR_ERR(phydev) != -ENODEV))\n 512:\t\t\t\t\treturn PTR_ERR(phydev);\n 513:\t\t\t}\n 514:\t\t}\n 515:\t\treturn 0;\n 516:\t}\n 517:\t\n 518:\t/* There are some C22 PHYs which do bad things when where is a C45\n 519:\t * transaction on the bus, like accepting a read themselves, and\n 520:\t * stomping over the true devices reply, to performing a write to\n 521:\t * themselves which was intended for another device. Now that C22\n 522:\t * devices have been found, see if any of them are bad for C45, and if we\n 523:\t * should skip the C45 scan.\n 524:\t */\n"
} |
| 85/2 | 2026/09/13 00:17 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 35292 output: 39 thoughts: 257 Thoughts: **My Analysis of the Marvell PHY Driver Interaction** Okay, so here's what's running through my head as I look at this code snippet. The `mdiobus_scan_c22` function is key here; it's the one actually reading those PHY ID registers, specifically `MII_PHYSID1` and `MII_PHYSID2`. This is the *foundation* for identifying the PHY. Now, the interesting part is how syzkaller is interacting with this when emulating USB devices like the `ax88172a`, `lan78xx`, or others using the `raw-gadget` approach. Syzkaller is dictating the responses to USB control transfers that are attempting to read those MII registers. That's a *crucial* point – syzkaller is providing the input, which will ultimately dictate whether the Marvell PHY is detected. The magic happens when the PHY IDs reported back match either `MARVELL_PHY_ID_88E1318S` or `MARVELL_PHY_ID_88E1510`. If that happens, `phy_device_register` gets called, and the Marvell PHY device gets registered. Boom! At that point, the driver probe, `marvell_probe`, kicks in. It's go time! And here's where it all connects to my work. I know that once the network device is brought up or accessed, `ethtool` can send an `ETHTOOL_SWOL` command. That will ultimately call `phy_ethtool_set_wol`, which then, in turn, calls the Marvell-specific `m88e1318_set_wol` function. This is how the Wake-on-LAN functionality is enabled. It's the whole workflow from PHY ID reading to WoL configuration. Hold on a second, I need to go back and double check the `marvell.c` source code. I should probably verify what the actual PHY ID values are for those `88E1318S` and `88E1510` devices, just to be absolutely sure that the assumptions are accurate. |
| 86/2 | 2026/09/13 00:18 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/marvell.c",
"FirstLine": 3940,
"LineCount": 40
}Results: {
"Contents": "3940:\t\t},\n3941:\t\t{\n3942:\t\t\t.phy_id = MARVELL_PHY_ID_88E1318S,\n3943:\t\t\t.phy_id_mask = MARVELL_PHY_ID_MASK,\n3944:\t\t\t.name = \"Marvell 88E1318S\",\n3945:\t\t\t/* PHY_GBIT_FEATURES */\n3946:\t\t\t.flags = PHY_ALWAYS_CALL_SUSPEND,\n3947:\t\t\t.probe = marvell_probe,\n3948:\t\t\t.config_init = m88e1318_config_init,\n3949:\t\t\t.config_aneg = m88e1318_config_aneg,\n3950:\t\t\t.read_status = marvell_read_status,\n3951:\t\t\t.config_intr = marvell_config_intr,\n3952:\t\t\t.handle_interrupt = marvell_handle_interrupt,\n3953:\t\t\t.get_wol = m88e1318_get_wol,\n3954:\t\t\t.set_wol = m88e1318_set_wol,\n3955:\t\t\t.resume = m88e1318_resume,\n3956:\t\t\t.suspend = m88e1318_suspend,\n3957:\t\t\t.read_page = marvell_read_page,\n3958:\t\t\t.write_page = marvell_write_page,\n3959:\t\t\t.get_sset_count = marvell_get_sset_count,\n3960:\t\t\t.get_strings = marvell_get_strings,\n3961:\t\t\t.get_stats = marvell_get_stats,\n3962:\t\t\t.led_brightness_set = m88e1318_led_brightness_set,\n3963:\t\t\t.led_blink_set = m88e1318_led_blink_set,\n3964:\t\t\t.led_hw_is_supported = m88e1318_led_hw_is_supported,\n3965:\t\t\t.led_hw_control_set = m88e1318_led_hw_control_set,\n3966:\t\t\t.led_hw_control_get = m88e1318_led_hw_control_get,\n3967:\t\t},\n3968:\t\t{\n3969:\t\t\t.phy_id = MARVELL_PHY_ID_88E1145,\n3970:\t\t\t.phy_id_mask = MARVELL_PHY_ID_MASK,\n3971:\t\t\t.name = \"Marvell 88E1145\",\n3972:\t\t\t/* PHY_GBIT_FEATURES */\n3973:\t\t\t.flags = PHY_POLL_CABLE_TEST,\n3974:\t\t\t.probe = marvell_probe,\n3975:\t\t\t.config_init = m88e1145_config_init,\n3976:\t\t\t.config_aneg = m88e1101_config_aneg,\n3977:\t\t\t.config_intr = marvell_config_intr,\n3978:\t\t\t.handle_interrupt = marvell_handle_interrupt,\n3979:\t\t\t.resume = genphy_resume,\n"
} |
| 87/2 | 2026/09/13 00:18 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 36907 output: 34 thoughts: 676 Thoughts: **Analyzing Marvell PHY Driver Wake-on-LAN Functionality** Okay, let's dive in. I need to understand how the Marvell PHY drivers handle Wake-on-LAN (WoL). First, I'm checking out the `marvell_probe` function. This seems to be the entry point for most Marvell PHYs, as the code is shared across the `marvell_drivers`. I see the usual device allocation, and the interesting bit is the "wakeup-source" property check. If present, and the interrupt is valid, it calls `devm_pm_set_wake_irq` and enables wakeup capability on the device. Then it proceeds to `marvell_hwmon_probe`. Next, I'm examining `m88e1318_set_wol`. This function appears to be responsible for actually configuring WoL. It retrieves the WoL options from `ethtool_wolinfo`, enables it. The code saves and restores the PHY page (typical for these sorts of PHYs). I see a crucial check for `device_can_wakeup` and whether WoL is currently enabled. If there's a mismatch, it attempts to set the device's wakeup enable state. The rollback in case of error is good practice. Now I need to understand how this interacts with power management. I'm taking a look at the suspend and resume functions – `m88e1318_suspend`, `m88e1510_suspend`, `m88e1318_resume`, and `m88e1510_resume`. Those are the usual suspects. I don't see anything immediately amiss. Finally, I need to check the Kconfig options that control which of these features are enabled. Let's see what the configuration options in `drivers/net/phy/Kconfig` have to say about this. |
| 88/2 | 2026/09/13 00:18 | tool | grepper |
0mArgs:{
"Expression": "config MARVELL_PHY",
"PathPrefix": "drivers/net/phy/Kconfig"
}Results: {
"Output": "drivers/net/phy/Kconfig=273=config LSI_ET1011C_PHY\n--\ndrivers/net/phy/Kconfig-277-\ndrivers/net/phy/Kconfig:278:config MARVELL_PHY\ndrivers/net/phy/Kconfig-279-\ttristate \"Marvell Alaska PHYs\"\n"
} |
| 89/2 | 2026/09/13 00:18 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 38124 output: 36 thoughts: 21 Thoughts: Here's a summary of my thought process, as requested: **Navigating the PHY Configuration Space** Okay, time to dive into the kernel's PHY configuration. I need to refresh my memory on some specific options. Let's start by looking at `drivers/net/phy/Kconfig`, specifically around line 278. That section likely covers the crucial aspects of configuring the Physical Layer Transceivers, and I know from experience that's where the heart of the PHY driver options are defined. This should give me a good baseline for understanding the present options and any dependencies they might have. It's the standard first step when needing a broader picture. |
| 90/2 | 2026/09/13 00:18 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/Kconfig",
"FirstLine": 275,
"LineCount": 25
}Results: {
"Contents": " 275:\t\thelp\n 276:\t\t Supports the LSI ET1011C PHY.\n 277:\t\n 278:\tconfig MARVELL_PHY\n 279:\t\ttristate \"Marvell Alaska PHYs\"\n 280:\t\thelp\n 281:\t\t Currently has a driver for the 88E1XXX\n 282:\t\n 283:\tconfig MARVELL_10G_PHY\n 284:\t\ttristate \"Marvell Alaska 10Gbit PHYs\"\n 285:\t\thelp\n 286:\t\t Support for the Marvell Alaska MV88X3310 and compatible PHYs.\n 287:\t\n 288:\tconfig MARVELL_88Q2XXX_PHY\n 289:\t\ttristate \"Marvell 88Q2XXX PHY\"\n 290:\t\tdepends on HWMON || HWMON=n\n 291:\t\thelp\n 292:\t\t Support for the Marvell 88Q2XXX 100/1000BASE-T1 Automotive Ethernet\n 293:\t\t PHYs.\n 294:\t\n 295:\tconfig MARVELL_88X2222_PHY\n 296:\t\ttristate \"Marvell 88X2222 PHY\"\n 297:\t\thelp\n 298:\t\t Support for the Marvell 88X2222 Dual-port Multi-speed Ethernet\n 299:\t\t Transceiver.\n"
} |
| 91/2 | 2026/09/13 00:18 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 38724 output: 297 thoughts: 2155 Thoughts: **Fuzzing Feasibility Analysis: Marvell PHY WoL and PM Suspend/Resume** Okay, let's break this down. First, the crucial question: can we even reach this code in a fuzzing environment? The rules dictate that we can only fuzz reachable code within standard virtualized environments. I need to make sure this Marvell PHY code isn't structurally unreachable. My initial thought is to check if Marvell PHYs are accessible in standard QEMU or using USB gadget emulation. Then, I remember syzkaller. Does syzkaller, in standard QEMU, attach a Marvell PHY to a virtual device? Not directly, but here's where it gets interesting: Syzkaller *can* emulate any USB device via raw-gadget, which opens a whole new avenue. Specifically, `syz_usb_connect` provides that capability. By emulating a USB ethernet device (like `ax88172a`, `asix`, or `lan78xx`), syzkaller can trigger the driver binding. Crucially, during driver initialization, the USB driver sets up an MDIO bus and *scans for PHYs*. Ah, here's the connection: when the emulated USB gadget returns Marvell PHY IDs, the phylib subsystem matches and binds `drivers/net/phy/marvell.c`! From there, `marvell_probe` runs. This is great, we're in! Then, user space can call `ioctl(SIOCETHTOOL, &wol)` to configure Wake-on-LAN (WoL) and call `m88e1318_set_wol`. Plus, syzkaller is already fuzzing PM suspend/resume, which potentially interact with this code. Now I need to delve into the rollback logic within `m88e1318_set_wol`. If `device_set_wakeup_enable` fails, the system rolls back by calling `m88e1318_set_wol(phydev, &wol_off)` again. That's a critical point to consider. Also, I need to focus on how `marvell_probe` interacts with the wakeup sources using `device_property_present` and `devm_pm_set_wake_irq`. The verdict: Yes, this code is reachable within syzkaller, using USB gadget emulation, `CONFIG_USB_NET_DRIVERS`, and `CONFIG_MARVELL_PHY`. Reachability is the primary gate, and it's met. This means it is `WorthFuzzing`. Next, I'll identify the necessary configurations to enable this: * `MARVELL_PHY` * `PHYLIB` * `NETDEVICES` * `USB_NET_DRIVERS` * `PM` I need to check the dependencies. Within `drivers/net/phy/Kconfig`, `MARVELL_PHY` is inside the `PHYLIB` menu, and thus depends on that. I must ensure both are enabled, along with `PM`. Now, the symbols to target. All these functions are static within `drivers/net/phy/marvell.c`, but they're not compiler-inlined; they're explicitly referenced by name. Let's make sure that is true by checking if their address is taken in the structures. Looking at the code, I see: * `m88e1318_set_wol`, has its address taken and used as a callback, this function is definitely kept as a symbol. Also, it is called recursively. * `marvell_probe`, has its address taken and used as a callback, this is also definitely kept as a symbol. * `m88e1318_suspend`, has its address taken and used as a callback. * `m88e1318_resume`, has its address taken and used as a callback. * `m88e1510_suspend`, has its address taken and used as a callback. * `m88e1510_resume`, has its address taken and used as a callback. * `marvell_wol_suspend_intrs`, called by the suspend functions. * `marvell_wol_resume_intrs`, called by the resume functions. There are also ethtool entry points (e.g. `phy_ethtool_set_wol` or phylink `phylink_ethtool_set_wol`). These symbols need to be included in my analysis. So my focus symbols are: `m88e1318_set_wol`, `marvell_probe`, `m88e1318_ |
| 92/2 | 2026/09/13 00:18 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"MARVELL_PHY",
"PHYLIB",
"NETDEVICES",
"USB_NET_DRIVERS",
"PM"
],
"FocusSymbols": [
"m88e1318_set_wol",
"marvell_probe",
"m88e1318_suspend",
"m88e1318_resume",
"m88e1510_suspend",
"m88e1510_resume",
"marvell_wol_suspend_intrs",
"marvell_wol_resume_intrs"
],
"Reasoning": "The patch modifies Wake-on-LAN (WoL), interrupt masking, and suspend/resume handling for Marvell PHYs (88E1318S and 88E1510), as well as wake-irq setup in marvell_probe(). Marvell PHYs can be discovered and attached over MDIO buses exposed by emulated USB network devices (e.g., via USB Raw Gadget), making them reachable in virtualized fuzzing environments. Once registered, the modified WoL configuration and rollback logic are exercisable via ethtool ioctl/netlink, and suspend/resume paths can be tested via power management interfaces.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"MARVELL_PHY",
"PHYLIB",
"NETDEVICES",
"USB_NET_DRIVERS",
"PM"
],
"FocusSymbols": [
"m88e1318_set_wol",
"marvell_probe",
"m88e1318_suspend",
"m88e1318_resume",
"m88e1510_suspend",
"m88e1510_resume",
"marvell_wol_suspend_intrs",
"marvell_wol_resume_intrs"
],
"Reasoning": "The patch modifies Wake-on-LAN (WoL), interrupt masking, and suspend/resume handling for Marvell PHYs (88E1318S and 88E1510), as well as wake-irq setup in marvell_probe(). Marvell PHYs can be discovered and attached over MDIO buses exposed by emulated USB network devices (e.g., via USB Raw Gadget), making them reachable in virtualized fuzzing environments. Once registered, the modified WoL configuration and rollback logic are exercisable via ethtool ioctl/netlink, and suspend/resume paths can be tested via power management interfaces.",
"WorthFuzzing": true
} |
| 93/1 | 2026/09/13 00:18 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 94/2 | 2026/09/13 00:18 | agent | kmsan-evaluator |
0mModel:core Args: null Results: {
"KMSANReasoning": "The patch adds Wake-on-LAN (WoL) interrupt and power management support (suspend/resume routines and wake-irq setup) for Marvell 88E1318S and 88E1510 PHY drivers. \n\nAll stack variables (e.g. `wol_off`, `oldpage`, `ret`, `err`) are explicitly initialized before use, and no kernel memory is copied to user space or left uninitialized in heap/stack allocations. The changes primarily involve hardware register writes over MDIO and Linux device PM wakeirq configuration. Any potential issues introduced would relate to error code handling, MDIO bus communication, or PM state management, none of which involve uninitialized memory accesses or information leaks. Therefore, dedicated KMSAN fuzzing is not warranted.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
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 087b13dfb2d69e265bbfbc7b467f39e2e7be58af
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Sep 13 00:15:11 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f71cffa884062..70aaa09f20478 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -30,6 +30,8 @@
#include <linux/ethtool_netlink.h>
#include <linux/phy.h>
#include <linux/phy_port.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/property.h>
#include <linux/marvell_phy.h>
#include <linux/bitfield.h>
#include <linux/of.h>
@@ -1902,6 +1904,61 @@ static int marvell_resume(struct phy_device *phydev)
return err;
}
+/* marvell_wol_suspend_intrs
+ *
+ * With WoL enabled the PHY has to stay powered to keep detecting a WoL
+ * packet, so instead of entering low power mode, mask all interrupt
+ * sources except the WoL event. On the 88E1318S/88E1510 the interrupt
+ * mask (MII_M1011_IMASK) is the same register as the Copper Specific
+ * Interrupt Enable Register (MII_88E1318S_PHY_CSIER), so writing only
+ * the WoL event enable bit unmask just that event.
+ */
+static int marvell_wol_suspend_intrs(struct phy_device *phydev)
+{
+ int oldpage, ret;
+
+ oldpage = phy_save_page(phydev);
+ if (oldpage < 0)
+ return oldpage;
+
+ ret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
+ if (ret < 0)
+ goto out;
+
+ ret = __phy_write(phydev, MII_88E1318S_PHY_CSIER,
+ MII_88E1318S_PHY_CSIER_WOL_EIE);
+out:
+ return phy_restore_page(phydev, oldpage, ret);
+}
+
+/* marvell_wol_resume_intrs
+ *
+ * marvell_config_intr() rewrites the whole MII_M1011_IMASK register
+ * (which is MII_88E1318S_PHY_CSIER) with MII_M1011_IMASK_INIT on
+ * resume, clearing the WoL event interrupt enable bit. Re-arm it if
+ * WoL is still enabled so a later WoL event keeps waking the system.
+ */
+static int marvell_wol_resume_intrs(struct phy_device *phydev)
+{
+ int oldpage, ret;
+
+ if (!phydev->wol_enabled)
+ return 0;
+
+ oldpage = phy_save_page(phydev);
+ if (oldpage < 0)
+ return oldpage;
+
+ ret = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
+ if (ret < 0)
+ goto out;
+
+ ret = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,
+ MII_88E1318S_PHY_CSIER_WOL_EIE);
+out:
+ return phy_restore_page(phydev, oldpage, ret);
+}
+
/* m88e1510_resume
*
* The 88e1510 PHY has an erratum where the phy downshift counter is not cleared
@@ -1934,9 +1991,25 @@ static int m88e1510_resume(struct phy_device *phydev)
/* downshift enabled, with previous counter value */
err = m88e1011_set_downshift(phydev, cnt);
+ if (err < 0)
+ return err;
}
- return err;
+ return marvell_wol_resume_intrs(phydev);
+}
+
+/* m88e1510_suspend
+ *
+ * If WoL is enabled the PHY receiver has to keep running to detect a
+ * magic packet, so keep it awake and unmask only the WoL event at the
+ * PHY. Otherwise suspend both the fiber and copper interfaces as usual.
+ */
+static int m88e1510_suspend(struct phy_device *phydev)
+{
+ if (phydev->wol_enabled)
+ return marvell_wol_suspend_intrs(phydev);
+
+ return marvell_suspend(phydev);
}
static int marvell_aneg_done(struct phy_device *phydev)
@@ -1969,8 +2042,12 @@ static void m88e1318_get_wol(struct phy_device *phydev,
static int m88e1318_set_wol(struct phy_device *phydev,
struct ethtool_wolinfo *wol)
{
+ struct device *dev = &phydev->mdio.dev;
+ bool wol_enable;
int err = 0, oldpage;
+ wol_enable = !!(wol->wolopts & (WAKE_MAGIC | WAKE_PHY));
+
oldpage = phy_save_page(phydev);
if (oldpage < 0)
goto error;
@@ -2075,7 +2152,49 @@ static int m88e1318_set_wol(struct phy_device *phydev,
}
error:
- return phy_restore_page(phydev, oldpage, err);
+ err = phy_restore_page(phydev, oldpage, err);
+ if (err < 0)
+ return err;
+
+ if (device_can_wakeup(dev) && wol_enable != device_may_wakeup(dev)) {
+ err = device_set_wakeup_enable(dev, wol_enable);
+ if (err < 0) {
+ /* Roll back the PHY WoL config if the PM state update failed */
+ struct ethtool_wolinfo wol_off = { .wolopts = 0 };
+ int rollback_err = m88e1318_set_wol(phydev, &wol_off);
+
+ if (rollback_err < 0)
+ phydev_err(phydev,
+ "Failed to disable WoL after wakeup enable error %d\n",
+ rollback_err);
+ }
+ }
+
+ return err;
+}
+
+/* m88e1318_suspend
+ *
+ * If WoL is enabled keep the PHY awake so it can detect a magic packet
+ * while the system is asleep, unmasking only the WoL event at the PHY.
+ * Otherwise suspend the PHY normally.
+ */
+static int m88e1318_suspend(struct phy_device *phydev)
+{
+ if (phydev->wol_enabled)
+ return marvell_wol_suspend_intrs(phydev);
+
+ return genphy_suspend(phydev);
+}
+
+static int m88e1318_resume(struct phy_device *phydev)
+{
+ int err = genphy_resume(phydev);
+
+ if (err < 0)
+ return err;
+
+ return marvell_wol_resume_intrs(phydev);
}
static int marvell_get_sset_count(struct phy_device *phydev)
@@ -3587,14 +3706,25 @@ static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index,
static int marvell_probe(struct phy_device *phydev)
{
+ struct device *dev = &phydev->mdio.dev;
struct marvell_priv *priv;
- priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
phydev->priv = priv;
+ if (device_property_present(dev, "wakeup-source") &&
+ phy_interrupt_is_valid(phydev)) {
+ int ret = devm_pm_set_wake_irq(dev, phydev->irq);
+
+ if (ret)
+ return ret;
+
+ device_set_wakeup_capable(dev, true);
+ }
+
return marvell_hwmon_probe(phydev);
}
@@ -3813,6 +3943,7 @@ static struct phy_driver marvell_drivers[] = {
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1318S",
/* PHY_GBIT_FEATURES */
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
.probe = marvell_probe,
.config_init = m88e1318_config_init,
.config_aneg = m88e1318_config_aneg,
@@ -3821,8 +3952,8 @@ static struct phy_driver marvell_drivers[] = {
.handle_interrupt = marvell_handle_interrupt,
.get_wol = m88e1318_get_wol,
.set_wol = m88e1318_set_wol,
- .resume = genphy_resume,
- .suspend = genphy_suspend,
+ .resume = m88e1318_resume,
+ .suspend = m88e1318_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -3920,7 +4051,7 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1510",
.driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
.features = PHY_GBIT_FIBRE_FEATURES,
- .flags = PHY_POLL_CABLE_TEST,
+ .flags = PHY_POLL_CABLE_TEST | PHY_ALWAYS_CALL_SUSPEND,
.probe = marvell_probe,
.config_init = m88e1510_config_init,
.config_aneg = m88e1510_config_aneg,
@@ -3930,7 +4061,7 @@ static struct phy_driver marvell_drivers[] = {
.get_wol = m88e1318_get_wol,
.set_wol = m88e1318_set_wol,
.resume = m88e1510_resume,
- .suspend = marvell_suspend,
+ .suspend = m88e1510_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
|
| 95/3 | 2026/09/13 00:18 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 4843 output: 39 thoughts: 614 Thoughts: **Assessing Uninitialized Memory Risks in a Marvell PHY Patch**
Okay, let's dive into this patch and see if it introduces any uninitialized memory risks that would warrant running KMSAN. This patch focuses on adding WoL interrupt handling for Marvell PHYs 88E1318S and 88E1510 during suspend and resume cycles. My initial impression is that it seems like a focused and well-defined set of changes, but as always, thoroughness is key.
The core of the patch revolves around the `drivers/net/phy/marvell.c` file. I see several key additions: functions like `marvell_wol_suspend_intrs()` and `marvell_wol_resume_intrs()` are introduced. The former writes to a specific register, `MII_88E1318S_PHY_CSIER`, which seems relatively contained. The latter re-enables the WoL interrupt based on `phydev->wol_enabled`, which feels like standard suspend/resume behavior.
I've also noticed a few wrapper functions like `m88e1510_resume()` and `m88e1318_suspend()` called and used during suspend and resume. I am going to need to look into those as well. I'll need to check the call traces and make sure all parameters are set and used correctly, that could be a potential area to overlook when checking for uninitialized memory use.
The `m88e1318_set_wol()` function is another point of interest. It updates the device's wakeup enable via `device_set_wakeup_enable()`. The conditional check, `device_can_wakeup(dev) && wol_enable != device_may_wakeup(dev)`, is interesting, and the fallback to `m88e1318_set_wol(phydev, &wol_off)` if `device_set_wakeup_enable()` fails is sensible. I need to make sure the `wol_off` structure is initialized correctly. It's defined as `struct ethtool_wolinfo wol_off = { .wolopts = 0 };`, which, in C, should zero-initialize all its members. That looks safe, but I will double-check that the definition of `ethtool_wolinfo` actually does contain the members I expect.
The `marvell_probe()` function seems to handle the device's wakeup capabilities based on the "wakeup-source" property and the validity of the interrupt. Calling `devm_pm_set_wake_irq()` and `device_set_wakeup_capable()` is standard practice.
Overall, the patch seems relatively contained in terms of scope. I do not see any glaring red flags so far. But, I will need to verify the usage and initial state of those variables I mentioned. Let me check the implementations of the relevant functions, particularly `m88e1318_set_wol()`, and carefully trace the data flow to ensure there are no subtle uninitialized memory access vulnerabilities hiding within the suspend/resume logic.
|
| 96/3 | 2026/09/13 00:18 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/marvell.c",
"FirstLine": 2040,
"LineCount": 80
}Results: {
"Contents": "2040:\t}\n2041:\t\n2042:\tstatic int m88e1318_set_wol(struct phy_device *phydev,\n2043:\t\t\t\t struct ethtool_wolinfo *wol)\n2044:\t{\n2045:\t\tstruct device *dev = \u0026phydev-\u003emdio.dev;\n2046:\t\tbool wol_enable;\n2047:\t\tint err = 0, oldpage;\n2048:\t\n2049:\t\twol_enable = !!(wol-\u003ewolopts \u0026 (WAKE_MAGIC | WAKE_PHY));\n2050:\t\n2051:\t\toldpage = phy_save_page(phydev);\n2052:\t\tif (oldpage \u003c 0)\n2053:\t\t\tgoto error;\n2054:\t\n2055:\t\tif (wol-\u003ewolopts \u0026 (WAKE_MAGIC | WAKE_PHY)) {\n2056:\t\t\t/* Explicitly switch to page 0x00, just to be sure */\n2057:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);\n2058:\t\t\tif (err \u003c 0)\n2059:\t\t\t\tgoto error;\n2060:\t\n2061:\t\t\t/* If WOL event happened once, the LED[2] interrupt pin\n2062:\t\t\t * will not be cleared unless we reading the interrupt status\n2063:\t\t\t * register. If interrupts are in use, the normal interrupt\n2064:\t\t\t * handling will clear the WOL event. Clear the WOL event\n2065:\t\t\t * before enabling it if !phy_interrupt_is_valid()\n2066:\t\t\t */\n2067:\t\t\tif (!phy_interrupt_is_valid(phydev))\n2068:\t\t\t\t__phy_read(phydev, MII_M1011_IEVENT);\n2069:\t\n2070:\t\t\t/* Enable the WOL interrupt */\n2071:\t\t\terr = __phy_set_bits(phydev, MII_88E1318S_PHY_CSIER,\n2072:\t\t\t\t\t MII_88E1318S_PHY_CSIER_WOL_EIE);\n2073:\t\t\tif (err \u003c 0)\n2074:\t\t\t\tgoto error;\n2075:\t\n2076:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);\n2077:\t\t\tif (err \u003c 0)\n2078:\t\t\t\tgoto error;\n2079:\t\n2080:\t\t\t/* Setup LED[2] as interrupt pin (active low) */\n2081:\t\t\terr = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,\n2082:\t\t\t\t\t MII_88E1318S_PHY_LED_TCR_FORCE_INT,\n2083:\t\t\t\t\t MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |\n2084:\t\t\t\t\t MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);\n2085:\t\t\tif (err \u003c 0)\n2086:\t\t\t\tgoto error;\n2087:\t\t}\n2088:\t\n2089:\t\tif (wol-\u003ewolopts \u0026 WAKE_MAGIC) {\n2090:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);\n2091:\t\t\tif (err \u003c 0)\n2092:\t\t\t\tgoto error;\n2093:\t\n2094:\t\t\t/* Store the device address for the magic packet */\n2095:\t\t\terr = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,\n2096:\t\t\t\t\t((phydev-\u003eattached_dev-\u003edev_addr[5] \u003c\u003c 8) |\n2097:\t\t\t\t\t phydev-\u003eattached_dev-\u003edev_addr[4]));\n2098:\t\t\tif (err \u003c 0)\n2099:\t\t\t\tgoto error;\n2100:\t\t\terr = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,\n2101:\t\t\t\t\t((phydev-\u003eattached_dev-\u003edev_addr[3] \u003c\u003c 8) |\n2102:\t\t\t\t\t phydev-\u003eattached_dev-\u003edev_addr[2]));\n2103:\t\t\tif (err \u003c 0)\n2104:\t\t\t\tgoto error;\n2105:\t\t\terr = __phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,\n2106:\t\t\t\t\t((phydev-\u003eattached_dev-\u003edev_addr[1] \u003c\u003c 8) |\n2107:\t\t\t\t\t phydev-\u003eattached_dev-\u003edev_addr[0]));\n2108:\t\t\tif (err \u003c 0)\n2109:\t\t\t\tgoto error;\n2110:\t\n2111:\t\t\t/* Clear WOL status and enable magic packet matching */\n2112:\t\t\terr = __phy_set_bits(phydev, MII_88E1318S_PHY_WOL_CTRL,\n2113:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |\n2114:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE);\n2115:\t\t\tif (err \u003c 0)\n2116:\t\t\t\tgoto error;\n2117:\t\t} else {\n2118:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);\n2119:\t\t\tif (err \u003c 0)\n"
} |
| 97/3 | 2026/09/13 00:18 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 7664 output: 39 thoughts: 21 Thoughts: Okay, here's my interpretation of what's going on, presented as a first-person thought process, keeping in mind my expertise: **Diving into `m88e1318_set_wol`** Alright, let's see what this `m88e1318_set_wol` function is all about. I'm assuming it's part of some low-level driver or firmware, likely dealing with setting Wake-on-LAN functionality, given the function name. I know from experience that these types of functions are often intricate because they have to interact directly with hardware registers and potentially manage power states. I need to figure out the context. What's the target hardware? What's the overall system architecture? Where does this function fit into the power management flow? Based on the function name, I suspect this function might handle enabling or disabling Wake-on-LAN features on a specific Network Interface Card or System. I'll need to look closely at how it's manipulating registers, what specific bits it's setting or clearing, and if there are any error handling mechanisms in place. And likely, there might be corresponding structures, and I expect to see references to some device-specific constants and macros as well. Let's see how well it's written and if there are obvious concurrency issues, or potential race conditions that are common with these types of operations. I'm ready to dig in and break it down. |
| 98/3 | 2026/09/13 00:18 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/marvell.c",
"FirstLine": 2120,
"LineCount": 60
}Results: {
"Contents": "2120:\t\t\t\tgoto error;\n2121:\t\n2122:\t\t\t/* Clear WOL status and disable magic packet matching */\n2123:\t\t\terr = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,\n2124:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE,\n2125:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);\n2126:\t\t\tif (err \u003c 0)\n2127:\t\t\t\tgoto error;\n2128:\t\t}\n2129:\t\n2130:\t\tif (wol-\u003ewolopts \u0026 WAKE_PHY) {\n2131:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);\n2132:\t\t\tif (err \u003c 0)\n2133:\t\t\t\tgoto error;\n2134:\t\n2135:\t\t\t/* Clear WOL status and enable link up event */\n2136:\t\t\terr = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL, 0,\n2137:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS |\n2138:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE);\n2139:\t\t\tif (err \u003c 0)\n2140:\t\t\t\tgoto error;\n2141:\t\t} else {\n2142:\t\t\terr = marvell_write_page(phydev, MII_MARVELL_WOL_PAGE);\n2143:\t\t\tif (err \u003c 0)\n2144:\t\t\t\tgoto error;\n2145:\t\n2146:\t\t\t/* Clear WOL status and disable link up event */\n2147:\t\t\terr = __phy_modify(phydev, MII_88E1318S_PHY_WOL_CTRL,\n2148:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_LINK_UP_ENABLE,\n2149:\t\t\t\t\t MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);\n2150:\t\t\tif (err \u003c 0)\n2151:\t\t\t\tgoto error;\n2152:\t\t}\n2153:\t\n2154:\terror:\n2155:\t\terr = phy_restore_page(phydev, oldpage, err);\n2156:\t\tif (err \u003c 0)\n2157:\t\t\treturn err;\n2158:\t\n2159:\t\tif (device_can_wakeup(dev) \u0026\u0026 wol_enable != device_may_wakeup(dev)) {\n2160:\t\t\terr = device_set_wakeup_enable(dev, wol_enable);\n2161:\t\t\tif (err \u003c 0) {\n2162:\t\t\t\t/* Roll back the PHY WoL config if the PM state update failed */\n2163:\t\t\t\tstruct ethtool_wolinfo wol_off = { .wolopts = 0 };\n2164:\t\t\t\tint rollback_err = m88e1318_set_wol(phydev, \u0026wol_off);\n2165:\t\n2166:\t\t\t\tif (rollback_err \u003c 0)\n2167:\t\t\t\t\tphydev_err(phydev,\n2168:\t\t\t\t\t\t \"Failed to disable WoL after wakeup enable error %d\\n\",\n2169:\t\t\t\t\t\t rollback_err);\n2170:\t\t\t}\n2171:\t\t}\n2172:\t\n2173:\t\treturn err;\n2174:\t}\n2175:\t\n2176:\t/* m88e1318_suspend\n2177:\t *\n2178:\t * If WoL is enabled keep the PHY awake so it can detect a magic packet\n2179:\t * while the system is asleep, unmasking only the WoL event at the PHY.\n"
} |
| 99/3 | 2026/09/13 00:18 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 9092 output: 193 thoughts: 908 Thoughts: **KMSAN Assessment: No Uninitialized Memory Risks Detected** Alright, let's break this down. First, I examined the `struct ethtool_wolinfo` usage within `m88e1318_set_wol`. The only field accessed is `wol->wolopts`, and crucially, `wol_off` is defined as a zeroed struct. There's no data being copied to userspace, no new buffers are allocated, and importantly, I see no uninitialized variables at play here. That's good. Now, let's look at the broader patch context. The code deals with hardware register manipulations using MDIO operations within `marvell_wol_suspend_intrs` and related functions. I've confirmed that these functions operate safely on hardware registers, using methods like `phy_save_page`, and there's logic in place, such as checking `phydev->wol_enabled` during resume. Error handling has also been added in places like `m88e1510_resume`. The probe function seems solid, using existing allocation mechanisms and handling wake-up source properties. I've carefully assessed for potential uninitialized memory risks. Specifically: * No kernel structures are being sent to user space where there might be initialization issues. * There's no conditional logic that depends on potentially uninitialized variables. * No complex data structures with uninitialized fields are being allocated. * I see no bounds checks or other logic that would allow access to uninitialized memory. The only potential bugs I can see are related to hardware errors, device PM, or wakeirq handling (perhaps some possible recursion). However, these are all functional/logic issues, not uninitialized memory issues that KMSAN is designed to catch. KMSAN hasn't reported anything, either. The central point here is that standard KASAN and other bug detectors would likely find any issues if they existed. KMSAN is for catching *uninitialized* reads, and that's just not present here. All variables are initialized immediately, so this patch doesn't introduce any risk of uninitialized memory usage. There are no copies to userspace or uninitialized reads. Given all this, I'm confident that `NeedsKMSAN` should be set to `false`. We can proceed to set the results. |
| 100/3 | 2026/09/13 00:18 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch adds Wake-on-LAN (WoL) interrupt and power management support (suspend/resume routines and wake-irq setup) for Marvell 88E1318S and 88E1510 PHY drivers. \n\nAll stack variables (e.g. `wol_off`, `oldpage`, `ret`, `err`) are explicitly initialized before use, and no kernel memory is copied to user space or left uninitialized in heap/stack allocations. The changes primarily involve hardware register writes over MDIO and Linux device PM wakeirq configuration. Any potential issues introduced would relate to error code handling, MDIO bus communication, or PM state management, none of which involve uninitialized memory accesses or information leaks. Therefore, dedicated KMSAN fuzzing is not warranted.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch adds Wake-on-LAN (WoL) interrupt and power management support (suspend/resume routines and wake-irq setup) for Marvell 88E1318S and 88E1510 PHY drivers. \n\nAll stack variables (e.g. `wol_off`, `oldpage`, `ret`, `err`) are explicitly initialized before use, and no kernel memory is copied to user space or left uninitialized in heap/stack allocations. The changes primarily involve hardware register writes over MDIO and Linux device PM wakeirq configuration. Any potential issues introduced would relate to error code handling, MDIO bus communication, or PM state management, none of which involve uninitialized memory accesses or information leaks. Therefore, dedicated KMSAN fuzzing is not warranted.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|