Re: Wake on LAN support for rge(4)

2020-12-23 Thread Otto Moerbeek
On Wed, Dec 23, 2020 at 12:35:46PM +0800, Kevin Lo wrote:

> Hi,
> 
> This diff implements WoL support in rge(4).  I can wakeup the machine with WoL
> after suspending it through `zzz` or powering off it through `halt -p`.

Thanks! This works as expected in my testing.

-Otto

> 
> Index: share/man/man4/rge.4
> ===
> RCS file: /cvs/src/share/man/man4/rge.4,v
> retrieving revision 1.4
> diff -u -p -u -p -r1.4 rge.4
> --- share/man/man4/rge.4  12 Oct 2020 02:11:10 -  1.4
> +++ share/man/man4/rge.4  23 Dec 2020 04:33:26 -
> @@ -37,6 +37,15 @@ Rivet Networks Killer E3000 Adapter (250
>  .It
>  TP-LINK TL-NG421 Adapter (2500baseT)
>  .El
> +.Pp
> +The
> +.Nm
> +driver additionally supports Wake on LAN (WoL).
> +See
> +.Xr arp 8
> +and
> +.Xr ifconfig 8
> +for more details.
>  .Sh SEE ALSO
>  .Xr arp 4 ,
>  .Xr ifmedia 4 ,
> Index: sys/dev/pci/if_rge.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_rge.c,v
> retrieving revision 1.9
> diff -u -p -u -p -r1.9 if_rge.c
> --- sys/dev/pci/if_rge.c  12 Dec 2020 11:48:53 -  1.9
> +++ sys/dev/pci/if_rge.c  23 Dec 2020 04:33:27 -
> @@ -59,6 +59,7 @@ int rge_debug = 0;
>  
>  int  rge_match(struct device *, void *, void *);
>  void rge_attach(struct device *, struct device *, void *);
> +int  rge_activate(struct device *, int);
>  int  rge_intr(void *);
>  int  rge_encap(struct rge_softc *, struct mbuf *, int);
>  int  rge_ioctl(struct ifnet *, u_long, caddr_t);
> @@ -111,6 +112,10 @@ int  rge_get_link_status(struct rge_soft
>  void rge_txstart(void *);
>  void rge_tick(void *);
>  void rge_link_state(struct rge_softc *);
> +#ifndef SMALL_KERNEL
> +int  rge_wol(struct ifnet *, int);
> +void rge_wol_power(struct rge_softc *);
> +#endif
>  
>  static const struct {
>   uint16_t reg;
> @@ -126,7 +131,7 @@ static const struct {
>  };
>  
>  struct cfattach rge_ca = {
> - sizeof(struct rge_softc), rge_match, rge_attach
> + sizeof(struct rge_softc), rge_match, rge_attach, NULL, rge_activate
>  };
>  
>  struct cfdriver rge_cd = {
> @@ -272,6 +277,11 @@ rge_attach(struct device *parent, struct
>   ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
>  #endif
>  
> +#ifndef SMALL_KERNEL
> + ifp->if_capabilities |= IFCAP_WOL;
> + ifp->if_wol = rge_wol;
> + rge_wol(ifp, 0);
> +#endif
>   timeout_set(>sc_timeout, rge_tick, sc);
>   task_set(>sc_task, rge_txstart, sc);
>  
> @@ -288,6 +298,25 @@ rge_attach(struct device *parent, struct
>  }
>  
>  int
> +rge_activate(struct device *self, int act)
> +{
> + struct rge_softc *sc = (struct rge_softc *)self;
> + int rv = 0;
> +
> + switch (act) {
> + case DVACT_POWERDOWN:
> + rv = config_activate_children(self, act);
> +#ifndef SMALL_KERNEL
> + rge_wol_power(sc);
> +#endif
> + default:
> + rv = config_activate_children(self, act);
> + break;
> + }
> + return (rv);
> +}
> +
> +int
>  rge_intr(void *arg)
>  {
>   struct rge_softc *sc = arg;
> @@ -2025,6 +2054,7 @@ rge_hw_init(struct rge_softc *sc)
>   /* Set PCIe uncorrectable error status. */
>   rge_write_csi(sc, 0x108,
>   rge_read_csi(sc, 0x108) | 0x0010);
> +
>  }
>  
>  void
> @@ -2391,3 +2421,48 @@ rge_link_state(struct rge_softc *sc)
>   if_link_state_change(ifp);
>   }
>  }
> +
> +#ifndef SMALL_KERNEL
> +int
> +rge_wol(struct ifnet *ifp, int enable)
> +{
> + struct rge_softc *sc = ifp->if_softc;
> +
> + if (enable) {
> + if (!(RGE_READ_1(sc, RGE_CFG1) & RGE_CFG1_PM_EN)) {
> + printf("%s: power management is disabled, "
> + "cannot do WOL\n", sc->sc_dev.dv_xname);
> + return (ENOTSUP);
> + }
> +
> + }
> +
> + rge_iff(sc);
> +
> + if (enable)
> + RGE_MAC_SETBIT(sc, 0xc0b6, 0x0001);
> + else
> + RGE_MAC_CLRBIT(sc, 0xc0b6, 0x0001);
> +
> + RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
> + RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE | RGE_CFG5_WOL_UCAST |
> + RGE_CFG5_WOL_MCAST | RGE_CFG5_WOL_BCAST);
> + RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_WOL_LINK | RGE_CFG3_WOL_MAGIC);
> + if (en

Wake on LAN support for rge(4)

2020-12-22 Thread Kevin Lo
Hi,

This diff implements WoL support in rge(4).  I can wakeup the machine with WoL
after suspending it through `zzz` or powering off it through `halt -p`.

Index: share/man/man4/rge.4
===
RCS file: /cvs/src/share/man/man4/rge.4,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 rge.4
--- share/man/man4/rge.412 Oct 2020 02:11:10 -  1.4
+++ share/man/man4/rge.423 Dec 2020 04:33:26 -
@@ -37,6 +37,15 @@ Rivet Networks Killer E3000 Adapter (250
 .It
 TP-LINK TL-NG421 Adapter (2500baseT)
 .El
+.Pp
+The
+.Nm
+driver additionally supports Wake on LAN (WoL).
+See
+.Xr arp 8
+and
+.Xr ifconfig 8
+for more details.
 .Sh SEE ALSO
 .Xr arp 4 ,
 .Xr ifmedia 4 ,
Index: sys/dev/pci/if_rge.c
===
RCS file: /cvs/src/sys/dev/pci/if_rge.c,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 if_rge.c
--- sys/dev/pci/if_rge.c12 Dec 2020 11:48:53 -  1.9
+++ sys/dev/pci/if_rge.c23 Dec 2020 04:33:27 -
@@ -59,6 +59,7 @@ int rge_debug = 0;
 
 intrge_match(struct device *, void *, void *);
 void   rge_attach(struct device *, struct device *, void *);
+intrge_activate(struct device *, int);
 intrge_intr(void *);
 intrge_encap(struct rge_softc *, struct mbuf *, int);
 intrge_ioctl(struct ifnet *, u_long, caddr_t);
@@ -111,6 +112,10 @@ intrge_get_link_status(struct rge_soft
 void   rge_txstart(void *);
 void   rge_tick(void *);
 void   rge_link_state(struct rge_softc *);
+#ifndef SMALL_KERNEL
+intrge_wol(struct ifnet *, int);
+void   rge_wol_power(struct rge_softc *);
+#endif
 
 static const struct {
uint16_t reg;
@@ -126,7 +131,7 @@ static const struct {
 };
 
 struct cfattach rge_ca = {
-   sizeof(struct rge_softc), rge_match, rge_attach
+   sizeof(struct rge_softc), rge_match, rge_attach, NULL, rge_activate
 };
 
 struct cfdriver rge_cd = {
@@ -272,6 +277,11 @@ rge_attach(struct device *parent, struct
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
 #endif
 
+#ifndef SMALL_KERNEL
+   ifp->if_capabilities |= IFCAP_WOL;
+   ifp->if_wol = rge_wol;
+   rge_wol(ifp, 0);
+#endif
timeout_set(>sc_timeout, rge_tick, sc);
task_set(>sc_task, rge_txstart, sc);
 
@@ -288,6 +298,25 @@ rge_attach(struct device *parent, struct
 }
 
 int
+rge_activate(struct device *self, int act)
+{
+   struct rge_softc *sc = (struct rge_softc *)self;
+   int rv = 0;
+
+   switch (act) {
+   case DVACT_POWERDOWN:
+   rv = config_activate_children(self, act);
+#ifndef SMALL_KERNEL
+   rge_wol_power(sc);
+#endif
+   default:
+   rv = config_activate_children(self, act);
+   break;
+   }
+   return (rv);
+}
+
+int
 rge_intr(void *arg)
 {
struct rge_softc *sc = arg;
@@ -2025,6 +2054,7 @@ rge_hw_init(struct rge_softc *sc)
/* Set PCIe uncorrectable error status. */
rge_write_csi(sc, 0x108,
rge_read_csi(sc, 0x108) | 0x0010);
+
 }
 
 void
@@ -2391,3 +2421,48 @@ rge_link_state(struct rge_softc *sc)
if_link_state_change(ifp);
}
 }
+
+#ifndef SMALL_KERNEL
+int
+rge_wol(struct ifnet *ifp, int enable)
+{
+   struct rge_softc *sc = ifp->if_softc;
+
+   if (enable) {
+   if (!(RGE_READ_1(sc, RGE_CFG1) & RGE_CFG1_PM_EN)) {
+   printf("%s: power management is disabled, "
+   "cannot do WOL\n", sc->sc_dev.dv_xname);
+   return (ENOTSUP);
+   }
+
+   }
+
+   rge_iff(sc);
+
+   if (enable)
+   RGE_MAC_SETBIT(sc, 0xc0b6, 0x0001);
+   else
+   RGE_MAC_CLRBIT(sc, 0xc0b6, 0x0001);
+
+   RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+   RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE | RGE_CFG5_WOL_UCAST |
+   RGE_CFG5_WOL_MCAST | RGE_CFG5_WOL_BCAST);
+   RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_WOL_LINK | RGE_CFG3_WOL_MAGIC);
+   if (enable)
+   RGE_SETBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE);
+   RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+
+   return (0);
+}
+
+void
+rge_wol_power(struct rge_softc *sc)
+{
+   /* Disable RXDV gate. */
+   RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
+   DELAY(2000);
+
+   RGE_SETBIT_1(sc, RGE_CFG1, RGE_CFG1_PM_EN);
+   RGE_SETBIT_1(sc, RGE_CFG2, RGE_CFG2_PMSTS_EN);
+}
+#endif
Index: sys/dev/pci/if_rgereg.h
===
RCS file: /cvs/src/sys/dev/pci/if_rgereg.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 if_rgereg.h
--- sys/dev/pci/if_rgereg.h 22 Nov 2020 14:06:22 -  1.5
+++ sys/dev/pci/if_rgereg.h 23 Dec 2020 04:33:27 -
@@ -111,16 +111,24 @@
 #d

Re: wake on lan

2011-03-13 Thread Stefan Sperling
On Sun, Mar 13, 2011 at 01:03:19AM +0100, Stefan Sperling wrote:
 Now that arp(8) can send Wake On Lan frames (a.k.a. magic packets),
 it would be nice to have a way to configure WOL from the operating system.

Some man page fixes, and ifconfig now prints a not supported message if
the user tries to enable WOL on an interface which doesn't support WOL.
Both suggested by jmc. 

Index: sbin/ifconfig/brconfig.h
===
RCS file: /cvs/src/sbin/ifconfig/brconfig.h,v
retrieving revision 1.3
diff -u -p -r1.3 brconfig.h
--- sbin/ifconfig/brconfig.h7 Jun 2010 15:05:42 -   1.3
+++ sbin/ifconfig/brconfig.h12 Mar 2011 22:48:05 -
@@ -68,7 +68,7 @@ int bridge_rule(int, char **, int);
 
 #defineIFFBITS \
 
\024\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
-\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST\21TXREADY\22NOINET6\23INET6_PRIVACY\24MPLS
+\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST\21TXREADY\22NOINET6\23INET6_PRIVACY\24MPLS\25WOL
 
 void printb(char *, unsigned int, char *);
 
Index: sbin/ifconfig/ifconfig.8
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.213
diff -u -p -r1.213 ifconfig.8
--- sbin/ifconfig/ifconfig.817 Feb 2011 08:32:29 -  1.213
+++ sbin/ifconfig/ifconfig.813 Mar 2011 10:05:35 -
@@ -435,6 +435,26 @@ This may be used to enable an interface 
 It happens automatically when setting the first address on an interface.
 If the interface was reset when previously marked down,
 the hardware will be re-initialized.
+.Pp
+.It Cm wol
+Enable Wake On LAN (WOL).
+When enabled, reception of a WOL frame (a.k.a. Magic Packet) will cause
+the network card to power up the system from standby or suspend mode.
+WOL frames can be sent using
+.Xr arp 8 .
+Support for WOL depends on various factors, some of which may not be under
+the control of the operating system.
+Configuration parameters in the system BIOS or firmware can affect WOL.
+.Pp
+WOL should not be enabled on interfaces that can receive traffic
+from the internet.
+It should only be enabled on dedicated management interfaces connected to
+networks where no packets can be injected by untrusted parties.
+WOL frames can be sent in routable IP packets and are not authenticated.
+.It Fl wol
+Disable WOL.
+WOL is disabled by default if possible.
+The operating system cannot disable WOL on some machines.
 .El
 .Pp
 .Nm
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.244
diff -u -p -r1.244 ifconfig.c
--- sbin/ifconfig/ifconfig.c1 Mar 2011 09:37:31 -   1.244
+++ sbin/ifconfig/ifconfig.c12 Mar 2011 23:10:43 -
@@ -461,6 +461,8 @@ const structcmd {
{ descr,  NEXTARG,0,  setifdesc },
{ -description, 1,0,  unsetifdesc },
{ -descr, 1,  0,  unsetifdesc },
+   { wol,IFXF_WOL,   0,  setifxflags },
+   { -wol,   -IFXF_WOL,  0,  setifxflags },
 #else /* SMALL */
{ group,  NEXTARG,0,  setignore },
{ powersave,  NEXTARG0,   0,  setignore },
@@ -474,6 +476,8 @@ const structcmd {
{ -inet6, IFXF_NOINET6,   0,  setignore } ,
{ description, NEXTARG,   0,  setignore },
{ descr,  NEXTARG,0,  setignore },
+   { wol,IFXF_WOL,   0,  setignore },
+   { -wol,   -IFXF_WOL,  0,  setignore },
 #endif /* SMALL */
 #if 0
/* XXX `create' special-cased below */
Index: share/man/man4/re.4
===
RCS file: /cvs/src/share/man/man4/re.4,v
retrieving revision 1.44
diff -u -p -r1.44 re.4
--- share/man/man4/re.4 8 Jul 2010 09:19:11 -   1.44
+++ share/man/man4/re.4 13 Mar 2011 10:17:41 -
@@ -168,6 +168,10 @@ Force full duplex operation.
 Force half duplex operation.
 .El
 .Pp
+The
+.Nm
+driver supports Wake On LAN.
+.Pp
 For more information on configuring this device, see
 .Xr ifconfig 8 .
 .Sh SEE ALSO
Index: share/man/man4/vr.4
===
RCS file: /cvs/src/share/man/man4/vr.4,v
retrieving revision 1.22
diff -u -p -r1.22 vr.4
--- share/man/man4/vr.4 16 Mar 2009 22:47:45 -  1.22
+++ share/man/man4/vr.4 13 Mar 2011 10:17:45 -
@@ -104,6 +104,11 @@ Force half duplex operation.
 .Pp
 Note that the 100baseTX media type is only available if supported
 by the adapter.
+.Pp
+The
+.Nm
+driver supports Wake On LAN.
+.Pp
 For more information on configuring this device, see
 .Xr ifconfig 8

Re: wake on lan

2011-03-13 Thread Stefan Sperling
On Sun, Mar 13, 2011 at 11:41:44AM +0100, Stefan Sperling wrote:
 On Sun, Mar 13, 2011 at 01:03:19AM +0100, Stefan Sperling wrote:
  Now that arp(8) can send Wake On Lan frames (a.k.a. magic packets),
  it would be nice to have a way to configure WOL from the operating system.
 
 Some man page fixes, and ifconfig now prints a not supported message if
 the user tries to enable WOL on an interface which doesn't support WOL.
 Both suggested by jmc. 

After integrating some feedback from Theo, this has been committed.
Test reports are still welcome.



wake on lan

2011-03-12 Thread Stefan Sperling
Now that arp(8) can send Wake On Lan frames (a.k.a. magic packets),
it would be nice to have a way to configure WOL from the operating system.

Some network cards need help from the OS to do WOL.
Some already do WOL without help from the OS.
For the latter it's nice to have a way to disable it.

This diff adds code to enable/disable WOL.
It's based on earlier diffs I've written for WOL which never went in,
and some discussion with Theo and Claudio.

If you have an re(4) or vr(4), you are lucky because those are the only
drivers supported so far. More drivers will be added later.

More often than not, WOL depends on BIOS settings.
Sometimes BIOS settings override what the OS wants, and vice versa.

Please test if you're interested in WOL. I'm particularly interested in
test reports with vr(4). The on-board vr(4) I have doesn't listen to the OS.
It only listens to the BIOS. Could someone owning a vr(4) verify that this
diff can enable and disable WOL regardless of (or in some combination with)
BIOS settings?

After booting the patched kernel, don't forget to run 'make includes'
in /usr/src before trying to compile ifconfig. Else, the if.h changes
won't be seen by ifconfig and it will fail to build.

Because this changes struct ifnet, sbin/route and usr.bin/netstat
may need to be recompiled, too.

Index: sbin/ifconfig/brconfig.h
===
RCS file: /cvs/src/sbin/ifconfig/brconfig.h,v
retrieving revision 1.3
diff -u -p -r1.3 brconfig.h
--- sbin/ifconfig/brconfig.h7 Jun 2010 15:05:42 -   1.3
+++ sbin/ifconfig/brconfig.h12 Mar 2011 22:48:05 -
@@ -68,7 +68,7 @@ int bridge_rule(int, char **, int);
 
 #defineIFFBITS \
 
\024\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
-\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST\21TXREADY\22NOINET6\23INET6_PRIVACY\24MPLS
+\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST\21TXREADY\22NOINET6\23INET6_PRIVACY\24MPLS\25WOL
 
 void printb(char *, unsigned int, char *);
 
Index: sbin/ifconfig/ifconfig.8
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.213
diff -u -p -r1.213 ifconfig.8
--- sbin/ifconfig/ifconfig.817 Feb 2011 08:32:29 -  1.213
+++ sbin/ifconfig/ifconfig.812 Mar 2011 22:55:55 -
@@ -435,6 +435,27 @@ This may be used to enable an interface 
 It happens automatically when setting the first address on an interface.
 If the interface was reset when previously marked down,
 the hardware will be re-initialized.
+.Pp
+.It Cm wol
+Enable Wake On Lan.
+When enabled, reception of a Wake On Lan frame (a.k.a. Magic Packet)
+will cause the network card to power up the system from standby or
+suspend mode.
+Wake On Lan frames can be sent with
+.Xr arp 8 .
+Support for Wake On Lan depends on various factors,
+some of which may not be under control of the operating system.
+Configuration parameters in the system BIOS or firmware can affect Wake On Lan.
+.Pp
+Wake On Lan should not be enabled on interfaces that can receive traffic
+from the internet.
+It should only be enabled on dedicated management interfaces connected to
+networks where no packets can be injected by untrusted parties.
+Wake On Lan frames can be sent in routable IP packets and are not 
authenticated.
+.It Fl wol
+Disable Wake On Lan.
+Wake On Lan is disabled by default if possible.
+The operating system cannot disable Wake On Lan on some machines.
 .El
 .Pp
 .Nm
Index: share/man/man4/re.4
===
RCS file: /cvs/src/share/man/man4/re.4,v
retrieving revision 1.44
diff -u -p -r1.44 re.4
--- share/man/man4/re.4 8 Jul 2010 09:19:11 -   1.44
+++ share/man/man4/re.4 12 Mar 2011 23:35:47 -
@@ -168,6 +168,10 @@ Force full duplex operation.
 Force half duplex operation.
 .El
 .Pp
+The
+.Nm
+driver supports Wake On Lan.
+.Pp
 For more information on configuring this device, see
 .Xr ifconfig 8 .
 .Sh SEE ALSO
Index: share/man/man4/vr.4
===
RCS file: /cvs/src/share/man/man4/vr.4,v
retrieving revision 1.22
diff -u -p -r1.22 vr.4
--- share/man/man4/vr.4 16 Mar 2009 22:47:45 -  1.22
+++ share/man/man4/vr.4 12 Mar 2011 23:36:21 -
@@ -104,6 +104,11 @@ Force half duplex operation.
 .Pp
 Note that the 100baseTX media type is only available if supported
 by the adapter.
+.Pp
+The
+.Nm
+driver supports Wake On Lan.
+.Pp
 For more information on configuring this device, see
 .Xr ifconfig 8 .
 .Sh DIAGNOSTICS
Index: sbin/ifconfig/ifconfig.c
===
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.244
diff -u -p -r1.244 ifconfig.c
--- sbin/ifconfig/ifconfig.c1 Mar 2011 09:37:31 -   1.244
+++ sbin/ifconfig/ifconfig.c12 Mar 2011