Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: pse-pd: Introduce attached_phydev to pse control

In preparation for reporting PSE events via ethtool notifications,
introduce an attached_phydev field in the pse_control structure.
This field stores the phy_device associated with the PSE PI,
ensuring that notifications are sent to the correct network
interface.

The attached_phydev pointer is directly tied to the PHY lifecycle. It
is set when the PHY is registered and cleared when the PHY is removed.
There is no need to use a refcount, as doing so could interfere with
the PHY removal process.

Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-1-78a1a645e2ee@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kory Maincent (Dent Project) and committed by
Jakub Kicinski
fa2f0454 a5b4e4f4

+26 -17
+14 -12
drivers/net/mdio/fwnode_mdio.c
··· 18 18 MODULE_DESCRIPTION("FWNODE MDIO bus (Ethernet PHY) accessors"); 19 19 20 20 static struct pse_control * 21 - fwnode_find_pse_control(struct fwnode_handle *fwnode) 21 + fwnode_find_pse_control(struct fwnode_handle *fwnode, 22 + struct phy_device *phydev) 22 23 { 23 24 struct pse_control *psec; 24 25 struct device_node *np; ··· 31 30 if (!np) 32 31 return NULL; 33 32 34 - psec = of_pse_control_get(np); 33 + psec = of_pse_control_get(np, phydev); 35 34 if (PTR_ERR(psec) == -ENOENT) 36 35 return NULL; 37 36 ··· 129 128 u32 phy_id; 130 129 int rc; 131 130 132 - psec = fwnode_find_pse_control(child); 133 - if (IS_ERR(psec)) 134 - return PTR_ERR(psec); 135 - 136 131 mii_ts = fwnode_find_mii_timestamper(child); 137 - if (IS_ERR(mii_ts)) { 138 - rc = PTR_ERR(mii_ts); 139 - goto clean_pse; 140 - } 132 + if (IS_ERR(mii_ts)) 133 + return PTR_ERR(mii_ts); 141 134 142 135 is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"); 143 136 if (is_c45 || fwnode_get_phy_id(child, &phy_id)) ··· 164 169 goto clean_phy; 165 170 } 166 171 172 + psec = fwnode_find_pse_control(child, phy); 173 + if (IS_ERR(psec)) { 174 + rc = PTR_ERR(psec); 175 + goto unregister_phy; 176 + } 177 + 167 178 phy->psec = psec; 168 179 169 180 /* phy->mii_ts may already be defined by the PHY driver. A ··· 181 180 182 181 return 0; 183 182 183 + unregister_phy: 184 + if (is_acpi_node(child) || is_of_node(child)) 185 + phy_device_remove(phy); 184 186 clean_phy: 185 187 phy_device_free(phy); 186 188 clean_mii_ts: 187 189 unregister_mii_timestamper(mii_ts); 188 - clean_pse: 189 - pse_control_put(psec); 190 190 191 191 return rc; 192 192 }
+8 -3
drivers/net/pse-pd/pse_core.c
··· 23 23 * @list: list entry for the pcdev's PSE controller list 24 24 * @id: ID of the PSE line in the PSE controller device 25 25 * @refcnt: Number of gets of this pse_control 26 + * @attached_phydev: PHY device pointer attached by the PSE control 26 27 */ 27 28 struct pse_control { 28 29 struct pse_controller_dev *pcdev; ··· 31 30 struct list_head list; 32 31 unsigned int id; 33 32 struct kref refcnt; 33 + struct phy_device *attached_phydev; 34 34 }; 35 35 36 36 static int of_load_single_pse_pi_pairset(struct device_node *node, ··· 601 599 EXPORT_SYMBOL_GPL(pse_control_put); 602 600 603 601 static struct pse_control * 604 - pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index) 602 + pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index, 603 + struct phy_device *phydev) 605 604 { 606 605 struct pse_control *psec; 607 606 int ret; ··· 641 638 psec->pcdev = pcdev; 642 639 list_add(&psec->list, &pcdev->pse_control_head); 643 640 psec->id = index; 641 + psec->attached_phydev = phydev; 644 642 kref_init(&psec->refcnt); 645 643 646 644 return psec; ··· 697 693 return pse_spec->args[0]; 698 694 } 699 695 700 - struct pse_control *of_pse_control_get(struct device_node *node) 696 + struct pse_control *of_pse_control_get(struct device_node *node, 697 + struct phy_device *phydev) 701 698 { 702 699 struct pse_controller_dev *r, *pcdev; 703 700 struct of_phandle_args args; ··· 748 743 } 749 744 750 745 /* pse_list_mutex also protects the pcdev's pse_control list */ 751 - psec = pse_control_get_internal(pcdev, psec_id); 746 + psec = pse_control_get_internal(pcdev, psec_id, phydev); 752 747 753 748 out: 754 749 mutex_unlock(&pse_list_mutex);
+4 -2
include/linux/pse-pd/pse.h
··· 250 250 int devm_pse_controller_register(struct device *dev, 251 251 struct pse_controller_dev *pcdev); 252 252 253 - struct pse_control *of_pse_control_get(struct device_node *node); 253 + struct pse_control *of_pse_control_get(struct device_node *node, 254 + struct phy_device *phydev); 254 255 void pse_control_put(struct pse_control *psec); 255 256 256 257 int pse_ethtool_get_status(struct pse_control *psec, ··· 269 268 270 269 #else 271 270 272 - static inline struct pse_control *of_pse_control_get(struct device_node *node) 271 + static inline struct pse_control *of_pse_control_get(struct device_node *node, 272 + struct phy_device *phydev) 273 273 { 274 274 return ERR_PTR(-ENOENT); 275 275 }