Loading arch/powerpc/sysdev/fsl_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ static int __init gfar_of_init(void) else gfar_data.interface = PHY_INTERFACE_MODE_MII; if (of_get_property(np, "fsl,magic-packet", NULL)) gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; ph = of_get_property(np, "phy-handle", NULL); if (ph == NULL) { u32 *fixed_link; Loading drivers/net/gianfar.c +120 −2 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l static void gfar_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); void gfar_halt(struct net_device *dev); #ifdef CONFIG_PM static void gfar_halt_nodisable(struct net_device *dev); #endif void gfar_start(struct net_device *dev); static void gfar_clear_exact_match(struct net_device *dev); static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); Loading Loading @@ -216,6 +219,7 @@ static int gfar_probe(struct platform_device *pdev) spin_lock_init(&priv->txlock); spin_lock_init(&priv->rxlock); spin_lock_init(&priv->bflock); platform_set_drvdata(pdev, dev); Loading Loading @@ -393,6 +397,103 @@ static int gfar_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM static int gfar_suspend(struct platform_device *pdev, pm_message_t state) { struct net_device *dev = platform_get_drvdata(pdev); struct gfar_private *priv = netdev_priv(dev); unsigned long flags; u32 tempval; int magic_packet = priv->wol_en && (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); netif_device_detach(dev); if (netif_running(dev)) { spin_lock_irqsave(&priv->txlock, flags); spin_lock(&priv->rxlock); gfar_halt_nodisable(dev); /* Disable Tx, and Rx if wake-on-LAN is disabled. */ tempval = gfar_read(&priv->regs->maccfg1); tempval &= ~MACCFG1_TX_EN; if (!magic_packet) tempval &= ~MACCFG1_RX_EN; gfar_write(&priv->regs->maccfg1, tempval); spin_unlock(&priv->rxlock); spin_unlock_irqrestore(&priv->txlock, flags); #ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); #endif if (magic_packet) { /* Enable interrupt on Magic Packet */ gfar_write(&priv->regs->imask, IMASK_MAG); /* Enable Magic Packet mode */ tempval = gfar_read(&priv->regs->maccfg2); tempval |= MACCFG2_MPEN; gfar_write(&priv->regs->maccfg2, tempval); } else { phy_stop(priv->phydev); } } return 0; } static int gfar_resume(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct gfar_private *priv = netdev_priv(dev); unsigned long flags; u32 tempval; int magic_packet = priv->wol_en && (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); if (!netif_running(dev)) { netif_device_attach(dev); return 0; } if (!magic_packet && priv->phydev) phy_start(priv->phydev); /* Disable Magic Packet mode, in case something * else woke us up. */ spin_lock_irqsave(&priv->txlock, flags); spin_lock(&priv->rxlock); tempval = gfar_read(&priv->regs->maccfg2); tempval &= ~MACCFG2_MPEN; gfar_write(&priv->regs->maccfg2, tempval); gfar_start(dev); spin_unlock(&priv->rxlock); spin_unlock_irqrestore(&priv->txlock, flags); netif_device_attach(dev); #ifdef CONFIG_GFAR_NAPI napi_enable(&priv->napi); #endif return 0; } #else #define gfar_suspend NULL #define gfar_resume NULL #endif /* Reads the controller's registers to determine what interface * connects it to the PHY. Loading Loading @@ -549,8 +650,9 @@ static void init_registers(struct net_device *dev) } #ifdef CONFIG_PM /* Halt the receive and transmit queues */ void gfar_halt(struct net_device *dev) static void gfar_halt_nodisable(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = priv->regs; Loading @@ -573,6 +675,15 @@ void gfar_halt(struct net_device *dev) (IEVENT_GRSC | IEVENT_GTSC))) cpu_relax(); } } #endif /* Halt the receive and transmit queues */ void gfar_halt(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = priv->regs; u32 tempval; /* Disable Rx and Tx */ tempval = gfar_read(®s->maccfg1); Loading Loading @@ -1969,7 +2080,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id) u32 events = gfar_read(&priv->regs->ievent); /* Clear IEVENT */ gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK); gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK); /* Magic Packet is not an error. */ if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && (events & IEVENT_MAG)) events &= ~IEVENT_MAG; /* Hmm... */ if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) Loading Loading @@ -2042,6 +2158,8 @@ MODULE_ALIAS("platform:fsl-gianfar"); static struct platform_driver gfar_driver = { .probe = gfar_probe, .remove = gfar_remove, .suspend = gfar_suspend, .resume = gfar_resume, .driver = { .name = "fsl-gianfar", .owner = THIS_MODULE, Loading drivers/net/gianfar.h +10 −2 Original line number Diff line number Diff line Loading @@ -168,6 +168,7 @@ extern const char gfar_driver_version[]; #define MACCFG2_GMII 0x00000200 #define MACCFG2_HUGEFRAME 0x00000020 #define MACCFG2_LENGTHCHECK 0x00000010 #define MACCFG2_MPEN 0x00000008 #define ECNTRL_INIT_SETTINGS 0x00001000 #define ECNTRL_TBI_MODE 0x00000020 Loading Loading @@ -240,6 +241,7 @@ extern const char gfar_driver_version[]; #define IEVENT_CRL 0x00020000 #define IEVENT_XFUN 0x00010000 #define IEVENT_RXB0 0x00008000 #define IEVENT_MAG 0x00000800 #define IEVENT_GRSC 0x00000100 #define IEVENT_RXF0 0x00000080 #define IEVENT_FIR 0x00000008 Loading @@ -252,7 +254,8 @@ extern const char gfar_driver_version[]; #define IEVENT_ERR_MASK \ (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR) | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \ | IEVENT_MAG) #define IMASK_INIT_CLEAR 0x00000000 #define IMASK_BABR 0x80000000 Loading @@ -270,6 +273,7 @@ extern const char gfar_driver_version[]; #define IMASK_CRL 0x00020000 #define IMASK_XFUN 0x00010000 #define IMASK_RXB0 0x00008000 #define IMASK_MAG 0x00000800 #define IMASK_GTSC 0x00000100 #define IMASK_RXFEN0 0x00000080 #define IMASK_FIR 0x00000008 Loading Loading @@ -737,10 +741,14 @@ struct gfar_private { unsigned int fifo_starve; unsigned int fifo_starve_off; /* Bitfield update lock */ spinlock_t bflock; unsigned char vlan_enable:1, rx_csum_enable:1, extended_hash:1, bd_stash_en:1; bd_stash_en:1, wol_en:1; /* Wake-on-LAN enabled */ unsigned short padding; unsigned int interruptTransmit; Loading drivers/net/gianfar_ethtool.c +39 −2 Original line number Diff line number Diff line Loading @@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; int err = 0; if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) return -EOPNOTSUPP; if (dev->flags & IFF_UP) { unsigned long flags; /* Halt TX and RX, and process the frames which * have already been received */ spin_lock_irqsave(&priv->txlock, flags); Loading @@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) stop_gfar(dev); } spin_lock_irqsave(&priv->bflock, flags); priv->rx_csum_enable = data; spin_unlock_irqrestore(&priv->bflock, flags); if (dev->flags & IFF_UP) err = startup_gfar(dev); Loading Loading @@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data) priv->msg_enable = data; } #ifdef CONFIG_PM static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct gfar_private *priv = netdev_priv(dev); if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) { wol->supported = WAKE_MAGIC; wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0; } else { wol->supported = wol->wolopts = 0; } } static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && wol->wolopts != 0) return -EINVAL; if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; spin_lock_irqsave(&priv->bflock, flags); priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0; spin_unlock_irqrestore(&priv->bflock, flags); return 0; } #endif const struct ethtool_ops gfar_ethtool_ops = { .get_settings = gfar_gsettings, Loading @@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = { .set_tx_csum = gfar_set_tx_csum, .get_msglevel = gfar_get_msglevel, .set_msglevel = gfar_set_msglevel, #ifdef CONFIG_PM .get_wol = gfar_get_wol, .set_wol = gfar_set_wol, #endif }; include/linux/fsl_devices.h +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ struct gianfar_mdio_data { #define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020 #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040 #define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080 #define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100 /* Flags in gianfar_platform_data */ #define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */ Loading Loading
arch/powerpc/sysdev/fsl_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ static int __init gfar_of_init(void) else gfar_data.interface = PHY_INTERFACE_MODE_MII; if (of_get_property(np, "fsl,magic-packet", NULL)) gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; ph = of_get_property(np, "phy-handle", NULL); if (ph == NULL) { u32 *fixed_link; Loading
drivers/net/gianfar.c +120 −2 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l static void gfar_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); void gfar_halt(struct net_device *dev); #ifdef CONFIG_PM static void gfar_halt_nodisable(struct net_device *dev); #endif void gfar_start(struct net_device *dev); static void gfar_clear_exact_match(struct net_device *dev); static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); Loading Loading @@ -216,6 +219,7 @@ static int gfar_probe(struct platform_device *pdev) spin_lock_init(&priv->txlock); spin_lock_init(&priv->rxlock); spin_lock_init(&priv->bflock); platform_set_drvdata(pdev, dev); Loading Loading @@ -393,6 +397,103 @@ static int gfar_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM static int gfar_suspend(struct platform_device *pdev, pm_message_t state) { struct net_device *dev = platform_get_drvdata(pdev); struct gfar_private *priv = netdev_priv(dev); unsigned long flags; u32 tempval; int magic_packet = priv->wol_en && (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); netif_device_detach(dev); if (netif_running(dev)) { spin_lock_irqsave(&priv->txlock, flags); spin_lock(&priv->rxlock); gfar_halt_nodisable(dev); /* Disable Tx, and Rx if wake-on-LAN is disabled. */ tempval = gfar_read(&priv->regs->maccfg1); tempval &= ~MACCFG1_TX_EN; if (!magic_packet) tempval &= ~MACCFG1_RX_EN; gfar_write(&priv->regs->maccfg1, tempval); spin_unlock(&priv->rxlock); spin_unlock_irqrestore(&priv->txlock, flags); #ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); #endif if (magic_packet) { /* Enable interrupt on Magic Packet */ gfar_write(&priv->regs->imask, IMASK_MAG); /* Enable Magic Packet mode */ tempval = gfar_read(&priv->regs->maccfg2); tempval |= MACCFG2_MPEN; gfar_write(&priv->regs->maccfg2, tempval); } else { phy_stop(priv->phydev); } } return 0; } static int gfar_resume(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct gfar_private *priv = netdev_priv(dev); unsigned long flags; u32 tempval; int magic_packet = priv->wol_en && (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); if (!netif_running(dev)) { netif_device_attach(dev); return 0; } if (!magic_packet && priv->phydev) phy_start(priv->phydev); /* Disable Magic Packet mode, in case something * else woke us up. */ spin_lock_irqsave(&priv->txlock, flags); spin_lock(&priv->rxlock); tempval = gfar_read(&priv->regs->maccfg2); tempval &= ~MACCFG2_MPEN; gfar_write(&priv->regs->maccfg2, tempval); gfar_start(dev); spin_unlock(&priv->rxlock); spin_unlock_irqrestore(&priv->txlock, flags); netif_device_attach(dev); #ifdef CONFIG_GFAR_NAPI napi_enable(&priv->napi); #endif return 0; } #else #define gfar_suspend NULL #define gfar_resume NULL #endif /* Reads the controller's registers to determine what interface * connects it to the PHY. Loading Loading @@ -549,8 +650,9 @@ static void init_registers(struct net_device *dev) } #ifdef CONFIG_PM /* Halt the receive and transmit queues */ void gfar_halt(struct net_device *dev) static void gfar_halt_nodisable(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = priv->regs; Loading @@ -573,6 +675,15 @@ void gfar_halt(struct net_device *dev) (IEVENT_GRSC | IEVENT_GTSC))) cpu_relax(); } } #endif /* Halt the receive and transmit queues */ void gfar_halt(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = priv->regs; u32 tempval; /* Disable Rx and Tx */ tempval = gfar_read(®s->maccfg1); Loading Loading @@ -1969,7 +2080,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id) u32 events = gfar_read(&priv->regs->ievent); /* Clear IEVENT */ gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK); gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK); /* Magic Packet is not an error. */ if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && (events & IEVENT_MAG)) events &= ~IEVENT_MAG; /* Hmm... */ if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) Loading Loading @@ -2042,6 +2158,8 @@ MODULE_ALIAS("platform:fsl-gianfar"); static struct platform_driver gfar_driver = { .probe = gfar_probe, .remove = gfar_remove, .suspend = gfar_suspend, .resume = gfar_resume, .driver = { .name = "fsl-gianfar", .owner = THIS_MODULE, Loading
drivers/net/gianfar.h +10 −2 Original line number Diff line number Diff line Loading @@ -168,6 +168,7 @@ extern const char gfar_driver_version[]; #define MACCFG2_GMII 0x00000200 #define MACCFG2_HUGEFRAME 0x00000020 #define MACCFG2_LENGTHCHECK 0x00000010 #define MACCFG2_MPEN 0x00000008 #define ECNTRL_INIT_SETTINGS 0x00001000 #define ECNTRL_TBI_MODE 0x00000020 Loading Loading @@ -240,6 +241,7 @@ extern const char gfar_driver_version[]; #define IEVENT_CRL 0x00020000 #define IEVENT_XFUN 0x00010000 #define IEVENT_RXB0 0x00008000 #define IEVENT_MAG 0x00000800 #define IEVENT_GRSC 0x00000100 #define IEVENT_RXF0 0x00000080 #define IEVENT_FIR 0x00000008 Loading @@ -252,7 +254,8 @@ extern const char gfar_driver_version[]; #define IEVENT_ERR_MASK \ (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR) | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \ | IEVENT_MAG) #define IMASK_INIT_CLEAR 0x00000000 #define IMASK_BABR 0x80000000 Loading @@ -270,6 +273,7 @@ extern const char gfar_driver_version[]; #define IMASK_CRL 0x00020000 #define IMASK_XFUN 0x00010000 #define IMASK_RXB0 0x00008000 #define IMASK_MAG 0x00000800 #define IMASK_GTSC 0x00000100 #define IMASK_RXFEN0 0x00000080 #define IMASK_FIR 0x00000008 Loading Loading @@ -737,10 +741,14 @@ struct gfar_private { unsigned int fifo_starve; unsigned int fifo_starve_off; /* Bitfield update lock */ spinlock_t bflock; unsigned char vlan_enable:1, rx_csum_enable:1, extended_hash:1, bd_stash_en:1; bd_stash_en:1, wol_en:1; /* Wake-on-LAN enabled */ unsigned short padding; unsigned int interruptTransmit; Loading
drivers/net/gianfar_ethtool.c +39 −2 Original line number Diff line number Diff line Loading @@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; int err = 0; if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) return -EOPNOTSUPP; if (dev->flags & IFF_UP) { unsigned long flags; /* Halt TX and RX, and process the frames which * have already been received */ spin_lock_irqsave(&priv->txlock, flags); Loading @@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) stop_gfar(dev); } spin_lock_irqsave(&priv->bflock, flags); priv->rx_csum_enable = data; spin_unlock_irqrestore(&priv->bflock, flags); if (dev->flags & IFF_UP) err = startup_gfar(dev); Loading Loading @@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data) priv->msg_enable = data; } #ifdef CONFIG_PM static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct gfar_private *priv = netdev_priv(dev); if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) { wol->supported = WAKE_MAGIC; wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0; } else { wol->supported = wol->wolopts = 0; } } static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && wol->wolopts != 0) return -EINVAL; if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; spin_lock_irqsave(&priv->bflock, flags); priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0; spin_unlock_irqrestore(&priv->bflock, flags); return 0; } #endif const struct ethtool_ops gfar_ethtool_ops = { .get_settings = gfar_gsettings, Loading @@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = { .set_tx_csum = gfar_set_tx_csum, .get_msglevel = gfar_get_msglevel, .set_msglevel = gfar_set_msglevel, #ifdef CONFIG_PM .get_wol = gfar_get_wol, .set_wol = gfar_set_wol, #endif };
include/linux/fsl_devices.h +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ struct gianfar_mdio_data { #define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020 #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040 #define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080 #define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100 /* Flags in gianfar_platform_data */ #define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */ Loading