diff options
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 321 |
1 files changed, 211 insertions, 110 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 55e319fa7fe6..7398704c4b55 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -25,11 +25,8 @@ | |||
25 | * | 25 | * |
26 | * Theory of operation | 26 | * Theory of operation |
27 | * | 27 | * |
28 | * The driver is initialized through platform_device. Structures which | 28 | * The driver is initialized through of_device. Configuration information |
29 | * define the configuration needed by the board are defined in a | 29 | * is therefore conveyed through an OF-style device tree. |
30 | * board structure in arch/ppc/platforms (though I do not | ||
31 | * discount the possibility that other architectures could one | ||
32 | * day be supported. | ||
33 | * | 30 | * |
34 | * The Gianfar Ethernet Controller uses a ring of buffer | 31 | * The Gianfar Ethernet Controller uses a ring of buffer |
35 | * descriptors. The beginning is indicated by a register | 32 | * descriptors. The beginning is indicated by a register |
@@ -78,7 +75,7 @@ | |||
78 | #include <linux/if_vlan.h> | 75 | #include <linux/if_vlan.h> |
79 | #include <linux/spinlock.h> | 76 | #include <linux/spinlock.h> |
80 | #include <linux/mm.h> | 77 | #include <linux/mm.h> |
81 | #include <linux/platform_device.h> | 78 | #include <linux/of_platform.h> |
82 | #include <linux/ip.h> | 79 | #include <linux/ip.h> |
83 | #include <linux/tcp.h> | 80 | #include <linux/tcp.h> |
84 | #include <linux/udp.h> | 81 | #include <linux/udp.h> |
@@ -92,6 +89,8 @@ | |||
92 | #include <linux/crc32.h> | 89 | #include <linux/crc32.h> |
93 | #include <linux/mii.h> | 90 | #include <linux/mii.h> |
94 | #include <linux/phy.h> | 91 | #include <linux/phy.h> |
92 | #include <linux/phy_fixed.h> | ||
93 | #include <linux/of.h> | ||
95 | 94 | ||
96 | #include "gianfar.h" | 95 | #include "gianfar.h" |
97 | #include "gianfar_mii.h" | 96 | #include "gianfar_mii.h" |
@@ -119,8 +118,9 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id); | |||
119 | static void adjust_link(struct net_device *dev); | 118 | static void adjust_link(struct net_device *dev); |
120 | static void init_registers(struct net_device *dev); | 119 | static void init_registers(struct net_device *dev); |
121 | static int init_phy(struct net_device *dev); | 120 | static int init_phy(struct net_device *dev); |
122 | static int gfar_probe(struct platform_device *pdev); | 121 | static int gfar_probe(struct of_device *ofdev, |
123 | static int gfar_remove(struct platform_device *pdev); | 122 | const struct of_device_id *match); |
123 | static int gfar_remove(struct of_device *ofdev); | ||
124 | static void free_skb_resources(struct gfar_private *priv); | 124 | static void free_skb_resources(struct gfar_private *priv); |
125 | static void gfar_set_multi(struct net_device *dev); | 125 | static void gfar_set_multi(struct net_device *dev); |
126 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); | 126 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); |
@@ -152,25 +152,158 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) | |||
152 | return (priv->vlan_enable || priv->rx_csum_enable); | 152 | return (priv->vlan_enable || priv->rx_csum_enable); |
153 | } | 153 | } |
154 | 154 | ||
155 | static int gfar_of_init(struct net_device *dev) | ||
156 | { | ||
157 | struct device_node *phy, *mdio; | ||
158 | const unsigned int *id; | ||
159 | const char *model; | ||
160 | const char *ctype; | ||
161 | const void *mac_addr; | ||
162 | const phandle *ph; | ||
163 | u64 addr, size; | ||
164 | int err = 0; | ||
165 | struct gfar_private *priv = netdev_priv(dev); | ||
166 | struct device_node *np = priv->node; | ||
167 | char bus_name[MII_BUS_ID_SIZE]; | ||
168 | |||
169 | if (!np || !of_device_is_available(np)) | ||
170 | return -ENODEV; | ||
171 | |||
172 | /* get a pointer to the register memory */ | ||
173 | addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); | ||
174 | priv->regs = ioremap(addr, size); | ||
175 | |||
176 | if (priv->regs == NULL) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | priv->interruptTransmit = irq_of_parse_and_map(np, 0); | ||
180 | |||
181 | model = of_get_property(np, "model", NULL); | ||
182 | |||
183 | /* If we aren't the FEC we have multiple interrupts */ | ||
184 | if (model && strcasecmp(model, "FEC")) { | ||
185 | priv->interruptReceive = irq_of_parse_and_map(np, 1); | ||
186 | |||
187 | priv->interruptError = irq_of_parse_and_map(np, 2); | ||
188 | |||
189 | if (priv->interruptTransmit < 0 || | ||
190 | priv->interruptReceive < 0 || | ||
191 | priv->interruptError < 0) { | ||
192 | err = -EINVAL; | ||
193 | goto err_out; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | mac_addr = of_get_mac_address(np); | ||
198 | if (mac_addr) | ||
199 | memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); | ||
200 | |||
201 | if (model && !strcasecmp(model, "TSEC")) | ||
202 | priv->device_flags = | ||
203 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
204 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
205 | FSL_GIANFAR_DEV_HAS_RMON | | ||
206 | FSL_GIANFAR_DEV_HAS_MULTI_INTR; | ||
207 | if (model && !strcasecmp(model, "eTSEC")) | ||
208 | priv->device_flags = | ||
209 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
210 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
211 | FSL_GIANFAR_DEV_HAS_RMON | | ||
212 | FSL_GIANFAR_DEV_HAS_MULTI_INTR | | ||
213 | FSL_GIANFAR_DEV_HAS_CSUM | | ||
214 | FSL_GIANFAR_DEV_HAS_VLAN | | ||
215 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | | ||
216 | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; | ||
217 | |||
218 | ctype = of_get_property(np, "phy-connection-type", NULL); | ||
219 | |||
220 | /* We only care about rgmii-id. The rest are autodetected */ | ||
221 | if (ctype && !strcmp(ctype, "rgmii-id")) | ||
222 | priv->interface = PHY_INTERFACE_MODE_RGMII_ID; | ||
223 | else | ||
224 | priv->interface = PHY_INTERFACE_MODE_MII; | ||
225 | |||
226 | if (of_get_property(np, "fsl,magic-packet", NULL)) | ||
227 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; | ||
228 | |||
229 | ph = of_get_property(np, "phy-handle", NULL); | ||
230 | if (ph == NULL) { | ||
231 | u32 *fixed_link; | ||
232 | |||
233 | fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); | ||
234 | if (!fixed_link) { | ||
235 | err = -ENODEV; | ||
236 | goto err_out; | ||
237 | } | ||
238 | |||
239 | snprintf(priv->phy_bus_id, BUS_ID_SIZE, PHY_ID_FMT, "0", | ||
240 | fixed_link[0]); | ||
241 | } else { | ||
242 | phy = of_find_node_by_phandle(*ph); | ||
243 | |||
244 | if (phy == NULL) { | ||
245 | err = -ENODEV; | ||
246 | goto err_out; | ||
247 | } | ||
248 | |||
249 | mdio = of_get_parent(phy); | ||
250 | |||
251 | id = of_get_property(phy, "reg", NULL); | ||
252 | |||
253 | of_node_put(phy); | ||
254 | of_node_put(mdio); | ||
255 | |||
256 | gfar_mdio_bus_name(bus_name, mdio); | ||
257 | snprintf(priv->phy_bus_id, BUS_ID_SIZE, "%s:%02x", | ||
258 | bus_name, *id); | ||
259 | } | ||
260 | |||
261 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ | ||
262 | ph = of_get_property(np, "tbi-handle", NULL); | ||
263 | if (ph) { | ||
264 | struct device_node *tbi = of_find_node_by_phandle(*ph); | ||
265 | struct of_device *ofdev; | ||
266 | struct mii_bus *bus; | ||
267 | |||
268 | if (!tbi) | ||
269 | return 0; | ||
270 | |||
271 | mdio = of_get_parent(tbi); | ||
272 | if (!mdio) | ||
273 | return 0; | ||
274 | |||
275 | ofdev = of_find_device_by_node(mdio); | ||
276 | |||
277 | of_node_put(mdio); | ||
278 | |||
279 | id = of_get_property(tbi, "reg", NULL); | ||
280 | if (!id) | ||
281 | return 0; | ||
282 | |||
283 | of_node_put(tbi); | ||
284 | |||
285 | bus = dev_get_drvdata(&ofdev->dev); | ||
286 | |||
287 | priv->tbiphy = bus->phy_map[*id]; | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | |||
292 | err_out: | ||
293 | iounmap(priv->regs); | ||
294 | return err; | ||
295 | } | ||
296 | |||
155 | /* Set up the ethernet device structure, private data, | 297 | /* Set up the ethernet device structure, private data, |
156 | * and anything else we need before we start */ | 298 | * and anything else we need before we start */ |
157 | static int gfar_probe(struct platform_device *pdev) | 299 | static int gfar_probe(struct of_device *ofdev, |
300 | const struct of_device_id *match) | ||
158 | { | 301 | { |
159 | u32 tempval; | 302 | u32 tempval; |
160 | struct net_device *dev = NULL; | 303 | struct net_device *dev = NULL; |
161 | struct gfar_private *priv = NULL; | 304 | struct gfar_private *priv = NULL; |
162 | struct gianfar_platform_data *einfo; | 305 | int err = 0; |
163 | struct resource *r; | 306 | DECLARE_MAC_BUF(mac); |
164 | int err = 0, irq; | ||
165 | |||
166 | einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; | ||
167 | |||
168 | if (NULL == einfo) { | ||
169 | printk(KERN_ERR "gfar %d: Missing additional data!\n", | ||
170 | pdev->id); | ||
171 | |||
172 | return -ENODEV; | ||
173 | } | ||
174 | 307 | ||
175 | /* Create an ethernet device instance */ | 308 | /* Create an ethernet device instance */ |
176 | dev = alloc_etherdev(sizeof (*priv)); | 309 | dev = alloc_etherdev(sizeof (*priv)); |
@@ -180,48 +313,19 @@ static int gfar_probe(struct platform_device *pdev) | |||
180 | 313 | ||
181 | priv = netdev_priv(dev); | 314 | priv = netdev_priv(dev); |
182 | priv->dev = dev; | 315 | priv->dev = dev; |
316 | priv->node = ofdev->node; | ||
183 | 317 | ||
184 | /* Set the info in the priv to the current info */ | 318 | err = gfar_of_init(dev); |
185 | priv->einfo = einfo; | ||
186 | |||
187 | /* fill out IRQ fields */ | ||
188 | if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | ||
189 | irq = platform_get_irq_byname(pdev, "tx"); | ||
190 | if (irq < 0) | ||
191 | goto regs_fail; | ||
192 | priv->interruptTransmit = irq; | ||
193 | |||
194 | irq = platform_get_irq_byname(pdev, "rx"); | ||
195 | if (irq < 0) | ||
196 | goto regs_fail; | ||
197 | priv->interruptReceive = irq; | ||
198 | |||
199 | irq = platform_get_irq_byname(pdev, "error"); | ||
200 | if (irq < 0) | ||
201 | goto regs_fail; | ||
202 | priv->interruptError = irq; | ||
203 | } else { | ||
204 | irq = platform_get_irq(pdev, 0); | ||
205 | if (irq < 0) | ||
206 | goto regs_fail; | ||
207 | priv->interruptTransmit = irq; | ||
208 | } | ||
209 | |||
210 | /* get a pointer to the register memory */ | ||
211 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
212 | priv->regs = ioremap(r->start, sizeof (struct gfar)); | ||
213 | 319 | ||
214 | if (NULL == priv->regs) { | 320 | if (err) |
215 | err = -ENOMEM; | ||
216 | goto regs_fail; | 321 | goto regs_fail; |
217 | } | ||
218 | 322 | ||
219 | spin_lock_init(&priv->txlock); | 323 | spin_lock_init(&priv->txlock); |
220 | spin_lock_init(&priv->rxlock); | 324 | spin_lock_init(&priv->rxlock); |
221 | spin_lock_init(&priv->bflock); | 325 | spin_lock_init(&priv->bflock); |
222 | INIT_WORK(&priv->reset_task, gfar_reset_task); | 326 | INIT_WORK(&priv->reset_task, gfar_reset_task); |
223 | 327 | ||
224 | platform_set_drvdata(pdev, dev); | 328 | dev_set_drvdata(&ofdev->dev, priv); |
225 | 329 | ||
226 | /* Stop the DMA engine now, in case it was running before */ | 330 | /* Stop the DMA engine now, in case it was running before */ |
227 | /* (The firmware could have used it, and left it running). */ | 331 | /* (The firmware could have used it, and left it running). */ |
@@ -239,13 +343,10 @@ static int gfar_probe(struct platform_device *pdev) | |||
239 | /* Initialize ECNTRL */ | 343 | /* Initialize ECNTRL */ |
240 | gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS); | 344 | gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS); |
241 | 345 | ||
242 | /* Copy the station address into the dev structure, */ | ||
243 | memcpy(dev->dev_addr, einfo->mac_addr, MAC_ADDR_LEN); | ||
244 | |||
245 | /* Set the dev->base_addr to the gfar reg region */ | 346 | /* Set the dev->base_addr to the gfar reg region */ |
246 | dev->base_addr = (unsigned long) (priv->regs); | 347 | dev->base_addr = (unsigned long) (priv->regs); |
247 | 348 | ||
248 | SET_NETDEV_DEV(dev, &pdev->dev); | 349 | SET_NETDEV_DEV(dev, &ofdev->dev); |
249 | 350 | ||
250 | /* Fill in the dev structure */ | 351 | /* Fill in the dev structure */ |
251 | dev->open = gfar_enet_open; | 352 | dev->open = gfar_enet_open; |
@@ -263,7 +364,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
263 | 364 | ||
264 | dev->ethtool_ops = &gfar_ethtool_ops; | 365 | dev->ethtool_ops = &gfar_ethtool_ops; |
265 | 366 | ||
266 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { | 367 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { |
267 | priv->rx_csum_enable = 1; | 368 | priv->rx_csum_enable = 1; |
268 | dev->features |= NETIF_F_IP_CSUM; | 369 | dev->features |= NETIF_F_IP_CSUM; |
269 | } else | 370 | } else |
@@ -271,7 +372,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
271 | 372 | ||
272 | priv->vlgrp = NULL; | 373 | priv->vlgrp = NULL; |
273 | 374 | ||
274 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { | 375 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { |
275 | dev->vlan_rx_register = gfar_vlan_rx_register; | 376 | dev->vlan_rx_register = gfar_vlan_rx_register; |
276 | 377 | ||
277 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 378 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
@@ -279,7 +380,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
279 | priv->vlan_enable = 1; | 380 | priv->vlan_enable = 1; |
280 | } | 381 | } |
281 | 382 | ||
282 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | 383 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { |
283 | priv->extended_hash = 1; | 384 | priv->extended_hash = 1; |
284 | priv->hash_width = 9; | 385 | priv->hash_width = 9; |
285 | 386 | ||
@@ -314,7 +415,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
314 | priv->hash_regs[7] = &priv->regs->gaddr7; | 415 | priv->hash_regs[7] = &priv->regs->gaddr7; |
315 | } | 416 | } |
316 | 417 | ||
317 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_PADDING) | 418 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING) |
318 | priv->padding = DEFAULT_PADDING; | 419 | priv->padding = DEFAULT_PADDING; |
319 | else | 420 | else |
320 | priv->padding = 0; | 421 | priv->padding = 0; |
@@ -368,29 +469,28 @@ regs_fail: | |||
368 | return err; | 469 | return err; |
369 | } | 470 | } |
370 | 471 | ||
371 | static int gfar_remove(struct platform_device *pdev) | 472 | static int gfar_remove(struct of_device *ofdev) |
372 | { | 473 | { |
373 | struct net_device *dev = platform_get_drvdata(pdev); | 474 | struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); |
374 | struct gfar_private *priv = netdev_priv(dev); | ||
375 | 475 | ||
376 | platform_set_drvdata(pdev, NULL); | 476 | dev_set_drvdata(&ofdev->dev, NULL); |
377 | 477 | ||
378 | iounmap(priv->regs); | 478 | iounmap(priv->regs); |
379 | free_netdev(dev); | 479 | free_netdev(priv->dev); |
380 | 480 | ||
381 | return 0; | 481 | return 0; |
382 | } | 482 | } |
383 | 483 | ||
384 | #ifdef CONFIG_PM | 484 | #ifdef CONFIG_PM |
385 | static int gfar_suspend(struct platform_device *pdev, pm_message_t state) | 485 | static int gfar_suspend(struct of_device *ofdev, pm_message_t state) |
386 | { | 486 | { |
387 | struct net_device *dev = platform_get_drvdata(pdev); | 487 | struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); |
388 | struct gfar_private *priv = netdev_priv(dev); | 488 | struct net_device *dev = priv->dev; |
389 | unsigned long flags; | 489 | unsigned long flags; |
390 | u32 tempval; | 490 | u32 tempval; |
391 | 491 | ||
392 | int magic_packet = priv->wol_en && | 492 | int magic_packet = priv->wol_en && |
393 | (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | 493 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); |
394 | 494 | ||
395 | netif_device_detach(dev); | 495 | netif_device_detach(dev); |
396 | 496 | ||
@@ -431,14 +531,14 @@ static int gfar_suspend(struct platform_device *pdev, pm_message_t state) | |||
431 | return 0; | 531 | return 0; |
432 | } | 532 | } |
433 | 533 | ||
434 | static int gfar_resume(struct platform_device *pdev) | 534 | static int gfar_resume(struct of_device *ofdev) |
435 | { | 535 | { |
436 | struct net_device *dev = platform_get_drvdata(pdev); | 536 | struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); |
437 | struct gfar_private *priv = netdev_priv(dev); | 537 | struct net_device *dev = priv->dev; |
438 | unsigned long flags; | 538 | unsigned long flags; |
439 | u32 tempval; | 539 | u32 tempval; |
440 | int magic_packet = priv->wol_en && | 540 | int magic_packet = priv->wol_en && |
441 | (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | 541 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); |
442 | 542 | ||
443 | if (!netif_running(dev)) { | 543 | if (!netif_running(dev)) { |
444 | netif_device_attach(dev); | 544 | netif_device_attach(dev); |
@@ -497,7 +597,7 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) | |||
497 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) | 597 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) |
498 | return PHY_INTERFACE_MODE_RMII; | 598 | return PHY_INTERFACE_MODE_RMII; |
499 | else { | 599 | else { |
500 | phy_interface_t interface = priv->einfo->interface; | 600 | phy_interface_t interface = priv->interface; |
501 | 601 | ||
502 | /* | 602 | /* |
503 | * This isn't autodetected right now, so it must | 603 | * This isn't autodetected right now, so it must |
@@ -510,7 +610,7 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) | |||
510 | } | 610 | } |
511 | } | 611 | } |
512 | 612 | ||
513 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) | 613 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) |
514 | return PHY_INTERFACE_MODE_GMII; | 614 | return PHY_INTERFACE_MODE_GMII; |
515 | 615 | ||
516 | return PHY_INTERFACE_MODE_MII; | 616 | return PHY_INTERFACE_MODE_MII; |
@@ -524,21 +624,18 @@ static int init_phy(struct net_device *dev) | |||
524 | { | 624 | { |
525 | struct gfar_private *priv = netdev_priv(dev); | 625 | struct gfar_private *priv = netdev_priv(dev); |
526 | uint gigabit_support = | 626 | uint gigabit_support = |
527 | priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? | 627 | priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? |
528 | SUPPORTED_1000baseT_Full : 0; | 628 | SUPPORTED_1000baseT_Full : 0; |
529 | struct phy_device *phydev; | 629 | struct phy_device *phydev; |
530 | char phy_id[BUS_ID_SIZE]; | ||
531 | phy_interface_t interface; | 630 | phy_interface_t interface; |
532 | 631 | ||
533 | priv->oldlink = 0; | 632 | priv->oldlink = 0; |
534 | priv->oldspeed = 0; | 633 | priv->oldspeed = 0; |
535 | priv->oldduplex = -1; | 634 | priv->oldduplex = -1; |
536 | 635 | ||
537 | snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id); | ||
538 | |||
539 | interface = gfar_get_interface(dev); | 636 | interface = gfar_get_interface(dev); |
540 | 637 | ||
541 | phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); | 638 | phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface); |
542 | 639 | ||
543 | if (interface == PHY_INTERFACE_MODE_SGMII) | 640 | if (interface == PHY_INTERFACE_MODE_SGMII) |
544 | gfar_configure_serdes(dev); | 641 | gfar_configure_serdes(dev); |
@@ -569,35 +666,31 @@ static int init_phy(struct net_device *dev) | |||
569 | static void gfar_configure_serdes(struct net_device *dev) | 666 | static void gfar_configure_serdes(struct net_device *dev) |
570 | { | 667 | { |
571 | struct gfar_private *priv = netdev_priv(dev); | 668 | struct gfar_private *priv = netdev_priv(dev); |
572 | struct gfar_mii __iomem *regs = | ||
573 | (void __iomem *)&priv->regs->gfar_mii_regs; | ||
574 | int tbipa = gfar_read(&priv->regs->tbipa); | ||
575 | struct mii_bus *bus = gfar_get_miibus(priv); | ||
576 | 669 | ||
577 | if (bus) | 670 | if (!priv->tbiphy) { |
578 | mutex_lock(&bus->mdio_lock); | 671 | printk(KERN_WARNING "SGMII mode requires that the device " |
672 | "tree specify a tbi-handle\n"); | ||
673 | return; | ||
674 | } | ||
579 | 675 | ||
580 | /* If the link is already up, we must already be ok, and don't need to | 676 | /* |
677 | * If the link is already up, we must already be ok, and don't need to | ||
581 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | 678 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured |
582 | * everything for us? Resetting it takes the link down and requires | 679 | * everything for us? Resetting it takes the link down and requires |
583 | * several seconds for it to come back. | 680 | * several seconds for it to come back. |
584 | */ | 681 | */ |
585 | if (gfar_local_mdio_read(regs, tbipa, MII_BMSR) & BMSR_LSTATUS) | 682 | if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS) |
586 | goto done; | 683 | return; |
587 | 684 | ||
588 | /* Single clk mode, mii mode off(for serdes communication) */ | 685 | /* Single clk mode, mii mode off(for serdes communication) */ |
589 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); | 686 | phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT); |
590 | 687 | ||
591 | gfar_local_mdio_write(regs, tbipa, MII_ADVERTISE, | 688 | phy_write(priv->tbiphy, MII_ADVERTISE, |
592 | ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | | 689 | ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | |
593 | ADVERTISE_1000XPSE_ASYM); | 690 | ADVERTISE_1000XPSE_ASYM); |
594 | 691 | ||
595 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | | 692 | phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE | |
596 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); | 693 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); |
597 | |||
598 | done: | ||
599 | if (bus) | ||
600 | mutex_unlock(&bus->mdio_lock); | ||
601 | } | 694 | } |
602 | 695 | ||
603 | static void init_registers(struct net_device *dev) | 696 | static void init_registers(struct net_device *dev) |
@@ -630,7 +723,7 @@ static void init_registers(struct net_device *dev) | |||
630 | gfar_write(&priv->regs->gaddr7, 0); | 723 | gfar_write(&priv->regs->gaddr7, 0); |
631 | 724 | ||
632 | /* Zero out the rmon mib registers if it has them */ | 725 | /* Zero out the rmon mib registers if it has them */ |
633 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { | 726 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { |
634 | memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib)); | 727 | memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib)); |
635 | 728 | ||
636 | /* Mask off the CAM interrupts */ | 729 | /* Mask off the CAM interrupts */ |
@@ -705,7 +798,7 @@ void stop_gfar(struct net_device *dev) | |||
705 | spin_unlock_irqrestore(&priv->txlock, flags); | 798 | spin_unlock_irqrestore(&priv->txlock, flags); |
706 | 799 | ||
707 | /* Free the IRQs */ | 800 | /* Free the IRQs */ |
708 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 801 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
709 | free_irq(priv->interruptError, dev); | 802 | free_irq(priv->interruptError, dev); |
710 | free_irq(priv->interruptTransmit, dev); | 803 | free_irq(priv->interruptTransmit, dev); |
711 | free_irq(priv->interruptReceive, dev); | 804 | free_irq(priv->interruptReceive, dev); |
@@ -919,7 +1012,7 @@ int startup_gfar(struct net_device *dev) | |||
919 | 1012 | ||
920 | /* If the device has multiple interrupts, register for | 1013 | /* If the device has multiple interrupts, register for |
921 | * them. Otherwise, only register for the one */ | 1014 | * them. Otherwise, only register for the one */ |
922 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 1015 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
923 | /* Install our interrupt handlers for Error, | 1016 | /* Install our interrupt handlers for Error, |
924 | * Transmit, and Receive */ | 1017 | * Transmit, and Receive */ |
925 | if (request_irq(priv->interruptError, gfar_error, | 1018 | if (request_irq(priv->interruptError, gfar_error, |
@@ -1751,7 +1844,7 @@ static void gfar_netpoll(struct net_device *dev) | |||
1751 | struct gfar_private *priv = netdev_priv(dev); | 1844 | struct gfar_private *priv = netdev_priv(dev); |
1752 | 1845 | ||
1753 | /* If the device has multiple interrupts, run tx/rx */ | 1846 | /* If the device has multiple interrupts, run tx/rx */ |
1754 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 1847 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
1755 | disable_irq(priv->interruptTransmit); | 1848 | disable_irq(priv->interruptTransmit); |
1756 | disable_irq(priv->interruptReceive); | 1849 | disable_irq(priv->interruptReceive); |
1757 | disable_irq(priv->interruptError); | 1850 | disable_irq(priv->interruptError); |
@@ -2045,7 +2138,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id) | |||
2045 | gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK); | 2138 | gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK); |
2046 | 2139 | ||
2047 | /* Magic Packet is not an error. */ | 2140 | /* Magic Packet is not an error. */ |
2048 | if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && | 2141 | if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && |
2049 | (events & IEVENT_MAG)) | 2142 | (events & IEVENT_MAG)) |
2050 | events &= ~IEVENT_MAG; | 2143 | events &= ~IEVENT_MAG; |
2051 | 2144 | ||
@@ -2111,16 +2204,24 @@ static irqreturn_t gfar_error(int irq, void *dev_id) | |||
2111 | /* work with hotplug and coldplug */ | 2204 | /* work with hotplug and coldplug */ |
2112 | MODULE_ALIAS("platform:fsl-gianfar"); | 2205 | MODULE_ALIAS("platform:fsl-gianfar"); |
2113 | 2206 | ||
2207 | static struct of_device_id gfar_match[] = | ||
2208 | { | ||
2209 | { | ||
2210 | .type = "network", | ||
2211 | .compatible = "gianfar", | ||
2212 | }, | ||
2213 | {}, | ||
2214 | }; | ||
2215 | |||
2114 | /* Structure for a device driver */ | 2216 | /* Structure for a device driver */ |
2115 | static struct platform_driver gfar_driver = { | 2217 | static struct of_platform_driver gfar_driver = { |
2218 | .name = "fsl-gianfar", | ||
2219 | .match_table = gfar_match, | ||
2220 | |||
2116 | .probe = gfar_probe, | 2221 | .probe = gfar_probe, |
2117 | .remove = gfar_remove, | 2222 | .remove = gfar_remove, |
2118 | .suspend = gfar_suspend, | 2223 | .suspend = gfar_suspend, |
2119 | .resume = gfar_resume, | 2224 | .resume = gfar_resume, |
2120 | .driver = { | ||
2121 | .name = "fsl-gianfar", | ||
2122 | .owner = THIS_MODULE, | ||
2123 | }, | ||
2124 | }; | 2225 | }; |
2125 | 2226 | ||
2126 | static int __init gfar_init(void) | 2227 | static int __init gfar_init(void) |
@@ -2130,7 +2231,7 @@ static int __init gfar_init(void) | |||
2130 | if (err) | 2231 | if (err) |
2131 | return err; | 2232 | return err; |
2132 | 2233 | ||
2133 | err = platform_driver_register(&gfar_driver); | 2234 | err = of_register_platform_driver(&gfar_driver); |
2134 | 2235 | ||
2135 | if (err) | 2236 | if (err) |
2136 | gfar_mdio_exit(); | 2237 | gfar_mdio_exit(); |
@@ -2140,7 +2241,7 @@ static int __init gfar_init(void) | |||
2140 | 2241 | ||
2141 | static void __exit gfar_exit(void) | 2242 | static void __exit gfar_exit(void) |
2142 | { | 2243 | { |
2143 | platform_driver_unregister(&gfar_driver); | 2244 | of_unregister_platform_driver(&gfar_driver); |
2144 | gfar_mdio_exit(); | 2245 | gfar_mdio_exit(); |
2145 | } | 2246 | } |
2146 | 2247 | ||