-static int sja1105_sgmii_read(struct sja1105_private *priv, int port, int mmd,
- int pcs_reg)
-{
- u64 addr = (mmd << 16) | pcs_reg;
- u32 val;
- int rc;
-
- if (port != SJA1105_SGMII_PORT)
- return -ENODEV;
-
- rc = sja1105_xfer_u32(priv, SPI_READ, addr, &val, NULL);
- if (rc < 0)
- return rc;
-
- return val;
-}
-
-static int sja1105_sgmii_write(struct sja1105_private *priv, int port, int mmd,
- int pcs_reg, u16 pcs_val)
-{
- u64 addr = (mmd << 16) | pcs_reg;
- u32 val = pcs_val;
- int rc;
-
- if (port != SJA1105_SGMII_PORT)
- return -ENODEV;
-
- rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &val, NULL);
- if (rc < 0)
- return rc;
-
- return val;
-}
-
-static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port,
- bool an_enabled, bool an_master)
-{
- u16 ac = SJA1105_AC_AUTONEG_MODE_SGMII;
-
- /* DIGITAL_CONTROL_1: Enable vendor-specific MMD1, allow the PHY to
- * stop the clock during LPI mode, make the MAC reconfigure
- * autonomously after PCS autoneg is done, flush the internal FIFOs.
- */
- sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1,
- SJA1105_DC1_EN_VSMMD1 |
- SJA1105_DC1_CLOCK_STOP_EN |
- SJA1105_DC1_MAC_AUTO_SW |
- SJA1105_DC1_INIT);
- /* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */
- sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC2,
- SJA1105_DC2_TX_POL_INV_DISABLE);
- /* AUTONEG_CONTROL: Use SGMII autoneg */
- if (an_master)
- ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK;
- sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, ac);
- /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise,
- * sja1105_sgmii_pcs_force_speed must be called later for the link
- * to become operational.
- */
- if (an_enabled)
- sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1,
- BMCR_ANENABLE | BMCR_ANRESTART);
-}
-
-static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv,
- int port, int speed)
-{
- int pcs_speed;
-
- switch (speed) {
- case SPEED_1000:
- pcs_speed = BMCR_SPEED1000;
- break;
- case SPEED_100:
- pcs_speed = BMCR_SPEED100;
- break;
- case SPEED_10:
- pcs_speed = BMCR_SPEED10;
- break;
- default:
- dev_err(priv->ds->dev, "Invalid speed %d\n", speed);
- return;
- }
- sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1,
- pcs_speed | BMCR_FULLDPLX);
-}
-