[][Update Ethernet MDIO CL45 programming sequence]
[Description]
Change Ethernet MDIO CL45 programming sequence.
Note: These patches porting from upstream Linux-5.18.
[Release-log]
N/A
Change-Id: I1025a3f17caed2d69536dae03ded0743935be812
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6023025
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index ab411d9..7ba9a01 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -400,12 +400,12 @@
static void mii_mgr_read_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data)
{
- mtk_cl45_ind_read(eth, port, devad, reg, data);
+ *data = _mtk_mdio_read(eth, port, mdiobus_c45_addr(devad, reg));
}
static void mii_mgr_write_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data)
{
- mtk_cl45_ind_write(eth, port, devad, reg, data);
+ _mtk_mdio_write(eth, port, mdiobus_c45_addr(devad, reg), data);
}
int mtk_do_priv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
index 43f4838..2113c1f 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
@@ -267,12 +267,10 @@
}
#endif
-extern u32 _mtk_mdio_read(struct mtk_eth *eth, u16 phy_addr, u16 phy_reg);
-extern u32 _mtk_mdio_write(struct mtk_eth *eth, u16 phy_addr,
- u16 phy_register, u16 write_data);
+extern u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg);
+extern u32 _mtk_mdio_write(struct mtk_eth *eth, int phy_addr,
+ int phy_reg, u16 write_data);
-extern u32 mtk_cl45_ind_read(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data);
-extern u32 mtk_cl45_ind_write(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data);
extern atomic_t force;
int debug_proc_init(struct mtk_eth *eth);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 40d840e..84cabce 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -103,18 +103,33 @@
return -1;
}
-u32 _mtk_mdio_write(struct mtk_eth *eth, u16 phy_addr,
- u16 phy_register, u16 write_data)
+u32 _mtk_mdio_write(struct mtk_eth *eth, int phy_addr,
+ int phy_reg, u16 write_data)
{
if (mtk_mdio_busy_wait(eth))
return -1;
write_data &= 0xffff;
- mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
- ((phy_register & 0x1f) << PHY_IAC_REG_SHIFT) |
- ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT) | write_data,
- MTK_PHY_IAC);
+ if (phy_reg & MII_ADDR_C45) {
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_ADDR_C45 |
+ ((mdiobus_c45_devad(phy_reg) & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT) | mdiobus_c45_regad(phy_reg),
+ MTK_PHY_IAC);
+
+ if (mtk_mdio_busy_wait(eth))
+ return -1;
+
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_WRITE |
+ ((mdiobus_c45_devad(phy_reg) & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT) | write_data,
+ MTK_PHY_IAC);
+ } else {
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
+ ((phy_reg & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT) | write_data,
+ MTK_PHY_IAC);
+ }
if (mtk_mdio_busy_wait(eth))
return -1;
@@ -122,17 +137,32 @@
return 0;
}
-u32 _mtk_mdio_read(struct mtk_eth *eth, u16 phy_addr, u16 phy_reg)
+u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
{
u32 d;
if (mtk_mdio_busy_wait(eth))
return 0xffff;
+ if (phy_reg & MII_ADDR_C45) {
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_ADDR_C45 |
+ ((mdiobus_c45_devad(phy_reg) & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT) | mdiobus_c45_regad(phy_reg),
+ MTK_PHY_IAC);
+
+ if (mtk_mdio_busy_wait(eth))
+ return 0xffff;
+
- mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
- ((phy_reg & 0x1f) << PHY_IAC_REG_SHIFT) |
- ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT),
- MTK_PHY_IAC);
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_READ_C45 |
+ ((mdiobus_c45_devad(phy_reg) & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT),
+ MTK_PHY_IAC);
+ } else {
+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
+ ((phy_reg & 0x1f) << PHY_IAC_REG_SHIFT) |
+ ((phy_addr & 0x1f) << PHY_IAC_ADDR_SHIFT),
+ MTK_PHY_IAC);
+ }
if (mtk_mdio_busy_wait(eth))
return 0xffff;
@@ -157,34 +187,6 @@
return _mtk_mdio_read(eth, phy_addr, phy_reg);
}
-u32 mtk_cl45_ind_read(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data)
-{
- mutex_lock(ð->mii_bus->mdio_lock);
-
- _mtk_mdio_write(eth, port, MII_MMD_ACC_CTL_REG, devad);
- _mtk_mdio_write(eth, port, MII_MMD_ADDR_DATA_REG, reg);
- _mtk_mdio_write(eth, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
- *data = _mtk_mdio_read(eth, port, MII_MMD_ADDR_DATA_REG);
-
- mutex_unlock(ð->mii_bus->mdio_lock);
-
- return 0;
-}
-
-u32 mtk_cl45_ind_write(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data)
-{
- mutex_lock(ð->mii_bus->mdio_lock);
-
- _mtk_mdio_write(eth, port, MII_MMD_ACC_CTL_REG, devad);
- _mtk_mdio_write(eth, port, MII_MMD_ADDR_DATA_REG, reg);
- _mtk_mdio_write(eth, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
- _mtk_mdio_write(eth, port, MII_MMD_ADDR_DATA_REG, data);
-
- mutex_unlock(ð->mii_bus->mdio_lock);
-
- return 0;
-}
-
static int mt7621_gmac0_rgmii_adjust(struct mtk_eth *eth,
phy_interface_t interface)
{
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 367f7f1..56db8c7 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -570,8 +570,11 @@
#define MTK_PHY_IAC 0x10004
#define PHY_IAC_ACCESS BIT(31)
#define PHY_IAC_READ BIT(19)
+#define PHY_IAC_READ_C45 (3 << 18)
+#define PHY_IAC_ADDR_C45 (0 << 18)
#define PHY_IAC_WRITE BIT(18)
#define PHY_IAC_START BIT(16)
+#define PHY_IAC_START_C45 (0 << 16)
#define PHY_IAC_ADDR_SHIFT 20
#define PHY_IAC_REG_SHIFT 25
#define PHY_IAC_TIMEOUT HZ