netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [(broken) PATCH] Sungem and wake_on_lan
@ 2004-11-09 14:11 Colin Leroy
  2004-11-10 22:57 ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 2+ messages in thread
From: Colin Leroy @ 2004-11-09 14:11 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev

Hi everyone,

I'm trying to implement wake_on_lan in sungem. I did it by mimicking the
Darwin AppleGMACEthernet driver. 
I have some problems with it; not only it doesn't work (pinging the
target machine does not wake it up, nor does ether-wake.c), but also the
normal resume crashes instead of working - before powering screen up,
so no log available...

My laptop has a BCM5221 PHY, I suppose it supports WOL but did not
check. Anyway it shouldn't crash on normal resume, as Darwin's driver
doesn't seem to have special cases depending on PHYs.

Before putting the laptop to sleep, I issue a 'sudo ethtool -s eth0 wol p'
to enable gp->wake_on_lan.

Here's the patch, in case anyone (BenH, David Miller ? :)) has an idea
about something i do wrong. 
Thanks,
-- 
Colin

diff -ur /tmp/linux-2.6.9/drivers/net/sungem.c drivers/net/sungem.c
--- /tmp/linux-2.6.9/drivers/net/sungem.c	2004-10-18 23:55:28.000000000 +0200
+++ drivers/net/sungem.c	2004-11-09 14:40:04.000000000 +0100
@@ -2132,7 +2132,29 @@
 	writel(mifcfg, gp->regs + MIF_CFG);
 
 	if (gp->wake_on_lan) {
-		/* Setup wake-on-lan */
+		u32 val_wake_up;
+		u32 xif_cfg = readl(gp->regs + MAC_XIFCFG);
+		unsigned char *e = &gp->dev->dev_addr[0];
+
+		/* set these bits for multicast filtering */
+		writel(MAC_RXCFG_HFE|MAC_RXCFG_SFCS|MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
+
+		/* write our MAC address */
+		writel((e[0] << 8) | e[1], gp->regs + MAC_WOL_MAGIC2);
+		writel((e[2] << 8) | e[3], gp->regs + MAC_WOL_MAGIC1);
+		writel((e[4] << 8) | e[5], gp->regs + MAC_WOL_MAGIC0);
+
+		/* write the pattern match count */
+		writel(PAT_MATCH_M | PAT_MATCH_N, gp->regs + PAT_MATCH_CFG);
+		
+		/* enable WOL */
+		val_wake_up = WOL_ENABLE;
+		if (!(xif_cfg & MAC_XIFCFG_GMII))
+			val_wake_up |= WOL_MODE_MII;
+		writel(val_wake_up, gp->regs + WOL_CSR_CFG);
+
+		/* sleep a bit, just to be sure */
+		msleep(10);
 	} else {
 		writel(0, gp->regs + MAC_RXCFG);
 		(void)readl(gp->regs + MAC_RXCFG);
@@ -2159,7 +2181,7 @@
 	}
 
 	if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend)
-		gp->phy_mii.def->ops->suspend(&gp->phy_mii, 0 /* wake on lan options */);
+		gp->phy_mii.def->ops->suspend(&gp->phy_mii, gp->wake_on_lan);
 
 	if (!gp->wake_on_lan) {
 		/* According to Apple, we must set the MDIO pins to this begnign
@@ -2622,13 +2644,30 @@
 	struct gem *gp = dev->priv;
 	return gp->msg_enable;
 }
-  
+
 static void gem_set_msglevel(struct net_device *dev, u32 value)
 {
 	struct gem *gp = dev->priv;
 	gp->msg_enable = value;
 }
-  
+
+static void gem_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct gem *gp = dev->priv;
+	wol->wolopts   = 0; 
+	/* let's say we support this, altough I don't know what it is */
+	wol->supported = WAKE_PHY|WAKE_UCAST;
+	if (gp->wake_on_lan == 1)
+		wol->wolopts = wol->supported;
+}
+
+static int gem_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct gem *gp = dev->priv;
+	gp->wake_on_lan = (wol->wolopts != 0);
+	return 0;
+}
+
 static struct ethtool_ops gem_ethtool_ops = {
 	.get_drvinfo		= gem_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
@@ -2637,6 +2676,8 @@
 	.nway_reset		= gem_nway_reset,
 	.get_msglevel		= gem_get_msglevel,
 	.set_msglevel		= gem_set_msglevel,
+	.get_wol		= gem_get_wol,
+	.set_wol		= gem_set_wol,
 };
 
 static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
diff -ur /tmp/linux-2.6.9/drivers/net/sungem.h drivers/net/sungem.h
--- /tmp/linux-2.6.9/drivers/net/sungem.h	2004-10-18 23:54:32.000000000 +0200
+++ drivers/net/sungem.h	2004-11-09 10:10:46.000000000 +0100
@@ -276,6 +276,9 @@
  */
 
 /* MAC Registers */
+#define MAC_WOL_MAGIC0	0x3000UL	/* six address bytes		*/
+#define MAC_WOL_MAGIC1	0x3004UL	
+#define MAC_WOL_MAGIC2	0x3008UL
 #define MAC_TXRST	0x6000UL	/* TX MAC Software Reset Command*/
 #define MAC_RXRST	0x6004UL	/* RX MAC Software Reset Command*/
 #define MAC_SNDPAUSE	0x6008UL	/* Send Pause Command Register	*/
@@ -750,6 +753,16 @@
 #define PCS_SCTRL_TXZ	0x0000c000	/* PLL input to Serialink	*/
 #define PCS_SCTRL_TXP	0x00030000	/* PLL input to Serialink	*/
 
+/* Pattern Match Count register. */
+#define PAT_MATCH_CFG	0x300CUL
+#define PAT_MATCH_N	0x0010UL
+#define PAT_MATCH_M	0x0000UL 	/* Darwin source notes (0<<8) !?*/
+
+/* Wake on Lan CSR Register */
+#define WOL_CSR_CFG	0x3010UL
+#define WOL_ENABLE	0x0001UL
+#define WOL_MODE_MII	0x0002UL
+
 /* Shared Output Select Register.  For test and debug, allows multiplexing
  * test outputs into the PROM address pins.  Set to zero for normal
  * operation.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-11-10 22:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-09 14:11 [(broken) PATCH] Sungem and wake_on_lan Colin Leroy
2004-11-10 22:57 ` Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).