diff mbox series

[net-next,v3,5/7] net: tn40xx: create software node for mdio and phy and add to mdiobus

Message ID 20241217-tn9510-v3a-v3-5-4d5ef6f686e0@gmx.net (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: tn40xx: add support for AQR105 based cards | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 15 this patch: 15
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 163 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-12-19--12-00 (tests: 881)

Commit Message

Hans-Frieder Vogt via B4 Relay Dec. 17, 2024, 9:07 p.m. UTC
From: Hans-Frieder Vogt <hfdevel@gmx.net>

Create a software node for the mdio function, with a child node for the
Aquantia AQR105 PHY, providing a firmware-name (and a bit more, which may
be used for future checks) to allow the PHY to load a MAC specific
firmware from the file system.

The name of the PHY software node follows the naming convention suggested
in the patch for the mdiobus_scan function (in the same patch series).

Signed-off-by: Hans-Frieder Vogt <hfdevel@gmx.net>
---
 drivers/net/ethernet/tehuti/tn40.c      | 10 ++++-
 drivers/net/ethernet/tehuti/tn40.h      | 30 +++++++++++++++
 drivers/net/ethernet/tehuti/tn40_mdio.c | 65 ++++++++++++++++++++++++++++++++-
 3 files changed, 103 insertions(+), 2 deletions(-)

Comments

Andrew Lunn Dec. 19, 2024, 4:45 p.m. UTC | #1
On Tue, Dec 17, 2024 at 10:07:36PM +0100, Hans-Frieder Vogt via B4 Relay wrote:
> From: Hans-Frieder Vogt <hfdevel@gmx.net>
> 
> Create a software node for the mdio function, with a child node for the
> Aquantia AQR105 PHY, providing a firmware-name (and a bit more, which may
> be used for future checks) to allow the PHY to load a MAC specific
> firmware from the file system.
> 
> The name of the PHY software node follows the naming convention suggested
> in the patch for the mdiobus_scan function (in the same patch series).
> 
> Signed-off-by: Hans-Frieder Vogt <hfdevel@gmx.net>
> ---
>  drivers/net/ethernet/tehuti/tn40.c      | 10 ++++-
>  drivers/net/ethernet/tehuti/tn40.h      | 30 +++++++++++++++
>  drivers/net/ethernet/tehuti/tn40_mdio.c | 65 ++++++++++++++++++++++++++++++++-
>  3 files changed, 103 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/tehuti/tn40.c b/drivers/net/ethernet/tehuti/tn40.c
> index 259bdac24cf211113b8f80934feb093d61e46f2d..5f73eb1f7d9f74294cd5546c2ef4797ebc24c052 100644
> --- a/drivers/net/ethernet/tehuti/tn40.c
> +++ b/drivers/net/ethernet/tehuti/tn40.c
> @@ -1778,7 +1778,7 @@ static int tn40_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	ret = tn40_phy_register(priv);
>  	if (ret) {
>  		dev_err(&pdev->dev, "failed to set up PHY.\n");
> -		goto err_free_irq;
> +		goto err_unregister_swnodes;
>  	}
>  
>  	ret = tn40_priv_init(priv);
> @@ -1795,6 +1795,10 @@ static int tn40_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	return 0;
>  err_unregister_phydev:
>  	tn40_phy_unregister(priv);
> +err_unregister_swnodes:
> +	fwnode_handle_put(dev_fwnode(&priv->mdio->dev));
> +	device_remove_software_node(&priv->mdio->dev);
> +	software_node_unregister_node_group(priv->nodes.group);
>  err_free_irq:
>  	pci_free_irq_vectors(pdev);
>  err_unset_drvdata:

This looks pretty unsymmetrical. The swnodes are added in
tn40_mdiobus_init(). I would add an tn40_mdiobus_remove() and call
that as the undo function for tn40_mdiobus_init() during cleanup.

	Andrew
FUJITA Tomonori Dec. 20, 2024, 1:24 a.m. UTC | #2
On Tue, 17 Dec 2024 22:07:36 +0100
Hans-Frieder Vogt via B4 Relay <devnull+hfdevel.gmx.net@kernel.org> wrote:

> From: Hans-Frieder Vogt <hfdevel@gmx.net>
> 
> Create a software node for the mdio function, with a child node for the
> Aquantia AQR105 PHY, providing a firmware-name (and a bit more, which may
> be used for future checks) to allow the PHY to load a MAC specific
> firmware from the file system.
> 
> The name of the PHY software node follows the naming convention suggested
> in the patch for the mdiobus_scan function (in the same patch series).
> 
> Signed-off-by: Hans-Frieder Vogt <hfdevel@gmx.net>
> ---
>  drivers/net/ethernet/tehuti/tn40.c      | 10 ++++-
>  drivers/net/ethernet/tehuti/tn40.h      | 30 +++++++++++++++
>  drivers/net/ethernet/tehuti/tn40_mdio.c | 65 ++++++++++++++++++++++++++++++++-
>  3 files changed, 103 insertions(+), 2 deletions(-)

Boards with QT2025 also creates a software node for AQR105 PHY?
Hans-Frieder Vogt Dec. 20, 2024, 5:48 p.m. UTC | #3
On 20.12.2024 02.24, FUJITA Tomonori wrote:
> On Tue, 17 Dec 2024 22:07:36 +0100
> Hans-Frieder Vogt via B4 Relay <devnull+hfdevel.gmx.net@kernel.org> wrote:
>
>> From: Hans-Frieder Vogt <hfdevel@gmx.net>
>>
>> Create a software node for the mdio function, with a child node for the
>> Aquantia AQR105 PHY, providing a firmware-name (and a bit more, which may
>> be used for future checks) to allow the PHY to load a MAC specific
>> firmware from the file system.
>>
>> The name of the PHY software node follows the naming convention suggested
>> in the patch for the mdiobus_scan function (in the same patch series).
>>
>> Signed-off-by: Hans-Frieder Vogt <hfdevel@gmx.net>
>> ---
>>   drivers/net/ethernet/tehuti/tn40.c      | 10 ++++-
>>   drivers/net/ethernet/tehuti/tn40.h      | 30 +++++++++++++++
>>   drivers/net/ethernet/tehuti/tn40_mdio.c | 65 ++++++++++++++++++++++++++++++++-
>>   3 files changed, 103 insertions(+), 2 deletions(-)
> Boards with QT2025 also creates a software node for AQR105 PHY?
Yes, that's the idea. Of course, creation of the software node could be made
dependent on the actual device, but creating it unconditionally just makes
things a bit easier.
Would you rather prefer to have the software node only created for a device
that is likely to need it?
diff mbox series

Patch

diff --git a/drivers/net/ethernet/tehuti/tn40.c b/drivers/net/ethernet/tehuti/tn40.c
index 259bdac24cf211113b8f80934feb093d61e46f2d..5f73eb1f7d9f74294cd5546c2ef4797ebc24c052 100644
--- a/drivers/net/ethernet/tehuti/tn40.c
+++ b/drivers/net/ethernet/tehuti/tn40.c
@@ -1778,7 +1778,7 @@  static int tn40_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	ret = tn40_phy_register(priv);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to set up PHY.\n");
-		goto err_free_irq;
+		goto err_unregister_swnodes;
 	}
 
 	ret = tn40_priv_init(priv);
