aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar_mii.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/gianfar_mii.c')
-rw-r--r--drivers/net/gianfar_mii.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index b8898927236a..ebcfb27a904e 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -78,7 +78,6 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
78 * same as system mdio bus, used for controlling the external PHYs, for eg. 78 * same as system mdio bus, used for controlling the external PHYs, for eg.
79 */ 79 */
80int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum) 80int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
81
82{ 81{
83 u16 value; 82 u16 value;
84 83
@@ -122,7 +121,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
122} 121}
123 122
124/* Reset the MIIM registers, and wait for the bus to free */ 123/* Reset the MIIM registers, and wait for the bus to free */
125int gfar_mdio_reset(struct mii_bus *bus) 124static int gfar_mdio_reset(struct mii_bus *bus)
126{ 125{
127 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; 126 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
128 unsigned int timeout = PHY_INIT_TIMEOUT; 127 unsigned int timeout = PHY_INIT_TIMEOUT;
@@ -152,14 +151,15 @@ int gfar_mdio_reset(struct mii_bus *bus)
152} 151}
153 152
154 153
155int gfar_mdio_probe(struct device *dev) 154static int gfar_mdio_probe(struct device *dev)
156{ 155{
157 struct platform_device *pdev = to_platform_device(dev); 156 struct platform_device *pdev = to_platform_device(dev);
158 struct gianfar_mdio_data *pdata; 157 struct gianfar_mdio_data *pdata;
159 struct gfar_mii __iomem *regs; 158 struct gfar_mii __iomem *regs;
159 struct gfar __iomem *enet_regs;
160 struct mii_bus *new_bus; 160 struct mii_bus *new_bus;
161 struct resource *r; 161 struct resource *r;
162 int err = 0; 162 int i, err = 0;
163 163
164 if (NULL == dev) 164 if (NULL == dev)
165 return -EINVAL; 165 return -EINVAL;
@@ -199,6 +199,34 @@ int gfar_mdio_probe(struct device *dev)
199 new_bus->dev = dev; 199 new_bus->dev = dev;
200 dev_set_drvdata(dev, new_bus); 200 dev_set_drvdata(dev, new_bus);
201 201
202 /*
203 * This is mildly evil, but so is our hardware for doing this.
204 * Also, we have to cast back to struct gfar_mii because of
205 * definition weirdness done in gianfar.h.
206 */
207 enet_regs = (struct gfar __iomem *)
208 ((char *)regs - offsetof(struct gfar, gfar_mii_regs));
209
210 /* Scan the bus, looking for an empty spot for TBIPA */
211 gfar_write(&enet_regs->tbipa, 0);
212 for (i = PHY_MAX_ADDR; i > 0; i--) {
213 u32 phy_id;
214 int r;
215
216 r = get_phy_id(new_bus, i, &phy_id);
217 if (r)
218 return r;
219
220 if (phy_id == 0xffffffff)
221 break;
222 }
223
224 /* The bus is full. We don't support using 31 PHYs, sorry */
225 if (i == 0)
226 return -EBUSY;
227
228 gfar_write(&enet_regs->tbipa, i);
229
202 err = mdiobus_register(new_bus); 230 err = mdiobus_register(new_bus);
203 231
204 if (0 != err) { 232 if (0 != err) {
@@ -218,7 +246,7 @@ reg_map_fail:
218} 246}
219 247
220 248
221int gfar_mdio_remove(struct device *dev) 249static int gfar_mdio_remove(struct device *dev)
222{ 250{
223 struct mii_bus *bus = dev_get_drvdata(dev); 251 struct mii_bus *bus = dev_get_drvdata(dev);
224 252