summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Marginean <alexandru.marginean@nxp.com>2019-11-14 18:28:30 +0200
committerJoe Hershberger <joe.hershberger@ni.com>2019-12-09 09:47:42 -0600
commit8a141d6e9cc1841082e4c996703eafb037ec63ad (patch)
treef72f9fc3c085dbdaa4052353153f730c5d6af72a
parentd718b697a1794876511d6a30a047acfce0b69312 (diff)
drivers: net: aquantia: use XFI, USXGMII interface types
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 <alexandru.marginean@nxp.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
-rw-r--r--drivers/net/phy/aquantia.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 1061fdfc16..601121dc3a 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -259,9 +259,11 @@ 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 num_retries = 5;
+ int usx_an = 0;
/*
* check if the system is out of reset and init sequence completed.
@@ -293,17 +295,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;
@@ -314,40 +333,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);