56b293257e2cb766d3f38e53cea857450b705cc7
[openwrt/staging/neocturne.git] /
1 From eda80b249df7bbc7b3dd13907343a3e59bfc57fd Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Tue, 4 Jan 2022 12:06:22 +0000
4 Subject: [PATCH 1/3] net: ethernet: mtk_eth_soc: fix return values and
5 refactor MDIO ops
6
7 Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
8 while writing or 0xffff if it happens while reading, return the
9 appropriate -ETIMEDOUT. Also fix return type to int instead of u32.
10 Refactor functions to use bitfield helpers instead of having various
11 masking and shifting constants in the code, which also results in the
12 register definitions in the header file being more obviously related
13 to what is stated in the MediaTek's Reference Manual.
14
15 Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
16 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 ---
19 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++++++++++++---------
20 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++++--
21 2 files changed, 41 insertions(+), 28 deletions(-)
22
23 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
24 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
25 @@ -92,46 +92,53 @@ static int mtk_mdio_busy_wait(struct mtk
26 }
27
28 dev_err(eth->dev, "mdio: MDIO timeout\n");
29 - return -1;
30 + return -ETIMEDOUT;
31 }
32
33 -static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
34 - u32 phy_register, u32 write_data)
35 +static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
36 + u32 write_data)
37 {
38 - if (mtk_mdio_busy_wait(eth))
39 - return -1;
40 + int ret;
41
42 - write_data &= 0xffff;
43 -
44 - mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
45 - (phy_register << PHY_IAC_REG_SHIFT) |
46 - (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
47 + ret = mtk_mdio_busy_wait(eth);
48 + if (ret < 0)
49 + return ret;
50 +
51 + mtk_w32(eth, PHY_IAC_ACCESS |
52 + PHY_IAC_START_C22 |
53 + PHY_IAC_CMD_WRITE |
54 + PHY_IAC_REG(phy_reg) |
55 + PHY_IAC_ADDR(phy_addr) |
56 + PHY_IAC_DATA(write_data),
57 MTK_PHY_IAC);
58
59 - if (mtk_mdio_busy_wait(eth))
60 - return -1;
61 + ret = mtk_mdio_busy_wait(eth);
62 + if (ret < 0)
63 + return ret;
64
65 return 0;
66 }
67
68 -static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
69 +static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
70 {
71 - u32 d;
72 -
73 - if (mtk_mdio_busy_wait(eth))
74 - return 0xffff;
75 + int ret;
76
77 - mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
78 - (phy_reg << PHY_IAC_REG_SHIFT) |
79 - (phy_addr << PHY_IAC_ADDR_SHIFT),
80 + ret = mtk_mdio_busy_wait(eth);
81 + if (ret < 0)
82 + return ret;
83 +
84 + mtk_w32(eth, PHY_IAC_ACCESS |
85 + PHY_IAC_START_C22 |
86 + PHY_IAC_CMD_C22_READ |
87 + PHY_IAC_REG(phy_reg) |
88 + PHY_IAC_ADDR(phy_addr),
89 MTK_PHY_IAC);
90
91 - if (mtk_mdio_busy_wait(eth))
92 - return 0xffff;
93 -
94 - d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
95 + ret = mtk_mdio_busy_wait(eth);
96 + if (ret < 0)
97 + return ret;
98
99 - return d;
100 + return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
101 }
102
103 static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
104 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
105 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
106 @@ -341,11 +341,17 @@
107 /* PHY Indirect Access Control registers */
108 #define MTK_PHY_IAC 0x10004
109 #define PHY_IAC_ACCESS BIT(31)
110 -#define PHY_IAC_READ BIT(19)
111 -#define PHY_IAC_WRITE BIT(18)
112 -#define PHY_IAC_START BIT(16)
113 -#define PHY_IAC_ADDR_SHIFT 20
114 -#define PHY_IAC_REG_SHIFT 25
115 +#define PHY_IAC_REG_MASK GENMASK(29, 25)
116 +#define PHY_IAC_REG(x) FIELD_PREP(PHY_IAC_REG_MASK, (x))
117 +#define PHY_IAC_ADDR_MASK GENMASK(24, 20)
118 +#define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
119 +#define PHY_IAC_CMD_MASK GENMASK(19, 18)
120 +#define PHY_IAC_CMD_WRITE FIELD_PREP(PHY_IAC_CMD_MASK, 1)
121 +#define PHY_IAC_CMD_C22_READ FIELD_PREP(PHY_IAC_CMD_MASK, 2)
122 +#define PHY_IAC_START_MASK GENMASK(17, 16)
123 +#define PHY_IAC_START_C22 FIELD_PREP(PHY_IAC_START_MASK, 1)
124 +#define PHY_IAC_DATA_MASK GENMASK(15, 0)
125 +#define PHY_IAC_DATA(x) FIELD_PREP(PHY_IAC_DATA_MASK, (x))
126 #define PHY_IAC_TIMEOUT HZ
127
128 #define MTK_MAC_MISC 0x1000c