@@ -32,6 +32,7 @@ struct tgec_mdio_controller {
32
32
__be32 mdio_addr ; /* MDIO address */
33
33
} __packed ;
34
34
35
+ #define MDIO_STAT_ENC BIT(6)
35
36
#define MDIO_STAT_CLKDIV (x ) (((x>>1) & 0xff) << 8)
36
37
#define MDIO_STAT_BSY (1 << 0)
37
38
#define MDIO_STAT_RD_ER (1 << 1)
@@ -91,20 +92,40 @@ static int xgmac_wait_until_done(struct device *dev,
91
92
static int xgmac_mdio_write (struct mii_bus * bus , int phy_id , int regnum , u16 value )
92
93
{
93
94
struct tgec_mdio_controller __iomem * regs = bus -> priv ;
94
- uint16_t dev_addr = regnum >> 16 ;
95
+ uint16_t dev_addr ;
96
+ u32 mdio_ctl , mdio_stat ;
95
97
int ret ;
96
98
97
- /* Set the port and dev addr */
98
- out_be32 (& regs -> mdio_ctl ,
99
- MDIO_CTL_PORT_ADDR (phy_id ) | MDIO_CTL_DEV_ADDR (dev_addr ));
99
+ mdio_stat = in_be32 (& regs -> mdio_stat );
100
+ if (regnum & MII_ADDR_C45 ) {
101
+ /* Clause 45 (ie 10G) */
102
+ dev_addr = (regnum >> 16 ) & 0x1f ;
103
+ mdio_stat |= MDIO_STAT_ENC ;
104
+ } else {
105
+ /* Clause 22 (ie 1G) */
106
+ dev_addr = regnum & 0x1f ;
107
+ mdio_stat &= ~MDIO_STAT_ENC ;
108
+ }
100
109
101
- /* Set the register address */
102
- out_be32 (& regs -> mdio_addr , regnum & 0xffff );
110
+ out_be32 (& regs -> mdio_stat , mdio_stat );
103
111
104
112
ret = xgmac_wait_until_free (& bus -> dev , regs );
105
113
if (ret )
106
114
return ret ;
107
115
116
+ /* Set the port and dev addr */
117
+ mdio_ctl = MDIO_CTL_PORT_ADDR (phy_id ) | MDIO_CTL_DEV_ADDR (dev_addr );
118
+ out_be32 (& regs -> mdio_ctl , mdio_ctl );
119
+
120
+ /* Set the register address */
121
+ if (regnum & MII_ADDR_C45 ) {
122
+ out_be32 (& regs -> mdio_addr , regnum & 0xffff );
123
+
124
+ ret = xgmac_wait_until_free (& bus -> dev , regs );
125
+ if (ret )
126
+ return ret ;
127
+ }
128
+
108
129
/* Write the value to the register */
109
130
out_be32 (& regs -> mdio_data , MDIO_DATA (value ));
110
131
@@ -123,21 +144,39 @@ static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
123
144
static int xgmac_mdio_read (struct mii_bus * bus , int phy_id , int regnum )
124
145
{
125
146
struct tgec_mdio_controller __iomem * regs = bus -> priv ;
126
- uint16_t dev_addr = regnum >> 16 ;
147
+ uint16_t dev_addr ;
148
+ uint32_t mdio_stat ;
127
149
uint32_t mdio_ctl ;
128
150
uint16_t value ;
129
151
int ret ;
130
152
153
+ mdio_stat = in_be32 (& regs -> mdio_stat );
154
+ if (regnum & MII_ADDR_C45 ) {
155
+ dev_addr = (regnum >> 16 ) & 0x1f ;
156
+ mdio_stat |= MDIO_STAT_ENC ;
157
+ } else {
158
+ dev_addr = regnum & 0x1f ;
159
+ mdio_stat = ~MDIO_STAT_ENC ;
160
+ }
161
+
162
+ out_be32 (& regs -> mdio_stat , mdio_stat );
163
+
164
+ ret = xgmac_wait_until_free (& bus -> dev , regs );
165
+ if (ret )
166
+ return ret ;
167
+
131
168
/* Set the Port and Device Addrs */
132
169
mdio_ctl = MDIO_CTL_PORT_ADDR (phy_id ) | MDIO_CTL_DEV_ADDR (dev_addr );
133
170
out_be32 (& regs -> mdio_ctl , mdio_ctl );
134
171
135
172
/* Set the register address */
136
- out_be32 (& regs -> mdio_addr , regnum & 0xffff );
173
+ if (regnum & MII_ADDR_C45 ) {
174
+ out_be32 (& regs -> mdio_addr , regnum & 0xffff );
137
175
138
- ret = xgmac_wait_until_free (& bus -> dev , regs );
139
- if (ret )
140
- return ret ;
176
+ ret = xgmac_wait_until_free (& bus -> dev , regs );
177
+ if (ret )
178
+ return ret ;
179
+ }
141
180
142
181
/* Initiate the read */
143
182
out_be32 (& regs -> mdio_ctl , mdio_ctl | MDIO_CTL_READ );
@@ -224,6 +263,9 @@ static struct of_device_id xgmac_mdio_match[] = {
224
263
{
225
264
.compatible = "fsl,fman-xmdio" ,
226
265
},
266
+ {
267
+ .compatible = "fsl,fman-memac-mdio" ,
268
+ },
227
269
{},
228
270
};
229
271
MODULE_DEVICE_TABLE (of , xgmac_mdio_match );
0 commit comments