[PATCH 04/12] net: phy: unify get_phy_device and phy_device_create parameter list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently these two public APIs are used to create a 'struct phy_device'
device. In addition to that the device get_phy_device() can adapt the
is_c45 parameter as well if supprted by the mii bus.

Both APIs do have a different set of parameters which can be unified to
upcoming API extension. For this the 'struct phy_device_config' is
introduced which is the only parameter for both functions. This new
mechnism also adds the possiblity to read the configuration back within
the driver for possible validation checks.

Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx>
---
 drivers/net/ethernet/adi/adin1110.c               |  6 ++-
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c       |  8 +++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 11 +++--
 drivers/net/ethernet/socionext/netsec.c           |  7 ++-
 drivers/net/mdio/fwnode_mdio.c                    | 13 +++---
 drivers/net/mdio/mdio-xgene.c                     |  6 ++-
 drivers/net/phy/fixed_phy.c                       |  6 ++-
 drivers/net/phy/mdio_bus.c                        |  7 ++-
 drivers/net/phy/nxp-tja11xx.c                     | 23 +++++-----
 drivers/net/phy/phy_device.c                      | 55 ++++++++++++-----------
 drivers/net/phy/sfp.c                             |  7 ++-
 include/linux/phy.h                               | 29 +++++++++---
 12 files changed, 121 insertions(+), 57 deletions(-)

diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c
index 3f316a0f4158..01b0c2a3a294 100644
--- a/drivers/net/ethernet/adi/adin1110.c
+++ b/drivers/net/ethernet/adi/adin1110.c
@@ -1565,6 +1565,9 @@ static int adin1110_probe_netdevs(struct adin1110_priv *priv)
 {
 	struct device *dev = &priv->spidev->dev;
 	struct adin1110_port_priv *port_priv;
+	struct phy_device_config config = {
+		.mii_bus = priv->mii_bus,
+	};
 	struct net_device *netdev;
 	int ret;
 	int i;
@@ -1599,7 +1602,8 @@ static int adin1110_probe_netdevs(struct adin1110_priv *priv)
 		netdev->priv_flags |= IFF_UNICAST_FLT;
 		netdev->features |= NETIF_F_NETNS_LOCAL;
 
-		port_priv->phydev = get_phy_device(priv->mii_bus, i + 1, false);
+		config.phy_addr = i + 1;
+		port_priv->phydev = get_phy_device(&config);
 		if (IS_ERR(port_priv->phydev)) {
 			netdev_err(netdev, "Could not find PHY with device address: %d.\n", i);
 			return PTR_ERR(port_priv->phydev);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index 16e7fb2c0dae..27ba903bbd0a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -1056,6 +1056,10 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)
 {
 	struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	struct phy_device_config config = {
+		.mii_bus = phy_data->mii,
+		.phy_addr = phy_data->mdio_addr,
+	};
 	struct phy_device *phydev;
 	int ret;
 
@@ -1086,8 +1090,8 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)
 	}
 
 	/* Create and connect to the PHY device */
-	phydev = get_phy_device(phy_data->mii, phy_data->mdio_addr,
-				(phy_data->phydev_mode == XGBE_MDIO_MODE_CL45));
+	config.is_c45 = phy_data->phydev_mode == XGBE_MDIO_MODE_CL45;
+	phydev = get_phy_device(&config);
 	if (IS_ERR(phydev)) {
 		netdev_err(pdata->netdev, "get_phy_device failed\n");
 		return -ENODEV;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 928d934cb21a..3c41c4db5d9b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -687,9 +687,12 @@ static int
 hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb,
 			u32 addr)
 {
+	struct phy_device_config config = {
+		.mii_bus = mdio,
+		.phy_addr = addr,
+	};
 	struct phy_device *phy;
 	const char *phy_type;
-	bool is_c45;
 	int rc;
 
 	rc = fwnode_property_read_string(mac_cb->fw_port,
@@ -698,13 +701,13 @@ hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb,
 		return rc;
 
 	if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_XGMII)))
