aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar_ethtool.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2008-07-11 19:04:45 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-07-16 18:57:47 -0400
commitd87eb12785c14de1586e3bad86ca2c0991300339 (patch)
tree9caa5a958d88910049a03bbfbd1a8a3367b6332b /drivers/net/gianfar_ethtool.c
parent7e1cc9c55a2a4af62f30fade62fb612a243def39 (diff)
gianfar: Add magic packet and suspend/resume support.
Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'drivers/net/gianfar_ethtool.c')
-rw-r--r--drivers/net/gianfar_ethtool.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 6007147cc1e9..fb7d3ccc0fdc 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
479static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) 479static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
480{ 480{
481 struct gfar_private *priv = netdev_priv(dev); 481 struct gfar_private *priv = netdev_priv(dev);
482 unsigned long flags;
482 int err = 0; 483 int err = 0;
483 484
484 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 485 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
485 return -EOPNOTSUPP; 486 return -EOPNOTSUPP;
486 487
487 if (dev->flags & IFF_UP) { 488 if (dev->flags & IFF_UP) {
488 unsigned long flags;
489
490 /* Halt TX and RX, and process the frames which 489 /* Halt TX and RX, and process the frames which
491 * have already been received */ 490 * have already been received */
492 spin_lock_irqsave(&priv->txlock, flags); 491 spin_lock_irqsave(&priv->txlock, flags);
@@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
502 stop_gfar(dev); 501 stop_gfar(dev);
503 } 502 }
504 503
504 spin_lock_irqsave(&priv->bflock, flags);
505 priv->rx_csum_enable = data; 505 priv->rx_csum_enable = data;
506 spin_unlock_irqrestore(&priv->bflock, flags);
506 507
507 if (dev->flags & IFF_UP) 508 if (dev->flags & IFF_UP)
508 err = startup_gfar(dev); 509 err = startup_gfar(dev);
@@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
564 priv->msg_enable = data; 565 priv->msg_enable = data;
565} 566}
566 567
568#ifdef CONFIG_PM
569static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
570{
571 struct gfar_private *priv = netdev_priv(dev);
572
573 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
574 wol->supported = WAKE_MAGIC;
575 wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
576 } else {
577 wol->supported = wol->wolopts = 0;
578 }
579}
580
581static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
582{
583 struct gfar_private *priv = netdev_priv(dev);
584 unsigned long flags;
585
586 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
587 wol->wolopts != 0)
588 return -EINVAL;
589
590 if (wol->wolopts & ~WAKE_MAGIC)
591 return -EINVAL;
592
593 spin_lock_irqsave(&priv->bflock, flags);
594 priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
595 spin_unlock_irqrestore(&priv->bflock, flags);
596
597 return 0;
598}
599#endif
567 600
568const struct ethtool_ops gfar_ethtool_ops = { 601const struct ethtool_ops gfar_ethtool_ops = {
569 .get_settings = gfar_gsettings, 602 .get_settings = gfar_gsettings,
@@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = {
585 .set_tx_csum = gfar_set_tx_csum, 618 .set_tx_csum = gfar_set_tx_csum,
586 .get_msglevel = gfar_get_msglevel, 619 .get_msglevel = gfar_get_msglevel,
587 .set_msglevel = gfar_set_msglevel, 620 .set_msglevel = gfar_set_msglevel,
621#ifdef CONFIG_PM
622 .get_wol = gfar_get_wol,
623 .set_wol = gfar_set_wol,
624#endif
588}; 625};