From 76314e98504e691f17a5d9d1362d476c534a5e0e Mon Sep 17 00:00:00 2001
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Date: Fri, 7 Jul 2023 11:14:32 +0800
Subject: [PATCH] 999-2727-net-phy-sfp-add-debug-info.patch

---
 drivers/net/phy/phylink.c     | 11 +++++++-
 drivers/net/phy/sfp-bus.c     |  3 +++
 drivers/net/phy/sfp.c         | 51 +++++++++++++++++++++++++++++------
 include/linux/mdio/mdio-i2c.h | 16 +++++++++++
 4 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 949e3b8..bb4cd28 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -782,6 +782,15 @@ static void phylink_resolve(struct work_struct *w)
 								  &link_state);
 			}
 
+			if (pl->phydev && !(link_state.link & pl->phy_state.link))
+				phylink_printk(KERN_DEBUG, pl,
+					       "resolve link status: system iface=%d, line iface=%d\n",
+					       link_state.link, pl->phy_state.link);
+			else if (!link_state.link)
+				phylink_printk(KERN_DEBUG, pl,
+					       "resolve link status: system iface=%d\n",
+					       link_state.link);
+
 			/* If we have a phy, the "up" state is the union of
 			 * both the PHY and the MAC
 			 */
@@ -2084,7 +2093,7 @@ static int phylink_sfp_config(struct phylink *pl, u8 mode,
 		return ret;
 	}
 
-	phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n",
+	phylink_info(pl, "requesting link mode %s/%s with support %*pb\n",
 		    phylink_an_mode_str(mode), phy_modes(config.interface),
 		    __ETHTOOL_LINK_MODE_MASK_NBITS, support);
 
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 4be2440..bcf45dd 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -279,6 +279,9 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
 	if (bus->sfp_quirk && bus->sfp_quirk->modes)
 		bus->sfp_quirk->modes(id, modes);
 
+	dev_info(bus->sfp_dev, "sfp: support mode %*pb\n",
+		 __ETHTOOL_LINK_MODE_MASK_NBITS, modes);
+
 	bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
 }
 EXPORT_SYMBOL_GPL(sfp_parse_support);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 0fdf5d6..0c335b1 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -480,7 +480,7 @@ static bool sfp_match(const char *qs, const char *str, size_t len)
 	return !strncmp(qs, str, len);
 }
 
-static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
+static const struct sfp_quirk *sfp_lookup_quirk(struct sfp *sfp, const struct sfp_eeprom_id *id)
 {
 	const struct sfp_quirk *q;
 	unsigned int i;
@@ -493,8 +493,14 @@ static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
 	for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
 		if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
 		    sfp_match(q->part, id->base.vendor_pn, ps) &&
-		    sfp_match(q->revision, id->base.vendor_rev, rs))
+		    sfp_match(q->revision, id->base.vendor_rev, rs)) {
+			dev_info(sfp->dev,
+			         "module %.*s %.*s rev %.*s has been found in the quirk list\n",
+				 (int)sizeof(id->base.vendor_name), id->base.vendor_name,
+				 (int)sizeof(id->base.vendor_pn), id->base.vendor_pn,
+				 (int)sizeof(id->base.vendor_rev), id->base.vendor_rev);
 			return q;
+		}
 
 	return NULL;
 }