-		is_c45 = true;
+		config.is_c45 = true;
 	else if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_SGMII)))
-		is_c45 = false;
+		config.is_c45 = false;
 	else
 		return -ENODATA;
 
-	phy = get_phy_device(mdio, addr, is_c45);
+	phy = get_phy_device(&config);
 	if (!phy || IS_ERR(phy))
 		return -EIO;
 
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 2d7347b71c41..a0786dfb827a 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -1948,6 +1948,11 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr)
 			return ret;
 		}
 	} else {
+		struct phy_device_config config = {
+			.mii_bus = bus,
+			.phy_addr = phy_addr,
+		};
+
 		/* Mask out all PHYs from auto probing. */
 		bus->phy_mask = ~0;
 		ret = mdiobus_register(bus);
@@ -1956,7 +1961,7 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr)
 			return ret;
 		}
 
-		priv->phydev = get_phy_device(bus, phy_addr, false);
+		priv->phydev = get_phy_device(&config);
 		if (IS_ERR(priv->phydev)) {
 			ret = PTR_ERR(priv->phydev);
 			dev_err(priv->dev, "get_phy_device err(%d)\n", ret);
diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index 1183ef5e203e..47ef702d4ffd 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -112,10 +112,13 @@ EXPORT_SYMBOL(fwnode_mdiobus_phy_device_register);
 int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 				struct fwnode_handle *child, u32 addr)
 {
+	struct phy_device_config config = {
+		.mii_bus = bus,
+		.phy_addr = addr,
+	};
 	struct mii_timestamper *mii_ts = NULL;
 	struct pse_control *psec = NULL;
 	struct phy_device *phy;
-	bool is_c45;
 	u32 phy_id;
 	int rc;
 
@@ -129,11 +132,11 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 		goto clean_pse;
 	}
 
-	is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45");
-	if (is_c45 || fwnode_get_phy_id(child, &phy_id))
-		phy = get_phy_device(bus, addr, is_c45);
+	config.is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45");
+	if (config.is_c45 || fwnode_get_phy_id(child, &config.phy_id))
+		phy = get_phy_device(&config);
 	else
