diff options
author | Andy Fleming <afleming@freescale.com> | 2008-12-16 18:29:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-16 18:29:15 -0500 |
commit | b31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 (patch) | |
tree | f8643c2fd1b137dd6c00bcd385ad36adfca4f540 /drivers/net/gianfar.c | |
parent | 257d938a0c17838c740eb68f0005b041444ac2c2 (diff) |
gianfar: Convert gianfar to an of_platform_driver
Does the same for the accompanying MDIO driver, and then modifies the TBI
configuration method. The old way used fields in einfo, which no longer
exists. The new way is to create an MDIO device-tree node for each instance
of gianfar, and create a tbi-handle property to associate ethernet controllers
with the TBI PHYs they are connected to.
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 | ||