diff options
| author | Tom Rini <[email protected]> | 2019-01-24 15:30:06 -0500 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2019-01-24 15:30:06 -0500 |
| commit | 68489ed037530ec29fc0bc452ad6e4b0c5db02ec (patch) | |
| tree | b1fb961b98f1e9a5ab5c3f0dc80fcfc32e00e689 /drivers/net/phy | |
| parent | 0c3b301f79fcad081c8509ee4cb06e7b0478c8c1 (diff) | |
| parent | 91c9cbabf935b37ab6c0b9b622e7faf0b350acb6 (diff) | |
Merge branch 'master' of git://git.denx.de/u-boot-net
Diffstat (limited to 'drivers/net/phy')
| -rw-r--r-- | drivers/net/phy/aquantia.c | 39 | ||||
| -rw-r--r-- | drivers/net/phy/micrel_ksz90x1.c | 4 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 15 | ||||
| -rw-r--r-- | drivers/net/phy/realtek.c | 29 |
4 files changed, 80 insertions, 7 deletions
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index a0abb232992..12df09877de 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -3,6 +3,7 @@ * Aquantia PHY drivers * * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2018 NXP */ #include <config.h> #include <common.h> @@ -19,6 +20,18 @@ #define AQUNTIA_SPEED_LSB_MASK 0x2000 #define AQUNTIA_SPEED_MSB_MASK 0x40 +#define AQUANTIA_SYSTEM_INTERFACE_SR 0xe812 +#define AQUANTIA_VENDOR_PROVISIONING_REG 0xC441 +#define AQUANTIA_FIRMWARE_ID 0x20 +#define AQUANTIA_RESERVED_STATUS 0xc885 +#define AQUANTIA_FIRMWARE_MAJOR_MASK 0xff00 +#define AQUANTIA_FIRMWARE_MINOR_MASK 0xff +#define AQUANTIA_FIRMWARE_BUILD_MASK 0xf0 + +#define AQUANTIA_USX_AUTONEG_CONTROL_ENA 0x0008 +#define AQUANTIA_SI_IN_USE_MASK 0x0078 +#define AQUANTIA_SI_USXGMII 0x0018 + /* registers in MDIO_MMD_VEND1 region */ #define GLOBAL_FIRMWARE_ID 0x20 #define GLOBAL_FAULT 0xc850 @@ -244,6 +257,7 @@ static int aquantia_upload_firmware(struct phy_device *phydev) int aquantia_config(struct phy_device *phydev) { u32 val, id, rstatus, fault; + u32 reg_val1 = 0; id = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FIRMWARE_ID); rstatus = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_RSTATUS_1); @@ -284,6 +298,21 @@ int aquantia_config(struct phy_device *phydev) phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, 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) { + phy_write(phydev, MDIO_MMD_PHYXS, + AQUANTIA_VENDOR_PROVISIONING_REG, + AQUANTIA_USX_AUTONEG_CONTROL_ENA); + printf("%s: system interface USXGMII\n", + phydev->dev->name); + } else { + printf("%s: system interface XFI\n", + phydev->dev->name); + } + } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) { /* 2.5GBASE-T mode */ phydev->advertising = SUPPORTED_1000baseT_Full; @@ -299,6 +328,16 @@ int aquantia_config(struct phy_device *phydev) val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK; phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val); } + + val = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_RESERVED_STATUS); + reg_val1 = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_FIRMWARE_ID); + + printf("%s: %s Firmware Version %x.%x.%x\n", phydev->dev->name, + phydev->drv->name, + (reg_val1 & AQUANTIA_FIRMWARE_MAJOR_MASK) >> 8, + reg_val1 & AQUANTIA_FIRMWARE_MINOR_MASK, + (val & AQUANTIA_FIRMWARE_BUILD_MASK) >> 4); + return 0; } diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index 3951535bf1f..63e7b0242b9 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -123,8 +123,8 @@ static int ksz90x1_of_config_group(struct phy_device *phydev, } else { changed = 1; /* Value was changed in OF */ /* Calculate the register value and fix corner cases */ - if (val[i] > ps_to_regval * 0xf) { - max = (1 << ofcfg->grp[i].size) - 1; + max = (1 << ofcfg->grp[i].size) - 1; + if (val[i] > ps_to_regval * max) { regval |= max << offset; } else { regval |= (val[i] / ps_to_regval) << offset; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 236913a1544..0c8b29dae44 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -620,7 +620,7 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev, } static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, - u32 phy_id, + u32 phy_id, bool is_c45, phy_interface_t interface) { struct phy_device *dev; @@ -650,6 +650,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, dev->addr = addr; dev->phy_id = phy_id; + dev->is_c45 = is_c45; dev->bus = bus; dev->drv = get_phy_driver(dev, interface); @@ -702,13 +703,17 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus, phy_interface_t interface) { u32 phy_id = 0xffffffff; + bool is_c45; while (phy_mask) { int addr = ffs(phy_mask) - 1; int r = get_phy_id(bus, addr, devad, &phy_id); /* If the PHY ID is mostly f's, we didn't find anything */ - if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) - return phy_device_create(bus, addr, phy_id, interface); + if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) { + is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true; + return phy_device_create(bus, addr, phy_id, is_c45, + interface); + } phy_mask &= ~(1 << addr); } return NULL; @@ -895,8 +900,8 @@ static struct phy_device *phy_connect_fixed(struct mii_dev *bus, while (sn > 0) { name = fdt_get_name(gd->fdt_blob, sn, NULL); if (name && strcmp(name, "fixed-link") == 0) { - phydev = phy_device_create(bus, - sn, PHY_FIXED_ID, interface); + phydev = phy_device_create(bus, sn, PHY_FIXED_ID, false, + interface); break; } sn = fdt_next_subnode(gd->fdt_blob, sn); diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index b3e6578df9a..dd45e11b3ad 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -57,6 +57,33 @@ #define MIIM_RTL8211F_TX_DELAY 0x100 #define MIIM_RTL8211F_LCR 0x10 +static int rtl8211f_phy_extread(struct phy_device *phydev, int addr, + int devaddr, int regnum) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211F_PAGE_SELECT); + int val; + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); + val = phy_read(phydev, MDIO_DEVAD_NONE, regnum); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); + + return val; +} + +static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr, + int devaddr, int regnum, u16 val) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211F_PAGE_SELECT); + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); + phy_write(phydev, MDIO_DEVAD_NONE, regnum, val); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); + + return 0; +} + static int rtl8211b_probe(struct phy_device *phydev) { #ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER @@ -336,6 +363,8 @@ static struct phy_driver RTL8211F_driver = { .config = &rtl8211f_config, .startup = &rtl8211f_startup, .shutdown = &genphy_shutdown, + .readext = &rtl8211f_phy_extread, + .writeext = &rtl8211f_phy_extwrite, }; int phy_realtek_init(void) |