-		phy = phy_device_create(bus, addr, phy_id, 0, NULL);
+		phy = phy_device_create(&config);
 	if (IS_ERR(phy)) {
 		rc = PTR_ERR(phy);
 		goto clean_mii_ts;
diff --git a/drivers/net/mdio/mdio-xgene.c b/drivers/net/mdio/mdio-xgene.c
index 7aafc221b5cf..6754c35aa6c3 100644
--- a/drivers/net/mdio/mdio-xgene.c
+++ b/drivers/net/mdio/mdio-xgene.c
@@ -262,9 +262,13 @@ static int xgene_xfi_mdio_read(struct mii_bus *bus, int phy_id, int reg)
 
 struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr)
 {
+	struct phy_device_config config = {
+		.mii_bus = bus,
+		.phy_addr = phy_addr,
+	};
 	struct phy_device *phy_dev;
 
-	phy_dev = get_phy_device(bus, phy_addr, false);
+	phy_dev = get_phy_device(&config);
 	if (!phy_dev || IS_ERR(phy_dev))
 		return NULL;
 
diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c
index aef739c20ac4..d217301a71d1 100644
--- a/drivers/net/phy/fixed_phy.c
+++ b/drivers/net/phy/fixed_phy.c
@@ -229,6 +229,9 @@ static struct phy_device *__fixed_phy_register(unsigned int irq,
 					       struct gpio_desc *gpiod)
 {
 	struct fixed_mdio_bus *fmb = &platform_fmb;
+	struct phy_device_config config = {
+		.mii_bus = fmb->mii_bus,
+	};
 	struct phy_device *phy;
 	int phy_addr;
 	int ret;
@@ -254,7 +257,8 @@ static struct phy_device *__fixed_phy_register(unsigned int irq,
 		return ERR_PTR(ret);
 	}
 
-	phy = get_phy_device(fmb->mii_bus, phy_addr, false);
+	config.phy_addr = phy_addr;
+	phy = get_phy_device(&config);
 	if (IS_ERR(phy)) {
 		fixed_phy_del(phy_addr);
 		return ERR_PTR(-EINVAL);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 389f33a12534..8390db7ae4bc 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -516,9 +516,14 @@ static int mdiobus_create_device(struct mii_bus *bus,
 static struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr, bool c45)
 {
 	struct phy_device *phydev = ERR_PTR(-ENODEV);
+	struct phy_device_config config = {
+		.mii_bus = bus,
+		.phy_addr = addr,
+		.is_c45 = c45,
+	};
 	int err;
 
-	phydev = get_phy_device(bus, addr, c45);
+	phydev = get_phy_device(&config);
 	if (IS_ERR(phydev))
 		return phydev;
 
diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c
index ec91e671f8aa..b5e03d66b7f5 100644
--- a/drivers/net/phy/nxp-tja11xx.c
+++ b/drivers/net/phy/nxp-tja11xx.c
@@ -554,17 +554,20 @@ static void tja1102_p1_register(struct work_struct *work)
 	struct device *dev = &phydev_phy0->mdio.dev;
 	struct device_node *np = dev->of_node;
 	struct device_node *child;
-	int ret;
 
 	for_each_available_child_of_node(np, child) {
+		struct phy_device_config config = {
+			.mii_bus = bus,
+			/* Real PHY ID of Port 1 is 0 */
+			.phy_id = PHY_ID_TJA1102,
+		};
 		struct phy_device *phy;
-		int addr;
 
-		addr = of_mdio_parse_addr(dev, child);
-		if (addr < 0) {
+		config.phy_addr = of_mdio_parse_addr(dev, child);
+		if (config.phy_addr < 0) {
 			dev_err(dev, "Can't parse addr\n");
 			continue;
-		} else if (addr != phydev_phy0->mdio.addr + 1) {
+		} else if (config.phy_addr != phydev_phy0->mdio.addr + 1) {
 			/* Currently we care only about double PHY chip TJA1102.
 			 * If some day NXP will decide to bring chips with more
 			 * PHYs, this logic should be reworked.
@@ -574,16 +577,15 @@ static void tja1102_p1_register(struct work_struct *work)
 			continue;
 		}
 
-		if (mdiobus_is_registered_device(bus, addr)) {
+		if (mdiobus_is_registered_device(bus, config.phy_addr)) {
 			dev_err(dev, "device is already registered\n");
 			continue;
 		}
 
-		/* Real PHY ID of Port 1 is 0 */
-		phy = phy_device_create(bus, addr, PHY_ID_TJA1102, false, NULL);
+		phy = phy_device_create(&config);
 		if (IS_ERR(phy)) {
 			dev_err(dev, "Can't create PHY device for Port 1: %i\n",
-				addr);
+				config.phy_addr);
 			continue;
 		}
 
@@ -592,7 +594,8 @@ static void tja1102_p1_register(struct work_struct *work)
 		 */
 		phy->mdio.dev.parent = dev;
 
-		ret = of_mdiobus_phy_device_register(bus, phy, child, addr);
+		ret = of_mdiobus_phy_device_register(bus, phy, child,
+						     config.phy_addr);
 		if (ret) {
 			/* All resources needed for Port 1 should be already
 			 * available for Port 0. Both ports use the same
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e4d08dcfed70..bb465a324eef 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -629,8 +629,10 @@ static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)
 	return 0;
 }
 
-static struct phy_device *phy_device_alloc(struct mii_bus *bus, int addr)
+static struct phy_device *phy_device_alloc(struct phy_device_config *config)
 {
+	struct mii_bus *bus = config->mii_bus;
+	int addr = config->phy_addr;
 	struct phy_device *dev;
 	struct mdio_device *mdiodev;
 
@@ -656,9 +658,15 @@ static struct phy_device *phy_device_alloc(struct mii_bus *bus, int addr)
 	return dev;
 }
 
-static int phy_device_init(struct phy_device *dev, u32 phy_id, bool is_c45,
-			   struct phy_c45_device_ids *c45_ids)
+static int phy_device_init(struct phy_device *dev,
+			   struct phy_device_config *config)
 {
+	struct phy_c45_device_ids *c45_ids = &config->c45_ids;
+	struct mii_bus *bus = config->mii_bus;
+	bool is_c45 = config->is_c45;
+	u32 phy_id = config->phy_id;
+	int addr = config->phy_addr;
+
 	dev->speed = SPEED_UNKNOWN;
 	dev->duplex = DUPLEX_UNKNOWN;
 	dev->pause = 0;
@@ -711,18 +719,16 @@ static int phy_device_init(struct phy_device *dev, u32 phy_id, bool is_c45,
 	return phy_request_driver_module(dev, phy_id);
 }
 
-struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
-				     bool is_c45,
-				     struct phy_c45_device_ids *c45_ids)
+struct phy_device *phy_device_create(struct phy_device_config *config)
 {
 	struct phy_device *dev;
 	int ret;
 
-	dev = phy_device_alloc(bus, addr);
+	dev = phy_device_alloc(config);
 	if (IS_ERR(dev))
 		return dev;
 
-	ret = phy_device_init(dev, phy_id, is_c45, c45_ids);
+	ret = phy_device_init(dev, config);
 	if (ret) {
 		put_device(&dev->mdio.dev);
 		dev = ERR_PTR(ret);
@@ -954,12 +960,16 @@ int fwnode_get_phy_id(struct fwnode_handle *fwnode, u32 *phy_id)
 }
 EXPORT_SYMBOL(fwnode_get_phy_id);
 
-static int phy_device_detect(struct mii_bus *bus, int addr, bool *is_c45,
-			     u32 *phy_id, struct phy_c45_device_ids *c45_ids)
+static int phy_device_detect(struct phy_device_config *config)
 {
+	struct phy_c45_device_ids *c45_ids = &config->c45_ids;
+	struct mii_bus *bus = config->mii_bus;
+	u32 *phy_id = &config->phy_id;
+	bool is_c45 = config->is_c45;
+	int addr = config->phy_addr;
 	int r;
 
-	if (*is_c45)
+	if (is_c45)
 		r = get_phy_c45_ids(bus, addr, c45_ids);
 	else
 		r = get_phy_c22_id(bus, addr, phy_id);
@@ -972,8 +982,8 @@ static int phy_device_detect(struct mii_bus *bus, int addr, bool *is_c45,
 	 * probe with C45 to see if we're able to get a valid PHY ID in the C45
 	 * space, if successful, create the C45 PHY device.
 	 */
-	if (!*is_c45 && *phy_id == 0 && bus->read_c45) {
-		*is_c45 = true;
+	if (!is_c45 && *phy_id == 0 && bus->read_c45) {
+		config->is_c45 = true;
 		return get_phy_c45_ids(bus, addr, c45_ids);
 	}
 
@@ -983,11 +993,9 @@ static int phy_device_detect(struct mii_bus *bus, int addr, bool *is_c45,
 /**
  * get_phy_device - reads the specified PHY device and returns its @phy_device
  *		    struct
- * @bus: the target MII bus
- * @addr: PHY address on the MII bus
- * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
+ * @config: The PHY device config
  *
- * Probe for a PHY at @addr on @bus.
+ * Use the @config parameters to probe for a PHY.
  *
  * When probing for a clause 22 PHY, then read the ID registers. If we find
  * a valid ID, allocate and return a &struct phy_device.
@@ -999,21 +1007,18 @@ static int phy_device_detect(struct mii_bus *bus, int addr, bool *is_c45,
  * Returns an allocated &struct phy_device on success, %-ENODEV if there is
  * no PHY present, or %-EIO on bus access error.
  */
-struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
+struct phy_device *get_phy_device(struct phy_device_config *config)
 {
-	struct phy_c45_device_ids c45_ids;
-	u32 phy_id = 0;
+	struct phy_c45_device_ids *c45_ids = &config->c45_ids;
 	int r;
 
-	c45_ids.devices_in_package = 0;
-	c45_ids.mmds_present = 0;
-	memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids));
+	memset(c45_ids->device_ids, 0xff, sizeof(c45_ids->device_ids));
 
-	r = phy_device_detect(bus, addr, &is_c45, &phy_id, &c45_ids);
+	r = phy_device_detect(config);
 	if (r)
 		return ERR_PTR(r);
 
-	return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
+	return phy_device_create(config);
 }
 EXPORT_SYMBOL(get_phy_device);
 
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index f0fcb06fbe82..8fb0a1a49aaf 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1635,10 +1635,15 @@ static void sfp_sm_phy_detach(struct sfp *sfp)
 
 static int sfp_sm_probe_phy(struct sfp *sfp, int addr, bool is_c45)
 {
+	struct phy_device_config config = {
+		.mii_bus = sfp->i2c_mii,
+		.phy_addr = addr,
+		.is_c45 = is_c45,
+	};
 	struct phy_device *phy;
 	int err;
 
-	phy = get_phy_device(sfp->i2c_mii, addr, is_c45);
+	phy = get_phy_device(&config);
 	if (phy == ERR_PTR(-ENODEV))
 		return PTR_ERR(phy);
 	if (IS_ERR(phy)) {
diff --git a/include/linux/phy.h b/include/linux/phy.h
index c17a98712555..498f4dc7669d 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -756,6 +756,27 @@ static inline struct phy_device *to_phy_device(const struct device *dev)
 	return container_of(to_mdio_device(dev), struct phy_device, mdio);
 }
 
+/**
+ * struct phy_device_config - Configuration of a PHY
+ *
+ * @mii_bus: The target MII bus the PHY is connected to
+ * @phy_addr: PHY address on the MII bus
+ * @phy_id: UID for this device found during discovery
+ * @c45_ids: 802.3-c45 Device Identifiers if is_c45.
+ * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
+ *
+ * The struct contain possible configuration parameters for a PHY device which
+ * are used to setup the struct phy_device.
+ */
+
+struct phy_device_config {
+	struct mii_bus *mii_bus;
+	int phy_addr;
+	u32 phy_id;
+	struct phy_c45_device_ids c45_ids;
+	bool is_c45;
+};
+
 /**
  * struct phy_tdr_config - Configuration of a TDR raw test
  *
@@ -1538,9 +1559,7 @@ int phy_modify_paged_changed(struct phy_device *phydev, int page, u32 regnum,
 int phy_modify_paged(struct phy_device *phydev, int page, u32 regnum,
 		     u16 mask, u16 set);
 
-struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
-				     bool is_c45,
-				     struct phy_c45_device_ids *c45_ids);
+struct phy_device *phy_device_create(struct phy_device_config *config);
 void phy_device_set_miits(struct phy_device *phydev,
 			  struct mii_timestamper *mii_ts);
 #if IS_ENABLED(CONFIG_PHYLIB)
@@ -1549,7 +1568,7 @@ struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode);
 struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode);
 struct phy_device *device_phy_find_device(struct device *dev);
 struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode);
-struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
+struct phy_device *get_phy_device(struct phy_device_config *config);
 int phy_device_register(struct phy_device *phy);
 void phy_device_free(struct phy_device *phydev);
 #else
@@ -1581,7 +1600,7 @@ struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
 }
 
 static inline
-struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
+struct phy_device *get_phy_device(struct phy_device_config *config)
 {
 	return NULL;
 }

-- 
2.39.2




[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux