| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/27 21:35 | flow | patch-triage |
22mArgs:null Results: {
"EnableConfigs": [
"NET",
"NETDEVICES",
"PHYLIB",
"PHYLINK"
],
"FocusSymbols": [
"phy_attach_direct",
"phy_detach",
"phylink_connect_phy",
"phylink_disconnect_phy",
"phylink_fwnode_phy_connect",
"phylink_of_phy_connect"
],
"KMSANReasoning": "The patch addresses state cleanup and IRQ restoration in PHY and phylink driver lifecycles (specifically restoring phydev-\u003eirq upon generic PHY driver detach/attach failure and clearing pl-\u003ephydev on phylink_bringup_phy failure). \n\nThese changes involve managing object lifecycles, resetting internal pointers to NULL, and resetting boolean flags. No uninitialized memory allocations, uninitialized reads, padding leaks, or user-space copies (copy_to_user/netlink) are introduced or modified. Any lifecycle or dangling pointer issues in this code path fall under KASAN (use-after-free / invalid access) or standard kernel assertions/LOCKDEP, making a dedicated KMSAN session unnecessary.",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies core PHY library and phylink subsystem logic in drivers/net/phy/phy_device.c and drivers/net/phy/phylink.c. It introduces phy_restore_genphy_irq to properly restore PHY interrupt configurations when detaching or failing to attach a generic PHY, and ensures phylink_clear_phydev is called to cleanly detach and reset state if phylink_bringup_phy fails. These changes affect reachable network PHY setup/teardown logic used by emulated network adapters (e.g. USB ethernet adapters and DSA loop devices) in virtualized environments.",
"WorthFuzzing": true
} |
| 1/1 | 2026/08/27 21:35 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 9c99235c784d6c7dbf643c85db861955014a62a4\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Aug 27 21:35:51 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c\nindex 94b2e85e00a37..be4c35db8de98 100644\n--- a/drivers/net/phy/phy_device.c\n+++ b/drivers/net/phy/phy_device.c\n@@ -1734,6 +1734,18 @@ static bool phy_drv_supports_irq(const struct phy_driver *phydrv)\n \treturn phydrv-\u003econfig_intr \u0026\u0026 phydrv-\u003ehandle_interrupt;\n }\n \n+/* Give back the interrupt phy_probe() parked when a driver with no interrupt\n+ * callbacks bound. mdiobus_alloc() defaults bus-\u003eirq[] to PHY_POLL and the\n+ * bind cycle does not touch the table, so whatever the bus recorded there\n+ * still stands. Only the parking is undone: any other value the PHY carries\n+ * was put there by someone else.\n+ */\n+static void phy_restore_genphy_irq(struct phy_device *phydev)\n+{\n+\tif (phydev-\u003eirq == PHY_POLL)\n+\t\tphydev-\u003eirq = phydev-\u003emdio.bus-\u003eirq[phydev-\u003emdio.addr];\n+}\n+\n /**\n * phy_attach_direct - attach a network device to a given PHY device pointer\n * @dev: network device to attach\n@@ -1896,6 +1908,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,\n \n error_module_put:\n \tmodule_put(d-\u003edriver-\u003eowner);\n+\tphy_restore_genphy_irq(phydev);\n \tphydev-\u003eis_genphy_driven = 0;\n \td-\u003edriver = NULL;\n error_put_device:\n@@ -1965,6 +1978,7 @@ void phy_detach(struct phy_device *phydev)\n \t * real driver could be loaded\n \t */\n \tif (phydev-\u003eis_genphy_driven) {\n+\t\tphy_restore_genphy_irq(phydev);\n \t\tdevice_release_driver(\u0026phydev-\u003emdio.dev);\n \t\tphydev-\u003eis_genphy_driven = 0;\n \t}\ndiff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c\nindex 5b8e956902fb5..a55e4a64028ff 100644\n--- a/drivers/net/phy/phylink.c\n+++ b/drivers/net/phy/phylink.c\n@@ -2083,6 +2083,18 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,\n \treturn phylink_validate(pl, supported, state);\n }\n \n+/* Disassociate @phy from @pl. Caller must hold pl-\u003ephydev_mutex. */\n+static void phylink_clear_phydev(struct phylink *pl, struct phy_device *phy)\n+{\n+\tmutex_lock(\u0026phy-\u003elock);\n+\tmutex_lock(\u0026pl-\u003estate_mutex);\n+\tpl-\u003ephydev = NULL;\n+\tpl-\u003ephy_enable_tx_lpi = false;\n+\tpl-\u003emac_tx_clk_stop = false;\n+\tmutex_unlock(\u0026pl-\u003estate_mutex);\n+\tmutex_unlock(\u0026phy-\u003elock);\n+}\n+\n static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,\n \t\t\t phy_interface_t interface)\n {\n@@ -2197,6 +2209,12 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,\n \tif (ret == 0 \u0026\u0026 phy_interrupt_is_valid(phy))\n \t\tphy_request_interrupt(phy);\n \n+\tif (ret) {\n+\t\tmutex_lock(\u0026pl-\u003ephydev_mutex);\n+\t\tphylink_clear_phydev(pl, phy);\n+\t\tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n+\t}\n+\n \treturn ret;\n }\n \n@@ -2347,15 +2365,8 @@ void phylink_disconnect_phy(struct phylink *pl)\n \n \tmutex_lock(\u0026pl-\u003ephydev_mutex);\n \tphy = pl-\u003ephydev;\n-\tif (phy) {\n-\t\tmutex_lock(\u0026phy-\u003elock);\n-\t\tmutex_lock(\u0026pl-\u003estate_mutex);\n-\t\tpl-\u003ephydev = NULL;\n-\t\tpl-\u003ephy_enable_tx_lpi = false;\n-\t\tpl-\u003emac_tx_clk_stop = false;\n-\t\tmutex_unlock(\u0026pl-\u003estate_mutex);\n-\t\tmutex_unlock(\u0026phy-\u003elock);\n-\t}\n+\tif (phy)\n+\t\tphylink_clear_phydev(pl, phy);\n \tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n \n \tif (phy) {\n"
} |
| 2/1 | 2026/08/27 21:35 | agent | patch-evaluator |
19mModel:core Args: null Results: {
"EnableConfigs": [
"NET",
"NETDEVICES",
"PHYLIB",
"PHYLINK"
],
"FocusSymbols": [
"phy_attach_direct",
"phy_detach",
"phylink_connect_phy",
"phylink_disconnect_phy",
"phylink_fwnode_phy_connect",
"phylink_of_phy_connect"
],
"Reasoning": "The patch modifies core PHY library and phylink subsystem logic in drivers/net/phy/phy_device.c and drivers/net/phy/phylink.c. It introduces phy_restore_genphy_irq to properly restore PHY interrupt configurations when detaching or failing to attach a generic PHY, and ensures phylink_clear_phydev is called to cleanly detach and reset state if phylink_bringup_phy fails. These changes affect reachable network PHY setup/teardown logic used by emulated network adapters (e.g. USB ethernet adapters and DSA loop devices) in virtualized environments.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 9c99235c784d6c7dbf643c85db861955014a62a4
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Aug 27 21:35:51 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 94b2e85e00a37..be4c35db8de98 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1734,6 +1734,18 @@ static bool phy_drv_supports_irq(const struct phy_driver *phydrv)
return phydrv->config_intr && phydrv->handle_interrupt;
}
+/* Give back the interrupt phy_probe() parked when a driver with no interrupt
+ * callbacks bound. mdiobus_alloc() defaults bus->irq[] to PHY_POLL and the
+ * bind cycle does not touch the table, so whatever the bus recorded there
+ * still stands. Only the parking is undone: any other value the PHY carries
+ * was put there by someone else.
+ */
+static void phy_restore_genphy_irq(struct phy_device *phydev)
+{
+ if (phydev->irq == PHY_POLL)
+ phydev->irq = phydev->mdio.bus->irq[phydev->mdio.addr];
+}
+
/**
* phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
@@ -1896,6 +1908,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
error_module_put:
module_put(d->driver->owner);
+ phy_restore_genphy_irq(phydev);
phydev->is_genphy_driven = 0;
d->driver = NULL;
error_put_device:
@@ -1965,6 +1978,7 @@ void phy_detach(struct phy_device *phydev)
* real driver could be loaded
*/
if (phydev->is_genphy_driven) {
+ phy_restore_genphy_irq(phydev);
device_release_driver(&phydev->mdio.dev);
phydev->is_genphy_driven = 0;
}
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 5b8e956902fb5..a55e4a64028ff 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2083,6 +2083,18 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
return phylink_validate(pl, supported, state);
}
+/* Disassociate @phy from @pl. Caller must hold pl->phydev_mutex. */
+static void phylink_clear_phydev(struct phylink *pl, struct phy_device *phy)
+{
+ mutex_lock(&phy->lock);
+ mutex_lock(&pl->state_mutex);
+ pl->phydev = NULL;
+ pl->phy_enable_tx_lpi = false;
+ pl->mac_tx_clk_stop = false;
+ mutex_unlock(&pl->state_mutex);
+ mutex_unlock(&phy->lock);
+}
+
static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
phy_interface_t interface)
{
@@ -2197,6 +2209,12 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
if (ret == 0 && phy_interrupt_is_valid(phy))
phy_request_interrupt(phy);
+ if (ret) {
+ mutex_lock(&pl->phydev_mutex);
+ phylink_clear_phydev(pl, phy);
+ mutex_unlock(&pl->phydev_mutex);
+ }
+
return ret;
}
@@ -2347,15 +2365,8 @@ void phylink_disconnect_phy(struct phylink *pl)
mutex_lock(&pl->phydev_mutex);
phy = pl->phydev;
- if (phy) {
- mutex_lock(&phy->lock);
- mutex_lock(&pl->state_mutex);
- pl->phydev = NULL;
- pl->phy_enable_tx_lpi = false;
- pl->mac_tx_clk_stop = false;
- mutex_unlock(&pl->state_mutex);
- mutex_unlock(&phy->lock);
- }
+ if (phy)
+ phylink_clear_phydev(pl, phy);
mutex_unlock(&pl->phydev_mutex);
if (phy) {
|
| 3/2 | 2026/08/27 21:35 | llm | patch-evaluator |
11mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 3119 output: 27 thoughts: 285 Thoughts: **Analyzing a Network PHY Patch** Okay, let's dive into this patch and figure out if there's anything here that warrants fuzzing or further investigation into reachability and potential configuration issues. My initial thought is to examine the functional changes closely. First, I see the changes are focused on `drivers/net/phy/phy_device.c` and `drivers/net/phy/phylink.c`. In `phy_device.c`, there's a modification to `phy_restore_genphy_irq(phydev)`. It looks like it restores `phydev->irq` to its previous value if it was `PHY_POLL` when errors occur in `phy_attach_direct` or `phy_detach`. Nothing immediately alarming, but error paths are always interesting. Over in `phylink.c`, we have a refactoring of the helper function `phylink_clear_phydev(pl, phy)`. And it appears to be used in an error path within `phylink_bringup_phy`, specifically within a mutex lock. Refactoring is good, and the error handling being improved is a good sign, but I want to understand the impact. Now, the important question arises: where is this built, and how are PHY devices and phylink used in environments like virtualized systems, QEMU, or even software devices? I need to understand if these changes have an impact beyond standard hardware. Can I reach these specific functions and configurations within those environments? Wait a minute. Are PHY devices, MDIO, and phylink even *reachable* in QEMU, syzkaller, or similar virtualized environments? Let's break out grep and see if these components are even being used in those contexts. That will tell me a lot about the potential scope of this patch. |
| 4/2 | 2026/08/27 21:47 | tool | grepper |
0mArgs:{
"Expression": "phylink_",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 10600 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/b53/b53_common.c=1525=void b53_port_event(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/b53/b53_common.c-1532-\tlink = !!(sts \u0026 BIT(port));\ndrivers/net/dsa/b53/b53_common.c:1533:\tdsa_port_phylink_mac_change(ds, port, link);\ndrivers/net/dsa/b53/b53_common.c-1534-}\ndrivers/net/dsa/b53/b53_common.c=1535=EXPORT_SYMBOL(b53_port_event);\ndrivers/net/dsa/b53/b53_common.c-1536-\ndrivers/net/dsa/b53/b53_common.c:1537:static void b53_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/b53/b53_common.c:1538:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/b53/b53_common.c-1539-{\n--\ndrivers/net/dsa/b53/b53_common.c-1575-\t/* Get the implementation specific capabilities */\ndrivers/net/dsa/b53/b53_common.c:1576:\tif (dev-\u003eops-\u003ephylink_get_caps)\ndrivers/net/dsa/b53/b53_common.c:1577:\t\tdev-\u003eops-\u003ephylink_get_caps(dev, port, config);\ndrivers/net/dsa/b53/b53_common.c-1578-}\ndrivers/net/dsa/b53/b53_common.c-1579-\ndrivers/net/dsa/b53/b53_common.c:1580:static struct phylink_pcs *b53_phylink_mac_select_pcs(struct phylink_config *config,\ndrivers/net/dsa/b53/b53_common.c-1581-\t\t\t\t\t\t phy_interface_t interface)\ndrivers/net/dsa/b53/b53_common.c-1582-{\ndrivers/net/dsa/b53/b53_common.c:1583:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/b53/b53_common.c-1584-\tstruct b53_device *dev = dp-\u003eds-\u003epriv;\ndrivers/net/dsa/b53/b53_common.c-1585-\ndrivers/net/dsa/b53/b53_common.c:1586:\tif (!dev-\u003eops-\u003ephylink_mac_select_pcs)\ndrivers/net/dsa/b53/b53_common.c-1587-\t\treturn NULL;\ndrivers/net/dsa/b53/b53_common.c-1588-\ndrivers/net/dsa/b53/b53_common.c:1589:\treturn dev-\u003eops-\u003ephylink_mac_select_pcs(dev, dp-\u003eindex, interface);\ndrivers/net/dsa/b53/b53_common.c-1590-}\ndrivers/net/dsa/b53/b53_common.c-1591-\ndrivers/net/dsa/b53/b53_common.c:1592:static void b53_phylink_mac_config(struct phylink_config *config,\ndrivers/net/dsa/b53/b53_common.c-1593-\t\t\t\t unsigned int mode,\ndrivers/net/dsa/b53/b53_common.c:1594:\t\t\t\t const struct phylink_link_state *state)\ndrivers/net/dsa/b53/b53_common.c-1595-{\ndrivers/net/dsa/b53/b53_common.c:1596:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/b53/b53_common.c-1597-\tphy_interface_t interface = state-\u003einterface;\n--\ndrivers/net/dsa/b53/b53_common.c-1614-\ndrivers/net/dsa/b53/b53_common.c:1615:static void b53_phylink_mac_link_down(struct phylink_config *config,\ndrivers/net/dsa/b53/b53_common.c-1616-\t\t\t\t unsigned int mode,\n--\ndrivers/net/dsa/b53/b53_common.c-1618-{\ndrivers/net/dsa/b53/b53_common.c:1619:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/b53/b53_common.c-1620-\tstruct b53_device *dev = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/b53/b53_common.c-1638-\ndrivers/net/dsa/b53/b53_common.c:1639:static void b53_phylink_mac_link_up(struct phylink_config *config,\ndrivers/net/dsa/b53/b53_common.c-1640-\t\t\t\t struct phy_device *phydev,\n--\ndrivers/net/dsa/b53/b53_common.c-1645-{\ndrivers/net/dsa/b53/b53_common.c:1646:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/b53/b53_common.c-1647-\tstruct dsa_switch *ds = dp-\u003eds;\n--\ndrivers/net/dsa/b53/b53_common.c=2692=EXPORT_SYMBOL_GPL(b53_set_ageing_time);\ndrivers/net/dsa/b53/b53_common.c-2693-\ndrivers/net/dsa/b53/b53_common.c:2694:static const struct phylink_mac_ops b53_phylink_mac_ops = {\ndrivers/net/dsa/b53/b53_common.c:2695:\t.mac_select_pcs\t= b53_phylink_mac_select_pcs,\ndrivers/net/dsa/b53/b53_common.c:2696:\t.mac_config\t= b53_phylink_mac_config,\ndrivers/net/dsa/b53/b53_common.c:2697:\t.mac_link_down\t= b53_phylink_mac_link_down,\ndrivers/net/dsa/b53/b53_common.c:2698:\t.mac_link_up\t= b53_phylink_mac_link_up,\ndrivers/net/dsa/b53/b53_common.c-2699-};\n--\ndrivers/net/dsa/b53/b53_common.c=2701=static const struct dsa_switch_ops b53_switch_ops = {\n--\ndrivers/net/dsa/b53/b53_common.c-2710-\t.phy_write\t\t= b53_phy_write16,\ndrivers/net/dsa/b53/b53_common.c:2711:\t.phylink_get_caps\t= b53_phylink_get_caps,\ndrivers/net/dsa/b53/b53_common.c-2712-\t.port_setup\t\t= b53_setup_port,\n--\ndrivers/net/dsa/b53/b53_common.c=3183=struct b53_device *b53_switch_alloc(struct device *base,\n--\ndrivers/net/dsa/b53/b53_common.c-3206-\tds-\u003eops = \u0026b53_switch_ops;\ndrivers/net/dsa/b53/b53_common.c:3207:\tds-\u003ephylink_mac_ops = \u0026b53_phylink_mac_ops;\ndrivers/net/dsa/b53/b53_common.c-3208-\tdev-\u003evlan_enabled = true;\n--\ndrivers/net/dsa/b53/b53_priv.h=34=struct b53_io_ops {\n--\ndrivers/net/dsa/b53/b53_priv.h-50-\tvoid (*phy_disable)(struct b53_device *dev, int port);\ndrivers/net/dsa/b53/b53_priv.h:51:\tvoid (*phylink_get_caps)(struct b53_device *dev, int port,\ndrivers/net/dsa/b53/b53_priv.h:52:\t\t\t\t struct phylink_config *config);\ndrivers/net/dsa/b53/b53_priv.h:53:\tstruct phylink_pcs *(*phylink_mac_select_pcs)(struct b53_device *dev,\ndrivers/net/dsa/b53/b53_priv.h-54-\t\t\t\t\t\t int port,\n--\ndrivers/net/dsa/b53/b53_priv.h=111=struct b53_pcs {\ndrivers/net/dsa/b53/b53_priv.h:112:\tstruct phylink_pcs pcs;\ndrivers/net/dsa/b53/b53_priv.h-113-\tstruct b53_device *dev;\n--\ndrivers/net/dsa/b53/b53_serdes.c-19-\ndrivers/net/dsa/b53/b53_serdes.c:20:static inline struct b53_pcs *pcs_to_b53_pcs(struct phylink_pcs *pcs)\ndrivers/net/dsa/b53/b53_serdes.c-21-{\n--\ndrivers/net/dsa/b53/b53_serdes.c=61=static u16 b53_serdes_read(struct b53_device *dev, u8 lane,\n--\ndrivers/net/dsa/b53/b53_serdes.c-67-\ndrivers/net/dsa/b53/b53_serdes.c:68:static int b53_serdes_config(struct phylink_pcs *pcs, unsigned int neg_mode,\ndrivers/net/dsa/b53/b53_serdes.c-69-\t\t\t phy_interface_t interface,\n--\ndrivers/net/dsa/b53/b53_serdes.c-88-\ndrivers/net/dsa/b53/b53_serdes.c:89:static void b53_serdes_an_restart(struct phylink_pcs *pcs)\ndrivers/net/dsa/b53/b53_serdes.c-90-{\n--\ndrivers/net/dsa/b53/b53_serdes.c-101-\ndrivers/net/dsa/b53/b53_serdes.c:102:static void b53_serdes_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,\ndrivers/net/dsa/b53/b53_serdes.c:103:\t\t\t\t struct phylink_link_state *state)\ndrivers/net/dsa/b53/b53_serdes.c-104-{\n--\ndrivers/net/dsa/b53/b53_serdes.c=157=EXPORT_SYMBOL(b53_serdes_link_set);\ndrivers/net/dsa/b53/b53_serdes.c-158-\ndrivers/net/dsa/b53/b53_serdes.c:159:static const struct phylink_pcs_ops b53_pcs_ops = {\ndrivers/net/dsa/b53/b53_serdes.c-160-\t.pcs_get_state = b53_serdes_get_state,\n--\ndrivers/net/dsa/b53/b53_serdes.c-164-\ndrivers/net/dsa/b53/b53_serdes.c:165:void b53_serdes_phylink_get_caps(struct b53_device *dev, int port,\ndrivers/net/dsa/b53/b53_serdes.c:166:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/b53/b53_serdes.c-167-{\n--\ndrivers/net/dsa/b53/b53_serdes.c-191-}\ndrivers/net/dsa/b53/b53_serdes.c:192:EXPORT_SYMBOL(b53_serdes_phylink_get_caps);\ndrivers/net/dsa/b53/b53_serdes.c-193-\ndrivers/net/dsa/b53/b53_serdes.c:194:struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev,\ndrivers/net/dsa/b53/b53_serdes.c-195-\t\t\t\t\t\t int port,\n--\ndrivers/net/dsa/b53/b53_serdes.c-209-}\ndrivers/net/dsa/b53/b53_serdes.c:210:EXPORT_SYMBOL(b53_serdes_phylink_mac_select_pcs);\ndrivers/net/dsa/b53/b53_serdes.c-211-\n--\ndrivers/net/dsa/b53/b53_serdes.h-99-\ndrivers/net/dsa/b53/b53_serdes.h:100:struct phylink_link_state;\ndrivers/net/dsa/b53/b53_serdes.h-101-\n--\ndrivers/net/dsa/b53/b53_serdes.h=110=void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode,\ndrivers/net/dsa/b53/b53_serdes.h-111-\t\t\t phy_interface_t interface, bool link_up);\ndrivers/net/dsa/b53/b53_serdes.h:112:struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev,\ndrivers/net/dsa/b53/b53_serdes.h-113-\t\t\t\t\t\t int port,\ndrivers/net/dsa/b53/b53_serdes.h-114-\t\t\t\t\t\t phy_interface_t interface);\ndrivers/net/dsa/b53/b53_serdes.h:115:void b53_serdes_phylink_get_caps(struct b53_device *dev, int port,\ndrivers/net/dsa/b53/b53_serdes.h:116:\t\t\t\t struct phylink_config *config);\ndrivers/net/dsa/b53/b53_serdes.h-117-#if IS_ENABLED(CONFIG_B53_SERDES)\n--\ndrivers/net/dsa/b53/b53_srab.c=435=static void b53_srab_irq_disable(struct b53_device *dev, int port)\n--\ndrivers/net/dsa/b53/b53_srab.c-445-\ndrivers/net/dsa/b53/b53_srab.c:446:static void b53_srab_phylink_get_caps(struct b53_device *dev, int port,\ndrivers/net/dsa/b53/b53_srab.c:447:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/b53/b53_srab.c-448-{\n--\ndrivers/net/dsa/b53/b53_srab.c-457-\t\t */\ndrivers/net/dsa/b53/b53_srab.c:458:\t\tb53_serdes_phylink_get_caps(dev, port, config);\ndrivers/net/dsa/b53/b53_srab.c-459-#endif\n--\ndrivers/net/dsa/b53/b53_srab.c=479=static const struct b53_io_ops b53_srab_ops = {\n--\ndrivers/net/dsa/b53/b53_srab.c-491-\t.irq_disable = b53_srab_irq_disable,\ndrivers/net/dsa/b53/b53_srab.c:492:\t.phylink_get_caps = b53_srab_phylink_get_caps,\ndrivers/net/dsa/b53/b53_srab.c-493-#if IS_ENABLED(CONFIG_B53_SERDES)\ndrivers/net/dsa/b53/b53_srab.c:494:\t.phylink_mac_select_pcs = b53_serdes_phylink_mac_select_pcs,\ndrivers/net/dsa/b53/b53_srab.c-495-\t.serdes_map_lane = b53_srab_serdes_map_lane,\n--\ndrivers/net/dsa/bcm_sf2.c=452=static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id)\n--\ndrivers/net/dsa/bcm_sf2.c-462-\t\tpriv-\u003eport_sts[7].link = true;\ndrivers/net/dsa/bcm_sf2.c:463:\t\tdsa_port_phylink_mac_change(ds, 7, true);\ndrivers/net/dsa/bcm_sf2.c-464-\t}\n--\ndrivers/net/dsa/bcm_sf2.c-466-\t\tpriv-\u003eport_sts[7].link = false;\ndrivers/net/dsa/bcm_sf2.c:467:\t\tdsa_port_phylink_mac_change(ds, 7, false);\ndrivers/net/dsa/bcm_sf2.c-468-\t}\n--\ndrivers/net/dsa/bcm_sf2.c=724=static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/bcm_sf2.c:725:\t\t\t\tstruct phylink_config *config)\ndrivers/net/dsa/bcm_sf2.c-726-{\n--\ndrivers/net/dsa/bcm_sf2.c-744-\ndrivers/net/dsa/bcm_sf2.c:745:static void bcm_sf2_sw_mac_config(struct phylink_config *config,\ndrivers/net/dsa/bcm_sf2.c-746-\t\t\t\t unsigned int mode,\ndrivers/net/dsa/bcm_sf2.c:747:\t\t\t\t const struct phylink_link_state *state)\ndrivers/net/dsa/bcm_sf2.c-748-{\ndrivers/net/dsa/bcm_sf2.c:749:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/bcm_sf2.c-750-\tu32 id_mode_dis = 0, port_mode;\n--\ndrivers/net/dsa/bcm_sf2.c=794=static void bcm_sf2_sw_mac_link_set(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/bcm_sf2.c-816-\ndrivers/net/dsa/bcm_sf2.c:817:static void bcm_sf2_sw_mac_link_down(struct phylink_config *config,\ndrivers/net/dsa/bcm_sf2.c-818-\t\t\t\t unsigned int mode,\n--\ndrivers/net/dsa/bcm_sf2.c-820-{\ndrivers/net/dsa/bcm_sf2.c:821:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/bcm_sf2.c-822-\tstruct bcm_sf2_priv *priv;\n--\ndrivers/net/dsa/bcm_sf2.c-837-\ndrivers/net/dsa/bcm_sf2.c:838:static void bcm_sf2_sw_mac_link_up(struct phylink_config *config,\ndrivers/net/dsa/bcm_sf2.c-839-\t\t\t\t struct phy_device *phydev,\n--\ndrivers/net/dsa/bcm_sf2.c-844-{\ndrivers/net/dsa/bcm_sf2.c:845:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/bcm_sf2.c-846-\tstruct bcm_sf2_priv *priv;\n--\ndrivers/net/dsa/bcm_sf2.c=906=static void bcm_sf2_sw_fixed_state(struct dsa_switch *ds, int port,\ndrivers/net/dsa/bcm_sf2.c:907:\t\t\t\t struct phylink_link_state *status)\ndrivers/net/dsa/bcm_sf2.c-908-{\n--\ndrivers/net/dsa/bcm_sf2.c=1203=static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/bcm_sf2.c-1215-\ndrivers/net/dsa/bcm_sf2.c:1216:static const struct phylink_mac_ops bcm_sf2_phylink_mac_ops = {\ndrivers/net/dsa/bcm_sf2.c-1217-\t.mac_config\t= bcm_sf2_sw_mac_config,\n--\ndrivers/net/dsa/bcm_sf2.c=1222=static const struct dsa_switch_ops bcm_sf2_ops = {\n--\ndrivers/net/dsa/bcm_sf2.c-1230-\t.get_phy_flags\t\t= bcm_sf2_sw_get_phy_flags,\ndrivers/net/dsa/bcm_sf2.c:1231:\t.phylink_get_caps\t= bcm_sf2_sw_get_caps,\ndrivers/net/dsa/bcm_sf2.c:1232:\t.phylink_fixed_state\t= bcm_sf2_sw_fixed_state,\ndrivers/net/dsa/bcm_sf2.c-1233-\t.suspend\t\t= bcm_sf2_sw_suspend,\n--\ndrivers/net/dsa/bcm_sf2.c=1365=static int bcm_sf2_sw_probe(struct platform_device *pdev)\n--\ndrivers/net/dsa/bcm_sf2.c-1426-\tds-\u003eops = \u0026bcm_sf2_ops;\ndrivers/net/dsa/bcm_sf2.c:1427:\tds-\u003ephylink_mac_ops = \u0026bcm_sf2_phylink_mac_ops;\ndrivers/net/dsa/bcm_sf2.c-1428-\n--\ndrivers/net/dsa/dsa_loop.c=321=static int dsa_loop_port_max_mtu(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/dsa_loop.c-325-\ndrivers/net/dsa/dsa_loop.c:326:static void dsa_loop_phylink_get_caps(struct dsa_switch *dsa, int port,\ndrivers/net/dsa/dsa_loop.c:327:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/dsa_loop.c-328-{\n--\ndrivers/net/dsa/dsa_loop.c=334=static const struct dsa_switch_ops dsa_loop_driver = {\n--\ndrivers/net/dsa/dsa_loop.c-351-\t.port_max_mtu\t\t= dsa_loop_port_max_mtu,\ndrivers/net/dsa/dsa_loop.c:352:\t.phylink_get_caps\t= dsa_loop_phylink_get_caps,\ndrivers/net/dsa/dsa_loop.c-353-};\n--\ndrivers/net/dsa/hirschmann/hellcreek.c=1458=static void hellcreek_teardown(struct dsa_switch *ds)\n--\ndrivers/net/dsa/hirschmann/hellcreek.c-1463-\ndrivers/net/dsa/hirschmann/hellcreek.c:1464:static void hellcreek_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/hirschmann/hellcreek.c:1465:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/hirschmann/hellcreek.c-1466-{\n--\ndrivers/net/dsa/hirschmann/hellcreek.c=1900=static const struct dsa_switch_ops hellcreek_ds_ops = {\n--\ndrivers/net/dsa/hirschmann/hellcreek.c-1906-\t.get_ts_info\t = hellcreek_get_ts_info,\ndrivers/net/dsa/hirschmann/hellcreek.c:1907:\t.phylink_get_caps = hellcreek_phylink_get_caps,\ndrivers/net/dsa/hirschmann/hellcreek.c-1908-\t.port_bridge_flags = hellcreek_bridge_flags,\n--\ndrivers/net/dsa/ks8995.c=448=static void\ndrivers/net/dsa/ks8995.c:449:ks8995_mac_config(struct phylink_config *config, unsigned int mode,\ndrivers/net/dsa/ks8995.c:450:\t\t const struct phylink_link_state *state)\ndrivers/net/dsa/ks8995.c-451-{\n--\ndrivers/net/dsa/ks8995.c=454=static void\ndrivers/net/dsa/ks8995.c:455:ks8995_mac_link_up(struct phylink_config *config, struct phy_device *phydev,\ndrivers/net/dsa/ks8995.c-456-\t\t unsigned int mode, phy_interface_t interface,\n--\ndrivers/net/dsa/ks8995.c-458-{\ndrivers/net/dsa/ks8995.c:459:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/ks8995.c-460-\tstruct ks8995_switch *ks = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/ks8995.c=508=static void\ndrivers/net/dsa/ks8995.c:509:ks8995_mac_link_down(struct phylink_config *config, unsigned int mode,\ndrivers/net/dsa/ks8995.c-510-\t\t phy_interface_t interface)\ndrivers/net/dsa/ks8995.c-511-{\ndrivers/net/dsa/ks8995.c:512:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/ks8995.c-513-\tstruct ks8995_switch *ks = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/ks8995.c-523-\ndrivers/net/dsa/ks8995.c:524:static const struct phylink_mac_ops ks8995_phylink_mac_ops = {\ndrivers/net/dsa/ks8995.c-525-\t.mac_config = ks8995_mac_config,\n--\ndrivers/net/dsa/ks8995.c=602=static void ks8995_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)\n--\ndrivers/net/dsa/ks8995.c-648-\ndrivers/net/dsa/ks8995.c:649:static void ks8995_phylink_get_caps(struct dsa_switch *dsa, int port,\ndrivers/net/dsa/ks8995.c:650:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/ks8995.c-651-{\n--\ndrivers/net/dsa/ks8995.c=732=static const struct dsa_switch_ops ks8995_ds_ops = {\n--\ndrivers/net/dsa/ks8995.c-741-\t.port_max_mtu = ks8995_get_max_mtu,\ndrivers/net/dsa/ks8995.c:742:\t.phylink_get_caps = ks8995_phylink_get_caps,\ndrivers/net/dsa/ks8995.c-743-};\n--\ndrivers/net/dsa/ks8995.c=746=static int ks8995_probe(struct spi_device *spi)\n--\ndrivers/net/dsa/ks8995.c-820-\tks-\u003eds-\u003eops = \u0026ks8995_ds_ops;\ndrivers/net/dsa/ks8995.c:821:\tks-\u003eds-\u003ephylink_mac_ops = \u0026ks8995_phylink_mac_ops;\ndrivers/net/dsa/ks8995.c-822-\tks-\u003eds-\u003epriv = ks;\n--\ndrivers/net/dsa/lan9303-core.c=1283=static int lan9303_port_mdb_del(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/lan9303-core.c-1297-\ndrivers/net/dsa/lan9303-core.c:1298:static void lan9303_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/lan9303-core.c:1299:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/lan9303-core.c-1300-{\n--\ndrivers/net/dsa/lan9303-core.c-1323-\ndrivers/net/dsa/lan9303-core.c:1324:static void lan9303_phylink_mac_config(struct phylink_config *config,\ndrivers/net/dsa/lan9303-core.c-1325-\t\t\t\t unsigned int mode,\ndrivers/net/dsa/lan9303-core.c:1326:\t\t\t\t const struct phylink_link_state *state)\ndrivers/net/dsa/lan9303-core.c-1327-{\n--\ndrivers/net/dsa/lan9303-core.c-1329-\ndrivers/net/dsa/lan9303-core.c:1330:static void lan9303_phylink_mac_link_down(struct phylink_config *config,\ndrivers/net/dsa/lan9303-core.c-1331-\t\t\t\t\t unsigned int mode,\n--\ndrivers/net/dsa/lan9303-core.c-1335-\ndrivers/net/dsa/lan9303-core.c:1336:static void lan9303_phylink_mac_link_up(struct phylink_config *config,\ndrivers/net/dsa/lan9303-core.c-1337-\t\t\t\t\tstruct phy_device *phydev,\n--\ndrivers/net/dsa/lan9303-core.c-1342-{\ndrivers/net/dsa/lan9303-core.c:1343:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lan9303-core.c-1344-\tstruct lan9303 *chip = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lan9303-core.c-1375-\ndrivers/net/dsa/lan9303-core.c:1376:static const struct phylink_mac_ops lan9303_phylink_mac_ops = {\ndrivers/net/dsa/lan9303-core.c:1377:\t.mac_config\t= lan9303_phylink_mac_config,\ndrivers/net/dsa/lan9303-core.c:1378:\t.mac_link_down\t= lan9303_phylink_mac_link_down,\ndrivers/net/dsa/lan9303-core.c:1379:\t.mac_link_up\t= lan9303_phylink_mac_link_up,\ndrivers/net/dsa/lan9303-core.c-1380-};\n--\ndrivers/net/dsa/lan9303-core.c=1382=static const struct dsa_switch_ops lan9303_switch_ops = {\n--\ndrivers/net/dsa/lan9303-core.c-1387-\t.phy_write\t\t= lan9303_phy_write,\ndrivers/net/dsa/lan9303-core.c:1388:\t.phylink_get_caps\t= lan9303_phylink_get_caps,\ndrivers/net/dsa/lan9303-core.c-1389-\t.get_ethtool_stats\t= lan9303_get_ethtool_stats,\n--\ndrivers/net/dsa/lan9303-core.c=1404=static int lan9303_register_switch(struct lan9303 *chip)\n--\ndrivers/net/dsa/lan9303-core.c-1413-\tchip-\u003eds-\u003eops = \u0026lan9303_switch_ops;\ndrivers/net/dsa/lan9303-core.c:1414:\tchip-\u003eds-\u003ephylink_mac_ops = \u0026lan9303_phylink_mac_ops;\ndrivers/net/dsa/lan9303-core.c-1415-\tchip-\u003eds-\u003ephys_mii_mask = GENMASK(LAN9303_NUM_PORTS - 1, 0);\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c=27=struct xway_gphy_match_data {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c-31-\ndrivers/net/dsa/lantiq/lantiq_gswip.c:32:static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/lantiq/lantiq_gswip.c:33:\t\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/lantiq/lantiq_gswip.c-34-{\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c-62-\ndrivers/net/dsa/lantiq/lantiq_gswip.c:63:static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/lantiq/lantiq_gswip.c:64:\t\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/lantiq/lantiq_gswip.c-65-{\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c=459=static const struct gswip_hw_info gswip_xrx200 = {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c-475-\t},\ndrivers/net/dsa/lantiq/lantiq_gswip.c:476:\t.phylink_get_caps = gswip_xrx200_phylink_get_caps,\ndrivers/net/dsa/lantiq/lantiq_gswip.c-477-\t.pce_microcode = \u0026gswip_pce_microcode,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c=482=static const struct gswip_hw_info gswip_xrx300 = {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.c-496-\t},\ndrivers/net/dsa/lantiq/lantiq_gswip.c:497:\t.phylink_get_caps = gswip_xrx300_phylink_get_caps,\ndrivers/net/dsa/lantiq/lantiq_gswip.c-498-\t.pce_microcode = \u0026gswip_pce_microcode,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.h=255=struct gswip_hw_info {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.h-263-\tenum dsa_tag_protocol tag_protocol;\ndrivers/net/dsa/lantiq/lantiq_gswip.h:264:\tvoid (*phylink_get_caps)(struct dsa_switch *ds, int port,\ndrivers/net/dsa/lantiq/lantiq_gswip.h:265:\t\t\t\t struct phylink_config *config);\ndrivers/net/dsa/lantiq/lantiq_gswip.h:266:\tstruct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip.h-267-\t\t\t\t\t phy_interface_t interface);\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1266=static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1291-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1292:static void gswip_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1293:\t\t\t\t struct phylink_config *config)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1294-{\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1296-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1297:\tpriv-\u003ehw_info-\u003ephylink_get_caps(ds, port, config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1298-}\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1375=static void gswip_port_set_pause(struct gswip_priv *priv, int port,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1404-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1405:static void gswip_phylink_mac_config(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1406-\t\t\t\t unsigned int mode,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1407:\t\t\t\t const struct phylink_link_state *state)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1408-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1409:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1410-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1455-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1456:static void gswip_phylink_mac_link_down(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1457-\t\t\t\t\tunsigned int mode,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1459-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1460:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1461-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1469-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1470:static void gswip_phylink_mac_link_up(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1471-\t\t\t\t struct phy_device *phydev,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1476-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1477:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1478-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1559=static int gswip_set_mac_eee(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1567-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1568:static void gswip_phylink_mac_disable_tx_lpi(struct phylink_config *config)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1569-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1570:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1571-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1576-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1577:static int gswip_phylink_mac_enable_tx_lpi(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1578-\t\t\t\t\t u32 timer, bool tx_clock_stop)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1579-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1580:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1581-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1592=static bool gswip_support_eee(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1601-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1602:static struct phylink_pcs *gswip_phylink_mac_select_pcs(struct phylink_config *config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1603-\t\t\t\t\t\t\tphy_interface_t interface)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1604-{\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1605:\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1606-\tstruct gswip_priv *priv = dp-\u003eds-\u003epriv;\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1613-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1614:static const struct phylink_mac_ops gswip_phylink_mac_ops = {\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1615:\t.mac_config\t\t= gswip_phylink_mac_config,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1616:\t.mac_link_down\t\t= gswip_phylink_mac_link_down,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1617:\t.mac_link_up\t\t= gswip_phylink_mac_link_up,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1618:\t.mac_disable_tx_lpi\t= gswip_phylink_mac_disable_tx_lpi,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1619:\t.mac_enable_tx_lpi\t= gswip_phylink_mac_enable_tx_lpi,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1620:\t.mac_select_pcs\t\t= gswip_phylink_mac_select_pcs,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1621-};\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1623=static const struct dsa_switch_ops gswip_switch_ops = {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1643-\t.port_max_mtu\t\t= gswip_port_max_mtu,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1644:\t.phylink_get_caps\t= gswip_phylink_get_caps,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1645-\t.get_strings\t\t= gswip_get_strings,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1678=int gswip_probe_common(struct gswip_priv *priv, u32 version)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1690-\tpriv-\u003eds-\u003eops = \u0026gswip_switch_ops;\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1691:\tpriv-\u003eds-\u003ephylink_mac_ops = \u0026gswip_phylink_mac_ops;\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1692-\tpriv-\u003eds-\u003epriv = priv;\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c=28=struct gsw1xx_priv {\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-34-\tstruct\t\t\tregmap *shell;\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:35:\tstruct\t\t\tphylink_pcs pcs;\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-36-\tstruct delayed_work\tclear_raneg;\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c=124=static void gsw1xx_mdio_regmap_unlock(void *mdio_lock)\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-128-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:129:static unsigned int gsw1xx_pcs_inband_caps(struct phylink_pcs *pcs,\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-130-\t\t\t\t\t phy_interface_t interface)\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-134-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:135:static struct gsw1xx_priv *pcs_to_gsw1xx(struct phylink_pcs *pcs)\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-136-{\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-139-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:140:static int gsw1xx_pcs_enable(struct phylink_pcs *pcs)\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-141-{\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-148-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:149:static void gsw1xx_pcs_disable(struct phylink_pcs *pcs)\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-150-{\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-161-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:162:static void gsw1xx_pcs_get_state(struct phylink_pcs *pcs,\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-163-\t\t\t\t unsigned int neg_mode,\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:164:\t\t\t\t struct phylink_link_state *state)\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-165-{\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c=234=static int gsw1xx_pcs_reset(struct gsw1xx_priv *priv, phy_interface_t interface)\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-334-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:335:static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-336-\t\t\t phy_interface_t interface,\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-369-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:370:\tswitch (phylink_get_link_timer_ns(interface)) {\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-371-\tcase 10000:\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-393-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:394:\ttxaneg = phylink_mii_c22_pcs_encode_advertisement(interface, advertising);\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-395-\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c=453=static void gsw1xx_pcs_clear_raneg(struct work_struct *work)\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-461-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:462:static void gsw1xx_pcs_an_restart(struct phylink_pcs *pcs)\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-463-{\n--\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-477-\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c:478:static void gsw1xx_pcs_link_up(struct phylink_pcs *pcs,\ndrivers/net/dsa/lantiq/mxl-gsw1xx.c-479-\t\t\t unsigned int neg_mode,\n--\n\n"
} |
| 5/2 | 2026/08/27 21:47 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 18207 output: 29 thoughts: 69 Thoughts: Here's my summary, as though I'm thinking through this process: **Diving into PHY Device Connections** Alright, let's get down to brass tacks. I need to understand how these PHY devices are being connected and disconnected within this system. My immediate focus is going to be on the relationship between `phy_device.c` and `phylink.c`. I need a clear picture of how they interact. To that end, I'm going to start by identifying all the points of contact. I'm thinking, a thorough search for the calls to functions that handle PHY management will be in order. Let's see... I'll need to track down callers of crucial functions like `phy_attach_direct`, `phy_detach`, `phylink_bringup_phy`, `phylink_disconnect_phy`, `phy_connect`, and `phy_attach`. These are the core operations, the places where the rubber meets the road, so to speak, in attaching, detaching, connecting, and disconnecting the PHYs. Understanding their usage patterns will be key to understanding the full picture here. I suspect there will be some interesting connections. |
| 6/2 | 2026/08/27 21:48 | tool | grepper |
0mArgs:{
"Expression": "phy_attach_direct",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c=931=static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-982-\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c:983:\tret = phy_attach_direct(pdata-\u003enetdev, phydev, phydev-\u003edev_flags,\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-984-\t\t\t\tPHY_INTERFACE_MODE_SGMII);\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-985-\tif (ret) {\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c:986:\t\tnetdev_err(pdata-\u003enetdev, \"phy_attach_direct failed\\n\");\ndrivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c-987-\t\tphy_device_remove(phydev);\n--\ndrivers/net/ethernet/hisilicon/hns/hns_enet.c=1159=int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)\n--\ndrivers/net/ethernet/hisilicon/hns/hns_enet.c-1180-\t} else {\ndrivers/net/ethernet/hisilicon/hns/hns_enet.c:1181:\t\tret = phy_attach_direct(ndev, phy_dev, 0, h-\u003ephy_if);\ndrivers/net/ethernet/hisilicon/hns/hns_enet.c-1182-\t}\n--\ndrivers/net/phy/phy_device.c=1225=int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,\n--\ndrivers/net/phy/phy_device.c-1233-\ndrivers/net/phy/phy_device.c:1234:\trc = phy_attach_direct(dev, phydev, phydev-\u003edev_flags, interface);\ndrivers/net/phy/phy_device.c-1235-\tif (rc)\n--\ndrivers/net/phy/phy_device.c=1743=static void phy_restore_genphy_irq(struct phy_device *phydev)\n--\ndrivers/net/phy/phy_device.c-1749-/**\ndrivers/net/phy/phy_device.c:1750: * phy_attach_direct - attach a network device to a given PHY device pointer\ndrivers/net/phy/phy_device.c-1751- * @dev: network device to attach\n--\ndrivers/net/phy/phy_device.c-1763- */\ndrivers/net/phy/phy_device.c:1764:int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,\ndrivers/net/phy/phy_device.c-1765-\t\t u32 flags, phy_interface_t interface)\n--\ndrivers/net/phy/phy_device.c-1919-}\ndrivers/net/phy/phy_device.c:1920:EXPORT_SYMBOL(phy_attach_direct);\ndrivers/net/phy/phy_device.c-1921-\n--\ndrivers/net/phy/phy_device.c-1926- * This detaches the phy device from its network device and the phy\ndrivers/net/phy/phy_device.c:1927: * driver, and drops the reference count taken in phy_attach_direct().\ndrivers/net/phy/phy_device.c-1928- */\n--\ndrivers/net/phy/phylink.c=2221=static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,\n--\ndrivers/net/phy/phylink.c-2234-\ndrivers/net/phy/phylink.c:2235:\treturn phy_attach_direct(pl-\u003enetdev, phy, flags, interface);\ndrivers/net/phy/phylink.c-2236-}\n--\ndrivers/net/phy/phylink.c-2243- * Connect @phy to the phylink instance specified by @pl by calling\ndrivers/net/phy/phylink.c:2244: * phy_attach_direct(). Configure the @phy according to the MAC driver's\ndrivers/net/phy/phylink.c-2245- * capabilities, start the PHYLIB state machine and enable any interrupts\n--\ndrivers/net/phy/phylink.c=2305=int phylink_fwnode_phy_connect(struct phylink *pl,\n--\ndrivers/net/phy/phylink.c-2338-\ndrivers/net/phy/phylink.c:2339:\tret = phy_attach_direct(pl-\u003enetdev, phy_dev, flags,\ndrivers/net/phy/phylink.c-2340-\t\t\t\tpl-\u003elink_interface);\n"
} |
| 7/2 | 2026/08/27 21:48 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 19846 output: 28 thoughts: 150 Thoughts: **Investigating PHY Device Implementations** Okay, so I need to figure out which drivers in the kernel utilize `phylink` or `phy_device`, and more importantly, which of them might lend themselves to testing within a virtual environment. I'm thinking QEMU, maybe a dummy setup, netlink, or even syzkaller could be useful here. The key is finding testable targets. First, I should check for any existing virtual PHY devices. Are there any drivers that simulate a PHY? Or maybe USB network drivers, something like `cdc_ncm` or `usbnet`? What about a DSA loopback or mock MDIO? And, crucially, can I leverage QEMU's emulated hardware, like the `e1000` or `igb` ethernet controllers? Do those use `phylink` or `phylib` internally? That's a huge question I need to answer. To make progress, I'll start by systematically searching for usages of key functions. Let's see which drivers are calling `phy_connect`, `phy_attach`, `phylink_create`, `phylink_connect_phy`, and `mdiobus_register`. This should give me a good handle on which parts of the codebase are most relevant and point me towards potential candidates for virtualization and testing. |
| 8/2 | 2026/08/27 21:49 | tool | grepper |
0mArgs:{
"Expression": "phylink_create",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "drivers/net/ethernet/altera/altera_tse_main.c=1128=static int altera_tse_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/altera/altera_tse_main.c-1415-\ndrivers/net/ethernet/altera/altera_tse_main.c:1416:\tpriv-\u003ephylink = phylink_create(\u0026priv-\u003ephylink_config,\ndrivers/net/ethernet/altera/altera_tse_main.c-1417-\t\t\t\t of_fwnode_handle(priv-\u003edevice-\u003eof_node),\n--\ndrivers/net/ethernet/atheros/ag71xx.c=1074=static int ag71xx_phylink_setup(struct ag71xx *ag)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1108-\ndrivers/net/ethernet/atheros/ag71xx.c:1109:\tphylink = phylink_create(\u0026ag-\u003ephylink_config, ag-\u003epdev-\u003edev.fwnode,\ndrivers/net/ethernet/atheros/ag71xx.c-1110-\t\t\t\t ag-\u003ephy_if_mode, \u0026ag71xx_phylink_mac_ops);\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-1085-\ndrivers/net/ethernet/cadence/macb_main.c:1086:\tbp-\u003ephylink = phylink_create(\u0026bp-\u003ephylink_config, bp-\u003epdev-\u003edev.fwnode,\ndrivers/net/ethernet/cadence/macb_main.c-1087-\t\t\t\t bp-\u003ephy_interface, \u0026macb_phylink_ops);\n--\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c=201=static int dpaa_netdev_init(struct net_device *net_dev,\n--\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c-274-\tmac_dev-\u003eupdate_speed = dpaa_eth_cgr_set_speed;\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c:275:\tmac_dev-\u003ephylink = phylink_create(\u0026mac_dev-\u003ephylink_config,\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c-276-\t\t\t\t\t dev_fwnode(mac_dev-\u003edev),\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c=560=int dpaa2_mac_connect(struct dpaa2_mac *mac)\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c-624-\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c:625:\tphylink = phylink_create(\u0026mac-\u003ephylink_config,\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c-626-\t\t\t\t dpmac_node, mac-\u003eif_mode,\n--\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c=931=static int enetc4_link_init(struct enetc_ndev_priv *priv,\n--\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-949-\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c:950:\terr = enetc_phylink_create(priv, node, \u0026enetc_pl_mac_ops);\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-951-\tif (err) {\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-952-\t\tdev_err(dev, \"Failed to create phylink\\n\");\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c:953:\t\tgoto err_phylink_create;\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-954-\t}\n--\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-957-\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c:958:err_phylink_create:\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-959-\tenetc_mdiobus_destroy(pf);\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c=795=static int enetc_pf_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-877-\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c:878:\terr = enetc_phylink_create(priv, node, \u0026enetc_mac_phylink_ops);\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-879-\tif (err)\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c:880:\t\tgoto err_phylink_create;\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-881-\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-889-\tenetc_phylink_destroy(priv);\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c:890:err_phylink_create:\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-891-\tenetc_mdiobus_destroy(pf);\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c=419=EXPORT_SYMBOL_GPL(enetc_mdiobus_destroy);\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-420-\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c:421:int enetc_phylink_create(struct enetc_ndev_priv *priv, struct device_node *node,\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-422-\t\t\t const struct phylink_mac_ops *ops)\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-461-\tpf-\u003ephylink_config.mac_capabilities = mac_caps;\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c:462:\tphylink = phylink_create(\u0026pf-\u003ephylink_config, of_fwnode_handle(node),\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-463-\t\t\t\t pf-\u003eif_mode, ops);\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-472-}\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c:473:EXPORT_SYMBOL_GPL(enetc_phylink_create);\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.c-474-\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.h=12=void enetc_mdiobus_destroy(struct enetc_pf *pf);\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.h:13:int enetc_phylink_create(struct enetc_ndev_priv *priv, struct device_node *node,\ndrivers/net/ethernet/freescale/enetc/enetc_pf_common.h-14-\t\t\t const struct phylink_mac_ops *ops);\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c=853=static int fs_enet_probe(struct platform_device *ofdev)\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-932-\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c:933:\tphylink = phylink_create(\u0026fep-\u003ephylink_config, dev_fwnode(fep-\u003edev),\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-934-\t\t\t\t phy_mode, \u0026fs_enet_phylink_mac_ops);\n--\ndrivers/net/ethernet/freescale/ucc_geth.c=3419=static int ucc_geth_probe(struct platform_device* ofdev)\n--\ndrivers/net/ethernet/freescale/ucc_geth.c-3573-\ndrivers/net/ethernet/freescale/ucc_geth.c:3574:\tphylink = phylink_create(\u0026ugeth-\u003ephylink_config, dev_fwnode(\u0026dev-\u003edev),\ndrivers/net/ethernet/freescale/ucc_geth.c-3575-\t\t\t\t phy_interface, \u0026ugeth_mac_ops);\n--\ndrivers/net/ethernet/marvell/mvneta.c=5480=static int mvneta_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/marvell/mvneta.c-5598-\ndrivers/net/ethernet/marvell/mvneta.c:5599:\tphylink = phylink_create(\u0026pp-\u003ephylink_config, pdev-\u003edev.fwnode,\ndrivers/net/ethernet/marvell/mvneta.c-5600-\t\t\t\t phy_mode, \u0026mvneta_phylink_ops);\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c=6840=static int mvpp2_port_probe(struct platform_device *pdev,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-7147-\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:7148:\t\tphylink = phylink_create(\u0026port-\u003ephylink_config, port_fwnode,\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-7149-\t\t\t\t\t phy_mode, \u0026mvpp2_phylink_ops);\n--\ndrivers/net/ethernet/marvell/prestera/prestera_main.c=370=static int prestera_port_sfp_bind(struct prestera_port *port)\n--\ndrivers/net/ethernet/marvell/prestera/prestera_main.c-416-\ndrivers/net/ethernet/marvell/prestera/prestera_main.c:417:\t\tphy_link = phylink_create(\u0026port-\u003ephy_config, fwnode,\ndrivers/net/ethernet/marvell/prestera/prestera_main.c-418-\t\t\t\t\t PHY_INTERFACE_MODE_INTERNAL,\n--\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c=4824=static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)\n--\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c-4968-\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c:4969:\tphylink = phylink_create(\u0026mac-\u003ephylink_config,\ndrivers/net/ethernet/mediatek/mtk_eth_soc.c-4970-\t\t\t\t of_fwnode_handle(mac-\u003eof_node),\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c=746=struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c-834-\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c:835:\tif (fbnic_phylink_create(netdev)) {\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c-836-\t\tfree_netdev(netdev);\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.h=111=int fbnic_phylink_get_fecparam(struct net_device *netdev,\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.h-112-\t\t\t struct ethtool_fecparam *fecparam);\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.h:113:int fbnic_phylink_create(struct net_device *netdev);\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.h-114-void fbnic_phylink_destroy(struct net_device *netdev);\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c=177=static const struct phylink_mac_ops fbnic_phylink_mac_ops = {\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-186-/**\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c:187: * fbnic_phylink_create - Phylink device creation\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-188- * @netdev: Network Device struct to attach phylink device\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-196- **/\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c:197:int fbnic_phylink_create(struct net_device *netdev)\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-198-{\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-231-\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c:232:\tphylink = phylink_create(\u0026fbn-\u003ephylink_config, NULL,\ndrivers/net/ethernet/meta/fbnic/fbnic_phylink.c-233-\t\t\t\t fbnic_phylink_select_interface(fbn-\u003eaui),\n--\ndrivers/net/ethernet/microchip/lan743x_main.c=3152=static const struct phylink_mac_ops lan743x_phylink_mac_ops = {\n--\ndrivers/net/ethernet/microchip/lan743x_main.c-3159-\ndrivers/net/ethernet/microchip/lan743x_main.c:3160:static int lan743x_phylink_create(struct lan743x_adapter *adapter)\ndrivers/net/ethernet/microchip/lan743x_main.c-3161-{\n--\ndrivers/net/ethernet/microchip/lan743x_main.c-3211-\ndrivers/net/ethernet/microchip/lan743x_main.c:3212:\tpl = phylink_create(\u0026adapter-\u003ephylink_config, NULL,\ndrivers/net/ethernet/microchip/lan743x_main.c-3213-\t\t\t adapter-\u003ephy_interface, \u0026lan743x_phylink_mac_ops);\n--\ndrivers/net/ethernet/microchip/lan743x_main.c=3691=static int lan743x_pcidev_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/microchip/lan743x_main.c-3750-\ndrivers/net/ethernet/microchip/lan743x_main.c:3751:\tret = lan743x_phylink_create(adapter);\ndrivers/net/ethernet/microchip/lan743x_main.c-3752-\tif (ret \u003c 0) {\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c=791=static int lan966x_probe_port(struct lan966x *lan966x, u32 p,\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c-855-\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c:856:\tphylink = phylink_create(\u0026port-\u003ephylink_config,\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c-857-\t\t\t\t portnp,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_main.c=312=static int sparx5_create_port(struct sparx5 *sparx5,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_main.c-388-\ndrivers/net/ethernet/microchip/sparx5/sparx5_main.c:389:\tphylink = phylink_create(\u0026spx5_port-\u003ephylink_config,\ndrivers/net/ethernet/microchip/sparx5/sparx5_main.c-390-\t\t\t\t of_fwnode_handle(config-\u003enode),\n--\ndrivers/net/ethernet/mscc/ocelot_net.c=1774=static const struct phylink_mac_ops ocelot_phylink_ops = {\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-1779-\ndrivers/net/ethernet/mscc/ocelot_net.c:1780:static int ocelot_port_phylink_create(struct ocelot *ocelot, int port,\ndrivers/net/ethernet/mscc/ocelot_net.c-1781-\t\t\t\t struct device_node *portnp)\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-1820-\ndrivers/net/ethernet/mscc/ocelot_net.c:1821:\tphylink = phylink_create(\u0026priv-\u003ephylink_config,\ndrivers/net/ethernet/mscc/ocelot_net.c-1822-\t\t\t\t of_fwnode_handle(portnp),\n--\ndrivers/net/ethernet/mscc/ocelot_net.c=1843=int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-1879-\ndrivers/net/ethernet/mscc/ocelot_net.c:1880:\terr = ocelot_port_phylink_create(ocelot, port, portnp);\ndrivers/net/ethernet/mscc/ocelot_net.c-1881-\tif (err)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=1374=static int stmmac_phylink_setup(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-1465-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1466:\tphylink = phylink_create(config, dev_fwnode(priv-\u003edevice),\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-1467-\t\t\t\t priv-\u003eplat-\u003ephy_interface,\n--\ndrivers/net/ethernet/tehuti/tn40_phy.c=45=int tn40_phy_register(struct tn40_priv *priv)\n--\ndrivers/net/ethernet/tehuti/tn40_phy.c-62-\ndrivers/net/ethernet/tehuti/tn40_phy.c:63:\tphylink = phylink_create(config, NULL, PHY_INTERFACE_MODE_XAUI,\ndrivers/net/ethernet/tehuti/tn40_phy.c-64-\t\t\t\t \u0026tn40_mac_ops);\n--\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c=2759=am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)\n--\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c-2843-\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c:2844:\tphylink = phylink_create(\u0026port-\u003eslave.phylink_config,\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c-2845-\t\t\t\t of_fwnode_handle(port-\u003eslave.port_np),\n--\ndrivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c=130=static int ngbe_phylink_init(struct wx *wx)\n--\ndrivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c-149-\ndrivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c:150:\tphylink = phylink_create(config, NULL, phy_mode, \u0026ngbe_mac_ops);\ndrivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c-151-\tif (IS_ERR(phylink))\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_aml.c=482=int txgbe_phylink_init_aml(struct txgbe *txgbe)\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_aml.c-512-\ndrivers/net/ethernet/wangxun/txgbe/txgbe_aml.c:513:\tphylink = phylink_create(config, NULL, phy_mode, \u0026txgbe_mac_ops_aml);\ndrivers/net/ethernet/wangxun/txgbe/txgbe_aml.c-514-\tif (IS_ERR(phylink))\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_phy.c=268=static int txgbe_phylink_init(struct txgbe *txgbe)\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_phy.c-292-\ndrivers/net/ethernet/wangxun/txgbe/txgbe_phy.c:293:\tphylink = phylink_create(config, fwnode, phy_mode, \u0026txgbe_mac_ops);\ndrivers/net/ethernet/wangxun/txgbe/txgbe_phy.c-294-\tif (IS_ERR(phylink))\n--\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c=2795=static int axienet_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c-3120-\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c:3121:\tlp-\u003ephylink = phylink_create(\u0026lp-\u003ephylink_config, pdev-\u003edev.fwnode,\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c-3122-\t\t\t\t lp-\u003ephy_mode,\n--\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c-3125-\t\tret = PTR_ERR(lp-\u003ephylink);\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c:3126:\t\tdev_err(\u0026pdev-\u003edev, \"phylink_create error (%i)\\n\", ret);\ndrivers/net/ethernet/xilinx/xilinx_axienet_main.c-3127-\t\tgoto cleanup_mdio;\n--\ndrivers/net/phy/phylink.c=515=static int phylink_validate_mac_and_pcs(struct phylink *pl,\n--\ndrivers/net/phy/phylink.c-530-\tif (pcs) {\ndrivers/net/phy/phylink.c:531:\t\t/* The PCS, if present, must be setup before phylink_create()\ndrivers/net/phy/phylink.c-532-\t\t * has been called. If the ops is not initialised, print an\n--\ndrivers/net/phy/phylink.c=1038=static enum inband_type phylink_get_inband_type(phy_interface_t interface)\n--\ndrivers/net/phy/phylink.c-1070- * phylink_pcs_neg_mode() - helper to determine PCS inband mode\ndrivers/net/phy/phylink.c:1071: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-1072- * @pcs: a pointer to \u0026struct phylink_pcs\n--\ndrivers/net/phy/phylink.c=1768=static int phylink_register_sfp(struct phylink *pl,\n--\ndrivers/net/phy/phylink.c-1792- * phylink_set_fixed_link() - set the fixed link\ndrivers/net/phy/phylink.c:1793: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-1794- * @state: a pointer to a struct phylink_link_state.\n--\ndrivers/net/phy/phylink.c=1830=EXPORT_SYMBOL_GPL(phylink_set_fixed_link);\n--\ndrivers/net/phy/phylink.c-1832-/**\ndrivers/net/phy/phylink.c:1833: * phylink_create() - create a phylink instance\ndrivers/net/phy/phylink.c-1834- * @config: a pointer to the target \u0026struct phylink_config\n--\ndrivers/net/phy/phylink.c-1847- */\ndrivers/net/phy/phylink.c:1848:struct phylink *phylink_create(struct phylink_config *config,\ndrivers/net/phy/phylink.c-1849-\t\t\t const struct fwnode_handle *fwnode,\n--\ndrivers/net/phy/phylink.c-1935-}\ndrivers/net/phy/phylink.c:1936:EXPORT_SYMBOL_GPL(phylink_create);\ndrivers/net/phy/phylink.c-1937-\n--\ndrivers/net/phy/phylink.c-1939- * phylink_destroy() - cleanup and destroy the phylink instance\ndrivers/net/phy/phylink.c:1940: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-1941- *\n--\ndrivers/net/phy/phylink.c=1956=EXPORT_SYMBOL_GPL(phylink_destroy);\n--\ndrivers/net/phy/phylink.c-1959- * phylink_expects_phy() - Determine if phylink expects a phy to be attached\ndrivers/net/phy/phylink.c:1960: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-1961- *\n--\ndrivers/net/phy/phylink.c=2221=static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,\n--\ndrivers/net/phy/phylink.c-2239- * phylink_connect_phy() - connect a PHY to the phylink instance\ndrivers/net/phy/phylink.c:2240: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2241- * @phy: a pointer to a \u0026struct phy_device.\n--\ndrivers/net/phy/phylink.c=2273=EXPORT_SYMBOL_GPL(phylink_connect_phy);\n--\ndrivers/net/phy/phylink.c-2276- * phylink_of_phy_connect() - connect the PHY specified in the DT mode.\ndrivers/net/phy/phylink.c:2277: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2278- * @dn: a pointer to a \u0026struct device_node.\n--\ndrivers/net/phy/phylink.c=2292=EXPORT_SYMBOL_GPL(phylink_of_phy_connect);\n--\ndrivers/net/phy/phylink.c-2295- * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.\ndrivers/net/phy/phylink.c:2296: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2297- * @fwnode: a pointer to a \u0026struct fwnode_handle.\n--\ndrivers/net/phy/phylink.c=2351=EXPORT_SYMBOL_GPL(phylink_fwnode_phy_connect);\n--\ndrivers/net/phy/phylink.c-2355- * instance.\ndrivers/net/phy/phylink.c:2356: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2357- *\n--\ndrivers/net/phy/phylink.c=2379=static void phylink_link_changed(struct phylink *pl, bool up, const char *what)\n--\ndrivers/net/phy/phylink.c-2388- * phylink_mac_change() - notify phylink of a change in MAC state\ndrivers/net/phy/phylink.c:2389: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2390- * @up: indicates whether the link is currently up.\n--\ndrivers/net/phy/phylink.c=2421=static irqreturn_t phylink_link_handler(int irq, void *data)\n--\ndrivers/net/phy/phylink.c-2431- * phylink_start() - start a phylink instance\ndrivers/net/phy/phylink.c:2432: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2433- *\n--\ndrivers/net/phy/phylink.c=2494=EXPORT_SYMBOL_GPL(phylink_start);\n--\ndrivers/net/phy/phylink.c-2497- * phylink_stop() - stop a phylink instance\ndrivers/net/phy/phylink.c:2498: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2499- *\n--\ndrivers/net/phy/phylink.c=2528=EXPORT_SYMBOL_GPL(phylink_stop);\n--\ndrivers/net/phy/phylink.c-2531- * phylink_rx_clk_stop_block() - block PHY ability to stop receive clock in LPI\ndrivers/net/phy/phylink.c:2532: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2533- *\n--\ndrivers/net/phy/phylink.c=2557=EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_block);\n--\ndrivers/net/phy/phylink.c-2560- * phylink_rx_clk_stop_unblock() - unblock PHY ability to stop receive clock\ndrivers/net/phy/phylink.c:2561: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2562- *\n--\ndrivers/net/phy/phylink.c=2599=static bool phylink_phy_pm_speed_ctrl(struct phylink *pl)\n--\ndrivers/net/phy/phylink.c-2606- * phylink_suspend() - handle a network device suspend event\ndrivers/net/phy/phylink.c:2607: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2608- * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan\n--\ndrivers/net/phy/phylink.c=2658=EXPORT_SYMBOL_GPL(phylink_suspend);\n--\ndrivers/net/phy/phylink.c-2661- * phylink_prepare_resume() - prepare to resume a network device\ndrivers/net/phy/phylink.c:2662: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2663- *\n--\ndrivers/net/phy/phylink.c=2683=EXPORT_SYMBOL_GPL(phylink_prepare_resume);\n--\ndrivers/net/phy/phylink.c-2686- * phylink_resume() - handle a network device resume event\ndrivers/net/phy/phylink.c:2687: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2688- *\n--\ndrivers/net/phy/phylink.c=2726=EXPORT_SYMBOL_GPL(phylink_resume);\n--\ndrivers/net/phy/phylink.c-2729- * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY\ndrivers/net/phy/phylink.c:2730: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2731- * @wol: a pointer to \u0026struct ethtool_wolinfo to hold the read parameters\n--\ndrivers/net/phy/phylink.c=2763=EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol);\n--\ndrivers/net/phy/phylink.c-2766- * phylink_ethtool_set_wol() - set wake on lan parameters\ndrivers/net/phy/phylink.c:2767: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2768- * @wol: a pointer to \u0026struct ethtool_wolinfo for the desired parameters\n--\ndrivers/net/phy/phylink.c=2895=static void phylink_get_ksettings(const struct phylink_link_state *state,\n--\ndrivers/net/phy/phylink.c-2910- * phylink_ethtool_ksettings_get() - get the current link settings\ndrivers/net/phy/phylink.c:2911: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2912- * @kset: a pointer to a \u0026struct ethtool_link_ksettings to hold link settings\n--\ndrivers/net/phy/phylink.c=2963=static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl,\n--\ndrivers/net/phy/phylink.c-2984- * phylink_ethtool_ksettings_set() - set the link settings\ndrivers/net/phy/phylink.c:2985: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-2986- * @kset: a pointer to a \u0026struct ethtool_link_ksettings for the desired modes\n--\ndrivers/net/phy/phylink.c=3151=EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_set);\n--\ndrivers/net/phy/phylink.c-3154- * phylink_ethtool_nway_reset() - restart negotiation\ndrivers/net/phy/phylink.c:3155: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3156- *\n--\ndrivers/net/phy/phylink.c=3176=EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset);\n--\ndrivers/net/phy/phylink.c-3179- * phylink_ethtool_get_pauseparam() - get the current pause parameters\ndrivers/net/phy/phylink.c:3180: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3181- * @pause: a pointer to a \u0026struct ethtool_pauseparam\n--\ndrivers/net/phy/phylink.c=3192=EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam);\n--\ndrivers/net/phy/phylink.c-3195- * phylink_ethtool_set_pauseparam() - set the current pause parameters\ndrivers/net/phy/phylink.c:3196: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3197- * @pause: a pointer to a \u0026struct ethtool_pauseparam\n--\ndrivers/net/phy/phylink.c=3278=EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);\n--\ndrivers/net/phy/phylink.c-3282- * counter\ndrivers/net/phy/phylink.c:3283: * @pl: a pointer to a \u0026struct phylink returned from phylink_create().\ndrivers/net/phy/phylink.c-3284- *\n--\ndrivers/net/phy/phylink.c=3301=EXPORT_SYMBOL_GPL(phylink_get_eee_err);\n--\ndrivers/net/phy/phylink.c-3304- * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters\ndrivers/net/phy/phylink.c:3305: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3306- * @eee: a pointer to a \u0026struct ethtool_keee for the read parameters\n--\ndrivers/net/phy/phylink.c=3327=EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee);\n--\ndrivers/net/phy/phylink.c-3330- * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters\ndrivers/net/phy/phylink.c:3331: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3332- * @eee: a pointer to a \u0026struct ethtool_keee for the desired parameters\n--\ndrivers/net/phy/phylink.c=3501=static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,\n--\ndrivers/net/phy/phylink.c-3519- * phylink_mii_ioctl() - generic mii ioctl interface\ndrivers/net/phy/phylink.c:3520: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3521- * @ifr: a pointer to a \u0026struct ifreq for socket ioctls\n--\ndrivers/net/phy/phylink.c=3594=EXPORT_SYMBOL_GPL(phylink_mii_ioctl);\n--\ndrivers/net/phy/phylink.c-3598- * link partners\ndrivers/net/phy/phylink.c:3599: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3600- * @sync: perform action synchronously\n--\ndrivers/net/phy/phylink.c=3619=EXPORT_SYMBOL_GPL(phylink_speed_down);\n--\ndrivers/net/phy/phylink.c-3623- * phylink_speed_down()\ndrivers/net/phy/phylink.c:3624: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-3625- *\n--\ndrivers/net/phy/phylink.c=4378=EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state);\n--\ndrivers/net/phy/phylink.c-4382- *\t\t\t\t which loses state\ndrivers/net/phy/phylink.c:4383: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-4384- *\n--\ndrivers/net/phy/phylink.c=4399=EXPORT_SYMBOL_GPL(phylink_replay_link_begin);\n--\ndrivers/net/phy/phylink.c-4403- *\t\t\t which lost state\ndrivers/net/phy/phylink.c:4404: * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\ndrivers/net/phy/phylink.c-4405- *\n--\ndrivers/net/usb/asix_devices.c=799=static int ax88772_phylink_setup(struct usbnet *dev)\n--\ndrivers/net/usb/asix_devices.c-819-\ndrivers/net/usb/asix_devices.c:820:\tphylink = phylink_create(\u0026priv-\u003ephylink_config, dev-\u003enet-\u003edev.fwnode,\ndrivers/net/usb/asix_devices.c-821-\t\t\t\t phy_if_mode, \u0026ax88772_phylink_mac_ops);\n--\ndrivers/net/usb/lan78xx.c=2799=static int lan78xx_phylink_setup(struct lan78xx_net *dev)\n--\ndrivers/net/usb/lan78xx.c-2838-\ndrivers/net/usb/lan78xx.c:2839:\tphylink = phylink_create(pc, dev-\u003enet-\u003edev.fwnode,\ndrivers/net/usb/lan78xx.c-2840-\t\t\t\t dev-\u003einterface, \u0026lan78xx_phylink_mac_ops);\n"
} |
| 9/2 | 2026/08/27 21:49 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 31274 output: 40 thoughts: 166 Thoughts: **My Initial Analysis of the Network Driver Landscape** Okay, so I'm seeing a pattern here. Looking at these network driver implementations – specifically `drivers/net/usb/asix_devices.c`, `lan78xx.c`, and the whole `drivers/net/dsa/` directory, including that `dsa_loop.c` example – it's clear they're leveraging phylink. That's a solid architectural choice, and it's something I've been keeping an eye on. And, of course, the mention of USB devices using gadget emulation through syzkaller opens up some fascinating testing possibilities via raw-gadget and vusb. The next step is to drill down into the patch changes. I need to understand *why* they adopted phylink and what specific problem they were addressing, or what new functionality has been added. That requires a careful examination of the diffs. Now, to get a deeper handle on the phylink internals themselves, I need to brush up on my knowledge of the phy/phylink architecture. I'm going to focus my attention on `drivers/net/phy/phy_device.c` from around lines 1730 to 1980 and `drivers/net/phy/phylink.c` from lines 2080 to 2370. This should give me a solid grasp of the core concepts, data structures, and the communication flow between the PHY and the network driver. This should allow me to understand how those device drivers are using it. |
| 10/2 | 2026/08/27 21:50 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phy_device.c",
"FirstLine": 1730,
"LineCount": 70
}Results: {
"Contents": "1730:\t}\n1731:\t\n1732:\tstatic bool phy_drv_supports_irq(const struct phy_driver *phydrv)\n1733:\t{\n1734:\t\treturn phydrv-\u003econfig_intr \u0026\u0026 phydrv-\u003ehandle_interrupt;\n1735:\t}\n1736:\t\n1737:\t/* Give back the interrupt phy_probe() parked when a driver with no interrupt\n1738:\t * callbacks bound. mdiobus_alloc() defaults bus-\u003eirq[] to PHY_POLL and the\n1739:\t * bind cycle does not touch the table, so whatever the bus recorded there\n1740:\t * still stands. Only the parking is undone: any other value the PHY carries\n1741:\t * was put there by someone else.\n1742:\t */\n1743:\tstatic void phy_restore_genphy_irq(struct phy_device *phydev)\n1744:\t{\n1745:\t\tif (phydev-\u003eirq == PHY_POLL)\n1746:\t\t\tphydev-\u003eirq = phydev-\u003emdio.bus-\u003eirq[phydev-\u003emdio.addr];\n1747:\t}\n1748:\t\n1749:\t/**\n1750:\t * phy_attach_direct - attach a network device to a given PHY device pointer\n1751:\t * @dev: network device to attach\n1752:\t * @phydev: Pointer to phy_device to attach\n1753:\t * @flags: PHY device's dev_flags\n1754:\t * @interface: PHY device's interface\n1755:\t *\n1756:\t * Description: Called by drivers to attach to a particular PHY\n1757:\t * device. The phy_device is found, and properly hooked up\n1758:\t * to the phy_driver. If no driver is attached, then a\n1759:\t * generic driver is used. The phy_device is given a ptr to\n1760:\t * the attaching device, and given a callback for link status\n1761:\t * change. The phy_device is returned to the attaching driver.\n1762:\t * This function takes a reference on the phy device.\n1763:\t */\n1764:\tint phy_attach_direct(struct net_device *dev, struct phy_device *phydev,\n1765:\t\t\t u32 flags, phy_interface_t interface)\n1766:\t{\n1767:\t\tstruct mii_bus *bus = phydev-\u003emdio.bus;\n1768:\t\tstruct device *d = \u0026phydev-\u003emdio.dev;\n1769:\t\tstruct module *ndev_owner = NULL;\n1770:\t\tint err;\n1771:\t\n1772:\t\t/* For Ethernet device drivers that register their own MDIO bus, we\n1773:\t\t * will have bus-\u003eowner match ndev_mod, so we do not want to increment\n1774:\t\t * our own module-\u003erefcnt here, otherwise we would not be able to\n1775:\t\t * unload later on.\n1776:\t\t */\n1777:\t\tif (dev)\n1778:\t\t\tndev_owner = dev-\u003edev.parent-\u003edriver-\u003eowner;\n1779:\t\tif (ndev_owner != bus-\u003eowner \u0026\u0026 !try_module_get(bus-\u003eowner)) {\n1780:\t\t\tphydev_err(phydev, \"failed to get the bus module\\n\");\n1781:\t\t\treturn -EIO;\n1782:\t\t}\n1783:\t\n1784:\t\tget_device(d);\n1785:\t\n1786:\t\t/* Assume that if there is no driver, that it doesn't\n1787:\t\t * exist, and we should use the genphy driver.\n1788:\t\t */\n1789:\t\tif (!d-\u003edriver) {\n1790:\t\t\tif (phydev-\u003eis_c45)\n1791:\t\t\t\td-\u003edriver = \u0026genphy_c45_driver.mdiodrv.driver;\n1792:\t\t\telse\n1793:\t\t\t\td-\u003edriver = \u0026genphy_driver.mdiodrv.driver;\n1794:\t\n1795:\t\t\tphydev-\u003eis_genphy_driven = 1;\n1796:\t\t}\n1797:\t\n1798:\t\tif (!try_module_get(d-\u003edriver-\u003eowner)) {\n1799:\t\t\tphydev_err(phydev, \"failed to get the device driver module\\n\");\n"
} |
| 11/2 | 2026/08/27 21:50 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 32990 output: 41 thoughts: 20 Thoughts: Okay, here's my take on those thoughts, framed as an expert diving into the code: **Deeper Dive into PHY Driver Interactions** Alright, the diff is interesting, but I need a more complete picture. I'm going to start digging into `phy_device.c` and `phylink.c`. Specifically, I'm going to focus on the code around that change. I know these files intimately – they're the heart of how we manage the physical layer interface and link negotiation. I need to understand exactly how this modification impacts the interactions between these two core components. What are the dependencies? What side effects might this have? A cursory glance at the diff isn't enough; I need to see the context, the function calls, the data structures being manipulated. This deeper dive will give me the insight I require to validate the change and understand any potential implications. I want to see the *why* as well as the *what*. Time to get my hands dirty and understand this fully. |
| 12/2 | 2026/08/27 21:50 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phy_device.c",
"FirstLine": 1890,
"LineCount": 100
}Results: {
"Contents": "1890:\t\n1891:\t\tphy_resume(phydev);\n1892:\t\n1893:\t\t/**\n1894:\t\t * If the external phy used by current mac interface is managed by\n1895:\t\t * another mac interface, so we should create a device link between\n1896:\t\t * phy dev and mac dev.\n1897:\t\t */\n1898:\t\tif (dev \u0026\u0026 phydev-\u003emdio.bus-\u003eparent \u0026\u0026 dev-\u003edev.parent != phydev-\u003emdio.bus-\u003eparent)\n1899:\t\t\tphydev-\u003edevlink = device_link_add(dev-\u003edev.parent, \u0026phydev-\u003emdio.dev,\n1900:\t\t\t\t\t\t\t DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);\n1901:\t\n1902:\t\treturn err;\n1903:\t\n1904:\terror:\n1905:\t\t/* phy_detach() does all of the cleanup below */\n1906:\t\tphy_detach(phydev);\n1907:\t\treturn err;\n1908:\t\n1909:\terror_module_put:\n1910:\t\tmodule_put(d-\u003edriver-\u003eowner);\n1911:\t\tphy_restore_genphy_irq(phydev);\n1912:\t\tphydev-\u003eis_genphy_driven = 0;\n1913:\t\td-\u003edriver = NULL;\n1914:\terror_put_device:\n1915:\t\tput_device(d);\n1916:\t\tif (ndev_owner != bus-\u003eowner)\n1917:\t\t\tmodule_put(bus-\u003eowner);\n1918:\t\treturn err;\n1919:\t}\n1920:\tEXPORT_SYMBOL(phy_attach_direct);\n1921:\t\n1922:\t/**\n1923:\t * phy_detach - detach a PHY device from its network device\n1924:\t * @phydev: target phy_device struct\n1925:\t *\n1926:\t * This detaches the phy device from its network device and the phy\n1927:\t * driver, and drops the reference count taken in phy_attach_direct().\n1928:\t */\n1929:\tvoid phy_detach(struct phy_device *phydev)\n1930:\t{\n1931:\t\tstruct net_device *dev = phydev-\u003eattached_dev;\n1932:\t\tstruct module *ndev_owner = NULL;\n1933:\t\tstruct mii_bus *bus;\n1934:\t\n1935:\t\tif (phydev-\u003edevlink) {\n1936:\t\t\tdevice_link_del(phydev-\u003edevlink);\n1937:\t\t\tphydev-\u003edevlink = NULL;\n1938:\t\t}\n1939:\t\n1940:\t\tif (phydev-\u003esysfs_links) {\n1941:\t\t\tif (dev)\n1942:\t\t\t\tsysfs_remove_link(\u0026dev-\u003edev.kobj, \"phydev\");\n1943:\t\t\tsysfs_remove_link(\u0026phydev-\u003emdio.dev.kobj, \"attached_dev\");\n1944:\t\t}\n1945:\t\n1946:\t\tif (!phydev-\u003eattached_dev)\n1947:\t\t\tsysfs_remove_file(\u0026phydev-\u003emdio.dev.kobj,\n1948:\t\t\t\t\t \u0026dev_attr_phy_standalone.attr);\n1949:\t\n1950:\t\tphy_suspend(phydev);\n1951:\t\tif (dev) {\n1952:\t\t\tstruct hwtstamp_provider *hwprov;\n1953:\t\n1954:\t\t\t/* hwprov may technically be protected by ops lock but\n1955:\t\t\t * not for devices with a phydev, see phy_link_topo_add_phy()\n1956:\t\t\t */\n1957:\t\t\thwprov = rtnl_dereference(dev-\u003ehwprov);\n1958:\t\t\t/* Disable timestamp if it is the one selected */\n1959:\t\t\tif (hwprov \u0026\u0026 hwprov-\u003ephydev == phydev) {\n1960:\t\t\t\trcu_assign_pointer(dev-\u003ehwprov, NULL);\n1961:\t\t\t\tkfree_rcu(hwprov, rcu_head);\n1962:\t\t\t}\n1963:\t\n1964:\t\t\tphydev-\u003eattached_dev-\u003ephydev = NULL;\n1965:\t\t\tphydev-\u003eattached_dev = NULL;\n1966:\t\t\tphy_link_topo_del_phy(dev, phydev);\n1967:\t\t}\n1968:\t\n1969:\t\tphydev-\u003ephy_link_change = NULL;\n1970:\t\tphydev-\u003ephylink = NULL;\n1971:\t\n1972:\t\tif (phydev-\u003emdio.dev.driver)\n1973:\t\t\tmodule_put(phydev-\u003emdio.dev.driver-\u003eowner);\n1974:\t\n1975:\t\t/* If the device had no specific driver before (i.e. - it\n1976:\t\t * was using the generic driver), we unbind the device\n1977:\t\t * from the generic driver so that there's a chance a\n1978:\t\t * real driver could be loaded\n1979:\t\t */\n1980:\t\tif (phydev-\u003eis_genphy_driven) {\n1981:\t\t\tphy_restore_genphy_irq(phydev);\n1982:\t\t\tdevice_release_driver(\u0026phydev-\u003emdio.dev);\n1983:\t\t\tphydev-\u003eis_genphy_driven = 0;\n1984:\t\t}\n1985:\t\n1986:\t\t/* Assert the reset signal */\n1987:\t\tphy_device_reset(phydev, 1);\n1988:\t\n1989:\t\t/*\n"
} |
| 13/2 | 2026/08/27 21:50 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 34765 output: 39 thoughts: 30 Thoughts: Here's my summary, as if I were thinking these thoughts: **Diving Deep into PHYLINK** Okay, time to get my hands dirty. I need to take a look at the `drivers/net/phy/phylink.c` file. Specifically, I'm zeroing in on the section around lines 2080 to 2370. This area is likely where a significant piece of the PHYLINK functionality resides, probably related to a critical part of the link negotiation or management logic. Given the size of that code block, it's probably doing some heavy lifting in how the PHY interacts with the network stack. I anticipate there will be a rich amount of detail there concerning the operational control of the PHY. It's time to get down to business and see what's what. |
| 14/2 | 2026/08/27 21:51 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phylink.c",
"FirstLine": 2190,
"LineCount": 80
}Results: {
"Contents": "2190:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, pl-\u003esupported,\n2191:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, phy-\u003eadvertising);\n2192:\t\n2193:\t\tif (pl-\u003econfig-\u003emac_managed_pm)\n2194:\t\t\tphy-\u003emac_managed_pm = true;\n2195:\t\n2196:\t\t/* Allow the MAC to stop its clock if the PHY has the capability */\n2197:\t\tpl-\u003emac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) \u003e 0;\n2198:\t\n2199:\t\tif (pl-\u003emac_supports_eee_ops) {\n2200:\t\t\t/* Explicitly configure whether the PHY is allowed to stop it's\n2201:\t\t\t * receive clock.\n2202:\t\t\t */\n2203:\t\t\tret = phy_eee_rx_clock_stop(phy,\n2204:\t\t\t\t\t\t pl-\u003econfig-\u003eeee_rx_clk_stop_enable);\n2205:\t\t\tif (ret == -EOPNOTSUPP)\n2206:\t\t\t\tret = 0;\n2207:\t\t}\n2208:\t\n2209:\t\tif (ret == 0 \u0026\u0026 phy_interrupt_is_valid(phy))\n2210:\t\t\tphy_request_interrupt(phy);\n2211:\t\n2212:\t\tif (ret) {\n2213:\t\t\tmutex_lock(\u0026pl-\u003ephydev_mutex);\n2214:\t\t\tphylink_clear_phydev(pl, phy);\n2215:\t\t\tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n2216:\t\t}\n2217:\t\n2218:\t\treturn ret;\n2219:\t}\n2220:\t\n2221:\tstatic int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,\n2222:\t\t\t\t phy_interface_t interface)\n2223:\t{\n2224:\t\tu32 flags = 0;\n2225:\t\n2226:\t\tif (WARN_ON(pl-\u003ecfg_link_an_mode == MLO_AN_FIXED))\n2227:\t\t\treturn -EINVAL;\n2228:\t\n2229:\t\tif (pl-\u003ephydev)\n2230:\t\t\treturn -EBUSY;\n2231:\t\n2232:\t\tif (pl-\u003econfig-\u003emac_requires_rxc)\n2233:\t\t\tflags |= PHY_F_RXC_ALWAYS_ON;\n2234:\t\n2235:\t\treturn phy_attach_direct(pl-\u003enetdev, phy, flags, interface);\n2236:\t}\n2237:\t\n2238:\t/**\n2239:\t * phylink_connect_phy() - connect a PHY to the phylink instance\n2240:\t * @pl: a pointer to a \u0026struct phylink returned from phylink_create()\n2241:\t * @phy: a pointer to a \u0026struct phy_device.\n2242:\t *\n2243:\t * Connect @phy to the phylink instance specified by @pl by calling\n2244:\t * phy_attach_direct(). Configure the @phy according to the MAC driver's\n2245:\t * capabilities, start the PHYLIB state machine and enable any interrupts\n2246:\t * that the PHY supports.\n2247:\t *\n2248:\t * This updates the phylink's ethtool supported and advertising link mode\n2249:\t * masks.\n2250:\t *\n2251:\t * Returns 0 on success or a negative errno.\n2252:\t */\n2253:\tint phylink_connect_phy(struct phylink *pl, struct phy_device *phy)\n2254:\t{\n2255:\t\tint ret;\n2256:\t\n2257:\t\t/* Use PHY device/driver interface */\n2258:\t\tif (pl-\u003elink_interface == PHY_INTERFACE_MODE_NA) {\n2259:\t\t\tpl-\u003elink_interface = phy-\u003einterface;\n2260:\t\t\tpl-\u003elink_config.interface = pl-\u003elink_interface;\n2261:\t\t}\n2262:\t\n2263:\t\tret = phylink_attach_phy(pl, phy, pl-\u003elink_interface);\n2264:\t\tif (ret \u003c 0)\n2265:\t\t\treturn ret;\n2266:\t\n2267:\t\tret = phylink_bringup_phy(pl, phy, pl-\u003elink_config.interface);\n2268:\t\tif (ret)\n2269:\t\t\tphy_detach(phy);\n"
} |
| 15/2 | 2026/08/27 21:51 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 36229 output: 39 thoughts: 140 Thoughts: **Analyzing the PHY Link Connection Process** Okay, let's break this down. I see we're looking at `phylink_connect_phy`. The core of it seems to be in `phylink_attach_phy` which sets things up, then `phylink_bringup_phy` which actually gets the PHY operational. If `phylink_attach_phy` fails, we just return the error, simple enough. But if `phylink_bringup_phy` fails, we detach the PHY. Makes sense, keep it clean. My mind is now zeroing in on `phylink_bringup_phy`. I recall some potential issues here, which is why I'm focusing on it. I seem to recall that before a certain patch, the `pl->phydev` assignment occurs somewhere in that function, around the 2110 mark, or in that neighborhood. I'll need to double-check that region, approximately lines 2100 to 2190 in the code, to ensure that the variable is assigned when required. I'll be looking at that section very carefully. The timing of the assignment could be critical for the overall process. |
| 16/2 | 2026/08/27 21:51 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phylink.c",
"FirstLine": 2090,
"LineCount": 50
}Results: {
"Contents": "2090:\t\tmutex_lock(\u0026pl-\u003estate_mutex);\n2091:\t\tpl-\u003ephydev = NULL;\n2092:\t\tpl-\u003ephy_enable_tx_lpi = false;\n2093:\t\tpl-\u003emac_tx_clk_stop = false;\n2094:\t\tmutex_unlock(\u0026pl-\u003estate_mutex);\n2095:\t\tmutex_unlock(\u0026phy-\u003elock);\n2096:\t}\n2097:\t\n2098:\tstatic int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,\n2099:\t\t\t\t phy_interface_t interface)\n2100:\t{\n2101:\t\tstruct phylink_link_state config;\n2102:\t\t__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);\n2103:\t\tchar *irq_str;\n2104:\t\tint ret;\n2105:\t\n2106:\t\t/*\n2107:\t\t * This is the new way of dealing with flow control for PHYs,\n2108:\t\t * as described by Timur Tabi in commit 529ed1275263 (\"net: phy:\n2109:\t\t * phy drivers should not set SUPPORTED_[Asym_]Pause\"). MAC drivers\n2110:\t\t * set their support using the MAC_SYM_PAUSE and MAC_ASYM_PAUSE\n2111:\t\t * capabilities and must NOT change the phy's pause settings directly.\n2112:\t\t */\n2113:\t\tphy_support_asym_pause(phy);\n2114:\t\n2115:\t\tmemset(\u0026config, 0, sizeof(config));\n2116:\t\tlinkmode_copy(supported, phy-\u003esupported);\n2117:\t\tlinkmode_copy(config.advertising, phy-\u003eadvertising);\n2118:\t\tconfig.interface = interface;\n2119:\t\n2120:\t\tret = phylink_validate_phy(pl, phy, supported, \u0026config);\n2121:\t\tif (ret) {\n2122:\t\t\tphylink_warn(pl, \"validation of %s with support %*pb and advertisement %*pb failed: %pe\\n\",\n2123:\t\t\t\t phy_modes(config.interface),\n2124:\t\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, phy-\u003esupported,\n2125:\t\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising,\n2126:\t\t\t\t ERR_PTR(ret));\n2127:\t\t\treturn ret;\n2128:\t\t}\n2129:\t\n2130:\t\tphy-\u003ephylink = pl;\n2131:\t\tphy-\u003ephy_link_change = phylink_phy_change;\n2132:\t\n2133:\t\tirq_str = phy_attached_info_irq(phy);\n2134:\t\tphylink_info(pl,\n2135:\t\t\t \"PHY [%s] driver [%s] (irq=%s)\\n\",\n2136:\t\t\t dev_name(\u0026phy-\u003emdio.dev), phy-\u003edrv-\u003ename, irq_str);\n2137:\t\tkfree(irq_str);\n2138:\t\n2139:\t\tmutex_lock(\u0026pl-\u003ephydev_mutex);\n"
} |
| 17/2 | 2026/08/27 21:51 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 37511 output: 39 thoughts: 22 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience and written in the first person: **Navigating the Phylink Codebase** Okay, let's dive into the `phylink.c` file. I need to refresh my memory on how this part interacts with the overall phylink process, so I'll jump right into lines 2140 to 2190. I'm focusing specifically on this section because I recall we were seeing some odd behavior related to [**insert specific problem the original user was having**], and I have a hunch it might be rooted here. Right, so glancing at this block of code, I'm noting the conditional check on [**specific variable or condition**]. It looks like this might be related to the [**specific process/function**] and how it handles [**specific data**]. I need to quickly determine if there are any obvious race conditions that could lead to data corruption in the current implementation, or possibly any off-by-one errors. Also, is this function re-entrant, and if not, how might it affect other threads? I’ll need to double check any associated mutexes or semaphores, just to be sure. I'm going to scan the surrounding code to check for the assignment of any potential null pointers. Perhaps there might be some missing error checking around [**specific function**]. Okay, time to check the logging output related to this function call, just in case. |
| 18/2 | 2026/08/27 21:51 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phylink.c",
"FirstLine": 2138,
"LineCount": 55
}Results: {
"Contents": "2138:\t\n2139:\t\tmutex_lock(\u0026pl-\u003ephydev_mutex);\n2140:\t\tmutex_lock(\u0026phy-\u003elock);\n2141:\t\tmutex_lock(\u0026pl-\u003estate_mutex);\n2142:\t\tpl-\u003ephydev = phy;\n2143:\t\tpl-\u003ephy_state.interface = interface;\n2144:\t\tpl-\u003ephy_state.pause = MLO_PAUSE_NONE;\n2145:\t\tpl-\u003ephy_state.speed = SPEED_UNKNOWN;\n2146:\t\tpl-\u003ephy_state.duplex = DUPLEX_UNKNOWN;\n2147:\t\tpl-\u003ephy_state.rate_matching = RATE_MATCH_NONE;\n2148:\t\tlinkmode_copy(pl-\u003esupported, supported);\n2149:\t\tlinkmode_copy(pl-\u003elink_config.advertising, config.advertising);\n2150:\t\n2151:\t\t/* Restrict the phy advertisement according to the MAC support. */\n2152:\t\tlinkmode_copy(phy-\u003eadvertising, config.advertising);\n2153:\t\n2154:\t\t/* If the MAC supports phylink managed EEE, restrict the EEE\n2155:\t\t * advertisement according to the MAC's LPI capabilities.\n2156:\t\t */\n2157:\t\tif (pl-\u003emac_supports_eee) {\n2158:\t\t\t/* If EEE is enabled, then we need to call phy_support_eee()\n2159:\t\t\t * to ensure that the advertising mask is appropriately set.\n2160:\t\t\t * This also enables EEE at the PHY.\n2161:\t\t\t */\n2162:\t\t\tif (pl-\u003eeee_cfg.eee_enabled)\n2163:\t\t\t\tphy_support_eee(phy);\n2164:\t\n2165:\t\t\tphy-\u003eeee_cfg.tx_lpi_enabled = pl-\u003eeee_cfg.tx_lpi_enabled;\n2166:\t\t\tphy-\u003eeee_cfg.tx_lpi_timer = pl-\u003eeee_cfg.tx_lpi_timer;\n2167:\t\n2168:\t\t\t/* Convert the MAC's LPI capabilities to linkmodes */\n2169:\t\t\tlinkmode_zero(pl-\u003esupported_lpi);\n2170:\t\t\tphylink_caps_to_linkmodes(pl-\u003esupported_lpi,\n2171:\t\t\t\t\t\t pl-\u003econfig-\u003elpi_capabilities);\n2172:\t\n2173:\t\t\t/* Restrict the PHYs EEE support/advertisement to the modes\n2174:\t\t\t * that the MAC supports.\n2175:\t\t\t */\n2176:\t\t\tlinkmode_and(phy-\u003eadvertising_eee, phy-\u003eadvertising_eee,\n2177:\t\t\t\t pl-\u003esupported_lpi);\n2178:\t\t} else if (pl-\u003emac_supports_eee_ops) {\n2179:\t\t\t/* MAC supports phylink EEE, but wants EEE always disabled. */\n2180:\t\t\tphy_disable_eee(phy);\n2181:\t\t}\n2182:\t\n2183:\t\tmutex_unlock(\u0026pl-\u003estate_mutex);\n2184:\t\tmutex_unlock(\u0026phy-\u003elock);\n2185:\t\tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n2186:\t\n2187:\t\tphylink_dbg(pl,\n2188:\t\t\t \"phy: %s setting supported %*pb advertising %*pb\\n\",\n2189:\t\t\t phy_modes(interface),\n2190:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, pl-\u003esupported,\n2191:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, phy-\u003eadvertising);\n2192:\t\n"
} |
| 19/2 | 2026/08/27 21:51 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 38830 output: 32 thoughts: 302 Thoughts: **Analyzing a PHY Link Bringup Issue** Okay, let's break this down. My initial observation is that `phylink_bringup_phy` is responsible for initializing the PHY device within the `pl` data structure. Specifically, it assigns the PHY device (`phy`) to `pl->phydev` and sets up some other internal state. The core of the problem seems to lie around line 2203, where the function `phy_eee_rx_clock_stop` is called. Critically, if `phy_eee_rx_clock_stop` fails, the `pl->phydev` field is *still* left non-NULL. This creates a really nasty race condition. I can see that if `phy_eee_rx_clock_stop` returns an error, any subsequent attempt to attach the PHY would return -EBUSY. That's because the `phylink_attach_phy` function checks if `pl->phydev` is already assigned and immediately returns -EBUSY. This is where the patch kicks in. It introduces a check, and if the `ret` from `phy_eee_rx_clock_stop` signals failure, the code now includes a mutex-protected call to `phylink_clear_phydev(pl, phy)`. That's smart; it's releasing the resource appropriately when the PHY initialization fails. So, the new code is attempting to clean up the partially initialized PHY in case of an error. The inclusion of the mutex is critical to prevent a race condition during PHY resource management. Now, I need to understand the wider context. I need to make sure I understand the interaction between `phy_device.c` and `phylink.c` and where they fit into the larger PHY driver structure. I'm going to look at where `phy_restore_genphy_irq` is called. I see it's called in `error_module_put` and `phy_detach` in `phy_device.c`, so I'll need to understand how these relate. I need to confirm the build dependencies. Where are `phy_device.c` and `phylink.c` built? I'll quickly check the Kconfig and Makefiles in `drivers/net/phy/` to understand exactly which configurations include these files. Grepping for the relevant Kconfig and Makefile entries should give me a quick overview of the build process for this section of code. |
| 20/2 | 2026/08/27 21:52 | tool | grepper |
0mArgs:{
"Expression": "phy_device|phylink",
"PathPrefix": "drivers/net/phy/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 14142 lines.\nUse more precise expression if possible.\n\ndrivers/net/phy/Makefile-3-\ndrivers/net/phy/Makefile:4:libphy-y\t\t\t:= phy.o phy-c45.o phy-core.o phy_device.o \\\ndrivers/net/phy/Makefile-5-\t\t\t\t linkmode.o phy_link_topology.o \\\n--\ndrivers/net/phy/Makefile=18=obj-$(CONFIG_PHYLIB)\t\t+= mdio_bus.o\ndrivers/net/phy/Makefile:19:obj-$(CONFIG_PHYLINK)\t\t+= phylink.o\ndrivers/net/phy/Makefile-20-obj-$(CONFIG_PHYLIB)\t\t+= libphy.o\n--\ndrivers/net/phy/adin.c=240=static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)\n--\ndrivers/net/phy/adin.c-251-\ndrivers/net/phy/adin.c:252:static u32 adin_get_reg_value(struct phy_device *phydev,\ndrivers/net/phy/adin.c-253-\t\t\t const char *prop_name,\n--\ndrivers/net/phy/adin.c-274-\ndrivers/net/phy/adin.c:275:static int adin_config_rgmii_mode(struct phy_device *phydev)\ndrivers/net/phy/adin.c-276-{\n--\ndrivers/net/phy/adin.c-320-\ndrivers/net/phy/adin.c:321:static int adin_config_rmii_mode(struct phy_device *phydev)\ndrivers/net/phy/adin.c-322-{\n--\ndrivers/net/phy/adin.c-347-\ndrivers/net/phy/adin.c:348:static int adin_get_downshift(struct phy_device *phydev, u8 *data)\ndrivers/net/phy/adin.c-349-{\n--\ndrivers/net/phy/adin.c-367-\ndrivers/net/phy/adin.c:368:static int adin_set_downshift(struct phy_device *phydev, u8 cnt)\ndrivers/net/phy/adin.c-369-{\n--\ndrivers/net/phy/adin.c-391-\ndrivers/net/phy/adin.c:392:static int adin_get_edpd(struct phy_device *phydev, u16 *tx_interval)\ndrivers/net/phy/adin.c-393-{\n--\ndrivers/net/phy/adin.c-412-\ndrivers/net/phy/adin.c:413:static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)\ndrivers/net/phy/adin.c-414-{\n--\ndrivers/net/phy/adin.c-439-\ndrivers/net/phy/adin.c:440:static int adin_get_fast_down(struct phy_device *phydev, u8 *msecs)\ndrivers/net/phy/adin.c-441-{\n--\ndrivers/net/phy/adin.c-455-\ndrivers/net/phy/adin.c:456:static int adin_set_fast_down(struct phy_device *phydev, const u8 *msecs)\ndrivers/net/phy/adin.c-457-{\n--\ndrivers/net/phy/adin.c-470-\ndrivers/net/phy/adin.c:471:static int adin_get_tunable(struct phy_device *phydev,\ndrivers/net/phy/adin.c-472-\t\t\t struct ethtool_tunable *tuna, void *data)\n--\ndrivers/net/phy/adin.c-485-\ndrivers/net/phy/adin.c:486:static int adin_set_tunable(struct phy_device *phydev,\ndrivers/net/phy/adin.c-487-\t\t\t struct ethtool_tunable *tuna, const void *data)\n--\ndrivers/net/phy/adin.c-500-\ndrivers/net/phy/adin.c:501:static int adin_config_clk_out(struct phy_device *phydev)\ndrivers/net/phy/adin.c-502-{\n--\ndrivers/net/phy/adin.c-527-\ndrivers/net/phy/adin.c:528:static int adin_config_zptm100(struct phy_device *phydev)\ndrivers/net/phy/adin.c-529-{\n--\ndrivers/net/phy/adin.c-540-\ndrivers/net/phy/adin.c:541:static int adin_config_init(struct phy_device *phydev)\ndrivers/net/phy/adin.c-542-{\n--\ndrivers/net/phy/adin.c-576-\ndrivers/net/phy/adin.c:577:static int adin_phy_ack_intr(struct phy_device *phydev)\ndrivers/net/phy/adin.c-578-{\n--\ndrivers/net/phy/adin.c-584-\ndrivers/net/phy/adin.c:585:static int adin_phy_config_intr(struct phy_device *phydev)\ndrivers/net/phy/adin.c-586-{\n--\ndrivers/net/phy/adin.c-607-\ndrivers/net/phy/adin.c:608:static irqreturn_t adin_phy_handle_interrupt(struct phy_device *phydev)\ndrivers/net/phy/adin.c-609-{\n--\ndrivers/net/phy/adin.c-625-\ndrivers/net/phy/adin.c:626:static int adin_cl45_to_adin_reg(struct phy_device *phydev, int devad,\ndrivers/net/phy/adin.c-627-\t\t\t\t u16 cl45_regnum)\n--\ndrivers/net/phy/adin.c-647-\ndrivers/net/phy/adin.c:648:static int adin_read_mmd(struct phy_device *phydev, int devad, u16 regnum)\ndrivers/net/phy/adin.c-649-{\n--\ndrivers/net/phy/adin.c-666-\ndrivers/net/phy/adin.c:667:static int adin_write_mmd(struct phy_device *phydev, int devad, u16 regnum,\ndrivers/net/phy/adin.c-668-\t\t\t u16 val)\n--\ndrivers/net/phy/adin.c-686-\ndrivers/net/phy/adin.c:687:static int adin_config_mdix(struct phy_device *phydev)\ndrivers/net/phy/adin.c-688-{\n--\ndrivers/net/phy/adin.c-723-\ndrivers/net/phy/adin.c:724:static int adin_config_aneg(struct phy_device *phydev)\ndrivers/net/phy/adin.c-725-{\n--\ndrivers/net/phy/adin.c-742-\ndrivers/net/phy/adin.c:743:static int adin_mdix_update(struct phy_device *phydev)\ndrivers/net/phy/adin.c-744-{\n--\ndrivers/net/phy/adin.c-783-\ndrivers/net/phy/adin.c:784:static int adin_read_status(struct phy_device *phydev)\ndrivers/net/phy/adin.c-785-{\n--\ndrivers/net/phy/adin.c-794-\ndrivers/net/phy/adin.c:795:static int adin_soft_reset(struct phy_device *phydev)\ndrivers/net/phy/adin.c-796-{\n--\ndrivers/net/phy/adin.c-814-\ndrivers/net/phy/adin.c:815:static int adin_get_sset_count(struct phy_device *phydev)\ndrivers/net/phy/adin.c-816-{\n--\ndrivers/net/phy/adin.c-819-\ndrivers/net/phy/adin.c:820:static void adin_get_strings(struct phy_device *phydev, u8 *data)\ndrivers/net/phy/adin.c-821-{\n--\ndrivers/net/phy/adin.c-827-\ndrivers/net/phy/adin.c:828:static int adin_read_mmd_stat_regs(struct phy_device *phydev,\ndrivers/net/phy/adin.c-829-\t\t\t\t const struct adin_hw_stat *stat,\n--\ndrivers/net/phy/adin.c-852-\ndrivers/net/phy/adin.c:853:static u64 adin_get_stat(struct phy_device *phydev, int i)\ndrivers/net/phy/adin.c-854-{\n--\ndrivers/net/phy/adin.c-875-\ndrivers/net/phy/adin.c:876:static void adin_get_stats(struct phy_device *phydev,\ndrivers/net/phy/adin.c-877-\t\t\t struct ethtool_stats *stats, u64 *data)\n--\ndrivers/net/phy/adin.c-889-\ndrivers/net/phy/adin.c:890:static int adin_probe(struct phy_device *phydev)\ndrivers/net/phy/adin.c-891-{\n--\ndrivers/net/phy/adin.c-903-\ndrivers/net/phy/adin.c:904:static int adin_cable_test_start(struct phy_device *phydev)\ndrivers/net/phy/adin.c-905-{\n--\ndrivers/net/phy/adin.c=923=static int adin_cable_test_report_trans(int result)\n--\ndrivers/net/phy/adin.c-944-\ndrivers/net/phy/adin.c:945:static int adin_cable_test_report_pair(struct phy_device *phydev,\ndrivers/net/phy/adin.c-946-\t\t\t\t unsigned int pair)\n--\ndrivers/net/phy/adin.c-976-\ndrivers/net/phy/adin.c:977:static int adin_cable_test_report(struct phy_device *phydev)\ndrivers/net/phy/adin.c-978-{\n--\ndrivers/net/phy/adin.c-990-\ndrivers/net/phy/adin.c:991:static int adin_cable_test_get_status(struct phy_device *phydev,\ndrivers/net/phy/adin.c-992-\t\t\t\t bool *finished)\n--\ndrivers/net/phy/adin1100.c=70=struct adin_priv {\n--\ndrivers/net/phy/adin1100.c-75-\ndrivers/net/phy/adin1100.c:76:static int adin_read_status(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-77-{\n--\ndrivers/net/phy/adin1100.c-96-\ndrivers/net/phy/adin1100.c:97:static int adin_config_aneg(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-98-{\n--\ndrivers/net/phy/adin1100.c-144-\ndrivers/net/phy/adin1100.c:145:static int adin_phy_ack_intr(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-146-{\n--\ndrivers/net/phy/adin1100.c-153-\ndrivers/net/phy/adin1100.c:154:static int adin_config_intr(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-155-{\n--\ndrivers/net/phy/adin1100.c-172-\ndrivers/net/phy/adin1100.c:173:static irqreturn_t adin_phy_handle_interrupt(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-174-{\n--\ndrivers/net/phy/adin1100.c-191-\ndrivers/net/phy/adin1100.c:192:static int adin_set_powerdown_mode(struct phy_device *phydev, bool en)\ndrivers/net/phy/adin1100.c-193-{\n--\ndrivers/net/phy/adin1100.c-206-\ndrivers/net/phy/adin1100.c:207:static int adin_suspend(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-208-{\n--\ndrivers/net/phy/adin1100.c-211-\ndrivers/net/phy/adin1100.c:212:static int adin_resume(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-213-{\n--\ndrivers/net/phy/adin1100.c-216-\ndrivers/net/phy/adin1100.c:217:static int adin_set_loopback(struct phy_device *phydev, bool enable, int speed)\ndrivers/net/phy/adin1100.c-218-{\n--\ndrivers/net/phy/adin1100.c-230-\ndrivers/net/phy/adin1100.c:231:static int adin_soft_reset(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-232-{\n--\ndrivers/net/phy/adin1100.c-243-\ndrivers/net/phy/adin1100.c:244:static int adin_get_features(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-245-{\n--\ndrivers/net/phy/adin1100.c-278-\ndrivers/net/phy/adin1100.c:279:static int adin_get_sqi(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-280-{\n--\ndrivers/net/phy/adin1100.c-303-\ndrivers/net/phy/adin1100.c:304:static int adin_get_sqi_max(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-305-{\n--\ndrivers/net/phy/adin1100.c-308-\ndrivers/net/phy/adin1100.c:309:static int adin_probe(struct phy_device *phydev)\ndrivers/net/phy/adin1100.c-310-{\n--\ndrivers/net/phy/adin1140-phy.c-16-\ndrivers/net/phy/adin1140-phy.c:17:static int adin1140_config_aneg(struct phy_device *phydev)\ndrivers/net/phy/adin1140-phy.c-18-{\n--\ndrivers/net/phy/adin1140-phy.c-25-\ndrivers/net/phy/adin1140-phy.c:26:static int adin1140_loopback(struct phy_device *phydev, bool enable, int speed)\ndrivers/net/phy/adin1140-phy.c-27-{\n--\ndrivers/net/phy/adin1140-phy.c-35-\ndrivers/net/phy/adin1140-phy.c:36:static int adin1140_read_status(struct phy_device *phydev)\ndrivers/net/phy/adin1140-phy.c-37-{\n--\ndrivers/net/phy/air_an8801.c=206=static const unsigned long an8801r_led_trig = BIT(TRIGGER_NETDEV_LINK) |\n--\ndrivers/net/phy/air_an8801.c-213-\ndrivers/net/phy/air_an8801.c:214:static int an8801_buckpbus_reg_rmw(struct phy_device *phydev,\ndrivers/net/phy/air_an8801.c-215-\t\t\t\t u32 addr, u32 mask, u32 set)\n--\ndrivers/net/phy/air_an8801.c-221-\ndrivers/net/phy/air_an8801.c:222:static int an8801_buckpbus_reg_set_bits(struct phy_device *phydev,\ndrivers/net/phy/air_an8801.c-223-\t\t\t\t\tu32 addr, u32 mask)\n--\ndrivers/net/phy/air_an8801.c-229-\ndrivers/net/phy/air_an8801.c:230:static int an8801_buckpbus_reg_clear_bits(struct phy_device *phydev,\ndrivers/net/phy/air_an8801.c-231-\t\t\t\t\t u32 addr, u32 mask)\n--\ndrivers/net/phy/air_an8801.c-237-\ndrivers/net/phy/air_an8801.c:238:static int an8801_buckpbus_reg_write(struct phy_device *phydev, u32 addr,\ndrivers/net/phy/air_an8801.c-239-\t\t\t\t u32 data)\n--\ndrivers/net/phy/air_an8801.c-245-\ndrivers/net/phy/air_an8801.c:246:static int an8801_buckpbus_reg_read(struct phy_device *phydev, u32 addr,\ndrivers/net/phy/air_an8801.c-247-\t\t\t\t u32 *data)\n--\ndrivers/net/phy/air_an8801.c=254=static u32 an8801r_led_blink_ms_to_hw(unsigned long req_ms)\n--\ndrivers/net/phy/air_an8801.c-271-\ndrivers/net/phy/air_an8801.c:272:static int an8801r_led_blink_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-273-\t\t\t\t unsigned long *delay_on,\n--\ndrivers/net/phy/air_an8801.c-332-\ndrivers/net/phy/air_an8801.c:333:static int an8801r_led_brightness_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-334-\t\t\t\t enum led_brightness value)\n--\ndrivers/net/phy/air_an8801.c-356-\ndrivers/net/phy/air_an8801.c:357:static int an8801r_led_hw_control_get(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-358-\t\t\t\t unsigned long *rules)\n--\ndrivers/net/phy/air_an8801.c=403=static int an8801r_led_trig_to_hw(unsigned long rules, u16 *on, u16 *blink)\n--\ndrivers/net/phy/air_an8801.c-441-\ndrivers/net/phy/air_an8801.c:442:static int an8801r_led_hw_is_supported(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-443-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_an8801.c-452-\ndrivers/net/phy/air_an8801.c:453:static int an8801r_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_an8801.c-454-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_an8801.c-479-\ndrivers/net/phy/air_an8801.c:480:static int an8801r_led_polarity_set(struct phy_device *phydev, int index,\ndrivers/net/phy/air_an8801.c-481-\t\t\t\t unsigned long modes)\n--\ndrivers/net/phy/air_an8801.c-504-\ndrivers/net/phy/air_an8801.c:505:static int an8801r_led_init(struct phy_device *phydev, u8 *led_cfg)\ndrivers/net/phy/air_an8801.c-506-{\n--\ndrivers/net/phy/air_an8801.c-562-\ndrivers/net/phy/air_an8801.c:563:static int an8801r_reset_wake(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-564-{\n--\ndrivers/net/phy/air_an8801.c-600-\ndrivers/net/phy/air_an8801.c:601:static int an8801r_ack_interrupt(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-602-{\n--\ndrivers/net/phy/air_an8801.c-614-\ndrivers/net/phy/air_an8801.c:615:static int an8801r_config_intr(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-616-{\n--\ndrivers/net/phy/air_an8801.c-651-\ndrivers/net/phy/air_an8801.c:652:static irqreturn_t an8801r_handle_interrupt(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-653-{\n--\ndrivers/net/phy/air_an8801.c-679-\ndrivers/net/phy/air_an8801.c:680:static void an8801r_get_wol(struct phy_device *phydev,\ndrivers/net/phy/air_an8801.c-681-\t\t\t struct ethtool_wolinfo *wol)\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-782-\ndrivers/net/phy/air_an8801.c:783:static int an8801r_of_init_leds(struct phy_device *phydev, u8 *led_cfg)\ndrivers/net/phy/air_an8801.c-784-{\n--\ndrivers/net/phy/air_an8801.c-829-\ndrivers/net/phy/air_an8801.c:830:static int an8801r_rgmii_rxdelay(struct phy_device *phydev, bool enable,\ndrivers/net/phy/air_an8801.c-831-\t\t\t\t u16 delay_steps)\n--\ndrivers/net/phy/air_an8801.c-851-\ndrivers/net/phy/air_an8801.c:852:static int an8801r_rgmii_txdelay(struct phy_device *phydev, bool enable,\ndrivers/net/phy/air_an8801.c-853-\t\t\t\t u16 delay_steps)\n--\ndrivers/net/phy/air_an8801.c-870-\ndrivers/net/phy/air_an8801.c:871:static int an8801r_rgmii_delay_config(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-872-{\n--\ndrivers/net/phy/air_an8801.c-901-\ndrivers/net/phy/air_an8801.c:902:static int an8801r_config_init(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-903-{\n--\ndrivers/net/phy/air_an8801.c-998-\ndrivers/net/phy/air_an8801.c:999:static int an8801r_read_status(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-1000-{\n--\ndrivers/net/phy/air_an8801.c-1033-\ndrivers/net/phy/air_an8801.c:1034:static int an8801r_probe(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-1035-{\n--\ndrivers/net/phy/air_an8801.c-1059-\ndrivers/net/phy/air_an8801.c:1060:static int an8801r_suspend(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-1061-{\n--\ndrivers/net/phy/air_an8801.c-1090-\ndrivers/net/phy/air_an8801.c:1091:static int an8801r_resume(struct phy_device *phydev)\ndrivers/net/phy/air_an8801.c-1092-{\n--\ndrivers/net/phy/air_en8811h.c=197=struct en8811h_priv {\n--\ndrivers/net/phy/air_en8811h.c-201-\tstruct clk_hw\t\thw;\ndrivers/net/phy/air_en8811h.c:202:\tstruct phy_device\t*phydev;\ndrivers/net/phy/air_en8811h.c-203-\tunsigned int\t\tcko_is_enabled;\n--\ndrivers/net/phy/air_en8811h.c=248=static int __air_pbus_reg_write(struct mdio_device *mdiodev,\n--\ndrivers/net/phy/air_en8811h.c-272-\ndrivers/net/phy/air_en8811h.c:273:static int __air_write_buf(struct phy_device *phydev, u32 address,\ndrivers/net/phy/air_en8811h.c-274-\t\t\t const struct firmware *fw)\n--\ndrivers/net/phy/air_en8811h.c-308-\ndrivers/net/phy/air_en8811h.c:309:static int air_write_buf(struct phy_device *phydev, u32 address,\ndrivers/net/phy/air_en8811h.c-310-\t\t\t const struct firmware *fw)\n--\ndrivers/net/phy/air_en8811h.c-326-\ndrivers/net/phy/air_en8811h.c:327:static int en8811h_wait_mcu_ready(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-328-{\n--\ndrivers/net/phy/air_en8811h.c-348-\ndrivers/net/phy/air_en8811h.c:349:static int an8811hb_check_crc(struct phy_device *phydev, u32 set1,\ndrivers/net/phy/air_en8811h.c-350-\t\t\t u32 mon2, u32 mon3)\n--\ndrivers/net/phy/air_en8811h.c-386-\ndrivers/net/phy/air_en8811h.c:387:static void en8811h_print_fw_version(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-388-{\n--\ndrivers/net/phy/air_en8811h.c-396-\ndrivers/net/phy/air_en8811h.c:397:static int an8811hb_load_file(struct phy_device *phydev, const char *name,\ndrivers/net/phy/air_en8811h.c-398-\t\t\t u32 address)\n--\ndrivers/net/phy/air_en8811h.c-412-\ndrivers/net/phy/air_en8811h.c:413:static int an8811hb_mcu_assert(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-414-{\n--\ndrivers/net/phy/air_en8811h.c-436-\ndrivers/net/phy/air_en8811h.c:437:static int an8811hb_mcu_deassert(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-438-{\n--\ndrivers/net/phy/air_en8811h.c-461-\ndrivers/net/phy/air_en8811h.c:462:static int an8811hb_load_firmware(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-463-{\n--\ndrivers/net/phy/air_en8811h.c-501-\ndrivers/net/phy/air_en8811h.c:502:static int en8811h_load_firmware(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-503-{\n--\ndrivers/net/phy/air_en8811h.c-557-\ndrivers/net/phy/air_en8811h.c:558:static int en8811h_restart_mcu(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-559-{\n--\ndrivers/net/phy/air_en8811h.c-579-\ndrivers/net/phy/air_en8811h.c:580:static int air_hw_led_on_set(struct phy_device *phydev, u8 index, bool on)\ndrivers/net/phy/air_en8811h.c-581-{\n--\ndrivers/net/phy/air_en8811h.c-609-\ndrivers/net/phy/air_en8811h.c:610:static int air_hw_led_blink_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-611-\t\t\t\tbool blinking)\n--\ndrivers/net/phy/air_en8811h.c-636-\ndrivers/net/phy/air_en8811h.c:637:static int air_led_blink_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-638-\t\t\t unsigned long *delay_on,\n--\ndrivers/net/phy/air_en8811h.c-669-\ndrivers/net/phy/air_en8811h.c:670:static int air_led_brightness_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-671-\t\t\t\t enum led_brightness value)\n--\ndrivers/net/phy/air_en8811h.c-694-\ndrivers/net/phy/air_en8811h.c:695:static int air_led_hw_control_get(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-696-\t\t\t\t unsigned long *rules)\n--\ndrivers/net/phy/air_en8811h.c-707-\ndrivers/net/phy/air_en8811h.c:708:static int air_led_hw_control_set(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-709-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_en8811h.c-768-\ndrivers/net/phy/air_en8811h.c:769:static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol)\ndrivers/net/phy/air_en8811h.c-770-{\n--\ndrivers/net/phy/air_en8811h.c-796-\ndrivers/net/phy/air_en8811h.c:797:static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode)\ndrivers/net/phy/air_en8811h.c-798-{\n--\ndrivers/net/phy/air_en8811h.c-845-\ndrivers/net/phy/air_en8811h.c:846:static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index,\ndrivers/net/phy/air_en8811h.c-847-\t\t\t\t unsigned long rules)\n--\ndrivers/net/phy/air_en8811h.c=859=static unsigned long an8811hb_clk_recalc_rate(struct clk_hw *hw,\n--\ndrivers/net/phy/air_en8811h.c-862-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:863:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-864-\tu32 pbus_value;\n--\ndrivers/net/phy/air_en8811h.c=874=static int an8811hb_clk_enable(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-876-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:877:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-878-\n--\ndrivers/net/phy/air_en8811h.c=884=static void an8811hb_clk_disable(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-886-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:887:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-888-\n--\ndrivers/net/phy/air_en8811h.c=893=static int an8811hb_clk_is_enabled(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-895-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:896:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-897-\tu32 pbus_value;\n--\ndrivers/net/phy/air_en8811h.c=958=static unsigned long en8811h_clk_recalc_rate(struct clk_hw *hw,\n--\ndrivers/net/phy/air_en8811h.c-961-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:962:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-963-\tu32 pbus_value;\n--\ndrivers/net/phy/air_en8811h.c=973=static int en8811h_clk_enable(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-975-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:976:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-977-\n--\ndrivers/net/phy/air_en8811h.c=983=static void en8811h_clk_disable(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-985-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:986:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-987-\n--\ndrivers/net/phy/air_en8811h.c=992=static int en8811h_clk_is_enabled(struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-994-\tstruct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);\ndrivers/net/phy/air_en8811h.c:995:\tstruct phy_device *phydev = priv-\u003ephydev;\ndrivers/net/phy/air_en8811h.c-996-\tu32 pbus_value;\n--\ndrivers/net/phy/air_en8811h.c=1032=static int en8811h_clk_provider_setup(struct device *dev, struct clk_hw *hw)\n--\ndrivers/net/phy/air_en8811h.c-1056-\ndrivers/net/phy/air_en8811h.c:1057:static int en8811h_leds_setup(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1058-{\n--\ndrivers/net/phy/air_en8811h.c-1073-\ndrivers/net/phy/air_en8811h.c:1074:static int an8811hb_probe(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1075-{\n--\ndrivers/net/phy/air_en8811h.c-1144-\ndrivers/net/phy/air_en8811h.c:1145:static int en8811h_probe(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1146-{\n--\ndrivers/net/phy/air_en8811h.c-1185-\ndrivers/net/phy/air_en8811h.c:1186:static int an8811hb_config_serdes_polarity(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1187-{\n--\ndrivers/net/phy/air_en8811h.c-1216-\ndrivers/net/phy/air_en8811h.c:1217:static int en8811h_config_serdes_polarity(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1218-{\n--\ndrivers/net/phy/air_en8811h.c-1253-\ndrivers/net/phy/air_en8811h.c:1254:static int an8811hb_config_init(struct phy_device *phydev)\ndrivers/net/phy/air_en8811h.c-1255-{\n--\ndrivers/net/phy/air_en8811h.c-1280-\ndrivers/net/phy/air_en8811h.c:1281:static int en8811h_config_init(struct phy_device *phydev)\n\n"
} |
| 21/2 | 2026/08/27 21:52 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 50603 output: 34 thoughts: 14 Thoughts: Here's a summary of my thought process, as requested: **Kconfig Dive** Alright, time to dive in. My immediate thought is to zero in on `drivers/net/phy/Kconfig`. That's where the PHY driver configurations live, and that's the logical starting point for understanding how this whole networking PHY thing is set up within the kernel build system. I'm thinking about dependency definitions, feature flags, and default selections—the whole Kconfig enchilada. I need to refresh my mental map of which PHY drivers are available, what their key characteristics are (like if they're generic or specific to certain hardware), and how they tie into the broader network subsystem. So, let's pull up that file and get to work. |
| 22/2 | 2026/08/27 21:52 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/Kconfig",
"FirstLine": 1,
"LineCount": 60
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\t#\n 3:\t# PHY Layer Configuration\n 4:\t#\n 5:\t\n 6:\tconfig PHYLINK\n 7:\t\ttristate\n 8:\t\tselect PHYLIB\n 9:\t\tselect SWPHY\n 10:\t\thelp\n 11:\t\t PHYlink models the link between the PHY and MAC, allowing fixed\n 12:\t\t configuration links, PHYs, and Serdes links with MAC level\n 13:\t\t autonegotiation modes.\n 14:\t\n 15:\tmenuconfig PHYLIB\n 16:\t\ttristate \"PHY Device support and infrastructure\"\n 17:\t\thelp\n 18:\t\t Ethernet controllers are usually attached to PHY\n 19:\t\t devices. This option provides infrastructure for\n 20:\t\t managing PHY devices.\n 21:\t\n 22:\tif PHYLIB\n 23:\t\n 24:\tconfig SWPHY\n 25:\t\tbool\n 26:\t\n 27:\tconfig PHY_PACKAGE\n 28:\t\t tristate\n 29:\t\n 30:\tconfig LED_TRIGGER_PHY\n 31:\t\tbool \"Support LED triggers for tracking link state\"\n 32:\t\tdepends on LEDS_TRIGGERS\n 33:\t\thelp\n 34:\t\t Adds support for a set of LED trigger events per-PHY. Link\n 35:\t\t state change will trigger the events, for consumption by an\n 36:\t\t LED class driver. There are triggers for each link speed currently\n 37:\t\t supported by the PHY and also a one common \"link\" trigger as a\n 38:\t\t logical-or of all the link speed ones.\n 39:\t\t All these triggers are named according to the following pattern:\n 40:\t\t \u003cmii bus id\u003e:\u003cphy\u003e:\u003cspeed\u003e\n 41:\t\n 42:\t\t Where speed is in the form:\n 43:\t\t\t\u003cSpeed in megabits\u003eMbps OR \u003cSpeed in gigabits\u003eGbps OR link\n 44:\t\t\tfor any speed known to the PHY.\n 45:\t\n 46:\tconfig OPEN_ALLIANCE_HELPERS\n 47:\t\tbool\n 48:\t\n 49:\tconfig PHYLIB_LEDS\n 50:\t\tdef_bool OF\n 51:\t\tdepends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB\n 52:\t\thelp\n 53:\t\t When LED class support is enabled, phylib can automatically\n 54:\t\t probe LED setting from device tree.\n 55:\t\n 56:\tconfig FIXED_PHY\n 57:\t\ttristate \"MDIO Bus/PHY emulation with fixed speed/link PHYs\"\n 58:\t\tselect SWPHY\n 59:\t\thelp\n 60:\t\t Adds the platform \"fixed\" MDIO Bus to cover the boards that use\n"
} |
| 23/2 | 2026/08/27 21:52 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 51548 output: 28 thoughts: 39 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Investigating the `PHYLINK` and `PHYLIB` Dependencies** Alright, time to get to the bottom of this. My focus is on understanding what specifically pulls in `PHYLINK` and `PHYLIB`. Given my understanding of the kernel's networking stack, the first place I'll target is the device driver configuration. I'm thinking drivers related to network interfaces are the most likely candidates. My plan is to start with a `grep` through the relevant Kconfig files. This means diving into `drivers/net/Kconfig` and, depending on the architecture I'm working with, possibly checking within `drivers/net/usb/Kconfig` too. I expect `PHYLINK` and `PHYLIB` will be included, and my aim is to find *where* in the hierarchy these are selected, and under what specific configurations. That should illuminate the triggering conditions I'm interested in and their role in the bigger picture of the networking subsystem. |
| 24/2 | 2026/08/27 21:53 | tool | grepper |
0mArgs:{
"Expression": "select PHYLINK",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "drivers/net/ethernet/altera/Kconfig=2=config ALTERA_TSE\n--\ndrivers/net/ethernet/altera/Kconfig-6-\tselect PHYLIB\ndrivers/net/ethernet/altera/Kconfig:7:\tselect PHYLINK\ndrivers/net/ethernet/altera/Kconfig-8-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/atheros/Kconfig=20=config AG71XX\n--\ndrivers/net/ethernet/atheros/Kconfig-22-\tdepends on ATH79 || COMPILE_TEST\ndrivers/net/ethernet/atheros/Kconfig:23:\tselect PHYLINK\ndrivers/net/ethernet/atheros/Kconfig-24-\timply NET_SELFTESTS\n--\ndrivers/net/ethernet/cadence/Kconfig=22=config MACB\n--\ndrivers/net/ethernet/cadence/Kconfig-25-\tdepends on PTP_1588_CLOCK_OPTIONAL\ndrivers/net/ethernet/cadence/Kconfig:26:\tselect PHYLINK\ndrivers/net/ethernet/cadence/Kconfig-27-\tselect CRC32\n--\ndrivers/net/ethernet/freescale/Kconfig=80=config UCC_GETH\n--\ndrivers/net/ethernet/freescale/Kconfig-83-\tselect FSL_PQ_MDIO\ndrivers/net/ethernet/freescale/Kconfig:84:\tselect PHYLINK\ndrivers/net/ethernet/freescale/Kconfig-85-\thelp\n--\ndrivers/net/ethernet/freescale/dpaa/Kconfig=2=menuconfig FSL_DPAA_ETH\n--\ndrivers/net/ethernet/freescale/dpaa/Kconfig-4-\tdepends on FSL_DPAA \u0026\u0026 FSL_FMAN\ndrivers/net/ethernet/freescale/dpaa/Kconfig:5:\tselect PHYLINK\ndrivers/net/ethernet/freescale/dpaa/Kconfig-6-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/freescale/dpaa2/Kconfig=2=config FSL_DPAA2_ETH\n--\ndrivers/net/ethernet/freescale/dpaa2/Kconfig-4-\tdepends on FSL_MC_BUS \u0026\u0026 FSL_MC_DPIO\ndrivers/net/ethernet/freescale/dpaa2/Kconfig:5:\tselect PHYLINK\ndrivers/net/ethernet/freescale/dpaa2/Kconfig-6-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/freescale/dpaa2/Kconfig=33=config FSL_DPAA2_SWITCH\n--\ndrivers/net/ethernet/freescale/dpaa2/Kconfig-37-\tdepends on FSL_MC_BUS \u0026\u0026 FSL_MC_DPIO\ndrivers/net/ethernet/freescale/dpaa2/Kconfig:38:\tselect PHYLINK\ndrivers/net/ethernet/freescale/dpaa2/Kconfig-39-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig=30=config FSL_ENETC\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig-37-\tselect NXP_ENETC_PF_COMMON\ndrivers/net/ethernet/freescale/enetc/Kconfig:38:\tselect PHYLINK\ndrivers/net/ethernet/freescale/enetc/Kconfig-39-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig=48=config NXP_ENETC4\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig-55-\tselect NXP_NTMP\ndrivers/net/ethernet/freescale/enetc/Kconfig:56:\tselect PHYLINK\ndrivers/net/ethernet/freescale/enetc/Kconfig-57-\tselect DIMLIB\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig=66=config FSL_ENETC_VF\n--\ndrivers/net/ethernet/freescale/enetc/Kconfig-71-\tselect FSL_ENETC_MDIO\ndrivers/net/ethernet/freescale/enetc/Kconfig:72:\tselect PHYLINK\ndrivers/net/ethernet/freescale/enetc/Kconfig-73-\tselect DIMLIB\n--\ndrivers/net/ethernet/freescale/fman/Kconfig=2=config FSL_FMAN\n--\ndrivers/net/ethernet/freescale/fman/Kconfig-5-\tselect GENERIC_ALLOCATOR\ndrivers/net/ethernet/freescale/fman/Kconfig:6:\tselect PHYLINK\ndrivers/net/ethernet/freescale/fman/Kconfig-7-\tselect PCS_LYNX\n--\ndrivers/net/ethernet/freescale/fs_enet/Kconfig=2=config FS_ENET\n--\ndrivers/net/ethernet/freescale/fs_enet/Kconfig-5-\tselect MII\ndrivers/net/ethernet/freescale/fs_enet/Kconfig:6:\tselect PHYLINK\ndrivers/net/ethernet/freescale/fs_enet/Kconfig-7-\n--\ndrivers/net/ethernet/marvell/Kconfig=59=config MVNETA\n--\ndrivers/net/ethernet/marvell/Kconfig-62-\tselect MVMDIO\ndrivers/net/ethernet/marvell/Kconfig:63:\tselect PHYLINK\ndrivers/net/ethernet/marvell/Kconfig-64-\tselect PAGE_POOL\n--\ndrivers/net/ethernet/marvell/Kconfig=86=config MVPP2\n--\ndrivers/net/ethernet/marvell/Kconfig-89-\tselect MVMDIO\ndrivers/net/ethernet/marvell/Kconfig:90:\tselect PHYLINK\ndrivers/net/ethernet/marvell/Kconfig-91-\tselect PAGE_POOL\n--\ndrivers/net/ethernet/marvell/prestera/Kconfig=6=config PRESTERA\n--\ndrivers/net/ethernet/marvell/prestera/Kconfig-10-\tselect NET_DEVLINK\ndrivers/net/ethernet/marvell/prestera/Kconfig:11:\tselect PHYLINK\ndrivers/net/ethernet/marvell/prestera/Kconfig-12-\thelp\n--\ndrivers/net/ethernet/mediatek/Kconfig=14=config NET_MEDIATEK_SOC\n--\ndrivers/net/ethernet/mediatek/Kconfig-17-\tselect PINCTRL\ndrivers/net/ethernet/mediatek/Kconfig:18:\tselect PHYLINK\ndrivers/net/ethernet/mediatek/Kconfig-19-\tselect DIMLIB\n--\ndrivers/net/ethernet/meta/Kconfig=20=config FBNIC\n--\ndrivers/net/ethernet/meta/Kconfig-29-\tselect PCS_XPCS\ndrivers/net/ethernet/meta/Kconfig:30:\tselect PHYLINK\ndrivers/net/ethernet/meta/Kconfig-31-\tselect PLDMFW\n--\ndrivers/net/ethernet/microchip/Kconfig=45=config LAN743X\n--\ndrivers/net/ethernet/microchip/Kconfig-51-\tselect CRC32\ndrivers/net/ethernet/microchip/Kconfig:52:\tselect PHYLINK\ndrivers/net/ethernet/microchip/Kconfig-53-\thelp\n--\ndrivers/net/ethernet/microchip/lan966x/Kconfig=1=config LAN966X_SWITCH\n--\ndrivers/net/ethernet/microchip/lan966x/Kconfig-7-\tdepends on BRIDGE || BRIDGE=n\ndrivers/net/ethernet/microchip/lan966x/Kconfig:8:\tselect PHYLINK\ndrivers/net/ethernet/microchip/lan966x/Kconfig-9-\tselect PAGE_POOL\n--\ndrivers/net/ethernet/microchip/sparx5/Kconfig=1=config SPARX5_SWITCH\n--\ndrivers/net/ethernet/microchip/sparx5/Kconfig-8-\tdepends on BRIDGE || BRIDGE=n\ndrivers/net/ethernet/microchip/sparx5/Kconfig:9:\tselect PHYLINK\ndrivers/net/ethernet/microchip/sparx5/Kconfig-10-\tselect PHY_SPARX5_SERDES\n--\ndrivers/net/ethernet/mscc/Kconfig=15=config MSCC_OCELOT_SWITCH_LIB\n--\ndrivers/net/ethernet/mscc/Kconfig-19-\tselect PACKING\ndrivers/net/ethernet/mscc/Kconfig:20:\tselect PHYLINK\ndrivers/net/ethernet/mscc/Kconfig-21-\ttristate\n--\ndrivers/net/ethernet/renesas/Kconfig=42=config RENESAS_ETHER_SWITCH\n--\ndrivers/net/ethernet/renesas/Kconfig-47-\tselect MII\ndrivers/net/ethernet/renesas/Kconfig:48:\tselect PHYLINK\ndrivers/net/ethernet/renesas/Kconfig-49-\tselect RENESAS_GEN4_PTP\n--\ndrivers/net/ethernet/stmicro/stmmac/Kconfig=2=config STMMAC_ETH\n--\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-9-\tselect PAGE_POOL\ndrivers/net/ethernet/stmicro/stmmac/Kconfig:10:\tselect PHYLINK\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-11-\tselect CRC32\n--\ndrivers/net/ethernet/tehuti/Kconfig=26=config TEHUTI_TN40\n--\ndrivers/net/ethernet/tehuti/Kconfig-30-\tselect FW_LOADER\ndrivers/net/ethernet/tehuti/Kconfig:31:\tselect PHYLINK\ndrivers/net/ethernet/tehuti/Kconfig-32-\thelp\n--\ndrivers/net/ethernet/ti/Kconfig=96=config TI_K3_AM65_CPSW_NUSS\n--\ndrivers/net/ethernet/ti/Kconfig-100-\tselect TI_DAVINCI_MDIO\ndrivers/net/ethernet/ti/Kconfig:101:\tselect PHYLINK\ndrivers/net/ethernet/ti/Kconfig-102-\tselect PAGE_POOL\n--\ndrivers/net/ethernet/wangxun/Kconfig=19=config LIBWX\n--\ndrivers/net/ethernet/wangxun/Kconfig-23-\tselect DIMLIB\ndrivers/net/ethernet/wangxun/Kconfig:24:\tselect PHYLINK\ndrivers/net/ethernet/wangxun/Kconfig-25-\thelp\n--\ndrivers/net/ethernet/xilinx/Kconfig=26=config XILINX_AXI_EMAC\n--\ndrivers/net/ethernet/xilinx/Kconfig-29-\tdepends on XILINX_DMA\ndrivers/net/ethernet/xilinx/Kconfig:30:\tselect PHYLINK\ndrivers/net/ethernet/xilinx/Kconfig-31-\tselect DIMLIB\n--\ndrivers/net/pcs/Kconfig=8=config PCS_XPCS\ndrivers/net/pcs/Kconfig-9-\ttristate \"Synopsys DesignWare Ethernet XPCS\"\ndrivers/net/pcs/Kconfig:10:\tselect PHYLINK\ndrivers/net/pcs/Kconfig-11-\thelp\n--\ndrivers/net/usb/Kconfig=113=config USB_LAN78XX\n--\ndrivers/net/usb/Kconfig-115-\tselect MII\ndrivers/net/usb/Kconfig:116:\tselect PHYLINK\ndrivers/net/usb/Kconfig-117-\tselect MICROCHIP_PHY\n--\ndrivers/net/usb/Kconfig=166=config USB_NET_AX8817X\n--\ndrivers/net/usb/Kconfig-169-\tselect CRC32\ndrivers/net/usb/Kconfig:170:\tselect PHYLINK\ndrivers/net/usb/Kconfig-171-\tselect AX88796B_PHY\n"
} |
| 25/2 | 2026/08/27 21:53 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 54883 output: 28 thoughts: 90 Thoughts: Okay, here's my interpretation of that. **Ethernet Device Drivers & Emulation for Testing** Right, so I'm thinking about these USB Ethernet drivers, `USB_LAN78XX` and `USB_NET_AX8817X`. Seems like they both hook into `PHYLINK` and `PHYLIB`, which is standard for handling the physical layer interface. That's a solid architectural choice, nothing surprising there. The exciting part is that I can emulate these USB Ethernet devices using USB raw-gadget or dummy_hcd within syzkaller or QEMU! I can leverage that to test them thoroughly. Also, I need to remember that `NET_DSA` also selects `PHYLINK`. I should double-check the `net/dsa/Kconfig` file to confirm how that ties into the overall picture. Gotta make sure I'm considering all potential interactions and dependencies during my testing strategy. I need to make sure I have an exhaustive test plan. |
| 26/2 | 2026/08/27 21:53 | tool | grepper |
0mArgs:{
"Expression": "PHYLINK",
"PathPrefix": "net/dsa/"
}Results: {
"Output": "net/dsa/Kconfig=3=menuconfig NET_DSA\n--\nnet/dsa/Kconfig-9-\tselect NET_SWITCHDEV\nnet/dsa/Kconfig:10:\tselect PHYLINK\nnet/dsa/Kconfig-11-\tselect NET_DEVLINK\n--\nnet/dsa/port.c=1617=int dsa_port_phylink_create(struct dsa_port *dp)\n--\nnet/dsa/port.c-1649-\tif (IS_ERR(pl)) {\nnet/dsa/port.c:1650:\t\tpr_err(\"error creating PHYLINK: %ld\\n\", PTR_ERR(pl));\nnet/dsa/port.c-1651-\t\treturn PTR_ERR(pl);\n--\nnet/dsa/port.c=1665=static int dsa_shared_port_phylink_register(struct dsa_port *dp)\n--\nnet/dsa/port.c-1671-\tdp-\u003epl_config.dev = ds-\u003edev;\nnet/dsa/port.c:1672:\tdp-\u003epl_config.type = PHYLINK_DEV;\nnet/dsa/port.c-1673-\n--\nnet/dsa/user.c=2654=static int dsa_user_phy_setup(struct net_device *user_dev)\n--\nnet/dsa/user.c-2662-\tdp-\u003epl_config.dev = \u0026user_dev-\u003edev;\nnet/dsa/user.c:2663:\tdp-\u003epl_config.type = PHYLINK_NETDEV;\nnet/dsa/user.c-2664-\nnet/dsa/user.c-2665-\t/* The get_fixed_state callback takes precedence over polling the\nnet/dsa/user.c:2666:\t * link GPIO in PHYLINK (see phylink_get_fixed_state). Only set\nnet/dsa/user.c-2667-\t * this if the switch provides such a callback.\n"
} |
| 27/2 | 2026/08/27 21:53 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 55741 output: 35 thoughts: 2057 Thoughts: **Analysis of the Network PHY/PHYLink Patch** Okay, let's break this down. First, I'm examining this patch to see what's actually changing under the hood. It seems to be cleaning up some error paths and resource management in the PHY (Physical Layer) and PHYLink subsystems. Specifically, it's about handling interrupt configurations and ensuring proper cleanup of PHY device pointers, especially during the bringup/teardown cycles. The first part looks at `phy_restore_genphy_irq`. This function seems to be making sure the interrupt configuration is correctly restored when the generic PHY driver is used, particularly after an error or detachment. It's critical because incorrect interrupt configuration could lead to broken network connectivity or instability, and is triggered on the error paths. The second part deals with `phylink_clear_phydev`. This is a helper function to disassociate a PHY device from a PHYLink instance. It's invoked in `phylink_disconnect_phy` and also as part of error handling in `phylink_bringup_phy`, making sure a PHY device isn't leaked on bringup failures. This is important for preventing resource leaks and ensuring PHY devices can be cleanly re-attached. Functionally, I can see that this patch is addressing real, potentially problematic scenarios. Failure to properly clear the `phydev` pointer could lead to the `-EBUSY` error and retry failure. The interrupt restoration fixes a race condition during PHY attach. Both are worth investigating. Now, according to the guidance, I need to decide if this warrants fuzzing. It's not just documentation or logging. It's modifying core network PHY logic, which is used across many different networking drivers. The changes are in reachable error paths, and not specific to any particular hardware. It's not vendor-specific or tied to a specialized PCIe card that can't be emulated. Therefore, it's definitely worth fuzzing. My next step is to identify `FocusSymbols` and `EnableConfigs`. Based on the instructions, the `FocusSymbols` are the non-static, exported entry points modified by or directly involved in the patch: `phy_attach_direct`, `phy_detach`, `phylink_connect_phy`, `phylink_disconnect_phy`, `phylink_of_phy_connect`, `phylink_fwnode_phy_connect`. The required `EnableConfigs` appear to be `PHYLIB` and `PHYLINK` from the driver's makefile. So, in summary: I've identified critical logic, relevant symbols, and required configuration options for further fuzzing analysis. This patch modifies reachable, core kernel logic and warrants further investigation via fuzzing. |
| 28/2 | 2026/08/27 21:54 | tool | grepper |
0mArgs:{
"Expression": "source \"drivers/net/phy/Kconfig\"",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "drivers/net/Kconfig=512=source \"drivers/net/ipa/Kconfig\"\ndrivers/net/Kconfig-513-\ndrivers/net/Kconfig:514:source \"drivers/net/phy/Kconfig\"\ndrivers/net/Kconfig-515-\n"
} |
| 29/2 | 2026/08/27 21:54 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 58498 output: 32 thoughts: 29 Thoughts: Here's my take: **Investigating Network Driver Configuration** Okay, time to dive into this. Based on what I'm looking at, my initial focus is going to be on the `drivers/net/Kconfig` file. I need to pinpoint the relevant configuration options that are controlling this particular aspect of the network stack. Specifically, I'll start by taking a look at line 514 and, generally speaking, the beginning of the `drivers/net/Kconfig` file. That should give me the broader context and likely some key dependencies or parent options that influence the behavior I'm seeing. This is where the magic happens, and I need to see what's set up here in `Kconfig`. This should lead me to the necessary information. |
| 30/2 | 2026/08/27 21:54 | tool | read-file |
0mArgs:{
"File": "drivers/net/Kconfig",
"FirstLine": 1,
"LineCount": 40
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\t#\n 3:\t# Network device configuration\n 4:\t#\n 5:\t\n 6:\tmenuconfig NETDEVICES\n 7:\t\tdefault y if UML\n 8:\t\tdepends on NET\n 9:\t\tbool \"Network device support\"\n 10:\t\thelp\n 11:\t\t You can say N here if you don't intend to connect your Linux box to\n 12:\t\t any other computer at all.\n 13:\t\n 14:\t\t You'll have to say Y if your computer contains a network card that\n 15:\t\t you want to use under Linux. If you are going to run SLIP or PPP over\n 16:\t\t telephone line or null modem cable you need say Y here. Connecting\n 17:\t\t two machines with parallel ports using PLIP needs this, as well as\n 18:\t\t AX.25/KISS for sending Internet traffic over amateur radio links.\n 19:\t\n 20:\t\t See also \"The Linux Network Administrator's Guide\" by Olaf Kirch and\n 21:\t\t Terry Dawson. Available at \u003chttp://www.tldp.org/guides.html\u003e.\n 22:\t\n 23:\t\t If unsure, say Y.\n 24:\t\n 25:\t# All the following symbols are dependent on NETDEVICES - do not repeat\n 26:\t# that for each of the symbols.\n 27:\tif NETDEVICES\n 28:\t\n 29:\tconfig MII\n 30:\t\ttristate\n 31:\t\n 32:\tconfig NET_CORE\n 33:\t\tdefault y\n 34:\t\tbool \"Network core driver support\"\n 35:\t\thelp\n 36:\t\t You can say N here if you do not intend to use any of the\n 37:\t\t networking core drivers (i.e. VLAN, bridging, bonding, etc.)\n 38:\t\n 39:\tif NET_CORE\n 40:\t\n"
} |
| 31/2 | 2026/08/27 21:54 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 59238 output: 232 thoughts: 373 Thoughts: **My Analysis of PHY Layer and Phylink Subsystem Changes** Okay, so I've been looking at this patch and, based on the dependencies, here's what I've got. `NETDEVICES` clearly depends on `NET`, and within `NETDEVICES`, we find `PHYLIB`. `PHYLINK` is the component that interacts with and selects between `PHYLIB` and `SWPHY`. To really test this, I need to make sure I've got a way to exercise `phylink` and `phylib`. It looks like drivers like `NET_DSA`, `USB_LAN78XX`, `USB_NET_AX8817X`, or `FIXED_PHY` can be used for that. Therefore, to ensure I can actually test these changes, I'll want to make sure the following configs are enabled: * `NET` * `NETDEVICES` * `PHYLIB` * `PHYLINK` Just to be thorough, I'm going to double-check everything and make sure the formatting is all correct before I continue. The patch focuses on these key functions: * `phy_attach_direct` * `phy_detach` * `phylink_connect_phy` * `phylink_disconnect_phy` * `phylink_of_phy_connect` * `phylink_fwnode_phy_connect` I also note the importance of making sure these configurations are set, as mentioned previously: * `NET` * `NETDEVICES` * `PHYLIB` * `PHYLINK` Looks like this is definitely worth fuzzing. The changes are in core PHY layer and phylink subsystem code (`phy_device.c` and `phylink.c`), specifically addressing error handling and cleanup. The patch ensures that `pl->phydev` is cleared when there is a failure during `phylink_bringup_phy`, preventing stale pointers and ensuring a successful connection. It also restores generic PHY IRQ configuration upon unbind or error using `phy_restore_genphy_irq()`. I can see these code paths are actually reachable in virtualized environments via emulated USB ethernet hardware, for example, the AX88179 or LAN78xx, or even DSA loopback devices. Alright, I'm ready to call `set-results`. |
| 32/2 | 2026/08/27 21:54 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"NET",
"NETDEVICES",
"PHYLIB",
"PHYLINK"
],
"FocusSymbols": [
"phy_attach_direct",
"phy_detach",
"phylink_connect_phy",
"phylink_disconnect_phy",
"phylink_fwnode_phy_connect",
"phylink_of_phy_connect"
],
"Reasoning": "The patch modifies core PHY library and phylink subsystem logic in drivers/net/phy/phy_device.c and drivers/net/phy/phylink.c. It introduces phy_restore_genphy_irq to properly restore PHY interrupt configurations when detaching or failing to attach a generic PHY, and ensures phylink_clear_phydev is called to cleanly detach and reset state if phylink_bringup_phy fails. These changes affect reachable network PHY setup/teardown logic used by emulated network adapters (e.g. USB ethernet adapters and DSA loop devices) in virtualized environments.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"NET",
"NETDEVICES",
"PHYLIB",
"PHYLINK"
],
"FocusSymbols": [
"phy_attach_direct",
"phy_detach",
"phylink_connect_phy",
"phylink_disconnect_phy",
"phylink_fwnode_phy_connect",
"phylink_of_phy_connect"
],
"Reasoning": "The patch modifies core PHY library and phylink subsystem logic in drivers/net/phy/phy_device.c and drivers/net/phy/phylink.c. It introduces phy_restore_genphy_irq to properly restore PHY interrupt configurations when detaching or failing to attach a generic PHY, and ensures phylink_clear_phydev is called to cleanly detach and reset state if phylink_bringup_phy fails. These changes affect reachable network PHY setup/teardown logic used by emulated network adapters (e.g. USB ethernet adapters and DSA loop devices) in virtualized environments.",
"WorthFuzzing": true
} |
| 33/1 | 2026/08/27 21:54 | action | If |
3mArgs:{
"WorthFuzzing": true
}Results: null |
| 34/2 | 2026/08/27 21:54 | agent | kmsan-evaluator |
3mModel:core Args: null Results: {
"KMSANReasoning": "The patch addresses state cleanup and IRQ restoration in PHY and phylink driver lifecycles (specifically restoring phydev-\u003eirq upon generic PHY driver detach/attach failure and clearing pl-\u003ephydev on phylink_bringup_phy failure). \n\nThese changes involve managing object lifecycles, resetting internal pointers to NULL, and resetting boolean flags. No uninitialized memory allocations, uninitialized reads, padding leaks, or user-space copies (copy_to_user/netlink) are introduced or modified. Any lifecycle or dangling pointer issues in this code path fall under KASAN (use-after-free / invalid access) or standard kernel assertions/LOCKDEP, making a dedicated KMSAN session unnecessary.",
"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: For your convenience, here is the diff of the changes:
commit 9c99235c784d6c7dbf643c85db861955014a62a4
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Aug 27 21:35:51 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 94b2e85e00a37..be4c35db8de98 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1734,6 +1734,18 @@ static bool phy_drv_supports_irq(const struct phy_driver *phydrv)
return phydrv->config_intr && phydrv->handle_interrupt;
}
+/* Give back the interrupt phy_probe() parked when a driver with no interrupt
+ * callbacks bound. mdiobus_alloc() defaults bus->irq[] to PHY_POLL and the
+ * bind cycle does not touch the table, so whatever the bus recorded there
+ * still stands. Only the parking is undone: any other value the PHY carries
+ * was put there by someone else.
+ */
+static void phy_restore_genphy_irq(struct phy_device *phydev)
+{
+ if (phydev->irq == PHY_POLL)
+ phydev->irq = phydev->mdio.bus->irq[phydev->mdio.addr];
+}
+
/**
* phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
@@ -1896,6 +1908,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
error_module_put:
module_put(d->driver->owner);
+ phy_restore_genphy_irq(phydev);
phydev->is_genphy_driven = 0;
d->driver = NULL;
error_put_device:
@@ -1965,6 +1978,7 @@ void phy_detach(struct phy_device *phydev)
* real driver could be loaded
*/
if (phydev->is_genphy_driven) {
+ phy_restore_genphy_irq(phydev);
device_release_driver(&phydev->mdio.dev);
phydev->is_genphy_driven = 0;
}
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 5b8e956902fb5..a55e4a64028ff 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2083,6 +2083,18 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
return phylink_validate(pl, supported, state);
}
+/* Disassociate @phy from @pl. Caller must hold pl->phydev_mutex. */
+static void phylink_clear_phydev(struct phylink *pl, struct phy_device *phy)
+{
+ mutex_lock(&phy->lock);
+ mutex_lock(&pl->state_mutex);
+ pl->phydev = NULL;
+ pl->phy_enable_tx_lpi = false;
+ pl->mac_tx_clk_stop = false;
+ mutex_unlock(&pl->state_mutex);
+ mutex_unlock(&phy->lock);
+}
+
static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
phy_interface_t interface)
{
@@ -2197,6 +2209,12 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
if (ret == 0 && phy_interrupt_is_valid(phy))
phy_request_interrupt(phy);
+ if (ret) {
+ mutex_lock(&pl->phydev_mutex);
+ phylink_clear_phydev(pl, phy);
+ mutex_unlock(&pl->phydev_mutex);
+ }
+
return ret;
}
@@ -2347,15 +2365,8 @@ void phylink_disconnect_phy(struct phylink *pl)
mutex_lock(&pl->phydev_mutex);
phy = pl->phydev;
- if (phy) {
- mutex_lock(&phy->lock);
- mutex_lock(&pl->state_mutex);
- pl->phydev = NULL;
- pl->phy_enable_tx_lpi = false;
- pl->mac_tx_clk_stop = false;
- mutex_unlock(&pl->state_mutex);
- mutex_unlock(&phy->lock);
- }
+ if (phy)
+ phylink_clear_phydev(pl, phy);
mutex_unlock(&pl->phydev_mutex);
if (phy) {
|
| 35/3 | 2026/08/27 21:54 | llm | kmsan-evaluator |
1mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 3116 output: 40 thoughts: 302 Thoughts: **Analyzing the PHY Driver Patch** Okay, let's dive into this patch. I need to understand what's being changed in the PHY driver. First, I see modifications in `drivers/net/phy/phy_device.c`. Specifically, there's a new function, `phy_restore_genphy_irq()`. The code snippet there looks like it's trying to re-establish the interrupt configuration for a PHY device. It seems that if the interrupt mode (`phydev->irq`) is set to `PHY_POLL`, it's restoring it to the default interrupt setting, likely derived from the MDIO bus's IRQ information. This function is being called in error handling paths within `phy_attach_direct` and during `phy_detach`. This tells me we're looking at a potential fix for interrupt handling during PHY attachment or detachment, which might be critical for robust network device operation. Next, I'm seeing changes in `drivers/net/phy/phylink.c`. There's a new function, `phylink_clear_phydev()`. The code here resets several fields related to the PHY device within a `phylink` structure. This includes setting `pl->phydev` to `NULL`, along with clearing `phy_enable_tx_lpi` and `mac_tx_clk_stop`. This smells like proper PHY device cleanup, probably on disconnection or in error scenarios. It looks like `phylink_clear_phydev` is being called in `phylink_bringup_phy` as part of error handling, implying that if the PHY initialization fails, the link's PHY device pointer gets cleared. Also, it has been introduced into `phylink_disconnect_phy` as well. This makes sense; it's clean and consistent. Now, I need to understand the larger context. I'll use `read-file` or `grepper` to find the calling sites of `phy_attach_direct`, `phy_detach`, `phylink_bringup_phy` and `phylink_disconnect_phy` to grasp how these functions fit into the overall PHY initialization and teardown sequence. This will reveal the motivations of the patch and where the problem might have existed. I'm especially interested in how the interrupt restoration and PHY device clearing interact, particularly in error cases. Let me dig into the surrounding code to determine how this addresses a particular failure or race condition. |
| 36/3 | 2026/08/27 21:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phy_device.c",
"FirstLine": 1725,
"LineCount": 40
}Results: {
"Contents": "1725:\t\n1726:\t\tif (!ret \u0026\u0026 phydev-\u003esfp_bus)\n1727:\t\t\tret = phy_setup_sfp_port(phydev);\n1728:\t\n1729:\t\treturn ret;\n1730:\t}\n1731:\t\n1732:\tstatic bool phy_drv_supports_irq(const struct phy_driver *phydrv)\n1733:\t{\n1734:\t\treturn phydrv-\u003econfig_intr \u0026\u0026 phydrv-\u003ehandle_interrupt;\n1735:\t}\n1736:\t\n1737:\t/* Give back the interrupt phy_probe() parked when a driver with no interrupt\n1738:\t * callbacks bound. mdiobus_alloc() defaults bus-\u003eirq[] to PHY_POLL and the\n1739:\t * bind cycle does not touch the table, so whatever the bus recorded there\n1740:\t * still stands. Only the parking is undone: any other value the PHY carries\n1741:\t * was put there by someone else.\n1742:\t */\n1743:\tstatic void phy_restore_genphy_irq(struct phy_device *phydev)\n1744:\t{\n1745:\t\tif (phydev-\u003eirq == PHY_POLL)\n1746:\t\t\tphydev-\u003eirq = phydev-\u003emdio.bus-\u003eirq[phydev-\u003emdio.addr];\n1747:\t}\n1748:\t\n1749:\t/**\n1750:\t * phy_attach_direct - attach a network device to a given PHY device pointer\n1751:\t * @dev: network device to attach\n1752:\t * @phydev: Pointer to phy_device to attach\n1753:\t * @flags: PHY device's dev_flags\n1754:\t * @interface: PHY device's interface\n1755:\t *\n1756:\t * Description: Called by drivers to attach to a particular PHY\n1757:\t * device. The phy_device is found, and properly hooked up\n1758:\t * to the phy_driver. If no driver is attached, then a\n1759:\t * generic driver is used. The phy_device is given a ptr to\n1760:\t * the attaching device, and given a callback for link status\n1761:\t * change. The phy_device is returned to the attaching driver.\n1762:\t * This function takes a reference on the phy device.\n1763:\t */\n1764:\tint phy_attach_direct(struct net_device *dev, struct phy_device *phydev,\n"
} |
| 37/3 | 2026/08/27 21:56 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 4663 output: 39 thoughts: 24 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Investigating a Potential Network Link Issue** Okay, so we've got a networking problem. Based on the clues, I need to zoom in on a specific area within the driver. My initial instinct points me towards `phylink.c`. Given the scope of the potential problem, I think the region around lines 2080 to 2220 is a good place to start. That section often deals with [ *insert specific function or area the expert would know based on `phylink.c`'s general role, e.g., "link state detection and PHY interaction, or perhaps initial link negotiation, or maybe even error handling related to speed and duplex mismatches, or register reads/writes related to autonegotiation"*]. I'll need to carefully examine the code in that range, paying close attention to [ *list specific things that the expert would look for, e.g. "error conditions, return values, any potential race conditions, buffer handling or possibly interrupt handling, or interactions with other modules, etc."* ]. I'll start by making sure there's no obvious logic flaw in that section, then maybe I'll dig down into the interactions if I need to. |
| 38/3 | 2026/08/27 21:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/phy/phylink.c",
"FirstLine": 2170,
"LineCount": 50
}Results: {
"Contents": "2170:\t\t\tphylink_caps_to_linkmodes(pl-\u003esupported_lpi,\n2171:\t\t\t\t\t\t pl-\u003econfig-\u003elpi_capabilities);\n2172:\t\n2173:\t\t\t/* Restrict the PHYs EEE support/advertisement to the modes\n2174:\t\t\t * that the MAC supports.\n2175:\t\t\t */\n2176:\t\t\tlinkmode_and(phy-\u003eadvertising_eee, phy-\u003eadvertising_eee,\n2177:\t\t\t\t pl-\u003esupported_lpi);\n2178:\t\t} else if (pl-\u003emac_supports_eee_ops) {\n2179:\t\t\t/* MAC supports phylink EEE, but wants EEE always disabled. */\n2180:\t\t\tphy_disable_eee(phy);\n2181:\t\t}\n2182:\t\n2183:\t\tmutex_unlock(\u0026pl-\u003estate_mutex);\n2184:\t\tmutex_unlock(\u0026phy-\u003elock);\n2185:\t\tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n2186:\t\n2187:\t\tphylink_dbg(pl,\n2188:\t\t\t \"phy: %s setting supported %*pb advertising %*pb\\n\",\n2189:\t\t\t phy_modes(interface),\n2190:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, pl-\u003esupported,\n2191:\t\t\t __ETHTOOL_LINK_MODE_MASK_NBITS, phy-\u003eadvertising);\n2192:\t\n2193:\t\tif (pl-\u003econfig-\u003emac_managed_pm)\n2194:\t\t\tphy-\u003emac_managed_pm = true;\n2195:\t\n2196:\t\t/* Allow the MAC to stop its clock if the PHY has the capability */\n2197:\t\tpl-\u003emac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) \u003e 0;\n2198:\t\n2199:\t\tif (pl-\u003emac_supports_eee_ops) {\n2200:\t\t\t/* Explicitly configure whether the PHY is allowed to stop it's\n2201:\t\t\t * receive clock.\n2202:\t\t\t */\n2203:\t\t\tret = phy_eee_rx_clock_stop(phy,\n2204:\t\t\t\t\t\t pl-\u003econfig-\u003eeee_rx_clk_stop_enable);\n2205:\t\t\tif (ret == -EOPNOTSUPP)\n2206:\t\t\t\tret = 0;\n2207:\t\t}\n2208:\t\n2209:\t\tif (ret == 0 \u0026\u0026 phy_interrupt_is_valid(phy))\n2210:\t\t\tphy_request_interrupt(phy);\n2211:\t\n2212:\t\tif (ret) {\n2213:\t\t\tmutex_lock(\u0026pl-\u003ephydev_mutex);\n2214:\t\t\tphylink_clear_phydev(pl, phy);\n2215:\t\t\tmutex_unlock(\u0026pl-\u003ephydev_mutex);\n2216:\t\t}\n2217:\t\n2218:\t\treturn ret;\n2219:\t}\n"
} |
| 39/3 | 2026/08/27 21:56 | llm | kmsan-evaluator |
1mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 5784 output: 172 thoughts: 661 Thoughts: **My Assessment of the Patch's KMSAN Implications** Okay, let's break this down. My initial thought is to examine the patch's actions within the context of potential KMSAN (Kernel Memory Sanitizer) vulnerabilities. I'm focusing specifically on the risk of uninitialized memory reads or information leaks, remembering that KASAN (Kernel Address Sanitizer) covers the more typical memory lifecycle issues like use-after-free and dangling pointers. First, I looked at the functions involved. `phy_restore_genphy_irq` is interesting. It restores `phydev->irq` from the MDIO bus's `bus->irq` array. This happens during detach or failure. `phylink_clear_phydev` cleans up state pointers, especially when phylink bringup fails. I then went through the KMSAN criteria in my head: 1. **Kernel data exposed to userspace:** Nope. Nothing here involves `copy_to_user`, `put_user`, netlink, ioctl, or any user-space interaction. 2. **Conditional logic on uninitialized data:** Not that I can see. 3. **Uninitialized data structures:** I'm not seeing any new memory allocations that wouldn't have default initialization. 4. **Bounds checks exposing uninitialized memory:** Nope. So, digging deeper, `bus->irq` is allocated and initialized by `mdiobus_alloc()`. Specifically, the contents of the `bus->irq` array are initialized either to PHY_POLL or specific IRQ numbers, preventing accidental use of uninitialized memory. `phylink_clear_phydev` sets fields to NULL or false, which is the cleanup stage. The error handling ensures `pl->phydev` is set to NULL on failure in `phylink_bringup_phy`, eliminating a dangling pointer. Consequently, this seems like purely state cleanup, lifecycle management, and IRQ restoration. KASAN is the right tool here for use-after-free or dangling pointers, and it will pick up those issues. This patch, based on my analysis, does *not* introduce any KMSAN concerns. I see no allocation, copying, or exposure of uninitialized memory. Finally, just to be completely clear in my reasoning, I'll solidify the comparison of KASAN and KMSAN. This patch focuses on clean lifecycle management within the kernel, making it a KASAN issue. KASAN will detect dangling pointers and use-after-free issues in the phylink/phy_device attach/detach paths. KMSAN deals with uninitialized memory reads or leaks *to user space*. This patch doesn't involve any of that. The restoring of `phydev->irq` uses data from a bus that is initialized by `mdiobus_alloc()`. No uninitialized memory is allocated, read, or copied to user space. Therefore, I'm confident in calling this `NeedsKMSAN` as `false`. |
| 40/3 | 2026/08/27 21:58 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch addresses state cleanup and IRQ restoration in PHY and phylink driver lifecycles (specifically restoring phydev-\u003eirq upon generic PHY driver detach/attach failure and clearing pl-\u003ephydev on phylink_bringup_phy failure). \n\nThese changes involve managing object lifecycles, resetting internal pointers to NULL, and resetting boolean flags. No uninitialized memory allocations, uninitialized reads, padding leaks, or user-space copies (copy_to_user/netlink) are introduced or modified. Any lifecycle or dangling pointer issues in this code path fall under KASAN (use-after-free / invalid access) or standard kernel assertions/LOCKDEP, making a dedicated KMSAN session unnecessary.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch addresses state cleanup and IRQ restoration in PHY and phylink driver lifecycles (specifically restoring phydev-\u003eirq upon generic PHY driver detach/attach failure and clearing pl-\u003ephydev on phylink_bringup_phy failure). \n\nThese changes involve managing object lifecycles, resetting internal pointers to NULL, and resetting boolean flags. No uninitialized memory allocations, uninitialized reads, padding leaks, or user-space copies (copy_to_user/netlink) are introduced or modified. Any lifecycle or dangling pointer issues in this code path fall under KASAN (use-after-free / invalid access) or standard kernel assertions/LOCKDEP, making a dedicated KMSAN session unnecessary.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|