realtek: simplify RTL8218B/RTL8214Fx detection
The current implementation has several issues: - it uses the hacky phy_port* macros - it uses SoC dependent raw pages - it disables/enables SoC dependent polling Get rid of these dependencies and access the mdio bus the normal way. Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de> Link: https://github.com/openwrt/openwrt/pull/19372 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
4ff02b46b9
commit
926ffa10b4
1 changed files with 19 additions and 30 deletions
|
@ -22,10 +22,8 @@ extern struct rtl83xx_soc_info soc_info;
|
||||||
extern struct mutex smi_lock;
|
extern struct mutex smi_lock;
|
||||||
extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
|
extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
|
||||||
extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val);
|
extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val);
|
||||||
extern int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
|
|
||||||
extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
|
extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
|
||||||
extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum);
|
extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum);
|
||||||
extern int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
|
|
||||||
|
|
||||||
#define PHY_PAGE_2 2
|
#define PHY_PAGE_2 2
|
||||||
#define PHY_PAGE_4 4
|
#define PHY_PAGE_4 4
|
||||||
|
@ -157,9 +155,9 @@ static int resume_polling(u64 saved_state)
|
||||||
|
|
||||||
static int rtl821x_match_phy_device(struct phy_device *phydev)
|
static int rtl821x_match_phy_device(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
u64 poll_state;
|
int oldpage, oldxpage, chip_mode, chip_cfg_mode;
|
||||||
int rawpage, port = phydev->mdio.addr & ~3;
|
struct mii_bus *bus = phydev->mdio.bus;
|
||||||
int oldpage, chip_mode, chip_cfg_mode;
|
int addr = phydev->mdio.addr & ~3;
|
||||||
|
|
||||||
if (phydev->phy_id == PHY_ID_RTL8218B_E)
|
if (phydev->phy_id == PHY_ID_RTL8218B_E)
|
||||||
return PHY_IS_RTL8218B_E;
|
return PHY_IS_RTL8218B_E;
|
||||||
|
@ -167,36 +165,27 @@ static int rtl821x_match_phy_device(struct phy_device *phydev)
|
||||||
if (phydev->phy_id != PHY_ID_RTL8214_OR_8218)
|
if (phydev->phy_id != PHY_ID_RTL8214_OR_8218)
|
||||||
return PHY_IS_NOT_RTL821X;
|
return PHY_IS_NOT_RTL821X;
|
||||||
|
|
||||||
if (soc_info.family == RTL8380_FAMILY_ID)
|
|
||||||
rawpage = RTL838X_PAGE_RAW;
|
|
||||||
else if (soc_info.family == RTL8390_FAMILY_ID)
|
|
||||||
rawpage = RTL839X_PAGE_RAW;
|
|
||||||
else
|
|
||||||
return PHY_IS_NOT_RTL821X;
|
|
||||||
|
|
||||||
poll_state = disable_polling(port);
|
|
||||||
/*
|
/*
|
||||||
* At this stage the write_page()/read_page() PHY functions are not yet
|
* RTL8214FC and RTL8218B are the same PHYs with different configurations. That info is
|
||||||
* registered and normal paged access is not possible. The following
|
* stored in the first PHY of the package. In all known configurations packages start at
|
||||||
* detection routine works because our MDIO bus has all the Realtek
|
* bus addresses that are multiples of four. Avoid paged access as this is not available
|
||||||
* PHY page handling (register 31) integrated into the port functions.
|
* during detection.
|
||||||
*/
|
*/
|
||||||
oldpage = phy_port_read_paged(phydev, port, rawpage, 31);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 31, 0xa42);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 29, 0x008);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 31, 0x278);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 18, 0x455);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 31, 0x260);
|
|
||||||
chip_mode = phy_port_read_paged(phydev, port, rawpage, 18);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 31, 0xa42);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 29, 0x000);
|
|
||||||
phy_port_write_paged(phydev, port, rawpage, 31, oldpage);
|
|
||||||
|
|
||||||
resume_polling(poll_state);
|
oldpage = mdiobus_read(bus, addr, 0x1f);
|
||||||
|
oldxpage = mdiobus_read(bus, addr, 0x1e);
|
||||||
|
|
||||||
pr_debug("%s(%d): got chip mode %x\n", __func__, phydev->mdio.addr, chip_mode);
|
mdiobus_write(bus, addr, 0x1e, 0x8);
|
||||||
|
mdiobus_write(bus, addr, 0x1f, 0x278);
|
||||||
|
mdiobus_write(bus, addr, 0x12, 0x455);
|
||||||
|
mdiobus_write(bus, addr, 0x1f, 0x260);
|
||||||
|
chip_mode = mdiobus_read(bus, addr, 0x12);
|
||||||
|
dev_dbg(&phydev->mdio.dev, "got RTL8218B/RTL8214Fx chip mode %04x\n", chip_mode);
|
||||||
|
|
||||||
/* we checked the 4th port of a RTL8218B and got no config values */
|
mdiobus_write(bus, addr, 0x1e, oldxpage);
|
||||||
|
mdiobus_write(bus, addr, 0x1f, oldpage);
|
||||||
|
|
||||||
|
/* no values while reading the 5th port during 5-8th port detection of RTL8218B */
|
||||||
if (!chip_mode)
|
if (!chip_mode)
|
||||||
return PHY_IS_RTL8218B_E;
|
return PHY_IS_RTL8218B_E;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue