+}
+
+/*
+ * Find out if PHY is in copper or serdes mode by looking at Expansion Reg
+ * 0x42 - "Operating Mode Status Register"
+ */
+static int BCM8482_is_serdes(struct tsec_private *priv)
+{
+ u16 val;
+ int serdes = 0;
+
+ write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+ val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
+
+ switch (val & 0x1f) {
+ case 0x0d: /* RGMII-to-100Base-FX */
+ case 0x0e: /* RGMII-to-SGMII */
+ case 0x0f: /* RGMII-to-SerDes */
+ case 0x12: /* SGMII-to-SerDes */
+ case 0x13: /* SGMII-to-100Base-FX */
+ case 0x16: /* SerDes-to-Serdes */
+ serdes = 1;
+ break;
+ case 0x6: /* RGMII-to-Copper */
+ case 0x14: /* SGMII-to-Copper */
+ case 0x17: /* SerDes-to-Copper */
+ break;
+ default:
+ printf("ERROR, invalid PHY mode (0x%x\n)", val);
+ break;
+ }
+
+ return serdes;
+}
+
+/*
+ * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating
+ * Mode Status Register"
+ */
+uint mii_parse_BCM5482_serdes_sr(struct tsec_private *priv)
+{
+ u16 val;
+ int i = 0;
+
+ /* Wait 1s for link - Clause 37 autonegotiation happens very fast */
+ while (1) {
+ write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL,
+ MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+ val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
+
+ if (val & 0x8000)
+ break;
+
+ if (i++ > 1000) {
+ priv->link = 0;
+ return 1;
+ }
+
+ udelay(1000); /* 1 ms */
+ }
+
+ priv->link = 1;
+ switch ((val >> 13) & 0x3) {
+ case (0x00):
+ priv->speed = 10;
+ break;
+ case (0x01):
+ priv->speed = 100;
+ break;
+ case (0x02):
+ priv->speed = 1000;
+ break;
+ }
+
+ priv->duplexity = (val & 0x1000) == 0x1000;
+
+ return 0;
+}
+
+/*
+ * Figure out if BCM5482 is in serdes or copper mode and determine link
+ * configuration accordingly
+ */
+static uint mii_parse_BCM5482_sr(uint mii_reg, struct tsec_private *priv)
+{
+ if (BCM8482_is_serdes(priv)) {
+ mii_parse_BCM5482_serdes_sr(priv);
+ priv->flags |= TSEC_FIBER;
+ } else {
+ /* Wait for auto-negotiation to complete or fail */
+ mii_parse_sr(mii_reg, priv);
+
+ /* Parse BCM54xx copper aux status register */
+ mii_reg = read_phy_reg(priv, MIIM_BCM54xx_AUXSTATUS);
+ mii_parse_BCM54xx_sr(mii_reg, priv);
+ }