aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index a06d8d1aaceb..baa35144134c 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -9,7 +9,7 @@
9 * Author: Andy Fleming 9 * Author: Andy Fleming
10 * Maintainer: Kumar Gala 10 * Maintainer: Kumar Gala
11 * 11 *
12 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. 12 * Copyright (c) 2002-2006 Freescale Semiconductor, Inc.
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify it 14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the 15 * under the terms of the GNU General Public License as published by the
@@ -133,6 +133,9 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
133#ifdef CONFIG_GFAR_NAPI 133#ifdef CONFIG_GFAR_NAPI
134static int gfar_poll(struct net_device *dev, int *budget); 134static int gfar_poll(struct net_device *dev, int *budget);
135#endif 135#endif
136#ifdef CONFIG_NET_POLL_CONTROLLER
137static void gfar_netpoll(struct net_device *dev);
138#endif
136int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); 139int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
137static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); 140static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
138static void gfar_vlan_rx_register(struct net_device *netdev, 141static void gfar_vlan_rx_register(struct net_device *netdev,
@@ -260,6 +263,9 @@ static int gfar_probe(struct platform_device *pdev)
260 dev->poll = gfar_poll; 263 dev->poll = gfar_poll;
261 dev->weight = GFAR_DEV_WEIGHT; 264 dev->weight = GFAR_DEV_WEIGHT;
262#endif 265#endif
266#ifdef CONFIG_NET_POLL_CONTROLLER
267 dev->poll_controller = gfar_netpoll;
268#endif
263 dev->stop = gfar_close; 269 dev->stop = gfar_close;
264 dev->get_stats = gfar_get_stats; 270 dev->get_stats = gfar_get_stats;
265 dev->change_mtu = gfar_change_mtu; 271 dev->change_mtu = gfar_change_mtu;
@@ -392,6 +398,38 @@ static int gfar_remove(struct platform_device *pdev)
392} 398}
393 399
394 400
401/* Reads the controller's registers to determine what interface
402 * connects it to the PHY.
403 */
404static phy_interface_t gfar_get_interface(struct net_device *dev)
405{
406 struct gfar_private *priv = netdev_priv(dev);
407 u32 ecntrl = gfar_read(&priv->regs->ecntrl);
408
409 if (ecntrl & ECNTRL_SGMII_MODE)
410 return PHY_INTERFACE_MODE_SGMII;
411
412 if (ecntrl & ECNTRL_TBI_MODE) {
413 if (ecntrl & ECNTRL_REDUCED_MODE)
414 return PHY_INTERFACE_MODE_RTBI;
415 else
416 return PHY_INTERFACE_MODE_TBI;
417 }
418
419 if (ecntrl & ECNTRL_REDUCED_MODE) {
420 if (ecntrl & ECNTRL_REDUCED_MII_MODE)
421 return PHY_INTERFACE_MODE_RMII;
422 else
423 return PHY_INTERFACE_MODE_RGMII;
424 }
425
426 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
427 return PHY_INTERFACE_MODE_GMII;
428
429 return PHY_INTERFACE_MODE_MII;
430}
431
432
395/* Initializes driver's PHY state, and attaches to the PHY. 433/* Initializes driver's PHY state, and attaches to the PHY.
396 * Returns 0 on success. 434 * Returns 0 on success.
397 */ 435 */
@@ -403,6 +441,7 @@ static int init_phy(struct net_device *dev)
403 SUPPORTED_1000baseT_Full : 0; 441 SUPPORTED_1000baseT_Full : 0;
404 struct phy_device *phydev; 442 struct phy_device *phydev;
405 char phy_id[BUS_ID_SIZE]; 443 char phy_id[BUS_ID_SIZE];
444 phy_interface_t interface;
406 445
407 priv->oldlink = 0; 446 priv->oldlink = 0;
408 priv->oldspeed = 0; 447 priv->oldspeed = 0;
@@ -410,7 +449,9 @@ static int init_phy(struct net_device *dev)
410 449
411 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id); 450 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id);
412 451
413 phydev = phy_connect(dev, phy_id, &adjust_link, 0); 452 interface = gfar_get_interface(dev);
453
454 phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
414 455
415 if (IS_ERR(phydev)) { 456 if (IS_ERR(phydev)) {
416 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); 457 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -1536,6 +1577,33 @@ static int gfar_poll(struct net_device *dev, int *budget)
1536} 1577}
1537#endif 1578#endif
1538 1579
1580#ifdef CONFIG_NET_POLL_CONTROLLER
1581/*
1582 * Polling 'interrupt' - used by things like netconsole to send skbs
1583 * without having to re-enable interrupts. It's not called while
1584 * the interrupt routine is executing.
1585 */
1586static void gfar_netpoll(struct net_device *dev)
1587{
1588 struct gfar_private *priv = netdev_priv(dev);
1589
1590 /* If the device has multiple interrupts, run tx/rx */
1591 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
1592 disable_irq(priv->interruptTransmit);
1593 disable_irq(priv->interruptReceive);
1594 disable_irq(priv->interruptError);
1595 gfar_interrupt(priv->interruptTransmit, dev);
1596 enable_irq(priv->interruptError);
1597 enable_irq(priv->interruptReceive);
1598 enable_irq(priv->interruptTransmit);
1599 } else {
1600 disable_irq(priv->interruptTransmit);
1601 gfar_interrupt(priv->interruptTransmit, dev);
1602 enable_irq(priv->interruptTransmit);
1603 }
1604}
1605#endif
1606
1539/* The interrupt handler for devices with one interrupt */ 1607/* The interrupt handler for devices with one interrupt */
1540static irqreturn_t gfar_interrupt(int irq, void *dev_id) 1608static irqreturn_t gfar_interrupt(int irq, void *dev_id)
1541{ 1609{