summaryrefslogtreecommitdiff
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig25
-rw-r--r--drivers/net/phy/aquantia.c1
-rw-r--r--drivers/net/phy/cortina.c59
-rw-r--r--drivers/net/phy/realtek.c34
-rw-r--r--drivers/net/phy/xilinx_phy.c2
5 files changed, 91 insertions, 30 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 7fd4a8d2616..f5821dfed96 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -13,6 +13,21 @@ menuconfig PHYLIB
if PHYLIB
+config PHY_ADDR_ENABLE
+ bool "Limit phy address"
+ default y if ARCH_SUNXI
+ help
+ Select this if you want to control which phy address is used
+
+if PHY_ADDR_ENABLE
+config PHY_ADDR
+ int "PHY address"
+ default 1 if ARCH_SUNXI
+ default 0
+ help
+ The address of PHY on MII bus. Usually in range of 0 to 31.
+endif
+
config B53_SWITCH
bool "Broadcom BCM53xx (RoboSwitch) Ethernet switch PHY support."
help
@@ -132,6 +147,16 @@ config PHY_NATSEMI
config PHY_REALTEK
bool "Realtek Ethernet PHYs support"
+config RTL8211E_PINE64_GIGABIT_FIX
+ bool "Fix gigabit throughput on some Pine64+ models"
+ depends on PHY_REALTEK
+ help
+ Configure the Realtek RTL8211E found on some Pine64+ models differently to
+ fix throughput on Gigabit links, turning off all internal delays in the
+ process. The settings that this touches are not documented in the CONFREG
+ section of the RTL8211E datasheet, but come from Realtek by way of the
+ Pine64 engineering team.
+
config RTL8211X_PHY_FORCE_MASTER
bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode"
depends on PHY_REALTEK
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index ad12f6d61fb..66781475456 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -7,6 +7,7 @@
*/
#include <config.h>
#include <common.h>
+#include <dm.h>
#include <phy.h>
#ifndef CONFIG_PHYLIB_10G
diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c
index 637d89a1e1b..9cb3a52c208 100644
--- a/drivers/net/phy/cortina.c
+++ b/drivers/net/phy/cortina.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*
* Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
*
*/
@@ -27,6 +28,7 @@
#error The Cortina PHY needs 10G support
#endif
+#ifndef CORTINA_NO_FW_UPLOAD
struct cortina_reg_config cortina_reg_cfg[] = {
/* CS4315_enable_sr_mode */
{VILLA_GLOBAL_MSEQCLKCTRL, 0x8004},
@@ -215,12 +217,22 @@ void cs4340_upload_firmware(struct phy_device *phydev)
phy_write(phydev, 0x00, fw_temp.reg_addr, fw_temp.reg_value);
}
}
+#endif
int cs4340_phy_init(struct phy_device *phydev)
{
+#ifndef CORTINA_NO_FW_UPLOAD
int timeout = 100; /* 100ms */
+#endif
int reg_value;
+ /*
+ * Cortina phy has provision to store
+ * phy firmware in attached dedicated EEPROM.
+ * Boards designed with EEPROM attached to Cortina
+ * does not require FW upload.
+ */
+#ifndef CORTINA_NO_FW_UPLOAD
/* step1: BIST test */
phy_write(phydev, 0x00, VILLA_GLOBAL_MSEQCLKCTRL, 0x0004);
phy_write(phydev, 0x00, VILLA_GLOBAL_LINE_SOFT_RESET, 0x0000);
@@ -241,6 +253,7 @@ int cs4340_phy_init(struct phy_device *phydev)
/* setp2: upload ucode */
cs4340_upload_firmware(phydev);
+#endif
reg_value = phy_read(phydev, 0x00, VILLA_GLOBAL_DWNLD_CHECKSUM_STATUS);
if (reg_value) {
debug("%s checksum status failed.\n", __func__);
@@ -295,45 +308,33 @@ int phy_cortina_init(void)
int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
{
int phy_reg;
- bool is_cortina_phy = false;
-
- switch (addr) {
-#ifdef CORTINA_PHY_ADDR1
- case CORTINA_PHY_ADDR1:
-#endif
-#ifdef CORTINA_PHY_ADDR2
- case CORTINA_PHY_ADDR2:
-#endif
-#ifdef CORTINA_PHY_ADDR3
- case CORTINA_PHY_ADDR3:
-#endif
-#ifdef CORTINA_PHY_ADDR4
- case CORTINA_PHY_ADDR4:
-#endif
- is_cortina_phy = true;
- break;
- default:
- break;
- }
/* Cortina PHY has non-standard offset of PHY ID registers */
- if (is_cortina_phy)
- phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_LSB);
- else
- phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
+ phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_LSB);
+ if (phy_reg < 0)
+ return -EIO;
+ *phy_id = (phy_reg & 0xffff) << 16;
+ phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_MSB);
if (phy_reg < 0)
return -EIO;
+ *phy_id |= (phy_reg & 0xffff);
- *phy_id = (phy_reg & 0xffff) << 16;
- if (is_cortina_phy)
- phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_MSB);
- else
- phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
+ if (*phy_id == PHY_UID_CS4340)
+ return 0;
+ /*
+ * If Cortina PHY not detected,
+ * try generic way to find PHY ID registers
+ */
+ phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
if (phy_reg < 0)
return -EIO;
+ *phy_id = (phy_reg & 0xffff) << 16;
+ phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
+ if (phy_reg < 0)
+ return -EIO;
*phy_id |= (phy_reg & 0xffff);
return 0;
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 6d917f86f44..d5c2a46c67e 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -13,6 +13,7 @@
#include <phy.h>
#define PHY_RTL8211x_FORCE_MASTER BIT(1)
+#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
#define PHY_AUTONEGOTIATE_TIMEOUT 5000
@@ -47,6 +48,13 @@
#define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800
#define MIIM_RTL8211F_PHYSTAT_LINK 0x0004
+#define MIIM_RTL8211E_CONFREG 0x1c
+#define MIIM_RTL8211E_CONFREG_TXD 0x0002
+#define MIIM_RTL8211E_CONFREG_RXD 0x0004
+#define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */
+
+#define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e
+
#define MIIM_RTL8211F_PAGE_SELECT 0x1f
#define MIIM_RTL8211F_TX_DELAY 0x100
#define MIIM_RTL8211F_LCR 0x10
@@ -60,6 +68,15 @@ static int rtl8211b_probe(struct phy_device *phydev)
return 0;
}
+static int rtl8211e_probe(struct phy_device *phydev)
+{
+#ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX
+ phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX;
+#endif
+
+ return 0;
+}
+
/* RealTek RTL8211x */
static int rtl8211x_config(struct phy_device *phydev)
{
@@ -81,6 +98,22 @@ static int rtl8211x_config(struct phy_device *phydev)
reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
}
+ if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) {
+ unsigned int reg;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+ 7);
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
+ /* Ensure both internal delays are turned off */
+ reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD);
+ /* Flip the magic undocumented bits */
+ reg |= MIIM_RTL8211E_CONFREG_MAGIC;
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg);
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+ 0);
+ }
/* read interrupt status just to clear it */
phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
@@ -279,6 +312,7 @@ static struct phy_driver RTL8211E_driver = {
.uid = 0x1cc915,
.mask = 0xffffff,
.features = PHY_GBIT_FEATURES,
+ .probe = &rtl8211e_probe,
.config = &rtl8211x_config,
.startup = &rtl8211e_startup,
.shutdown = &genphy_shutdown,
diff --git a/drivers/net/phy/xilinx_phy.c b/drivers/net/phy/xilinx_phy.c
index 3f80f0495e8..7142a99ce58 100644
--- a/drivers/net/phy/xilinx_phy.c
+++ b/drivers/net/phy/xilinx_phy.c
@@ -105,7 +105,7 @@ static int xilinxphy_of_init(struct phy_device *phydev)
debug("%s\n", __func__);
phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
- "phy-type", -1);
+ "xlnx,phy-type", -1);
if (phytype == XAE_PHY_TYPE_1000BASE_X)
phydev->flags |= XAE_PHY_TYPE_1000BASE_X;