Signed-off-by: Scott Wood [EMAIL PROTECTED]
---
Documentation/powerpc/booting-without-of.txt |5 +-
arch/powerpc/sysdev/fsl_soc.c|3 +
drivers/net/gianfar.c| 118 +-
drivers/net/gianfar.h| 12 ++-
drivers/net/gianfar_ethtool.c| 41 +-
include/linux/fsl_devices.h |1 +
6 files changed, 172 insertions(+), 8 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt
b/Documentation/powerpc/booting-without-of.txt
index 8aee3bd..145903a 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1301,14 +1301,15 @@ platforms are moved over to use the
flattened-device-tree model.
1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
- Recommended properties:
+ Other properties:
- phy-connection-type : a string naming the controller/PHY interface type,
i.e., mii (default), rmii, gmii, rgmii, rgmii-id, sgmii,
tbi, or rtbi. This property is only really needed if the connection
is of type rgmii-id, as all other connection types are detected by
hardware.
-
+- fsl,magic-packet : If present, indicates that the hardware supports
+ waking up via magic packet.
Example:
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ca54563..2fcd714 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -357,6 +357,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;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 25bdd08..f218dcc 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -142,6 +142,7 @@ static int gfar_clean_tx_ring(struct net_device *dev);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int
length);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
+static void gfar_halt_nodisable(struct net_device *dev);
void gfar_halt(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
@@ -216,6 +217,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);
@@ -393,6 +395,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)) {
+