[U-Boot-Users] [PATCH] Add support for treating unknown PHYs as generic PHYs

Andy Fleming afleming at gmail.com
Wed May 2 23:01:54 CEST 2007


From: David Updegraff <dave at cray.com>

When bringing up u-boot on new boards, PHY support sometimes gets
neglected.  Most PHYs don't really need any special support,
though.  By adding a generic entry that always matches if nothing
else does, we can provide support for "unsupported" PHYs for the
tsec.

The generic PHY driver supports most PHYs, including gigabit.

Signed-off-by: David Updegraff <dave at cray.com>
Signed-off-by: Andy Fleming <afleming at freescale.com>
---

I have unwound my tree, and applied this patch in place of the previous one.

 drivers/tsec.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/drivers/tsec.c b/drivers/tsec.c
index ed35f22..25566a7 100644
--- a/drivers/tsec.c
+++ b/drivers/tsec.c
@@ -385,6 +385,76 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
 	return 0;
 }

+/* Generic function which updates the speed and duplex.  If
+ * autonegotiation is enabled, it uses the AND of the link
+ * partner's advertised capabilities and our advertised
+ * capabilities.  If autonegotiation is disabled, we use the
+ * appropriate bits in the control register.
+ *
+ * Stolen from Linux's mii.c and phy_device.c
+ */
+uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
+{
+	/* We're using autonegotiation */
+	if (mii_reg & PHY_BMSR_AUTN_ABLE) {
+		uint lpa = 0;
+		uint gblpa = 0;
+
+		/* Check for gigabit capability */
+		if (mii_reg & PHY_BMSR_EXT) {
+			/* We want a list of states supported by
+			 * both PHYs in the link
+			 */
+			gblpa = read_phy_reg(priv, PHY_1000BTSR);
+			gblpa &= read_phy_reg(priv, PHY_1000BTCR) << 2;
+		}
+
+		/* Set the baseline so we only have to set them
+		 * if they're different
+		 */
+		priv->speed = 10;
+		priv->duplexity = 0;
+
+		/* Check the gigabit fields */
+		if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+			priv->speed = 1000;
+
+			if (gblpa & PHY_1000BTSR_1000FD)
+				priv->duplexity = 1;
+
+			/* We're done! */
+			return 0;
+		}
+
+		lpa = read_phy_reg(priv, PHY_ANAR);
+		lpa &= read_phy_reg(priv, PHY_ANLPAR);
+
+		if (lpa & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) {
+			priv->speed = 100;
+
+			if (lpa & PHY_ANLPAR_TXFD)
+				priv->duplexity = 1;
+
+		} else if (lpa & PHY_ANLPAR_10FD)
+			priv->duplexity = 1;
+	} else {
+		uint bmcr = read_phy_reg(priv, PHY_BMCR);
+
+		priv->speed = 10;
+		priv->duplexity = 0;
+
+		if (bmcr & PHY_BMCR_DPLX)
+			priv->duplexity = 1;
+
+		if (bmcr & PHY_BMCR_1000_MBPS)
+			priv->speed = 1000;
+		else if (bmcr & PHY_BMCR_100_MBPS)
+			priv->speed = 100;
+	}
+
+	return 0;
+}
+
 /*
  * Parse the BCM54xx status register for speed and duplex information.
  * The linux sungem_phy has this information, but in a table format.
@@ -722,6 +792,7 @@ static void startup_tsec(struct eth_device *dev)
 	/* Start up the PHY */
 	if(priv->phyinfo)
 		phy_run_commands(priv, priv->phyinfo->startup);
+
 	adjust_link(dev);

 	/* Enable Transmit and Receive */
@@ -1092,6 +1163,27 @@ struct phy_info phy_info_dm9161 = {
 			   {miim_end,}
 			   },
 };
+/* a generic flavor.  */
+struct phy_info phy_info_generic =  {
+	0,
+	"Unknown/Generic PHY",
+	32,
+	(struct phy_cmd[]) { /* config */
+		{PHY_BMCR, PHY_BMCR_RESET, NULL},
+		{PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) { /* startup */
+		{PHY_BMSR, miim_read, NULL},
+		{PHY_BMSR, miim_read, &mii_parse_sr},
+		{PHY_BMSR, miim_read, &mii_parse_link},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) { /* shutdown */
+		{miim_end,}
+	}
+};
+

 uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
 {
@@ -1207,6 +1299,7 @@ struct phy_info *phy_info[] = {
 	&phy_info_lxt971,
 	&phy_info_VSC8244,
 	&phy_info_dp83865,
+	&phy_info_generic,
 	NULL
 };

-- 
1.5.0.2.230.gfbe3d-dirty




More information about the U-Boot mailing list