Skip to content

Commit 1fcf77c

Browse files
puppybanedavem330
authored andcommitted
net/fsl: Add mEMAC MDIO support to XGMAC MDIO
The Freescale mEMAC supports operating at 10/100/1000/10G, and its associated MDIO controller is likewise capable of operating both Clause 22 and Clause 45 MDIO buses. It is nearly identical to the MDIO controller on the XGMAC, so we just modify that driver. Portions of this driver developed by: Sandeep Singh <sandeep@freescale.com> Roy Zang <tie-fei.zang@freescale.com> Signed-off-by: Andy Fleming <afleming@gmail.com> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2f43836 commit 1fcf77c

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

drivers/net/ethernet/freescale/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ config FSL_XGMAC_MDIO
6969
select PHYLIB
7070
select OF_MDIO
7171
---help---
72-
This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
72+
This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and
73+
on the FMan mEMAC (which supports both Clauses 22 and 45)
7374

7475
config UCC_GETH
7576
tristate "Freescale QE Gigabit Ethernet"

drivers/net/ethernet/freescale/xgmac_mdio.c

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct tgec_mdio_controller {
3232
__be32 mdio_addr; /* MDIO address */
3333
} __packed;
3434

35+
#define MDIO_STAT_ENC BIT(6)
3536
#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8)
3637
#define MDIO_STAT_BSY (1 << 0)
3738
#define MDIO_STAT_RD_ER (1 << 1)
@@ -91,20 +92,40 @@ static int xgmac_wait_until_done(struct device *dev,
9192
static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
9293
{
9394
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;
9597
int ret;
9698

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+
}
100109

101-
/* Set the register address */
102-
out_be32(&regs->mdio_addr, regnum & 0xffff);
110+
out_be32(&regs->mdio_stat, mdio_stat);
103111

104112
ret = xgmac_wait_until_free(&bus->dev, regs);
105113
if (ret)
106114
return ret;
107115

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+
108129
/* Write the value to the register */
109130
out_be32(&regs->mdio_data, MDIO_DATA(value));
110131

@@ -123,21 +144,39 @@ static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
123144
static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
124145
{
125146
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;
127149
uint32_t mdio_ctl;
128150
uint16_t value;
129151
int ret;
130152

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+
131168
/* Set the Port and Device Addrs */
132169
mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
133170
out_be32(&regs->mdio_ctl, mdio_ctl);
134171

135172
/* 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);
137175

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+
}
141180

142181
/* Initiate the read */
143182
out_be32(&regs->mdio_ctl, mdio_ctl | MDIO_CTL_READ);
@@ -224,6 +263,9 @@ static struct of_device_id xgmac_mdio_match[] = {
224263
{
225264
.compatible = "fsl,fman-xmdio",
226265
},
266+
{
267+
.compatible = "fsl,fman-memac-mdio",
268+
},
227269
{},
228270
};
229271
MODULE_DEVICE_TABLE(of, xgmac_mdio_match);

0 commit comments

Comments
 (0)