@@ -1795,6 +1795,10 @@  static int tn40_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return 0;
 err_unregister_phydev:
 	tn40_phy_unregister(priv);
+err_unregister_swnodes:
+	fwnode_handle_put(dev_fwnode(&priv->mdio->dev));
+	device_remove_software_node(&priv->mdio->dev);
+	software_node_unregister_node_group(priv->nodes.group);
 err_free_irq:
 	pci_free_irq_vectors(pdev);
 err_unset_drvdata:
@@ -1816,6 +1820,10 @@  static void tn40_remove(struct pci_dev *pdev)
 	unregister_netdev(ndev);
 
 	tn40_phy_unregister(priv);
+	/* cleanup software nodes */
+	fwnode_handle_put(dev_fwnode(&priv->mdio->dev));
+	device_remove_software_node(&priv->mdio->dev);
+	software_node_unregister_node_group(priv->nodes.group);
 	pci_free_irq_vectors(priv->pdev);
 	pci_set_drvdata(pdev, NULL);
 	iounmap(priv->regs);
diff --git a/drivers/net/ethernet/tehuti/tn40.h b/drivers/net/ethernet/tehuti/tn40.h
index 490781fe512053d0d2cf0d6e819fc11d078a6733..e083f34f29849186a5ea68ed710a96ba9def116e 100644
--- a/drivers/net/ethernet/tehuti/tn40.h
+++ b/drivers/net/ethernet/tehuti/tn40.h
@@ -4,6 +4,7 @@ 
 #ifndef _TN40_H_
 #define _TN40_H_
 
+#include <linux/property.h>
 #include "tn40_regs.h"
 
 #define TN40_DRV_NAME "tn40xx"
@@ -102,10 +103,39 @@  struct tn40_txdb {
 	int size; /* Number of elements in the db */
 };
 
