aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/fec_mpc52xx_phy.c55
1 files changed, 22 insertions, 33 deletions
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 08e18bcb970f..45dd9bdc5d62 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -2,6 +2,7 @@
2 * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver 2 * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver
3 * 3 *
4 * Copyright (C) 2007 Domen Puncer, Telargo, Inc. 4 * Copyright (C) 2007 Domen Puncer, Telargo, Inc.
5 * Copyright (C) 2008 Wolfram Sang, Pengutronix
5 * 6 *
6 * This file is licensed under the terms of the GNU General Public License 7 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any 8 * version 2. This program is licensed "as is" without any warranty of any
@@ -21,58 +22,45 @@ struct mpc52xx_fec_mdio_priv {
21 struct mpc52xx_fec __iomem *regs; 22 struct mpc52xx_fec __iomem *regs;
22}; 23};
23 24
24static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg) 25static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
26 int reg, u32 value)
25{ 27{
26 struct mpc52xx_fec_mdio_priv *priv = bus->priv; 28 struct mpc52xx_fec_mdio_priv *priv = bus->priv;
27 struct mpc52xx_fec __iomem *fec; 29 struct mpc52xx_fec __iomem *fec;
28 int tries = 100; 30 int tries = 100;
29 u32 request = FEC_MII_READ_FRAME; 31
32 value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
33 value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
30 34
31 fec = priv->regs; 35 fec = priv->regs;
32 out_be32(&fec->ievent, FEC_IEVENT_MII); 36 out_be32(&fec->ievent, FEC_IEVENT_MII);
33 37 out_be32(&priv->regs->mii_data, value);
34 request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
35 request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
36
37 out_be32(&priv->regs->mii_data, request);
38 38
39 /* wait for it to finish, this takes about 23 us on lite5200b */ 39 /* wait for it to finish, this takes about 23 us on lite5200b */
40 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) 40 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
41 udelay(5); 41 udelay(5);
42 42
43 if (tries == 0) 43 if (!tries)
44 return -ETIMEDOUT; 44 return -ETIMEDOUT;
45 45
46 return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK; 46 return value & FEC_MII_DATA_OP_RD ?
47 in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK : 0;
47} 48}
48 49
49static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data) 50static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
50{ 51{
51 struct mpc52xx_fec_mdio_priv *priv = bus->priv; 52 return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, FEC_MII_READ_FRAME);
52 struct mpc52xx_fec __iomem *fec; 53}
53 u32 value = data;
54 int tries = 100;
55
56 fec = priv->regs;
57 out_be32(&fec->ievent, FEC_IEVENT_MII);
58
59 value |= FEC_MII_WRITE_FRAME;
60 value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
61 value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
62
63 out_be32(&priv->regs->mii_data, value);
64
65 /* wait for request to finish */
66 while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
67 udelay(5);
68
69 if (tries == 0)
70 return -ETIMEDOUT;
71 54
72 return 0; 55static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg,
56 u16 data)
57{
58 return mpc52xx_fec_mdio_transfer(bus, phy_id, reg,
59 data | FEC_MII_WRITE_FRAME);
73} 60}
74 61
75static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) 62static int mpc52xx_fec_mdio_probe(struct of_device *of,
63 const struct of_device_id *match)
76{ 64{
77 struct device *dev = &of->dev; 65 struct device *dev = &of->dev;
78 struct device_node *np = of->node; 66 struct device_node *np = of->node;
@@ -131,7 +119,8 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i
131 dev_set_drvdata(dev, bus); 119 dev_set_drvdata(dev, bus);
132 120
133 /* set MII speed */ 121 /* set MII speed */
134 out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); 122 out_be32(&priv->regs->mii_speed,
123 ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
135 124
136 /* enable MII interrupt */ 125 /* enable MII interrupt */
137 out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII); 126 out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII);