242e39421e969fb1c732cf2c3f096fb94274dbb6
[openwrt/staging/blogic.git] /
1 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
2 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
3 @@ -103,10 +103,30 @@ static u32 _mtk_mdio_write(struct mtk_et
4
5 write_data &= 0xffff;
6
7 - mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
8 - (phy_register << PHY_IAC_REG_SHIFT) |
9 - (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
10 - MTK_PHY_IAC);
11 + if (phy_register & MII_ADDR_C45) {
12 + u8 dev_num = (phy_register >> 16) & 0x1f;
13 + u16 reg = (u16)(phy_register & 0xffff);
14 +
15 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_SET_ADDR |
16 + (phy_addr << PHY_IAC_ADDR_SHIFT) |
17 + (dev_num << PHY_IAC_REG_SHIFT) |
18 + reg,
19 + MTK_PHY_IAC);
20 +
21 + if (mtk_mdio_busy_wait(eth))
22 + return 0xffff;
23 +
24 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_WRITE |
25 + (phy_addr << PHY_IAC_ADDR_SHIFT) |
26 + (dev_num << PHY_IAC_REG_SHIFT) |
27 + write_data,
28 + MTK_PHY_IAC);
29 + } else {
30 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
31 + (phy_register << PHY_IAC_REG_SHIFT) |
32 + (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
33 + MTK_PHY_IAC);
34 + }
35
36 if (mtk_mdio_busy_wait(eth))
37 return -1;
38 @@ -121,10 +141,29 @@ static u32 _mtk_mdio_read(struct mtk_eth
39 if (mtk_mdio_busy_wait(eth))
40 return 0xffff;
41
42 - mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
43 - (phy_reg << PHY_IAC_REG_SHIFT) |
44 - (phy_addr << PHY_IAC_ADDR_SHIFT),
45 - MTK_PHY_IAC);
46 + if (phy_reg & MII_ADDR_C45) {
47 + u8 dev_num = (phy_reg >> 16) & 0x1f;
48 + u16 reg = (u16)(phy_reg & 0xffff);
49 +
50 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_SET_ADDR |
51 + (phy_addr << PHY_IAC_ADDR_SHIFT) |
52 + (dev_num << PHY_IAC_REG_SHIFT) |
53 + reg,
54 + MTK_PHY_IAC);
55 +
56 + if (mtk_mdio_busy_wait(eth))
57 + return 0xffff;
58 +
59 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_READ_C45 |
60 + (phy_addr << PHY_IAC_ADDR_SHIFT) |
61 + (dev_num << PHY_IAC_REG_SHIFT),
62 + MTK_PHY_IAC);
63 + } else {
64 + mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
65 + (phy_reg << PHY_IAC_REG_SHIFT) |
66 + (phy_addr << PHY_IAC_ADDR_SHIFT),
67 + MTK_PHY_IAC);
68 + }
69
70 if (mtk_mdio_busy_wait(eth))
71 return 0xffff;
72 @@ -584,6 +623,7 @@ static int mtk_mdio_init(struct mtk_eth
73 eth->mii_bus->name = "mdio";
74 eth->mii_bus->read = mtk_mdio_read;
75 eth->mii_bus->write = mtk_mdio_write;
76 + eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
77 eth->mii_bus->priv = eth;
78 eth->mii_bus->parent = eth->dev;
79
80 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
81 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
82 @@ -340,9 +340,12 @@
83 /* PHY Indirect Access Control registers */
84 #define MTK_PHY_IAC 0x10004
85 #define PHY_IAC_ACCESS BIT(31)
86 +#define PHY_IAC_SET_ADDR 0
87 #define PHY_IAC_READ BIT(19)
88 +#define PHY_IAC_READ_C45 (BIT(18) | BIT(19))
89 #define PHY_IAC_WRITE BIT(18)
90 #define PHY_IAC_START BIT(16)
91 +#define PHY_IAC_START_C45 0
92 #define PHY_IAC_ADDR_SHIFT 20
93 #define PHY_IAC_REG_SHIFT 25
94 #define PHY_IAC_TIMEOUT HZ