+#define NODE_PROP(_NAME, _PROP)	(		\
+	(const struct software_node) {		\
+		.name = _NAME,			\
+		.properties = _PROP,		\
+	})
+
+#define NODE_PAR_PROP(_NAME, _PAR, _PROP)	(	\
+	(const struct software_node) {		\
+		.name = _NAME,			\
+		.parent = _PAR,			\
+		.properties = _PROP,		\
+	})
+
+enum tn40_swnodes {
+	SWNODE_MDIO,
+	SWNODE_PHY,
+	SWNODE_MAX
+};
+
+struct tn40_nodes {
+	char phy_name[32];
+	char mdio_name[32];
+	struct property_entry phy_props[3];
+	struct software_node swnodes[SWNODE_MAX];
+	const struct software_node *group[SWNODE_MAX + 1];
+};
+
 struct tn40_priv {
 	struct net_device *ndev;
 	struct pci_dev *pdev;
 
+	struct tn40_nodes nodes;
+
 	struct napi_struct napi;
 	/* RX FIFOs: 1 for data (full) descs, and 2 for free descs */
 	struct tn40_rxd_fifo rxd_fifo0;
diff --git a/drivers/net/ethernet/tehuti/tn40_mdio.c b/drivers/net/ethernet/tehuti/tn40_mdio.c
index af18615d64a8a290c7f79e56260b9aacf82c0386..b8ee553f60d1beadeda828584adfea670f0d4ca8 100644
--- a/drivers/net/ethernet/tehuti/tn40_mdio.c
+++ b/drivers/net/ethernet/tehuti/tn40_mdio.c
@@ -14,6 +14,8 @@ 
 	 (FIELD_PREP(TN40_MDIO_PRTAD_MASK, (port))))
 #define TN40_MDIO_CMD_READ BIT(15)
 
+#define AQR105_FIRMWARE "tehuti/aqr105-tn40xx.cld"
+
 static void tn40_mdio_set_speed(struct tn40_priv *priv, u32 speed)
 {
 	void __iomem *regs = priv->regs;
@@ -111,6 +113,46 @@  static int tn40_mdio_write_c45(struct mii_bus *mii_bus, int addr, int devnum,
 	return  tn40_mdio_write(mii_bus->priv, addr, devnum, regnum, val);
 }
 
+/* registers an mdio node and an aqr105 PHY at address 1
+ * tn40_mdio-%id {
+ *	ethernet-phy@1 {
+ *		compatible = "ethernet-phy-id03a1.b4a3";
+ *		reg = <1>;
+ *		firmware-name = AQR105_FIRMWARE;
+ *	};
+ * };
+ */
+static int tn40_swnodes_register(struct tn40_priv *priv)
+{
+	struct tn40_nodes *nodes = &priv->nodes;
+	struct pci_dev *pdev = priv->pdev;
+	struct software_node *swnodes;
+	u32 id;
+
+	id = pci_dev_id(pdev);
+
+	snprintf(nodes->phy_name, sizeof(nodes->phy_name), "ethernet-phy@1");
+	snprintf(nodes->mdio_name, sizeof(nodes->mdio_name), "tn40_mdio-%x",
+		 id);
+
+	swnodes = nodes->swnodes;
+
+	swnodes[SWNODE_MDIO] = NODE_PROP(nodes->mdio_name, NULL);
+
+	nodes->phy_props[0] = PROPERTY_ENTRY_STRING("compatible",
+						    "ethernet-phy-id03a1.b4a3");
+	nodes->phy_props[1] = PROPERTY_ENTRY_U32("reg", 1);
+	nodes->phy_props[2] = PROPERTY_ENTRY_STRING("firmware-name",
+						    AQR105_FIRMWARE);
+	swnodes[SWNODE_PHY] = NODE_PAR_PROP(nodes->phy_name,
+					    &swnodes[SWNODE_MDIO],
+					    nodes->phy_props);
+
+	nodes->group[SWNODE_PHY] = &swnodes[SWNODE_PHY];
+	nodes->group[SWNODE_MDIO] = &swnodes[SWNODE_MDIO];
+	return software_node_register_node_group(nodes->group);
+}
+
 int tn40_mdiobus_init(struct tn40_priv *priv)
 {
 	struct pci_dev *pdev = priv->pdev;
@@ -130,13 +172,34 @@  int tn40_mdiobus_init(struct tn40_priv *priv)
 	bus->read_c45 = tn40_mdio_read_c45;
 	bus->write_c45 = tn40_mdio_write_c45;
 
+	ret = tn40_swnodes_register(priv);
+	if (ret) {
+		pr_err("swnodes failed\n");
+		return ret;
+	}
+
+	ret = device_add_software_node(&bus->dev,
+				       priv->nodes.group[SWNODE_MDIO]);
+	if (ret) {
+		dev_err(&pdev->dev, "device_add_software_node failed: %d\n",
+			ret);
+	}
+
 	ret = devm_mdiobus_register(&pdev->dev, bus);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register mdiobus %d %u %u\n",
 			ret, bus->state, MDIOBUS_UNREGISTERED);
-		return ret;
+		goto err_swnodes_unregister;
 	}
 	tn40_mdio_set_speed(priv, TN40_MDIO_SPEED_6MHZ);
 	priv->mdio = bus;
 	return 0;
+
+err_swnodes_unregister:
+	fwnode_handle_put(dev_fwnode(&bus->dev));
+	device_remove_software_node(&bus->dev);
+	software_node_unregister_node_group(priv->nodes.group);
+	return ret;
 }
+
+MODULE_FIRMWARE(AQR105_FIRMWARE);