diff mbox series

[U-Boot,v2,03/11] drivers: net: aquantia: use XFI, USXGMII interface types

Message ID 20190812131521.28556-4-alexandru.marginean@nxp.com
State Superseded
Delegated to: Joe Hershberger
Headers show
Series Aquantia PHY driver updates to reduce FW dependency | expand

Commit Message

Alexandru Marginean Aug. 12, 2019, 1:15 p.m. UTC
The PHY supports XFI and USXGMII, the notable difference being that USX AN
is enabled for USXGMII.  Legacy code uses XGMII for any 10G proto and
detects whether USX AN should be enabled or not using a PHY status
register.  Keep that functionality too, so we don't break existing drivers.

Signed-off-by: Razvan Ionut Cirjan <razvanionut.cirjan@nxp.com>
Signed-off-by: Alex Marginean <alexm.osslist@gmail.com>
---
 drivers/net/phy/aquantia.c | 47 ++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 465ec2d342..7be1a40608 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -256,8 +256,10 @@  static int aquantia_upload_firmware(struct phy_device *phydev)
 
 int aquantia_config(struct phy_device *phydev)
 {
+	int interface = phydev->interface;
 	u32 val, id, rstatus, fault;
 	u32 reg_val1 = 0;
+	int usx_an = 0;
 
 	id = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FIRMWARE_ID);
 	rstatus = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_RSTATUS_1);
@@ -278,17 +280,34 @@  int aquantia_config(struct phy_device *phydev)
 		if (ret != 0)
 			return ret;
 	}
+	/*
+	 * for backward compatibility convert XGMII into either XFI or USX based
+	 * on FW config
+	 */
+	if (interface == PHY_INTERFACE_MODE_XGMII) {
+		reg_val1 = phy_read(phydev, MDIO_MMD_PHYXS,
+				    AQUANTIA_SYSTEM_INTERFACE_SR);
+		if ((reg_val1 & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII)
+			interface = PHY_INTERFACE_MODE_USXGMII;
+		else
+			interface = PHY_INTERFACE_MODE_XFI;
+	}
 
 	val = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR);
 
-	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
 		/* 1000BASE-T mode */
 		phydev->advertising = SUPPORTED_1000baseT_Full;
 		phydev->supported = phydev->advertising;
 
 		val = (val & ~AQUNTIA_SPEED_LSB_MASK) | AQUNTIA_SPEED_MSB_MASK;
 		phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
-	} else if (phydev->interface == PHY_INTERFACE_MODE_XGMII) {
+		break;
+	case PHY_INTERFACE_MODE_USXGMII:
+		usx_an = 1;
+		/* FALLTHROUGH */
+	case PHY_INTERFACE_MODE_XFI:
 		/* 10GBASE-T mode */
 		phydev->advertising = SUPPORTED_10000baseT_Full;
 		phydev->supported = phydev->advertising;
@@ -299,40 +318,40 @@  int aquantia_config(struct phy_device *phydev)
 				  AQUNTIA_SPEED_LSB_MASK |
 				  AQUNTIA_SPEED_MSB_MASK);
 
-		val = phy_read(phydev, MDIO_MMD_PHYXS,
-			       AQUANTIA_SYSTEM_INTERFACE_SR);
 		/* If SI is USXGMII then start USXGMII autoneg */
-		if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) {
-			reg_val1 =  phy_read(phydev, MDIO_MMD_PHYXS,
-					     AQUANTIA_VENDOR_PROVISIONING_REG);
+		reg_val1 =  phy_read(phydev, MDIO_MMD_PHYXS,
+				     AQUANTIA_VENDOR_PROVISIONING_REG);
 
+		if (usx_an) {
 			reg_val1 |= AQUANTIA_USX_AUTONEG_CONTROL_ENA;
-
-			phy_write(phydev, MDIO_MMD_PHYXS,
-				  AQUANTIA_VENDOR_PROVISIONING_REG,
-				  reg_val1);
 			printf("%s: system interface USXGMII\n",
 			       phydev->dev->name);
 		} else {
+			reg_val1 &= ~AQUANTIA_USX_AUTONEG_CONTROL_ENA;
 			printf("%s: system interface XFI\n",
 			       phydev->dev->name);
 		}
 
-	} else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) {
+		phy_write(phydev, MDIO_MMD_PHYXS,
+			  AQUANTIA_VENDOR_PROVISIONING_REG, reg_val1);
+		break;
+	case PHY_INTERFACE_MODE_SGMII_2500:
 		/* 2.5GBASE-T mode */
 		phydev->advertising = SUPPORTED_1000baseT_Full;
 		phydev->supported = phydev->advertising;
 
 		phy_write(phydev, MDIO_MMD_AN, AQUNTIA_10G_CTL, 1);
 		phy_write(phydev, MDIO_MMD_AN, AQUNTIA_VENDOR_P1, 0x9440);
-	} else if (phydev->interface == PHY_INTERFACE_MODE_MII) {
+		break;
+	case PHY_INTERFACE_MODE_MII:
 		/* 100BASE-TX mode */
 		phydev->advertising = SUPPORTED_100baseT_Full;
 		phydev->supported = phydev->advertising;
 
 		val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK;
 		phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
-	}
+		break;
+	};
 
 	val = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_RESERVED_STATUS);
 	reg_val1 = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_FIRMWARE_ID);