@@ -1597,7 +1603,7 @@ static void sfp_hwmon_exit(struct sfp *sfp)
 /* Helpers */
 static void sfp_module_tx_disable(struct sfp *sfp)
 {
-	dev_dbg(sfp->dev, "tx disable %u -> %u\n",
+	dev_info(sfp->dev, "tx disable %u -> %u\n",
 		sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 1);
 	sfp->state |= SFP_F_TX_DISABLE;
 	sfp_set_state(sfp, sfp->state);
@@ -1605,7 +1611,7 @@ static void sfp_module_tx_disable(struct sfp *sfp)
 
 static void sfp_module_tx_enable(struct sfp *sfp)
 {
-	dev_dbg(sfp->dev, "tx disable %u -> %u\n",
+	dev_info(sfp->dev, "tx disable %u -> %u\n",
 		sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 0);
 	sfp->state &= ~SFP_F_TX_DISABLE;
 	sfp_set_state(sfp, sfp->state);
@@ -1660,7 +1666,8 @@ 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 *phy;
-	int err;
+	int err, i;
+	u32 id;
 
 	phy = get_phy_device(sfp->i2c_mii, addr, is_c45);
 	if (phy == ERR_PTR(-ENODEV))
@@ -1677,6 +1684,30 @@ static int sfp_sm_probe_phy(struct sfp *sfp, int addr, bool is_c45)
 		return err;
 	}
 
+	if (phy->is_c45) {
+		for (i = 0; i < ARRAY_SIZE(phy->c45_ids.device_ids); i++) {
+			id = phy->c45_ids.device_ids[i];
+			if (id == 0xffffffff)
+				continue;
+
+			dev_info(sfp->dev,
+				 "CL45 PHY device [0x%04x:0x%04x] found!\n",
+				 (id >> 16) & 0xffff, id & 0xffff);
+		}
+	} else {
+		id = phy->phy_id;
+		dev_info(sfp->dev,
+			 "CL22 PHY device [0x%04x:0x%04x] found!\n",
+			 (id >> 16) & 0xffff, id & 0xffff);
+	}
+
+	dev_info(sfp->dev, "CL%s PHY driver [%s] found!\n",
+		 phy->is_c45 ? "45" : "22",
+		 phy->drv ? phy->drv->name : "not");
+
+	dev_info(sfp->dev, "phy: support mode %*pb\n",
+		__ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported);
+
 	err = sfp_add_phy(sfp->sfp_bus, phy);
 	if (err) {
 		phy_device_remove(phy);
@@ -1779,6 +1810,10 @@ static int sfp_sm_add_mdio_bus(struct sfp *sfp)
 static int sfp_sm_probe_for_phy(struct sfp *sfp)
 {
 	int err = 0;
+	struct phy_device *phy;
+
+	dev_info(sfp->dev, "probing phy device through the [%s] protocol\n",
+	         mdio_i2c_proto_type(sfp->mdio_protocol));
 
 	switch (sfp->mdio_protocol) {
 	case MDIO_I2C_NONE:
@@ -2090,7 +2125,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
 	else
 		sfp->mdio_protocol = MDIO_I2C_NONE;
 
-	sfp->quirk = sfp_lookup_quirk(&id);
+	sfp->quirk = sfp_lookup_quirk(sfp, &id);
 	if (sfp->quirk && sfp->quirk->fixup)
 		sfp->quirk->fixup(sfp);
 
@@ -2419,7 +2454,7 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event)
 {
 	mutex_lock(&sfp->sm_mutex);
 
-	dev_dbg(sfp->dev, "SM: enter %s:%s:%s event %s\n",
+	dev_info(sfp->dev, "SM: enter %s:%s:%s event %s\n",
 		mod_state_to_str(sfp->sm_mod_state),
 		dev_state_to_str(sfp->sm_dev_state),
 		sm_state_to_str(sfp->sm_state),
@@ -2429,7 +2464,7 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event)
 	sfp_sm_module(sfp, event);
 	sfp_sm_main(sfp, event);
 
-	dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n",
+	dev_info(sfp->dev, "SM: exit %s:%s:%s\n",
 		mod_state_to_str(sfp->sm_mod_state),
 		dev_state_to_str(sfp->sm_dev_state),
 		sm_state_to_str(sfp->sm_state));
diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h
index 1c21140..4bf833d 100644
--- a/include/linux/mdio/mdio-i2c.h
+++ b/include/linux/mdio/mdio-i2c.h
@@ -18,6 +18,22 @@ enum mdio_i2c_proto {
 	MDIO_I2C_ROLLBALL,
 };
 
+static inline const char *mdio_i2c_proto_type(int type)
+{
+	switch (type) {
+	case MDIO_I2C_NONE:
+		return "MDIO_I2C_NONE";
+	case MDIO_I2C_MARVELL_C22:
+		return "MDIO_I2C_MARVELL_C22";
+	case MDIO_I2C_C45:
+		return "MDIO_I2C_C45";
+	case MDIO_I2C_ROLLBALL:
+		return "MDIO_I2C_ROLLBALL";
+	default:
+		return "UNKNOWN";
+	}
+}
+
 struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
 			       enum mdio_i2c_proto protocol);
 
-- 
2.18.0

