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_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_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_4 4
static int rtl821x_match_phy_device(struct phy_device *phydev)
{
- u64 poll_state;
- int rawpage, port = phydev->mdio.addr & ~3;
- int oldpage, chip_mode, chip_cfg_mode;
+ int oldpage, oldxpage, chip_mode, chip_cfg_mode;
+ struct mii_bus *bus = phydev->mdio.bus;
+ int addr = phydev->mdio.addr & ~3;
if (phydev->phy_id == PHY_ID_RTL8218B_E)
return PHY_IS_RTL8218B_E;
if (phydev->phy_id != PHY_ID_RTL8214_OR_8218)
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
- * registered and normal paged access is not possible. The following
- * detection routine works because our MDIO bus has all the Realtek
- * PHY page handling (register 31) integrated into the port functions.
+ * RTL8214FC and RTL8218B are the same PHYs with different configurations. That info is
+ * stored in the first PHY of the package. In all known configurations packages start at
+ * bus addresses that are multiples of four. Avoid paged access as this is not available
+ * 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);
+
+ 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);
- pr_debug("%s(%d): got chip mode %x\n", __func__, phydev->mdio.addr, chip_mode);
+ mdiobus_write(bus, addr, 0x1e, oldxpage);
+ mdiobus_write(bus, addr, 0x1f, oldpage);
- /* we checked the 4th port of a RTL8218B and got no config values */
+ /* no values while reading the 5th port during 5-8th port detection of RTL8218B */
if (!chip_mode)
return PHY_IS_RTL8218B_E;