kern/83807: [sis] [patch] if_sis: Wake On Lan support for
FreeBSD
Stefan Sperling
stsp at stsp.name
Thu Aug 30 04:10:07 PDT 2007
The following reply was made to PR kern/83807; it has been noted by GNATS.
From: Stefan Sperling <stsp at stsp.name>
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/83807: [sis] [patch] if_sis: Wake On Lan support for
FreeBSD
Date: Thu, 30 Aug 2007 12:58:23 +0200
--U+BazGySraz5kW0T
Content-Type: multipart/mixed; boundary="/9DWx/yDrRhgMJTb"
Content-Disposition: inline
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Updated patch for 7-current as of 29th of August 2007.
This is just a port of the 6.2 patch, no driver fixes or additions.
I have reports that neither if_xl support nor if_nve support work :(
--=20
stefan
http://stsp.name PGP Key: 0xF59D25F0
--/9DWx/yDrRhgMJTb
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="FreeBSD-7-wol-2007-08-29.diff"
Content-Transfer-Encoding: quoted-printable
Index: sbin/ifconfig/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sbin/ifconfig/Makefile,v
retrieving revision 1.33
diff -u -r1.33 Makefile
--- sbin/ifconfig/Makefile 17 Apr 2007 00:35:09 -0000 1.33
+++ sbin/ifconfig/Makefile 28 Aug 2007 11:25:34 -0000
@@ -32,6 +32,8 @@
SRCS+=3D ifbridge.c # bridge support
SRCS+=3D iflagg.c # lagg support
=20
+SRCS+=3D ifwol.c # wake on lan support
+
.if ${MK_IPX_SUPPORT} !=3D "no" && !defined(RELEASE_CRUNCH)
SRCS+=3D af_ipx.c # IPX support
DPADD=3D ${LIBIPX}
Index: sbin/ifconfig/ifconfig.8
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.142
diff -u -r1.142 ifconfig.8
--- sbin/ifconfig/ifconfig.8 1 Aug 2007 00:33:52 -0000 1.142
+++ sbin/ifconfig/ifconfig.8 28 Aug 2007 11:22:33 -0000
@@ -1240,6 +1240,27 @@
If that is the case, then the first four keys
(1-4) will be the standard temporary keys and any others will be adaptor
specific keys such as permanent keys stored in NVRAM.
+.It Cm wakeon Ar events
+Enable Wake On Lan support, if available. The=20
+.Ar events
+argument is a comma seperated list of package types that shall
+trigger wake events. The set of valid package types is
+.Dq Li unicast ,
+.Dq Li multicast ,
+.Dq Li broadcast ,
+and
+.Dq Li magic .
+These enable wake on unicast, multicast, broadcast and Magic Packet(tm),
+respectively.
+A SecureOn password, if supported, can be be enabled using the
+.Dq Li sopasswd:<password>=20
+event.
+SecureOn passwords only work in combination with
+.Dq Li magic .
+The password must consist of 12 hexadecimal digits.
+.It Fl wakeon
+Disable Wake On Lan.
+.Pp
.It Cm wme
Enable Wireless Multimedia Extensions (WME) support, if available,
for the specified interface.
@@ -1247,7 +1268,6 @@
efficient communication of realtime and multimedia data.
To disable WME support, use
.Fl wme .
-.Pp
The following parameters are meaningful only when WME support is in use.
Parameters are specified per-AC (Access Category) and
split into those that are used by a station when acting
Index: sbin/ifconfig/ifwol.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sbin/ifconfig/ifwol.c
diff -N sbin/ifconfig/ifwol.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sbin/ifconfig/ifwol.c 29 Aug 2007 21:34:42 -0000
@@ -0,0 +1,228 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2005 Stefan Sperling.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/if_media.h>
+#include <net/route.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+
+#include "ifconfig.h"
+
+static void wol_status(int s);
+static void setwol(const char *, int, int, const struct afswtch *);
+static void parse_args(const char *, struct if_wolopts *);
+static void parse_sopasswd(const char *, u_char *);
+static void unsetwol(const char *, int, int, const struct afswtch *);
+static void print_wol_events(uint32_t events);
+
+/*
+ * Print wake on lan capabilities and events the device currently heeds.
+ */
+static void
+wol_status(int s)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, name, IFNAMSIZ);
+
+ if (ioctl(s, SIOCGIFWOLSUPP, &ifr) < 0)
+ /* Device does not support wake on lan */
+ return;
+
+ printf("\tsupported wake events:");
+ print_wol_events(ifr.ifr_wolopts.ifwol_supported);
+ printf("\n");
+
+ if (ioctl(s, SIOCGIFWOLOPTS, &ifr) < 0)
+ err(EX_USAGE, "SIOCGIFWOLOPTS");
+
+ if (ifr.ifr_wolopts.ifwol_events =3D=3D 0)
+ return;
+
+ printf("\twill wake on:");
+ print_wol_events(ifr.ifr_wolopts.ifwol_events);
+ printf("\n");
+}
+
+static void
+print_wol_events(uint32_t events)
+{
+ if (events & IFWOL_WAKE_ON_UNICAST)
+ printf(" unicast");
+ if (events & IFWOL_WAKE_ON_MULTICAST)
+ printf(" multicast");
+ if (events & IFWOL_WAKE_ON_BROADCAST)
+ printf(" broadcast");
+ if (events & IFWOL_WAKE_ON_MAGIC) {
+ printf(" magic");
+ if (events & IFWOL_ENABLE_SOPASSWD)
+ printf("[SecureOn password]");
+ }
+}
+
+/*
+ * Set wake on lan events.
+ */
+static void
+setwol(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, name, IFNAMSIZ);
+
+ if (ioctl(s, SIOCGIFWOLSUPP, &ifr) < 0)
+ err(EX_USAGE, "device does not support wake on lan");
+
+ parse_args(val, &ifr.ifr_wolopts);
+ if (ioctl(s, SIOCSIFWOLOPTS, &ifr) < 0)
+ err(EX_USAGE, "SIOCSIFWOLOPTS");
+}
+
+/*=20
+ * Parse the argument string, which may contain one or more of the
+ * following:
+ * =20
+ * unicast,multicast,broadcast,magic,sopasswd:xxxxxxxxxxxx,
+ *
+ * and fill the wolopts structure accordingly.
+ *=20
+ */
+static void
+parse_args(const char* args, struct if_wolopts *wolopts)
+{
+ uint32_t wol_events =3D 0;
+ char* opt;
+
+ for (opt =3D strdup(args); (opt =3D strtok(opt, ",")) !=3D NULL; opt =3D =
NULL) {
+ if (strcmp(opt, "unicast") =3D=3D 0)
+ wol_events |=3D IFWOL_WAKE_ON_UNICAST;
+ else if (strcmp(opt, "multicast") =3D=3D 0)
+ wol_events |=3D IFWOL_WAKE_ON_MULTICAST;
+ else if (strcmp(opt, "broadcast") =3D=3D 0)
+ wol_events |=3D IFWOL_WAKE_ON_BROADCAST;
+ else if (strcmp(opt, "magic") =3D=3D 0)
+ wol_events |=3D IFWOL_WAKE_ON_MAGIC;
+ else if (strcmp(opt, "sopasswd") =3D=3D 0)
+ errx(EX_USAGE, "no SecureOn password specfied.");
+ else if (strncmp(opt, "sopasswd:", strlen("sopasswd:")) =3D=3D 0) {
+ wol_events |=3D IFWOL_ENABLE_SOPASSWD;
+ parse_sopasswd(opt + strlen("sopasswd:"), wolopts->ifwol_sopasswd);
+ } else {
+ errx(EX_USAGE, "unknown wake event %s", opt);
+ }
+ }
+ free(opt);
+ wolopts->ifwol_events =3D wol_events;
+}
+
+/* SecureOn passwords are not like plain text passwords. Instead, they con=
sist
+ * of 6 bytes (ie unsigned char). Try to prevent users from giving anythin=
g other
+ * than a string of six concatenated unsigned chars in hex as password.
+ */
+static void
+parse_sopasswd(const char *pw, u_char *dest) {
+ char substr[3];
+ int len, i, n;
+
+ len =3D strlen(pw) / 2;
+ if (len !=3D 6)
+ errx(EX_USAGE, "Invalid SecureOn password.");
+
+ for (i =3D 0; i < len; i++) {
+ (void)strncpy(substr, pw, 2);
+ substr[2] =3D '\0';
+ if (sscanf(substr, "%x", &n) !=3D 1)
+ errx(EX_USAGE, "Invalid SecureOn password.");
+ if (n < 0x0 || n > 0xff)
+ errx(EX_USAGE, "Invalid SecureOn password.");
+ *dest++ =3D (u_char)n;
+ pw +=3D 2;
+ }
+}
+
+/*
+ * Unset all wake on lan events.
+ */
+static void
+unsetwol(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, name, IFNAMSIZ);
+
+ if (ioctl(s, SIOCGIFWOLSUPP, &ifr) < 0)
+ err(EX_USAGE, "device does not support wake on lan");
+
+ ifr.ifr_wolopts.ifwol_events =3D IFWOL_DISABLE;
+ if (ioctl(s, SIOCSIFWOLOPTS, &ifr) < 0)
+ err(EX_USAGE, "SIOCSIFWOLOPTS");
+}
+
+static struct cmd wol_cmds[] =3D {
+ DEF_CMD_ARG("wakeon", setwol),
+ DEF_CMD("-wakeon", 0, unsetwol)
+};
+static struct afswtch af_wol =3D {
+ .af_name =3D "af_wol",
+ .af_af =3D AF_UNSPEC,
+ .af_other_status =3D wol_status,
+};
+
+static __constructor void
+ifwol_ctor(void)
+{
+#define N(a) (sizeof(a) / sizeof(a[0]))
+ int i;
+
+ for (i =3D 0; i < N(wol_cmds); i++)
+ cmd_register(&wol_cmds[i]);
+ af_register(&af_wol);
+#undef N
+}
Index: sys/dev/nve/if_nve.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/dev/nve/if_nve.c,v
retrieving revision 1.28
diff -u -r1.28 if_nve.c
--- sys/dev/nve/if_nve.c 12 Jun 2007 02:21:02 -0000 1.28
+++ sys/dev/nve/if_nve.c 28 Aug 2007 11:22:33 -0000
@@ -177,6 +177,10 @@
static NV_SINT32 nve_oslockrelease(PNV_VOID, NV_SINT32, PNV_VOID);
static PNV_VOID nve_osreturnbufvirt(PNV_VOID, PNV_VOID);
=20
+static void nve_enable_wol(struct nve_softc *);
+static void nve_get_wolopts(struct nve_softc *, struct if_wolopts *);
+static int nve_set_wolopts(struct nve_softc *, struct if_wolopts *);
+
static device_method_t nve_methods[] =3D {
/* Device interface */
DEVMETHOD(device_probe, nve_probe),
@@ -726,6 +730,10 @@
=20
sc =3D device_get_softc(dev);
=20
+ NVE_LOCK(sc);
+ nve_enable_wol(sc);
+ NVE_UNLOCK(sc);
+
/* Stop hardware activity */
NVE_LOCK(sc);
nve_stop(sc);
@@ -1037,6 +1045,21 @@
mii =3D device_get_softc(sc->miibus);
error =3D ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
+ case SIOCGIFWOLSUPP:
+ ifr->ifr_wolopts.ifwol_supported =3D NVE_SUPPORTED_WOL_EVENTS;
+ error =3D 0;
+ break;
+ case SIOCGIFWOLOPTS:
+ NVE_LOCK(sc);
+ nve_get_wolopts(sc, &ifr->ifr_wolopts);
+ NVE_UNLOCK(sc);
+ error =3D 0;
+ break;
+ case SIOCSIFWOLOPTS:
+ NVE_LOCK(sc);
+ error =3D nve_set_wolopts(sc, &ifr->ifr_wolopts);
+ NVE_UNLOCK(sc);
+ break;
=20
default:
/* Everything else we forward to generic ether ioctl */
@@ -1776,3 +1799,49 @@
}
=20
/* --- End on NVOSAPI interface --- */
+
+/*
+ * Enable Wake On Lan.
+ */
+static void
+nve_enable_wol(struct nve_softc *sc)
+{
+ ADAPTER_POWERSTATE pstate =3D {0};
+
+ if (sc->wol_events =3D=3D 0)
+ return;
+=09
+ if (sc->wol_events & IFWOL_WAKE_ON_MAGIC) {
+ pstate.ulPowerFlags =3D POWER_STATE_D3;
+ pstate.ulMagicPacketWakeUpFlags =3D POWER_STATE_ALL;
+ pstate.ulLinkChangeWakeUpFlags =3D 0;
+ pstate.ulPatternWakeUpFlags =3D 0;
+ sc->hwapi->pfnSetPowerState(sc->hwapi->pADCX, &pstate);
+ }
+}
+
+/*
+ * Write current wake on lan settings into an if_wolopts structure.
+ */
+static void
+nve_get_wolopts(struct nve_softc *sc, struct if_wolopts *wolopts)
+{
+ wolopts->ifwol_events =3D sc->wol_events;
+}
+
+/*
+ * Set wake on lan options.
+ */
+static int
+nve_set_wolopts(struct nve_softc *sc, struct if_wolopts *wolopts)
+{
+ if (wolopts->ifwol_events =3D=3D IFWOL_DISABLE)
+ sc->wol_events =3D 0;
+ else {
+ if ((wolopts->ifwol_events & ~NVE_SUPPORTED_WOL_EVENTS) !=3D 0)
+ return EINVAL;
+ sc->wol_events =3D wolopts->ifwol_events;
+ }
+
+ return 0;
+}
Index: sys/dev/nve/if_nvereg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/dev/nve/if_nvereg.h,v
retrieving revision 1.8
diff -u -r1.8 if_nvereg.h
--- sys/dev/nve/if_nvereg.h 5 Dec 2006 15:31:05 -0000 1.8
+++ sys/dev/nve/if_nvereg.h 28 Aug 2007 11:22:33 -0000
@@ -69,6 +69,8 @@
#define NVE_DEBUG_MII 0x0100
#define NVE_DEBUG_ALL 0xFFFF
=20
+#define NVE_SUPPORTED_WOL_EVENTS IFWOL_WAKE_ON_MAGIC
+
#if NVE_DEBUG
#define DEBUGOUT(level, fmt, args...) if (NVE_DEBUG & level) \
printf(fmt, ## args)
@@ -143,6 +145,8 @@
=20
struct mtx mtx;
=20
+ uint32_t wol_events;
+
/* Stuff for dealing with the NVIDIA OS API */
struct callout ostimer;
PTIMER_FUNC ostimer_func;
Index: sys/net/if.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/net/if.c,v
retrieving revision 1.273
diff -u -r1.273 if.c
--- sys/net/if.c 27 Jul 2007 11:59:57 -0000 1.273
+++ sys/net/if.c 28 Aug 2007 11:26:37 -0000
@@ -1760,6 +1760,7 @@
case SIOCSLIFPHYADDR:
case SIOCSIFMEDIA:
case SIOCSIFGENERIC:
+ case SIOCSIFWOLOPTS:
error =3D priv_check(td, PRIV_NET_HWIOCTL);
if (error)
return (error);
@@ -1781,6 +1782,8 @@
case SIOCGLIFPHYADDR:
case SIOCGIFMEDIA:
case SIOCGIFGENERIC:
+ case SIOCGIFWOLOPTS:
+ case SIOCGIFWOLSUPP:
if (ifp->if_ioctl =3D=3D NULL)
return (EOPNOTSUPP);
IFF_LOCKGIANT(ifp);
Index: sys/net/if.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/net/if.h,v
retrieving revision 1.108
diff -u -r1.108 if.h
--- sys/net/if.h 11 Jun 2007 20:08:11 -0000 1.108
+++ sys/net/if.h 28 Aug 2007 11:22:33 -0000
@@ -273,6 +273,28 @@
#define IFAN_DEPARTURE 1 /* interface departure */
=20
/*
+ * Wake on Lan related options.
+ */
+struct if_wolopts {
+ uint32_t ifwol_supported;/* indicates wol capabilities */
+ uint32_t ifwol_events; /* indicates desired wake events */
+
+ /* Supported wake on lan events.
+ * A given device may not support all of these,
+ * or even support wake events not listed here.
+ * If you add wake more events, make to sure to teach
+ * ifconfig about them too. */
+#define IFWOL_DISABLE 0x01 /* clears all other events */
+#define IFWOL_WAKE_ON_UNICAST 0x02
+#define IFWOL_WAKE_ON_MULTICAST 0x04
+#define IFWOL_WAKE_ON_BROADCAST 0x08
+#define IFWOL_WAKE_ON_MAGIC 0x10 /* wake on Magic Packet(tm) */
+#define IFWOL_ENABLE_SOPASSWD 0x20 /* whether to set SecureOn password */
+
+ u_char ifwol_sopasswd[6]; /* SecureOn password */
+};
+
+/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
@@ -284,6 +306,7 @@
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
+ struct if_wolopts ifru_wolopts;
short ifru_flags[2];
short ifru_index;
int ifru_metric;
@@ -296,6 +319,7 @@
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_wolopts ifr_ifru.ifru_wolopts /* wake on lan related options */
#define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */
#define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */
#define ifr_metric ifr_ifru.ifru_metric /* metric */
Index: sys/pci/if_sis.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_sis.c,v
retrieving revision 1.150
diff -u -r1.150 if_sis.c
--- sys/pci/if_sis.c 24 Feb 2007 14:27:36 -0000 1.150
+++ sys/pci/if_sis.c 29 Aug 2007 23:35:02 -0000
@@ -138,6 +138,10 @@
static void sis_startl(struct ifnet *);
static void sis_stop(struct sis_softc *);
static void sis_watchdog(struct sis_softc *);
+static void sis_get_wolopts(struct sis_softc *, struct if_wolopts *);
+static int sis_set_wolopts(struct sis_softc *, struct if_wolopts *);
+static void sis_enable_wol(struct sis_softc *);
+static uint32_t sis_translate_wol_events(uint32_t);
=20
=20
static struct resource_spec sis_res_spec[] =3D {
@@ -2157,6 +2161,21 @@
}
#endif /* DEVICE_POLLING */
break;
+ case SIOCGIFWOLSUPP:
+ ifr->ifr_wolopts.ifwol_supported =3D NS_SUPPORTED_WOL_EVENTS;
+ error =3D 0;
+ break;
+ case SIOCGIFWOLOPTS:
+ SIS_LOCK(sc);
+ sis_get_wolopts(sc, &ifr->ifr_wolopts);
+ SIS_UNLOCK(sc);
+ error =3D 0;
+ break;
+ case SIOCSIFWOLOPTS:
+ SIS_LOCK(sc);
+ error =3D sis_set_wolopts(sc, &ifr->ifr_wolopts);
+ SIS_UNLOCK(sc);
+ break;
default:
error =3D ether_ioctl(ifp, command, data);
break;
@@ -2264,9 +2283,141 @@
SIS_LOCK(sc);
sis_reset(sc);
sis_stop(sc);
+ sis_enable_wol(sc);
SIS_UNLOCK(sc);
}
=20
+/*
+ * Translate wake on lan events defined in if.h
+ * into flags the chip understands.
+ */
+static uint32_t
+sis_translate_wol_events(uint32_t wol_events)
+{
+ uint32_t sis_wol_events =3D 0;
+=09
+ if (wol_events & IFWOL_WAKE_ON_UNICAST)
+ sis_wol_events |=3D NS_WCSR_WAKE_UCAST;
+ if (wol_events & IFWOL_WAKE_ON_MULTICAST)
+ sis_wol_events |=3D NS_WCSR_WAKE_MCAST;
+ if (wol_events & IFWOL_WAKE_ON_BROADCAST)
+ sis_wol_events |=3D NS_WCSR_WAKE_BCAST;
+ if (wol_events & IFWOL_WAKE_ON_MAGIC)
+ sis_wol_events |=3D NS_WCSR_WAKE_MAGIC;
+
+ return sis_wol_events;
+}
+
+/*
+ * Write current wake on lan settings into an if_wolopts structure.
+ * Note that the sopasswd field in the structure is cleared, because
+ * the password is confidential.
+ */
+static void
+sis_get_wolopts(struct sis_softc *sc, struct if_wolopts *wolopts)
+{
+ int i;
+
+ SIS_LOCK_ASSERT(sc);
+
+ wolopts->ifwol_events =3D sc->ns_wol_events;
+=09
+ /* Do not disclose Secure On password. */
+#define N(a) (sizeof(a) / sizeof(a[0]))
+ for (i =3D 0; i < N(wolopts->ifwol_sopasswd); i++)
+ wolopts->ifwol_sopasswd[i] =3D '\0';
+#undef N
+}
+=09
+/*
+ * Set wake on lan options.
+ */
+static int
+sis_set_wolopts(struct sis_softc *sc, struct if_wolopts *wolopts)
+{
+ SIS_LOCK_ASSERT(sc);
+
+ /* FIXME: handle sopasswd */
+
+ if (wolopts->ifwol_events =3D=3D IFWOL_DISABLE)
+ sc->ns_wol_events =3D 0;
+ else {
+ if ((wolopts->ifwol_events & ~NS_SUPPORTED_WOL_EVENTS) !=3D 0)
+ return EINVAL;
+ sc->ns_wol_events =3D wolopts->ifwol_events;
+ }
+
+ return 0;
+}
+
+/*=20
+ * Enable Wake On Lan on the DP83815,
+ * if any wake on lan options have been set.
+ */
+static void
+sis_enable_wol(struct sis_softc *sc)
+{
+ SIS_LOCK_ASSERT(sc);
+=09
+ if (sc->sis_type !=3D SIS_TYPE_83815)
+ return;
+
+ /* Check whether any wake on lan events have been set. */
+ if (sc->ns_wol_events =3D=3D 0)
+ return;
+
+ /*
+ * Configure the recieve filter to accept potential wake packets,
+ * configure wake events and enter low-power state.
+ */
+
+ /* Stop reciever. */
+ SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_DISABLE);
+=09
+ /* Reset recieve pointer */
+ CSR_WRITE_4(sc, SIS_RX_LISTPTR, 0);
+
+ /* Re-enable reciever (now in "silent recieve mode.") */
+ SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
+
+ /* Clear recieve filter register, so that the enable bit is unset.
+ * Other bits in this register can only be configured while the enable
+ * bit is zero. */
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, 0);
+
+ /*=20
+ * Accept unicast packets. The datasheet seems to be inaccurate.
+ * It suggests simply setting the unicast bit in NS_RXFILTCTL,
+ * but this does not seem to work. Instead, we "perfect match"
+ * our own mac address, which makes the rx filter accept unicast
+ * packets. (section below copy pasted from sis_initl routine)
+ */
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR0);
+ CSR_WRITE_4(sc, SIS_RXFILT_DATA,
+ ((u_int16_t *)IF_LLADDR(sc->sis_ifp))[0]);
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR1);
+ CSR_WRITE_4(sc, SIS_RXFILT_DATA,
+ ((u_int16_t *)IF_LLADDR(sc->sis_ifp))[1]);
+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR2);
+ CSR_WRITE_4(sc, SIS_RXFILT_DATA,
+ ((u_int16_t *)IF_LLADDR(sc->sis_ifp))[2]);
+ SIS_SETBIT(sc, SIS_RXFILT_CTL, NS_RXFILTCTL_PERFECT);
+
+ /* Allow broadcast and multicast packets, too. */
+ SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_BROAD);
+ SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ALLMULTI);
+
+ /* Re-enable RX filter. */
+ SIS_SETBIT(sc, SIS_RXFILT_CTL, SIS_RXFILTCTL_ENABLE);
+
+ /* Configure wake on lan events */
+ CSR_WRITE_4(sc, NS_WCSR, sis_translate_wol_events(sc->ns_wol_events));
+
+ /* Set appropriate power state, so the card stays active
+ * after system shutdown. */
+ CSR_WRITE_4(sc, NS_CLKRUN, NS_CLKRUN_PMESTS | NS_CLKRUN_PMEENB);
+}
+
static device_method_t sis_methods[] =3D {
/* Device interface */
DEVMETHOD(device_probe, sis_probe),
Index: sys/pci/if_sisreg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_sisreg.h,v
retrieving revision 1.38
diff -u -r1.38 if_sisreg.h
--- sys/pci/if_sisreg.h 24 Feb 2007 14:27:36 -0000 1.38
+++ sys/pci/if_sisreg.h 28 Aug 2007 11:22:33 -0000
@@ -77,6 +77,7 @@
/* NS DP83815/6 registers */
#define NS_IHR 0x1C
#define NS_CLKRUN 0x3C
+#define NS_WCSR 0x40
#define NS_SRR 0x58
#define NS_BMCR 0x80
#define NS_BMSR 0x84
@@ -461,6 +462,7 @@
#endif
int in_tick;
struct mtx sis_mtx;
+ uint32_t ns_wol_events;
};
=20
#define SIS_TIMEOUT 1000
@@ -505,3 +507,17 @@
#define SIS_PSTATE_D3 0x0003
#define SIS_PME_EN 0x0010
#define SIS_PME_STATUS 0x8000
+
+/* DP83815 pci config space power management register */
+#define NS_PMCSR 0x44
+
+/* DP83815 Wake On Lan Command/Status register */
+#define NS_WCSR_WAKE_UCAST 0x00000002
+#define NS_WCSR_WAKE_MCAST 0x00000004
+#define NS_WCSR_WAKE_BCAST 0x00000008
+#define NS_WCSR_WAKE_MAGIC 0x00000200
+
+/* FIXME: handle sopasswd */
+#define NS_SUPPORTED_WOL_EVENTS (IFWOL_WAKE_ON_UNICAST | IFWOL_WAKE_ON_MUL=
TICAST \
+ | IFWOL_WAKE_ON_BROADCAST | IFWOL_WAKE_ON_MAGIC)
+
Index: sys/pci/if_vr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_vr.c,v
retrieving revision 1.126
diff -u -r1.126 if_vr.c
--- sys/pci/if_vr.c 23 Apr 2007 12:19:02 -0000 1.126
+++ sys/pci/if_vr.c 28 Aug 2007 11:29:49 -0000
@@ -165,6 +165,10 @@
#ifdef DEVICE_POLLING
int rxcycles;
#endif
+ int vr_wolsupport; /* Chip supports WOL. */
+ uint32_t vr_wolevents; /* Wake on Lan satus */
+ /* some chips have 6 "patterns" for WOL instead of 4 */
+ int vr_wol6patterns;
};
=20
static int vr_probe(device_t);
@@ -201,6 +205,10 @@
static int vr_list_rx_init(struct vr_softc *);
static int vr_list_tx_init(struct vr_softc *);
=20
+static int vr_set_wolopts(struct vr_softc *, struct if_wolopts *);
+static void vr_get_wolopts(struct vr_softc *, struct if_wolopts *);
+static void vr_enable_wol(struct vr_softc *);
+
#ifdef VR_USEIOSPACE
#define VR_RES SYS_RES_IOPORT
#define VR_RID VR_PCI_LOIO
@@ -587,7 +595,7 @@
#endif
=20
/*
- * Windows may put the chip in suspend mode when it
+ * Windows or WOL may put the chip in suspend mode when it
* shuts down. Be sure to kick it in the head to wake it
* up again.
*/
@@ -638,6 +646,13 @@
=20
sc->vr_suspended =3D 0;
=20
+ /* Check Wake on Lan support. */
+ if (sc->vr_revid >=3D REV_ID_VT6102 ) {
+ sc->vr_wolsupport =3D 1;
+ if (sc->vr_revid >=3D REV_ID_VT6105_B0)
+ sc->vr_wol6patterns =3D 1;
+ }
+
/* Hook interrupt last to avoid having to lock softc */
error =3D bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET | INTR_MPSAFE,
NULL, vr_intr, sc, &sc->vr_intrhand);
@@ -1517,6 +1532,21 @@
else
ifp->if_hwassist =3D 0;
break;
+ case SIOCGIFWOLSUPP:
+ ifr->ifr_wolopts.ifwol_supported =3D VR_SUPPORTED_WOL_EVENTS;
+ error =3D 0;
+ break;
+ case SIOCGIFWOLOPTS:
+ VR_LOCK(sc);
+ vr_get_wolopts(sc, &ifr->ifr_wolopts);
+ VR_UNLOCK(sc);
+ error =3D 0;
+ break;
+ case SIOCSIFWOLOPTS:
+ VR_LOCK(sc);
+ error =3D vr_set_wolopts(sc, &ifr->ifr_wolopts);
+ VR_UNLOCK(sc);
+ break;
default:
error =3D ether_ioctl(ifp, command, data);
break;
@@ -1595,6 +1625,92 @@
static void
vr_shutdown(device_t dev)
{
+ struct vr_softc *sc;
=20
+ sc =3D device_get_softc(dev);
+ VR_LOCK(sc);
+ vr_enable_wol(sc);
+ VR_UNLOCK(sc);
vr_detach(dev);
}
+
+static void
+vr_enable_wol(struct vr_softc *sc)
+{
+ VR_LOCK_ASSERT(sc);
+=09
+ /* Check whether wake on lan is available
+ * and whether events have been set. */
+ if (!sc->vr_wolsupport || sc->vr_wolevents =3D=3D 0)
+ return;
+
+ /* Set the chip to power state D0 */
+ VR_CLRBIT(sc, VR_STICKHW, (VR_STICKHW_DS0|VR_STICKHW_DS1));
+
+ /* Clear WOL configuration */
+ CSR_WRITE_1(sc, VR_WOLCRCLR, 0xFF);
+ if (sc->vr_wol6patterns)
+ CSR_WRITE_1(sc, VR_WOLCRCLR1, 0x03);
+
+ /* Clear power-event status. */
+ CSR_WRITE_1(sc, VR_PWRCSRCLR, 0xFF);
+
+ /* Don't use extra patterns. */
+ if (sc->vr_wol6patterns)
+ CSR_WRITE_1(sc, VR_WOLCGCLR, 0x04);
+=09
+ /* Set unicast wake event if applicable. */
+ if (sc->vr_wolevents & IFWOL_WAKE_ON_UNICAST)
+ VR_SETBIT(sc, VR_WOLCRSET, VR_WAKE_UCAST);
+=09
+ /* Set magic wake event if applicable. */
+ if (sc->vr_wolevents & IFWOL_WAKE_ON_MAGIC) {
+ VR_SETBIT(sc, VR_WOLCRSET, VR_WAKE_MAGIC);
+ /* enable EEPROM-controlled wake-up */
+ VR_SETBIT(sc, VR_CONFIG, 0x03);
+ }
+#if 0
+ /* Set broadcast/multicast wake event if applicable. */
+ /* Does not work for some reason :( */
+ if (sc->vr_wolevents & IFWOL_WAKE_ON_BROADCAST ||
+ sc->vr_wolevents & IFWOL_WAKE_ON_MULTICAST)
+ CSR_WRITE_1(sc, VR_WOLCGSET, VR_WAKE_BMCAST);
+#endif
+ /* Enable Wake On Lan. */
+ CSR_WRITE_1(sc, VR_PWCFGSET, 0x01);
+ VR_SETBIT(sc, VR_STICKHW, VR_STICKHW_WOL_ENB);
+
+ /* Set power state to D3 */
+ VR_SETBIT(sc, VR_STICKHW, (VR_STICKHW_DS0|VR_STICKHW_DS1));
+}
+
+
+/*
+ * Write current wake on lan settings into an if_wolopts structure.
+ */
+static void
+vr_get_wolopts(struct vr_softc *sc, struct if_wolopts *wolopts)
+{
+ VR_LOCK_ASSERT(sc);
+ wolopts->ifwol_events =3D sc->vr_wolevents;
+}
+=09
+/*
+ * Set wake on lan options.
+ */
+static int
+vr_set_wolopts(struct vr_softc *sc, struct if_wolopts *wolopts)
+{
+ VR_LOCK_ASSERT(sc);
+
+ if (wolopts->ifwol_events =3D=3D IFWOL_DISABLE)
+ sc->vr_wolevents =3D 0;
+ else {
+ if ((wolopts->ifwol_events & ~VR_SUPPORTED_WOL_EVENTS) !=3D 0)
+ return EINVAL;
+ sc->vr_wolevents =3D wolopts->ifwol_events;
+ }
+
+ return 0;
+}
+
Index: sys/pci/if_vrreg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_vrreg.h,v
retrieving revision 1.34
diff -u -r1.34 if_vrreg.h
--- sys/pci/if_vrreg.h 23 Apr 2007 12:19:02 -0000 1.34
+++ sys/pci/if_vrreg.h 28 Aug 2007 11:22:33 -0000
@@ -283,6 +283,21 @@
#define VR_STICKHW_WOL_STS 0x08
#define VR_STICKHW_LEGWOL_ENB 0x80
=20
+/* Wake on Lan definitions (snooped from Linux driver) */
+#define VR_WOLCRSET 0xA0
+#define VR_PWCFGSET 0xA1
+#define VR_WOLCGSET 0xA3
+#define VR_WOLCRCLR 0xA4
+#define VR_WOLCRCLR1 0xA6
+#define VR_WOLCGCLR 0xA7
+#define VR_PWRCSRCLR 0xAC
+#define VR_WAKE_UCAST 0x10
+#define VR_WAKE_MAGIC 0x20
+#define VR_WAKE_BMCAST 0x30
+#define VR_WAKE_LINKON 0x40
+#define VR_WAKE_LINKOFF 0x80
+#define VR_SUPPORTED_WOL_EVENTS (IFWOL_WAKE_ON_UNICAST | IFWOL_WAKE_ON_MAG=
IC)
+
/*
* BCR0 register bits. (At least for the VT6102 chip.)
*/
@@ -474,10 +489,14 @@
#define REV_ID_VT3065_A 0x40
#define REV_ID_VT3065_B 0x41
#define REV_ID_VT3065_C 0x42
+#define REV_ID_VT6102 0x40
#define REV_ID_VT6102_APOLLO 0x74
#define REV_ID_VT3106 0x80
#define REV_ID_VT3106_J 0x80 /* 0x80-0x8F */
#define REV_ID_VT3106_S 0x90 /* 0x90-0xA0 */
+#define REV_ID_VT6105 0x80
+#define REV_ID_VT6105_B0 0x83
+
=20
/*
* PCI low memory base and low I/O base register, and
Index: sys/pci/if_xl.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_xl.c,v
retrieving revision 1.210
diff -u -r1.210 if_xl.c
--- sys/pci/if_xl.c 6 Aug 2007 14:26:03 -0000 1.210
+++ sys/pci/if_xl.c 28 Aug 2007 11:22:33 -0000
@@ -249,6 +249,9 @@
static void xl_shutdown(device_t);
static int xl_suspend(device_t);
static int xl_resume(device_t);
+static void xl_get_wolopts(struct xl_softc *, struct if_wolopts *);
+static int xl_set_wolopts(struct xl_softc *, struct if_wolopts *);
+static void xl_enable_wol(device_t dev);
=20
#ifdef DEVICE_POLLING
static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
@@ -3223,6 +3226,25 @@
ifp->if_hwassist =3D 0;
XL_UNLOCK(sc);
break;
+ case SIOCGIFWOLSUPP:
+ if (sc->xl_type =3D=3D XL_TYPE_905B)
+ ifr->ifr_wolopts.ifwol_supported =3D
+ XL_SUPPORTED_WOL_EVENTS;
+ else
+ ifr->ifr_wolopts.ifwol_supported =3D 0;
+ error =3D 0;
+ break;
+ case SIOCGIFWOLOPTS:
+ XL_LOCK(sc);
+ xl_get_wolopts(sc, &ifr->ifr_wolopts);
+ XL_UNLOCK(sc);
+ error =3D 0;
+ break;
+ case SIOCSIFWOLOPTS:
+ XL_LOCK(sc);
+ error =3D xl_set_wolopts(sc, &ifr->ifr_wolopts);
+ XL_UNLOCK(sc);
+ break;
default:
error =3D ether_ioctl(ifp, command, data);
break;
@@ -3354,6 +3376,7 @@
XL_LOCK(sc);
xl_reset(sc);
xl_stop(sc);
+ xl_enable_wol(dev);
XL_UNLOCK(sc);
}
=20
@@ -3390,3 +3413,85 @@
=20
return (0);
}
+
+/*
+ * Write current wake on lan settings into an if_wolopts structure.
+ */
+static void
+xl_get_wolopts(struct xl_softc *sc, struct if_wolopts *wolopts)
+{
+ XL_LOCK_ASSERT(sc);
+=09
+ if (sc->xl_type =3D=3D XL_TYPE_905B)
+ wolopts->ifwol_events =3D sc->xl_wol_events;
+ else
+ wolopts->ifwol_events =3D 0;
+}
+
+/*
+ * Set wake on lan options.
+ */
+static int
+xl_set_wolopts(struct xl_softc *sc, struct if_wolopts *wolopts)
+{
+ XL_LOCK_ASSERT(sc);
+
+ if (sc->xl_type !=3D XL_TYPE_905B)
+ return ENOTSUP;
+
+ if (wolopts->ifwol_events =3D=3D IFWOL_DISABLE)
+ sc->xl_wol_events =3D 0;
+ else {
+ if ((wolopts->ifwol_events & ~XL_SUPPORTED_WOL_EVENTS) !=3D 0)
+ return EINVAL;
+ sc->xl_wol_events =3D wolopts->ifwol_events;
+ }
+
+ return 0;
+}
+
+/*=20
+ * Enable Wake On Lan if any wake on lan options have been set.
+ */
+static void
+xl_enable_wol(device_t dev)
+{
+ u_int8_t rxfilt;
+ u_int32_t config;
+ struct xl_softc *sc;
+
+ sc =3D device_get_softc(dev);
+
+ XL_LOCK_ASSERT(sc);
+
+ if (sc->xl_type !=3D XL_TYPE_905B)
+ return;
+=09
+ /* Check whether any wake on lan events have been set. */
+ if (sc->xl_wol_events =3D=3D 0)
+ return;
+
+ /* Configure wake on lan events. */
+ XL_SEL_WIN(7);
+ if (sc->xl_wol_events & IFWOL_WAKE_ON_MAGIC)
+ CSR_WRITE_2(sc, XL_W7_BM_WOL, XL_WAKE_ON_MAGIC);
+=09
+ /* Configure the recieve filter to accept WOL packets.
+ * We want to recieve everything. */
+ XL_SEL_WIN(5);
+ rxfilt =3D CSR_READ_1(sc, XL_W5_RX_FILTER);
+ CSR_WRITE_1(sc, XL_W5_RX_FILTER,
+ rxfilt | XL_RXFILTER_INDIVIDUAL | XL_RXFILTER_ALLMULTI
+ | XL_RXFILTER_BROADCAST | XL_RXFILTER_ALLFRAMES);
+
+ /* Make sure reciever is enabled. */
+ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
+
+ /* Make sure power management is enabled. */
+ config =3D pci_read_config(dev, XL_PCI_PWRMGMTCTRL, 2);
+ pci_write_config(dev, XL_PCI_PWRMGMTCTRL, config | XL_PME_EN, 2);
+
+ /* Set appropriate power state, so the card stays active
+ * after system shutdown. */
+ (void)pci_set_powerstate(dev, PCI_POWERSTATE_D3);
+}
Index: sys/pci/if_xlreg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/pci/if_xlreg.h,v
retrieving revision 1.59
diff -u -r1.59 if_xlreg.h
--- sys/pci/if_xlreg.h 6 Dec 2006 02:18:41 -0000 1.59
+++ sys/pci/if_xlreg.h 28 Aug 2007 11:22:33 -0000
@@ -408,6 +408,7 @@
#define XL_W7_BM_LEN 0x06
#define XL_W7_BM_STATUS 0x0B
#define XL_W7_BM_TIMEr 0x0A
+#define XL_W7_BM_WOL 0x0C
=20
/*
* bus master control registers
@@ -613,6 +614,7 @@
#ifdef DEVICE_POLLING
int rxcycles;
#endif
+ uint32_t xl_wol_events;
};
=20
#define XL_LOCK(_sc) mtx_lock(&(_sc)->xl_mtx)
@@ -741,3 +743,7 @@
#ifndef IFM_10_FL
#define IFM_10_FL 13 /* 10baseFL - Fiber */
#endif
+
+#define XL_WAKE_ON_MAGIC 0x0002
+#define XL_SUPPORTED_WOL_EVENTS IFWOL_WAKE_ON_MAGIC
+
Index: sys/sys/sockio.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/ncvs/src/sys/sys/sockio.h,v
retrieving revision 1.31
diff -u -r1.31 sockio.h
--- sys/sys/sockio.h 9 Jul 2006 06:04:00 -0000 1.31
+++ sys/sys/sockio.h 29 Aug 2007 16:48:16 -0000
@@ -118,6 +118,13 @@
#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */
#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners =
*/
=20
+#define SIOCGIFWOLOPTS _IOWR('i', 125, struct ifreq) /* get wake on lan
+ options */
+#define SIOCSIFWOLOPTS _IOW('i', 126, struct ifreq) /* set wake on lan
+ options */
+#define SIOCGIFWOLSUPP _IOWR('i', 127, struct ifreq) /* get wake on lan
+ modes supported by
+ device */
#define SIOCAIFGROUP _IOW('i', 135, struct ifgroupreq) /* add an ifgroup =
*/
#define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */
#define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup =
*/
--/9DWx/yDrRhgMJTb--
--U+BazGySraz5kW0T
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (FreeBSD)
iD8DBQFG1qLP5dMCc/WdJfARArYBAJ4ning6e8WF4WIc/tOGFHtbp72dHQCg7X+3
+13lwRCloS3NqFbaWcpLbmY=
=Tx8N
-----END PGP SIGNATURE-----
--U+BazGySraz5kW0T--
More information about the freebsd-bugs
mailing list