diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/gianfar.c | 7 | ||||
-rw-r--r-- | drivers/net/gianfar_mii.c | 21 | ||||
-rw-r--r-- | drivers/net/gianfar_mii.h | 3 |
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 64b201134fdb..249541a1814b 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -586,6 +586,10 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
586 | struct gfar_mii __iomem *regs = | 586 | struct gfar_mii __iomem *regs = |
587 | (void __iomem *)&priv->regs->gfar_mii_regs; | 587 | (void __iomem *)&priv->regs->gfar_mii_regs; |
588 | int tbipa = gfar_read(&priv->regs->tbipa); | 588 | int tbipa = gfar_read(&priv->regs->tbipa); |
589 | struct mii_bus *bus = gfar_get_miibus(priv); | ||
590 | |||
591 | if (bus) | ||
592 | mutex_lock(&bus->mdio_lock); | ||
589 | 593 | ||
590 | /* Single clk mode, mii mode off(for serdes communication) */ | 594 | /* Single clk mode, mii mode off(for serdes communication) */ |
591 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); | 595 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); |
@@ -596,6 +600,9 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
596 | 600 | ||
597 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | | 601 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | |
598 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); | 602 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); |
603 | |||
604 | if (bus) | ||
605 | mutex_unlock(&bus->mdio_lock); | ||
599 | } | 606 | } |
600 | 607 | ||
601 | static void init_registers(struct net_device *dev) | 608 | static void init_registers(struct net_device *dev) |
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index bf73eea98010..0e2595d24933 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c | |||
@@ -269,6 +269,27 @@ static struct device_driver gianfar_mdio_driver = { | |||
269 | .remove = gfar_mdio_remove, | 269 | .remove = gfar_mdio_remove, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static int match_mdio_bus(struct device *dev, void *data) | ||
273 | { | ||
274 | const struct gfar_private *priv = data; | ||
275 | const struct platform_device *pdev = to_platform_device(dev); | ||
276 | |||
277 | return !strcmp(pdev->name, gianfar_mdio_driver.name) && | ||
278 | pdev->id == priv->einfo->mdio_bus; | ||
279 | } | ||
280 | |||
281 | /* Given a gfar_priv structure, find the mii_bus controlled by this device (not | ||
282 | * necessarily the same as the bus the gfar's PHY is on), if one exists. | ||
283 | * Normally only the first gianfar controls a mii_bus. */ | ||
284 | struct mii_bus *gfar_get_miibus(const struct gfar_private *priv) | ||
285 | { | ||
286 | /*const*/ struct device *d; | ||
287 | |||
288 | d = bus_find_device(gianfar_mdio_driver.bus, NULL, (void *)priv, | ||
289 | match_mdio_bus); | ||
290 | return d ? dev_get_drvdata(d) : NULL; | ||
291 | } | ||
292 | |||
272 | int __init gfar_mdio_init(void) | 293 | int __init gfar_mdio_init(void) |
273 | { | 294 | { |
274 | return driver_register(&gianfar_mdio_driver); | 295 | return driver_register(&gianfar_mdio_driver); |
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 2af28b16a0e2..02dc970ca1ff 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef __GIANFAR_MII_H | 18 | #ifndef __GIANFAR_MII_H |
19 | #define __GIANFAR_MII_H | 19 | #define __GIANFAR_MII_H |
20 | 20 | ||
21 | struct gfar_private; /* forward ref */ | ||
22 | |||
21 | #define MIIMIND_BUSY 0x00000001 | 23 | #define MIIMIND_BUSY 0x00000001 |
22 | #define MIIMIND_NOTVALID 0x00000004 | 24 | #define MIIMIND_NOTVALID 0x00000004 |
23 | 25 | ||
@@ -44,6 +46,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); | |||
44 | int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, | 46 | int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, |
45 | int regnum, u16 value); | 47 | int regnum, u16 value); |
46 | int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); | 48 | int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); |
49 | struct mii_bus *gfar_get_miibus(const struct gfar_private *priv); | ||
47 | int __init gfar_mdio_init(void); | 50 | int __init gfar_mdio_init(void); |
48 | void gfar_mdio_exit(void); | 51 | void gfar_mdio_exit(void); |
49 | #endif /* GIANFAR_PHY_H */ | 52 | #endif /* GIANFAR_PHY_H */ |