diff mbox series

[net-next,v3,4/8] net: txgbe: Add SFP module identify

Message ID 20230419082739.295180-5-jiawenwu@trustnetic.com
State Superseded
Headers show
Series TXGBE PHYLINK support | expand

Commit Message

Jiawen Wu April 19, 2023, 8:27 a.m. UTC
Register SFP platform device to get modules information.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/ethernet/wangxun/Kconfig          |  1 +
 .../net/ethernet/wangxun/txgbe/txgbe_phy.c    | 27 +++++++++++++++++++
 .../net/ethernet/wangxun/txgbe/txgbe_type.h   |  1 +
 3 files changed, 29 insertions(+)

Comments

Vladimir Oltean April 19, 2023, 1:55 p.m. UTC | #1
On Wed, Apr 19, 2023 at 04:27:35PM +0800, Jiawen Wu wrote:
> +	ret = txgbe_sfp_register(txgbe);
> +	if (ret) {
> +		wx_err(txgbe->wx, "failed to register sfp\n");
> +		goto err;
> +	}

The usual error handling pattern is to jump to specific labels within
the error unwind code path (which duplicates the normal teardown path
except for the first operation), rather than calling the single cleanup
function - here txgbe_remove_phy() - and filling that with "if" conditions.
Normally (at least in the networking layer except for Qdiscs, that's all
I know), one would expect that if txgbe_init_phy() fails, txgbe_remove_phy()
is never called. So, given that expectation, txgbe->sfp_dev would never
be NULL.

> +
>  	return 0;
>  
>  err:
> @@ -131,6 +156,8 @@ int txgbe_init_phy(struct txgbe *txgbe)
>  
>  void txgbe_remove_phy(struct txgbe *txgbe)
>  {
> +	if (txgbe->sfp_dev)
> +		platform_device_unregister(txgbe->sfp_dev);
>  	if (txgbe->i2c_dev)
>  		platform_device_unregister(txgbe->i2c_dev);
>  
> diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
> index 771aefbc7c80..aa94c4fce311 100644
> --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
> +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
> @@ -149,6 +149,7 @@ struct txgbe_nodes {
>  struct txgbe {
>  	struct wx *wx;
>  	struct txgbe_nodes nodes;
> +	struct platform_device *sfp_dev;
>  	struct platform_device *i2c_dev;
>  };
>  
> -- 
> 2.27.0
>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/wangxun/Kconfig b/drivers/net/ethernet/wangxun/Kconfig
index 8acd6a0d84dc..d2dbaf19e53d 100644
--- a/drivers/net/ethernet/wangxun/Kconfig
+++ b/drivers/net/ethernet/wangxun/Kconfig
@@ -42,6 +42,7 @@  config TXGBE
 	depends on PCI
 	select I2C_DESIGNWARE_PLATFORM
 	select LIBWX
+	select SFP
 	help
 	  This driver supports Wangxun(R) 10GbE PCI Express family of
 	  adapters.
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
index 8bb7f1d9acc7..faa0479f1df3 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -105,6 +105,25 @@  static int txgbe_i2c_register(struct txgbe *txgbe)
 	return 0;
 }
 
+static int txgbe_sfp_register(struct txgbe *txgbe)
+{
+	struct pci_dev *pdev = txgbe->wx->pdev;
+	struct platform_device_info info = {};
+	struct platform_device *sfp_dev;
+
+	info.parent = &pdev->dev;
+	info.fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_SFP]);
+	info.name = "sfp";
+	info.id = (pdev->bus->number << 8) | pdev->devfn;
+	sfp_dev = platform_device_register_full(&info);
+	if (IS_ERR(sfp_dev))
+		return PTR_ERR(sfp_dev);
+
+	txgbe->sfp_dev = sfp_dev;
+
+	return 0;
+}
+
 int txgbe_init_phy(struct txgbe *txgbe)
 {
 	int ret;
@@ -121,6 +140,12 @@  int txgbe_init_phy(struct txgbe *txgbe)
 		goto err;
 	}
 
+	ret = txgbe_sfp_register(txgbe);
+	if (ret) {
+		wx_err(txgbe->wx, "failed to register sfp\n");
+		goto err;
+	}
+
 	return 0;
 
 err:
@@ -131,6 +156,8 @@  int txgbe_init_phy(struct txgbe *txgbe)
 
 void txgbe_remove_phy(struct txgbe *txgbe)
 {
+	if (txgbe->sfp_dev)
+		platform_device_unregister(txgbe->sfp_dev);
 	if (txgbe->i2c_dev)
 		platform_device_unregister(txgbe->i2c_dev);
 
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
index 771aefbc7c80..aa94c4fce311 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
@@ -149,6 +149,7 @@  struct txgbe_nodes {
 struct txgbe {
 	struct wx *wx;
 	struct txgbe_nodes nodes;
+	struct platform_device *sfp_dev;
 	struct platform_device *i2c_dev;
 };