FreeBSD Bugzilla – Attachment 55452 Details for
Bug 83807
[sis] [patch] if_sis: Wake On Lan support for FreeBSD
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
FreeBSD-6.0-wol-2006-05-06.diff
FreeBSD-6.0-wol-2006-05-06.diff (text/plain; charset=us-ascii), 31.95 KB, created by
Stefan Sperling
on 2006-10-20 10:58:50 UTC
(
hide
)
Description:
FreeBSD-6.0-wol-2006-05-06.diff
Filename:
MIME Type:
Creator:
Stefan Sperling
Created:
2006-10-20 10:58:50 UTC
Size:
31.95 KB
patch
obsolete
>Index: sbin/ifconfig/Makefile >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sbin/ifconfig/Makefile,v >retrieving revision 1.29 >diff -u -r1.29 Makefile >--- sbin/ifconfig/Makefile 5 Jun 2005 03:32:51 -0000 1.29 >+++ sbin/ifconfig/Makefile 6 May 2006 11:08:41 -0000 >@@ -28,6 +28,8 @@ > > SRCS+= ifbridge.c # bridge support > >+SRCS+= ifwol.c # wake on lan support >+ > .if !defined(RELEASE_CRUNCH) > SRCS+= af_ipx.c # IPX support > DPADD= ${LIBIPX} >Index: sbin/ifconfig/ifconfig.8 >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sbin/ifconfig/ifconfig.8,v >retrieving revision 1.95.2.14 >diff -u -r1.95.2.14 ifconfig.8 >--- sbin/ifconfig/ifconfig.8 10 Mar 2006 22:05:53 -0000 1.95.2.14 >+++ sbin/ifconfig/ifconfig.8 6 May 2006 10:49:48 -0000 >@@ -896,6 +896,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 >+.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> >+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. >@@ -903,7 +924,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 >=================================================================== >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 6 May 2006 11:14:15 -0000 >@@ -0,0 +1,232 @@ >+/* $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 WARRANTIES >+ * 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(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)); >+ strncpy(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 == 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) >+{ >+ char *args; >+ struct ifreq ifr; >+ >+ memset(&ifr, 0, sizeof(ifr)); >+ strncpy(ifr.ifr_name, name, IFNAMSIZ); >+ >+ if (ioctl(s, SIOCGIFWOLSUPP, &ifr) < 0) >+ err(EX_USAGE, "device does not support wake on lan"); >+ >+ args = strdup(val); >+ parse_args(args, &ifr.ifr_wolopts); >+ free(args); >+ if (ioctl(s, SIOCSIFWOLOPTS, &ifr) < 0) >+ err(EX_USAGE, "SIOCSIFWOLOPTS"); >+} >+ >+/* >+ * Parse the argument string, which may contain one or more of the >+ * following: >+ * >+ * unicast,multicast,broadcast,magic,sopasswd:xxxxxxxxxxxx, >+ * >+ * and fill the wolopts structure accordingly. >+ * >+ */ >+static void >+parse_args(const char* args, struct if_wolopts *wolopts) >+{ >+ uint32_t wol_events = 0; >+ char* opt; >+ >+ for (opt = strdup(args); (opt = strtok(opt, ",")) != NULL; opt = NULL) { >+ if (strcmp(opt, "unicast") == 0) >+ wol_events |= IFWOL_WAKE_ON_UNICAST; >+ else if (strcmp(opt, "multicast") == 0) >+ wol_events |= IFWOL_WAKE_ON_MULTICAST; >+ else if (strcmp(opt, "broadcast") == 0) >+ wol_events |= IFWOL_WAKE_ON_BROADCAST; >+ else if (strcmp(opt, "magic") == 0) >+ wol_events |= IFWOL_WAKE_ON_MAGIC; >+ else if (strcmp(opt, "sopasswd") == 0) >+ errx(EX_USAGE, "no SecureOn password specfied."); >+ else if (strncmp(opt, "sopasswd:", strlen("sopasswd:")) == 0) { >+ wol_events |= 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 = wol_events; >+} >+ >+/* SecureOn passwords are not like plain text passwords. Instead, they consist >+ * of 6 bytes (ie unsigned char). Try to prevent users from giving anything other >+ * than a string of six concatenated unsigned chars in hex as password. >+ */ >+static void >+parse_sopasswd(char *pw, u_char *dest) { >+ char substr[3]; >+ int len, i, n; >+ >+ len = strlen(pw) / 2; >+ if (len != 6) >+ errx(EX_USAGE, "Invalid SecureOn password."); >+ >+ for (i = 0; i < len; i++) { >+ (void)strncpy(substr, pw, 2); >+ substr[2] = '\0'; >+ if (sscanf(substr, "%x", &n) != 1) >+ errx(EX_USAGE, "Invalid SecureOn password."); >+ if (n < 0x0 || n > 0xff) >+ /* Should never happen, but just in case... */ >+ errx(EX_USAGE, "Invalid SecureOn password."); >+ *dest++ = (u_char)n; >+ pw += 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)); >+ strncpy(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 = IFWOL_DISABLE; >+ if (ioctl(s, SIOCSIFWOLOPTS, &ifr) < 0) >+ err(EX_USAGE, "SIOCSIFWOLOPTS"); >+} >+ >+static struct cmd wol_cmds[] = { >+ DEF_CMD_ARG("wakeon", setwol), >+ DEF_CMD("-wakeon", 0, unsetwol) >+}; >+static struct afswtch af_wol = { >+ .af_name = "af_wol", >+ .af_af = AF_UNSPEC, >+ .af_other_status = wol_status, >+}; >+ >+static __constructor void >+ifwol_ctor(void) >+{ >+#define N(a) (sizeof(a) / sizeof(a[0])) >+ int i; >+ >+ for (i = 0; i < N(wol_cmds); i++) >+ cmd_register(&wol_cmds[i]); >+ af_register(&af_wol); >+#undef N >+} >Index: sys/dev/nve/if_nve.c >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/dev/nve/if_nve.c,v >retrieving revision 1.7.2.8 >diff -u -r1.7.2.8 if_nve.c >--- sys/dev/nve/if_nve.c 25 Dec 2005 21:57:03 -0000 1.7.2.8 >+++ sys/dev/nve/if_nve.c 5 May 2006 23:05:57 -0000 >@@ -179,6 +179,10 @@ > static NV_SINT32 nve_oslockrelease(PNV_VOID, NV_SINT32, PNV_VOID); > static PNV_VOID nve_osreturnbufvirt(PNV_VOID, PNV_VOID); > >+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[] = { > /* Device interface */ > DEVMETHOD(device_probe, nve_probe), >@@ -718,6 +722,10 @@ > > sc = device_get_softc(dev); > >+ NVE_LOCK(sc); >+ nve_enable_wol(sc); >+ NVE_UNLOCK(sc); >+ > /* Stop hardware activity */ > NVE_LOCK(sc); > nve_stop(sc); >@@ -1018,6 +1026,21 @@ > mii = device_get_softc(sc->miibus); > error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); > break; >+ case SIOCGIFWOLSUPP: >+ ifr->ifr_wolopts.ifwol_supported = NVE_SUPPORTED_WOL_EVENTS; >+ error = 0; >+ break; >+ case SIOCGIFWOLOPTS: >+ NVE_LOCK(sc); >+ nve_get_wolopts(sc, &ifr->ifr_wolopts); >+ NVE_UNLOCK(sc); >+ error = 0; >+ break; >+ case SIOCSIFWOLOPTS: >+ NVE_LOCK(sc); >+ error = nve_set_wolopts(sc, &ifr->ifr_wolopts); >+ NVE_UNLOCK(sc); >+ break; > > default: > /* Everything else we forward to generic ether ioctl */ >@@ -1736,3 +1759,49 @@ > } > > /* --- End on NVOSAPI interface --- */ >+ >+/* >+ * Enable Wake On Lan. >+ */ >+static void >+nve_enable_wol(struct nve_softc *sc) >+{ >+ ADAPTER_POWERSTATE pstate = {0}; >+ >+ if (sc->wol_events == 0) >+ return; >+ >+ if (sc->wol_events & IFWOL_WAKE_ON_MAGIC) { >+ pstate.ulPowerFlags = POWER_STATE_D3; >+ pstate.ulMagicPacketWakeUpFlags = POWER_STATE_ALL; >+ pstate.ulLinkChangeWakeUpFlags = 0; >+ pstate.ulPatternWakeUpFlags = 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 = 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 == IFWOL_DISABLE) >+ sc->wol_events = 0; >+ else { >+ if ((wolopts->ifwol_events & ~NVE_SUPPORTED_WOL_EVENTS) != 0) >+ return EINVAL; >+ sc->wol_events = wolopts->ifwol_events; >+ } >+ >+ return 0; >+} >Index: sys/dev/nve/if_nvereg.h >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/dev/nve/if_nvereg.h,v >retrieving revision 1.3.2.1 >diff -u -r1.3.2.1 if_nvereg.h >--- sys/dev/nve/if_nvereg.h 12 Dec 2005 19:40:04 -0000 1.3.2.1 >+++ sys/dev/nve/if_nvereg.h 5 May 2006 23:05:57 -0000 >@@ -67,6 +67,8 @@ > #define NVE_DEBUG_MII 0x0100 > #define NVE_DEBUG_ALL 0xFFFF > >+#define NVE_SUPPORTED_WOL_EVENTS IFWOL_WAKE_ON_MAGIC >+ > #if NVE_DEBUG > #define DEBUGOUT(level, fmt, args...) if (NVE_DEBUG & level) \ > printf(fmt, ## args) >@@ -141,6 +143,8 @@ > > struct mtx mtx; > >+ uint32_t wol_events; >+ > /* Stuff for dealing with the NVIDIA OS API */ > struct callout ostimer; > PTIMER_FUNC ostimer_func; >Index: sys/net/if.c >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/net/if.c,v >retrieving revision 1.234.2.13 >diff -u -r1.234.2.13 if.c >--- sys/net/if.c 15 Feb 2006 03:37:15 -0000 1.234.2.13 >+++ sys/net/if.c 5 May 2006 23:05:57 -0000 >@@ -1436,6 +1436,7 @@ > case SIOCSLIFPHYADDR: > case SIOCSIFMEDIA: > case SIOCSIFGENERIC: >+ case SIOCSIFWOLOPTS: > error = suser(td); > if (error) > return (error); >@@ -1457,6 +1458,8 @@ > case SIOCGLIFPHYADDR: > case SIOCGIFMEDIA: > case SIOCGIFGENERIC: >+ case SIOCGIFWOLOPTS: >+ case SIOCGIFWOLSUPP: > if (ifp->if_ioctl == NULL) > return (EOPNOTSUPP); > IFF_LOCKGIANT(ifp); >Index: sys/net/if.h >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/net/if.h,v >retrieving revision 1.96.2.4 >diff -u -r1.96.2.4 if.h >--- sys/net/if.h 15 Feb 2006 03:37:15 -0000 1.96.2.4 >+++ sys/net/if.h 5 May 2006 23:05:57 -0000 >@@ -254,6 +254,28 @@ > #define IFAN_DEPARTURE 1 /* interface departure */ > > /* >+ * 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 >@@ -265,6 +287,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; >@@ -277,6 +300,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 >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/pci/if_sis.c,v >retrieving revision 1.132.2.7 >diff -u -r1.132.2.7 if_sis.c >--- sys/pci/if_sis.c 17 Mar 2006 21:30:57 -0000 1.132.2.7 >+++ sys/pci/if_sis.c 5 May 2006 23:05:57 -0000 >@@ -126,6 +126,10 @@ > static void sis_startl(struct ifnet *); > static void sis_stop(struct sis_softc *); > static void sis_watchdog(struct ifnet *); >+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); > > #ifdef SIS_USEIOSPACE > #define SIS_RES SYS_RES_IOPORT >@@ -170,7 +174,7 @@ > static void > sis_dma_map_ring(void *arg, bus_dma_segment_t *segs, int nseg, int error) > { >- u_int32_t *p; >+ uint32_t *p; > > p = arg; > *p = segs->ds_addr; >@@ -258,7 +262,7 @@ > sis_eeprom_getword(struct sis_softc *sc, int addr, uint16_t *dest) > { > int i; >- u_int16_t word = 0; >+ uint16_t word = 0; > > /* Force EEPROM to idle state. */ > sis_eeprom_idle(sc); >@@ -301,11 +305,11 @@ > sis_read_eeprom(struct sis_softc *sc, caddr_t dest, int off, int cnt, int swap) > { > int i; >- u_int16_t word = 0, *ptr; >+ uint16_t word = 0, *ptr; > > for (i = 0; i < cnt; i++) { > sis_eeprom_getword(sc, off + i, &word); >- ptr = (u_int16_t *)(dest + (i * 2)); >+ ptr = (uint16_t *)(dest + (i * 2)); > if (swap) > *ptr = ntohs(word); > else >@@ -354,7 +358,7 @@ > sis_read_cmos(struct sis_softc *sc, device_t dev, caddr_t dest, int off, int cnt) > { > device_t bridge; >- u_int8_t reg; >+ uint8_t reg; > int i; > bus_space_tag_t btag; > >@@ -383,7 +387,7 @@ > static void > sis_read_mac(struct sis_softc *sc, device_t dev, caddr_t dest) > { >- u_int32_t filtsave, csrsave; >+ uint32_t filtsave, csrsave; > > filtsave = CSR_READ_4(sc, SIS_RXFILT_CTL); > csrsave = CSR_READ_4(sc, SIS_CSR); >@@ -394,11 +398,11 @@ > CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave & ~SIS_RXFILTCTL_ENABLE); > > CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0); >- ((u_int16_t *)dest)[0] = CSR_READ_2(sc, SIS_RXFILT_DATA); >+ ((uint16_t *)dest)[0] = CSR_READ_2(sc, SIS_RXFILT_DATA); > CSR_WRITE_4(sc, SIS_RXFILT_CTL,SIS_FILTADDR_PAR1); >- ((u_int16_t *)dest)[1] = CSR_READ_2(sc, SIS_RXFILT_DATA); >+ ((uint16_t *)dest)[1] = CSR_READ_2(sc, SIS_RXFILT_DATA); > CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2); >- ((u_int16_t *)dest)[2] = CSR_READ_2(sc, SIS_RXFILT_DATA); >+ ((uint16_t *)dest)[2] = CSR_READ_2(sc, SIS_RXFILT_DATA); > > CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave); > CSR_WRITE_4(sc, SIS_CSR, csrsave); >@@ -731,7 +735,7 @@ > { > struct ifnet *ifp; > struct ifmultiaddr *ifma; >- u_int32_t h = 0, i, filtsave; >+ uint32_t h = 0, i, filtsave; > int bit, index; > > ifp = sc->sis_ifp; >@@ -782,8 +786,8 @@ > { > struct ifnet *ifp; > struct ifmultiaddr *ifma; >- u_int32_t h, i, n, ctl; >- u_int16_t hashes[16]; >+ uint32_t h, i, n, ctl; >+ uint16_t hashes[16]; > > ifp = sc->sis_ifp; > >@@ -984,7 +988,7 @@ > * Why? Who the hell knows. > */ > { >- u_int16_t tmp[4]; >+ uint16_t tmp[4]; > > sis_read_eeprom(sc, (caddr_t)&tmp, > NS_EE_NODEADDR, 4, 0); >@@ -1406,7 +1410,7 @@ > struct ifnet *ifp; > struct sis_desc *cur_rx; > int total_len = 0; >- u_int32_t rxstat; >+ uint32_t rxstat; > > SIS_LOCK_ASSERT(sc); > >@@ -1501,7 +1505,7 @@ > sis_txeof(struct sis_softc *sc) > { > struct ifnet *ifp; >- u_int32_t idx; >+ uint32_t idx; > > SIS_LOCK_ASSERT(sc); > ifp = sc->sis_ifp; >@@ -1605,7 +1609,7 @@ > sis_startl(ifp); > > if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) { >- u_int32_t status; >+ uint32_t status; > > /* Reading the ISR register clears all interrupts. */ > status = CSR_READ_4(sc, SIS_ISR); >@@ -1631,7 +1635,7 @@ > { > struct sis_softc *sc; > struct ifnet *ifp; >- u_int32_t status; >+ uint32_t status; > > sc = arg; > ifp = sc->sis_ifp; >@@ -1785,7 +1789,7 @@ > { > struct sis_softc *sc; > struct mbuf *m_head = NULL; >- u_int32_t idx, queued = 0; >+ uint32_t idx, queued = 0; > > sc = ifp->if_softc; > >@@ -1872,23 +1876,23 @@ > if (sc->sis_type == SIS_TYPE_83815) { > CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR0); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[0]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[0]); > CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR1); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[1]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[1]); > CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR2); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[2]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[2]); > } else { > CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR0); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[0]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[0]); > CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR1); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[1]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[1]); > CSR_WRITE_4(sc, SIS_RXFILT_CTL, SIS_FILTADDR_PAR2); > CSR_WRITE_4(sc, SIS_RXFILT_DATA, >- ((u_int16_t *)IFP2ENADDR(sc->sis_ifp))[2]); >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[2]); > } > > /* Init circular TX/RX lists. */ >@@ -2162,6 +2166,21 @@ > } > #endif /* DEVICE_POLLING */ > break; >+ case SIOCGIFWOLSUPP: >+ ifr->ifr_wolopts.ifwol_supported = NS_SUPPORTED_WOL_EVENTS; >+ error = 0; >+ break; >+ case SIOCGIFWOLOPTS: >+ SIS_LOCK(sc); >+ sis_get_wolopts(sc, &ifr->ifr_wolopts); >+ SIS_UNLOCK(sc); >+ error = 0; >+ break; >+ case SIOCSIFWOLOPTS: >+ SIS_LOCK(sc); >+ error = sis_set_wolopts(sc, &ifr->ifr_wolopts); >+ SIS_UNLOCK(sc); >+ break; > default: > error = ether_ioctl(ifp, command, data); > break; >@@ -2271,9 +2290,141 @@ > SIS_LOCK(sc); > sis_reset(sc); > sis_stop(sc); >+ sis_enable_wol(sc); > SIS_UNLOCK(sc); > } > >+/* >+ * 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 = 0; >+ >+ if (wol_events & IFWOL_WAKE_ON_UNICAST) >+ sis_wol_events |= NS_WCSR_WAKE_UCAST; >+ if (wol_events & IFWOL_WAKE_ON_MULTICAST) >+ sis_wol_events |= NS_WCSR_WAKE_MCAST; >+ if (wol_events & IFWOL_WAKE_ON_BROADCAST) >+ sis_wol_events |= NS_WCSR_WAKE_BCAST; >+ if (wol_events & IFWOL_WAKE_ON_MAGIC) >+ sis_wol_events |= 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 = sc->ns_wol_events; >+ >+ /* Do not disclose Secure On password. */ >+#define N(a) (sizeof(a) / sizeof(a[0])) >+ for (i = 0; i < N(wolopts->ifwol_sopasswd); i++) >+ wolopts->ifwol_sopasswd[i] = '\0'; >+#undef N >+} >+ >+/* >+ * 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 == IFWOL_DISABLE) >+ sc->ns_wol_events = 0; >+ else { >+ if ((wolopts->ifwol_events & ~NS_SUPPORTED_WOL_EVENTS) != 0) >+ return EINVAL; >+ sc->ns_wol_events = wolopts->ifwol_events; >+ } >+ >+ return 0; >+} >+ >+/* >+ * 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); >+ >+ if (sc->sis_type != SIS_TYPE_83815) >+ return; >+ >+ /* Check whether any wake on lan events have been set. */ >+ if (sc->ns_wol_events == 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); >+ >+ /* 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); >+ >+ /* >+ * 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, >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[0]); >+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR1); >+ CSR_WRITE_4(sc, SIS_RXFILT_DATA, >+ ((uint16_t *)IFP2ENADDR(sc->sis_ifp))[1]); >+ CSR_WRITE_4(sc, SIS_RXFILT_CTL, NS_FILTADDR_PAR2); >+ CSR_WRITE_4(sc, SIS_RXFILT_DATA, >+ ((uint16_t *)IFP2ENADDR(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[] = { > /* Device interface */ > DEVMETHOD(device_probe, sis_probe), >Index: sys/pci/if_sisreg.h >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/pci/if_sisreg.h,v >retrieving revision 1.33.2.1 >diff -u -r1.33.2.1 if_sisreg.h >--- sys/pci/if_sisreg.h 29 Sep 2005 18:52:21 -0000 1.33.2.1 >+++ sys/pci/if_sisreg.h 6 May 2006 10:59:50 -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 >@@ -463,6 +464,7 @@ > #endif > int in_tick; > struct mtx sis_mtx; >+ uint32_t ns_wol_events; > }; > > #define SIS_LOCK(_sc) mtx_lock(&(_sc)->sis_mtx) >@@ -523,3 +525,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_MULTICAST \ >+ | IFWOL_WAKE_ON_BROADCAST | IFWOL_WAKE_ON_MAGIC) >+ >Index: sys/pci/if_vr.c >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/pci/if_vr.c,v >retrieving revision 1.104.2.6 >diff -u -r1.104.2.6 if_vr.c >--- sys/pci/if_vr.c 17 Mar 2006 21:30:57 -0000 1.104.2.6 >+++ sys/pci/if_vr.c 5 May 2006 23:05:57 -0000 >@@ -169,6 +169,10 @@ > static int vr_list_rx_init(struct vr_softc *); > static int vr_list_tx_init(struct vr_softc *); > >+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 >@@ -710,7 +714,7 @@ > #endif > > /* >- * 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. > */ >@@ -761,6 +765,13 @@ > > sc->suspended = 0; > >+ /* Check Wake on Lan support. */ >+ if (sc->vr_revid >= REV_ID_VT6102 ) { >+ sc->wol_support = 1; >+ if (sc->vr_revid >= REV_ID_VT6105_B0) >+ sc->wol_6patterns = 1; >+ } >+ > /* Hook interrupt last to avoid having to lock softc */ > error = bus_setup_intr(dev, sc->vr_irq, INTR_TYPE_NET | INTR_MPSAFE, > vr_intr, sc, &sc->vr_intrhand); >@@ -1618,6 +1629,21 @@ > } > #endif /* DEVICE_POLLING */ > break; >+ case SIOCGIFWOLSUPP: >+ ifr->ifr_wolopts.ifwol_supported = VR_SUPPORTED_WOL_EVENTS; >+ error = 0; >+ break; >+ case SIOCGIFWOLOPTS: >+ VR_LOCK(sc); >+ vr_get_wolopts(sc, &ifr->ifr_wolopts); >+ VR_UNLOCK(sc); >+ error = 0; >+ break; >+ case SIOCSIFWOLOPTS: >+ VR_LOCK(sc); >+ error = vr_set_wolopts(sc, &ifr->ifr_wolopts); >+ VR_UNLOCK(sc); >+ break; > default: > error = ether_ioctl(ifp, command, data); > break; >@@ -1702,6 +1728,92 @@ > static void > vr_shutdown(device_t dev) > { >+ struct vr_softc *sc; > >+ sc = 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); >+ >+ /* Check whether wake on lan is available >+ * and whether events have been set. */ >+ if (!sc->wol_support || sc->wol_events == 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->wol_6patterns) >+ 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->wol_6patterns) >+ CSR_WRITE_1(sc, VR_WOLCGCLR, 0x04); >+ >+ /* Set unicast wake event if applicable. */ >+ if (sc->wol_events & IFWOL_WAKE_ON_UNICAST) >+ VR_SETBIT(sc, VR_WOLCRSET, VR_WAKE_UCAST); >+ >+ /* Set magic wake event if applicable. */ >+ if (sc->wol_events & 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->wol_events & IFWOL_WAKE_ON_BROADCAST || >+ sc->wol_events & 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 = sc->wol_events; >+} >+ >+/* >+ * 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 == IFWOL_DISABLE) >+ sc->wol_events = 0; >+ else { >+ if ((wolopts->ifwol_events & ~VR_SUPPORTED_WOL_EVENTS) != 0) >+ return EINVAL; >+ sc->wol_events = wolopts->ifwol_events; >+ } >+ >+ return 0; >+} >+ >Index: sys/pci/if_vrreg.h >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/pci/if_vrreg.h,v >retrieving revision 1.22.2.1 >diff -u -r1.22.2.1 if_vrreg.h >--- sys/pci/if_vrreg.h 8 Nov 2005 16:05:56 -0000 1.22.2.1 >+++ sys/pci/if_vrreg.h 5 May 2006 23:05:58 -0000 >@@ -283,6 +283,21 @@ > #define VR_STICKHW_WOL_STS 0x08 > #define VR_STICKHW_LEGWOL_ENB 0x80 > >+/* 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_MAGIC) >+ > /* > * BCR0 register bits. (At least for the VT6102 chip.) > */ >@@ -471,6 +486,10 @@ > #ifdef DEVICE_POLLING > int rxcycles; > #endif >+ int wol_support; /* Chip supports WOL. */ >+ uint32_t wol_events; /* Wake on Lan satus */ >+ int wol_6patterns; /* some chips have 6 patterns >+ for WOL instead of 4 */ > }; > > #define VR_F_RESTART 0x01 /* Restart unit on next tick */ >@@ -545,10 +564,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 >+ > > /* > * PCI low memory base and low I/O base register, and >Index: sys/sys/sockio.h >=================================================================== >RCS file: /usr/mylocal/ncvs/src/sys/sys/sockio.h,v >retrieving revision 1.28.2.1 >diff -u -r1.28.2.1 sockio.h >--- sys/sys/sockio.h 15 Feb 2006 03:37:15 -0000 1.28.2.1 >+++ sys/sys/sockio.h 5 May 2006 23:05:58 -0000 >@@ -117,4 +117,11 @@ > #define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */ > #define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */ > >+#define SIOCGIFWOLOPTS _IOWR('i', 124, struct ifreq) /* get wake on lan >+ options */ >+#define SIOCSIFWOLOPTS _IOW('i', 125, struct ifreq) /* set wake on lan >+ options */ >+#define SIOCGIFWOLSUPP _IOWR('i', 126, struct ifreq) /* get wake on lan >+ modes supported by >+ device */ > #endif /* !_SYS_SOCKIO_H_ */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 83807
: 55452 |
55453
|
55454