diff options
author | ngie <ngie@FreeBSD.org> | 2015-10-05 00:11:49 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2015-10-05 00:11:49 +0000 |
commit | e3bac3a30a41f56ac36f4791a7df260f2155c8db (patch) | |
tree | ac20948d4aa368300bc16ece67336a1bed25e992 | |
parent | ca6cf0ba737487849f2ee102afce74545600850c (diff) | |
parent | 85fa330dc74592563cea8d7cf0e628fd30683993 (diff) | |
download | FreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.zip FreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.tar.gz |
MFhead @ r281414
-rw-r--r-- | Makefile.inc1 | 5 | ||||
-rw-r--r-- | bin/cat/cat.c | 43 | ||||
-rw-r--r-- | games/Makefile | 21 | ||||
-rw-r--r-- | games/Makefile.inc | 6 | ||||
-rw-r--r-- | games/tests/Makefile | 10 | ||||
-rw-r--r-- | include/Makefile | 8 | ||||
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 16 | ||||
-rw-r--r-- | lib/libc/sys/posix_fadvise.2 | 12 | ||||
-rw-r--r-- | lib/libohash/ohash.h | 2 | ||||
-rw-r--r-- | lib/libusb/Makefile | 4 | ||||
-rw-r--r-- | lib/libz/Makefile | 2 | ||||
-rw-r--r-- | sbin/ipf/ipftest/Makefile | 24 | ||||
-rw-r--r-- | sbin/ipfw/ipfw2.c | 2 | ||||
-rw-r--r-- | share/dtrace/Makefile | 3 | ||||
-rwxr-xr-x | share/dtrace/blocking | 57 | ||||
-rw-r--r-- | share/man/man7/hier.7 | 5 | ||||
-rw-r--r-- | share/mk/bsd.sys.mk | 2 | ||||
-rw-r--r-- | share/mk/meta.stage.mk | 7 | ||||
-rw-r--r-- | sys/arm/arm/bcopy_page.S | 4 | ||||
-rw-r--r-- | sys/arm/arm/bcopyinout.S | 3 | ||||
-rw-r--r-- | sys/arm/arm/machdep.c | 2 | ||||
-rw-r--r-- | sys/arm/arm/vm_machdep.c | 2 | ||||
-rw-r--r-- | sys/arm/include/asm.h | 2 | ||||
-rw-r--r-- | sys/arm/include/atomic-v4.h | 33 | ||||
-rw-r--r-- | sys/arm/include/atomic-v6.h | 28 | ||||
-rw-r--r-- | sys/arm/include/atomic.h | 28 | ||||
-rw-r--r-- | sys/arm64/arm64/trap.c | 7 | ||||
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c | 2 | ||||
-rw-r--r-- | sys/dev/ath/if_ath_beacon.c | 6 | ||||
-rw-r--r-- | sys/dev/ath/if_ath_keycache.c | 3 | ||||
-rw-r--r-- | sys/dev/ath/if_ath_keycache.h | 3 | ||||
-rw-r--r-- | sys/dev/drm2/drmP.h | 6 | ||||
-rw-r--r-- | sys/dev/drm2/drm_crtc.c | 20 | ||||
-rw-r--r-- | sys/dev/drm2/drm_fops.c | 2 | ||||
-rw-r--r-- | sys/dev/drm2/drm_pci.c | 2 | ||||
-rw-r--r-- | sys/dev/drm2/drm_stub.c | 6 | ||||
-rw-r--r-- | sys/dev/drm2/i915/i915_dma.c | 2 | ||||
-rw-r--r-- | sys/dev/drm2/i915/i915_drv.c | 1 | ||||
-rw-r--r-- | sys/dev/drm2/i915/intel_opregion.c | 4 | ||||
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 5 | ||||
-rw-r--r-- | sys/dev/mwl/if_mwl.c | 21 | ||||
-rw-r--r-- | sys/dev/ral/rt2560.c | 5 | ||||
-rw-r--r-- | sys/dev/ral/rt2661.c | 4 | ||||
-rw-r--r-- | sys/dev/ral/rt2860.c | 3 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_rum.c | 1223 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_rumreg.h | 81 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_rumvar.h | 64 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_run.c | 117 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_runreg.h | 1 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_runvar.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_upgt.c | 5 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_ural.c | 27 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_urtwn.c | 6 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_zyd.c | 22 | ||||
-rw-r--r-- | sys/dev/wpi/if_wpi.c | 13 | ||||
-rw-r--r-- | sys/dev/wtap/if_wtap.c | 4 | ||||
-rw-r--r-- | sys/kern/subr_sbuf.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 6 | ||||
-rw-r--r-- | sys/mips/conf/WZR-300HP | 12 | ||||
-rw-r--r-- | sys/mips/conf/WZR-300HP.hints | 12 | ||||
-rw-r--r-- | sys/net/if_gif.c | 10 | ||||
-rw-r--r-- | sys/net/if_gre.c | 9 | ||||
-rw-r--r-- | sys/net/if_lagg.c | 9 | ||||
-rw-r--r-- | sys/net/if_lagg.h | 2 | ||||
-rw-r--r-- | sys/net/if_me.c | 7 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto.c | 50 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto.h | 8 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_ccmp.c | 36 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_none.c | 16 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_tkip.c | 52 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_wep.c | 56 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.c | 52 | ||||
-rw-r--r-- | sys/net80211/ieee80211_output.c | 14 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.h | 5 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 3 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 87 | ||||
-rw-r--r-- | sys/netinet6/nd6.h | 2 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 40 | ||||
-rw-r--r-- | sys/netpfil/ipfw/ip_fw_sockopt.c | 2 | ||||
-rw-r--r-- | sys/vm/vm_page.c | 2 | ||||
-rw-r--r-- | sys/vm/vm_pageout.c | 1 | ||||
-rw-r--r-- | sys/vm/vm_pageout.h | 1 | ||||
-rw-r--r-- | targets/pseudo/userland/games/Makefile.depend | 26 | ||||
-rw-r--r-- | usr.bin/Makefile | 14 | ||||
-rw-r--r-- | usr.bin/caesar/Makefile (renamed from games/caesar/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/caesar/Makefile.depend (renamed from games/caesar/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/caesar/caesar.6 (renamed from games/caesar/caesar.6) | 0 | ||||
-rw-r--r-- | usr.bin/caesar/caesar.c (renamed from games/caesar/caesar.c) | 0 | ||||
-rw-r--r-- | usr.bin/caesar/rot13.sh (renamed from games/caesar/rot13.sh) | 0 | ||||
-rw-r--r-- | usr.bin/factor/Makefile (renamed from games/factor/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/factor/Makefile.depend (renamed from games/factor/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/factor/factor.6 (renamed from games/factor/factor.6) | 0 | ||||
-rw-r--r-- | usr.bin/factor/factor.c (renamed from games/factor/factor.c) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/Makefile (renamed from games/fortune/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/Makefile.inc (renamed from games/fortune/Makefile.inc) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/Notes (renamed from games/fortune/Notes) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/README (renamed from games/fortune/README) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/Makefile (renamed from games/fortune/datfiles/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/Makefile.depend (renamed from games/fortune/datfiles/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/fortunes (renamed from games/fortune/datfiles/fortunes) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/fortunes.sp.ok (renamed from games/fortune/datfiles/fortunes.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/freebsd-tips (renamed from games/fortune/datfiles/freebsd-tips) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/freebsd-tips.sp.ok (renamed from games/fortune/datfiles/freebsd-tips.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/gerrold.limerick (renamed from games/fortune/datfiles/gerrold.limerick) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/limerick (renamed from games/fortune/datfiles/limerick) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/limerick.sp.ok (renamed from games/fortune/datfiles/limerick.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/murphy (renamed from games/fortune/datfiles/murphy) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/murphy-o (renamed from games/fortune/datfiles/murphy-o) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/murphy.sp.ok (renamed from games/fortune/datfiles/murphy.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/startrek (renamed from games/fortune/datfiles/startrek) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/startrek.sp.ok (renamed from games/fortune/datfiles/startrek.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/zippy (renamed from games/fortune/datfiles/zippy) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/datfiles/zippy.sp.ok (renamed from games/fortune/datfiles/zippy.sp.ok) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/fortune/Makefile (renamed from games/fortune/fortune/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/fortune/Makefile.depend (renamed from games/fortune/fortune/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/fortune/fortune.6 (renamed from games/fortune/fortune/fortune.6) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/fortune/fortune.c (renamed from games/fortune/fortune/fortune.c) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/fortune/pathnames.h (renamed from games/fortune/fortune/pathnames.h) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/strfile/Makefile (renamed from games/fortune/strfile/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/strfile/Makefile.depend (renamed from games/fortune/strfile/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/strfile/strfile.8 (renamed from games/fortune/strfile/strfile.8) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/strfile/strfile.c (renamed from games/fortune/strfile/strfile.c) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/strfile/strfile.h (renamed from games/fortune/strfile/strfile.h) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/Do_spell (renamed from games/fortune/tools/Do_spell) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/Do_troff (renamed from games/fortune/tools/Do_troff) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/Troff.mac (renamed from games/fortune/tools/Troff.mac) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/Troff.sed (renamed from games/fortune/tools/Troff.sed) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/do_sort (renamed from games/fortune/tools/do_sort) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/tools/do_uniq.py (renamed from games/fortune/tools/do_uniq.py) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/unstr/Makefile (renamed from games/fortune/unstr/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/unstr/Makefile.depend (renamed from games/fortune/unstr/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/fortune/unstr/unstr.c (renamed from games/fortune/unstr/unstr.c) | 0 | ||||
-rw-r--r-- | usr.bin/grdc/Makefile (renamed from games/grdc/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/grdc/Makefile.depend (renamed from games/grdc/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/grdc/grdc.6 (renamed from games/grdc/grdc.6) | 0 | ||||
-rw-r--r-- | usr.bin/grdc/grdc.c (renamed from games/grdc/grdc.c) | 0 | ||||
-rw-r--r-- | usr.bin/morse/Makefile (renamed from games/morse/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/morse/Makefile.depend (renamed from games/morse/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/morse/morse.6 (renamed from games/morse/morse.6) | 0 | ||||
-rw-r--r-- | usr.bin/morse/morse.c (renamed from games/morse/morse.c) | 0 | ||||
-rw-r--r-- | usr.bin/number/Makefile (renamed from games/number/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/number/Makefile.depend (renamed from games/number/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/number/number.6 (renamed from games/number/number.6) | 0 | ||||
-rw-r--r-- | usr.bin/number/number.c (renamed from games/number/number.c) | 0 | ||||
-rw-r--r-- | usr.bin/pom/Makefile (renamed from games/pom/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/pom/Makefile.depend (renamed from games/pom/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/pom/pom.6 (renamed from games/pom/pom.6) | 0 | ||||
-rw-r--r-- | usr.bin/pom/pom.c (renamed from games/pom/pom.c) | 0 | ||||
-rw-r--r-- | usr.bin/primes/Makefile (renamed from games/primes/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/primes/Makefile.depend (renamed from games/primes/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/primes/pattern.c (renamed from games/primes/pattern.c) | 0 | ||||
-rw-r--r-- | usr.bin/primes/pr_tbl.c (renamed from games/primes/pr_tbl.c) | 0 | ||||
-rw-r--r-- | usr.bin/primes/primes.c (renamed from games/primes/primes.c) | 0 | ||||
-rw-r--r-- | usr.bin/primes/primes.h (renamed from games/primes/primes.h) | 0 | ||||
-rw-r--r-- | usr.bin/primes/spsp.c (renamed from games/primes/spsp.c) | 0 | ||||
-rw-r--r-- | usr.bin/random/Makefile (renamed from games/random/Makefile) | 0 | ||||
-rw-r--r-- | usr.bin/random/Makefile.depend (renamed from games/random/Makefile.depend) | 0 | ||||
-rw-r--r-- | usr.bin/random/random.6 (renamed from games/random/random.6) | 0 | ||||
-rw-r--r-- | usr.bin/random/random.c (renamed from games/random/random.c) | 0 | ||||
-rw-r--r-- | usr.bin/random/randomize_fd.c (renamed from games/random/randomize_fd.c) | 0 | ||||
-rw-r--r-- | usr.bin/random/randomize_fd.h (renamed from games/random/randomize_fd.h) | 0 | ||||
-rw-r--r-- | usr.bin/truss/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/truss/aarch64-fbsd.c | 110 | ||||
-rw-r--r-- | usr.bin/truss/amd64-cloudabi64.c | 113 | ||||
-rw-r--r-- | usr.bin/truss/amd64cloudabi64.conf | 13 | ||||
-rw-r--r-- | usr.bin/truss/syscall.h | 3 | ||||
-rw-r--r-- | usr.bin/truss/syscalls.c | 29 | ||||
-rw-r--r-- | usr.sbin/bhyve/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/bhyverun.c | 4 | ||||
-rw-r--r-- | usr.sbin/bhyve/fwctl.c | 549 | ||||
-rw-r--r-- | usr.sbin/bhyve/fwctl.h | 54 | ||||
-rw-r--r-- | usr.sbin/ctld/ctl.conf.5 | 2 | ||||
-rw-r--r-- | usr.sbin/ctld/ctld.c | 5 | ||||
-rw-r--r-- | usr.sbin/ctld/ctld.h | 1 | ||||
-rw-r--r-- | usr.sbin/kldxref/kldxref.c | 5 | ||||
-rw-r--r-- | usr.sbin/rpc.yppasswdd/yppasswdd_server.c | 4 | ||||
-rw-r--r-- | usr.sbin/rpcbind/rpcb_svc_com.c | 11 |
177 files changed, 2689 insertions, 763 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1 index 24f466c..389950c 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -61,9 +61,6 @@ SUBDIR= ${SUBDIR_OVERRIDE} .else SUBDIR= lib libexec SUBDIR+=bin -.if ${MK_GAMES} != "no" -SUBDIR+=games -.endif .if ${MK_CDDL} != "no" SUBDIR+=cddl .endif @@ -1285,7 +1282,7 @@ legacy: _bt= _bootstrap-tools .if ${MK_GAMES} != "no" -_strfile= games/fortune/strfile +_strfile= usr.bin/fortune/strfile .endif .if ${MK_GCC} != "no" && ${MK_CXX} != "no" diff --git a/bin/cat/cat.c b/bin/cat/cat.c index f724cb0..b5f99ee 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <sys/socket.h> #include <sys/un.h> #include <errno.h> +#include <netdb.h> #endif #include <ctype.h> @@ -167,6 +168,7 @@ scanfiles(char *argv[], int cooked) FILE *fp; i = 0; + fd = -1; while ((path = argv[i]) != NULL || i == 0) { if (path == NULL || strcmp(path, "-") == 0) { filename = "stdin"; @@ -302,31 +304,40 @@ raw_cat(int rfd) static int udom_open(const char *path, int flags) { - struct sockaddr_un sou; - int fd; - unsigned int len; - - bzero(&sou, sizeof(sou)); + struct addrinfo hints, *res, *res0; + char rpath[PATH_MAX]; + int fd = -1; + int error; /* - * Construct the unix domain socket address and attempt to connect + * Construct the unix domain socket address and attempt to connect. */ - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd >= 0) { - sou.sun_family = AF_UNIX; - if ((len = strlcpy(sou.sun_path, path, - sizeof(sou.sun_path))) >= sizeof(sou.sun_path)) { - close(fd); - errno = ENAMETOOLONG; + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_LOCAL; + if (realpath(path, rpath) == NULL) + return (-1); + error = getaddrinfo(rpath, NULL, &hints, &res0); + if (error) { + warn("%s", gai_strerror(error)); + errno = EINVAL; + return (-1); + } + for (res = res0; res != NULL; res = res->ai_next) { + fd = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (fd < 0) { + freeaddrinfo(res0); return (-1); } - len = offsetof(struct sockaddr_un, sun_path[len+1]); - - if (connect(fd, (void *)&sou, len) < 0) { + error = connect(fd, res->ai_addr, res->ai_addrlen); + if (error == 0) + break; + else { close(fd); fd = -1; } } + freeaddrinfo(res0); /* * handle the open flags by shutting down appropriate directions diff --git a/games/Makefile b/games/Makefile deleted file mode 100644 index 4a3da52..0000000 --- a/games/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.include <src.opts.mk> - -SUBDIR= \ - caesar \ - factor \ - fortune \ - grdc \ - morse \ - number \ - pom \ - primes \ - random \ - ${_tests} - -.if ${MK_TESTS} != "no" -_tests= tests -.endif - -.include <bsd.subdir.mk> diff --git a/games/Makefile.inc b/games/Makefile.inc deleted file mode 100644 index 40525f8..0000000 --- a/games/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93 -# $FreeBSD$ - -BINDIR?= /usr/bin -FILESDIR?= ${SHAREDIR}/games -WARNS?= 6 diff --git a/games/tests/Makefile b/games/tests/Makefile deleted file mode 100644 index 45f93d9..0000000 --- a/games/tests/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.include <bsd.own.mk> - -TESTSDIR= ${TESTSBASE}/games - -.PATH: ${.CURDIR:H:H}/tests -KYUAFILE= yes - -.include <bsd.test.mk> diff --git a/include/Makefile b/include/Makefile index 3c3f993..1cecff7 100644 --- a/include/Makefile +++ b/include/Makefile @@ -166,7 +166,7 @@ compat: -f ${.CURDIR}/../etc/mtree/BSD.include.dist \ -p ${DESTDIR}${INCLUDEDIR} > /dev/null .if ${MK_META_MODE} == "yes" - touch ${.TARGET} + @touch ${.TARGET} .endif copies: @@ -255,8 +255,7 @@ copies: ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \ ${DESTDIR}${INCLUDEDIR}/teken .if ${MK_META_MODE} == "yes" - cd ${.OBJDIR} - touch ${.TARGET} + @touch ${.OBJDIR}/${.TARGET} .endif symlinks: @@ -373,8 +372,7 @@ symlinks: ${DESTDIR}${INCLUDEDIR}/rpc; \ done .if ${MK_META_MODE} == "yes" - cd ${.OBJDIR} - touch ${.TARGET} + @touch ${.OBJDIR}/${.TARGET} .endif .if ${MACHINE} == "host" diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 8b47aef..95c588b 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -168,12 +168,6 @@ struct explore { }; static const struct explore explore[] = { - { PF_LOCAL, SOCK_DGRAM, ANY, - AF_ANY | PROTOCOL_ANY }, - { PF_LOCAL, SOCK_STREAM, ANY, - AF_ANY | PROTOCOL_ANY }, - { PF_LOCAL, SOCK_SEQPACKET, ANY, - AF_ANY | PROTOCOL_ANY }, #ifdef INET6 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY }, @@ -200,6 +194,12 @@ static const struct explore explore[] = { AF_ANY | SOCKTYPE_ANY }, { PF_INET, SOCK_RAW, ANY, AF_ANY | PROTOCOL_ANY }, + { PF_LOCAL, SOCK_DGRAM, ANY, + AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY }, + { PF_LOCAL, SOCK_STREAM, ANY, + AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY }, + { PF_LOCAL, SOCK_SEQPACKET, ANY, + AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY }, { -1, 0, 0, 0 }, }; @@ -1245,7 +1245,9 @@ explore_numeric(const struct addrinfo *pai, const char *hostname, if (pai->ai_family == afd->a_af) { GET_AI(ai, afd, p); GET_PORT(ai, servname); - if ((pai->ai_flags & AI_CANONNAME)) { + if ((pai->ai_family == AF_INET || + pai->ai_family == AF_INET6) && + (pai->ai_flags & AI_CANONNAME)) { /* * Set the numeric address itself as the canonical * name, based on a clarification in RFC3493. diff --git a/lib/libc/sys/posix_fadvise.2 b/lib/libc/sys/posix_fadvise.2 index 8691f6b..641bc9b 100644 --- a/lib/libc/sys/posix_fadvise.2 +++ b/lib/libc/sys/posix_fadvise.2 @@ -28,7 +28,7 @@ .\" @(#)madvise.2 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd January 30, 2014 +.Dd October 3, 2015 .Dt POSIX_FADVISE 2 .Os .Sh NAME @@ -89,11 +89,13 @@ read or written. Future access to this data may require a read operation. .El .Sh RETURN VALUES -.Rv -std posix_fadvise -.Sh ERRORS -The +If successful, .Fn posix_fadvise -system call returns zero on success, and an error on failure: +returns zero. +It returns an error on failure, without setting +.Va errno . +.Sh ERRORS +Possible failure conditions: .Bl -tag -width Er .It Bq Er EBADF The diff --git a/lib/libohash/ohash.h b/lib/libohash/ohash.h index 03de431..ff21c85 100644 --- a/lib/libohash/ohash.h +++ b/lib/libohash/ohash.h @@ -20,6 +20,8 @@ #ifndef OHASH_H #define OHASH_H +#include <stddef.h> + /* Open hashing support. * Open hashing was chosen because it is much lighter than other hash * techniques, and more efficient in most cases. diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile index 25d886a..be55aa6 100644 --- a/lib/libusb/Makefile +++ b/lib/libusb/Makefile @@ -35,10 +35,10 @@ SRCS+= libusb10_io.c .if defined(COMPAT_32BIT) CFLAGS+= -DCOMPAT_32BIT -.else +.endif + FILES= libusb-0.1.pc libusb-1.0.pc libusb-2.0.pc FILESDIR= ${LIBDATADIR}/pkgconfig -.endif # # Cross platform support diff --git a/lib/libz/Makefile b/lib/libz/Makefile index aed4ee3..7a80fcb 100644 --- a/lib/libz/Makefile +++ b/lib/libz/Makefile @@ -68,10 +68,8 @@ test: example minigzip (export LD_LIBRARY_PATH=. ; \ echo hello world | ./minigzip | ./minigzip -d ) -.ifndef COMPAT_32BIT FILES= zlib.pc FILESDIR= ${LIBDATADIR}/pkgconfig -.endif .include <bsd.lib.mk> diff --git a/sbin/ipf/ipftest/Makefile b/sbin/ipf/ipftest/Makefile index 32b074c..7d8260a 100644 --- a/sbin/ipf/ipftest/Makefile +++ b/sbin/ipf/ipftest/Makefile @@ -32,15 +32,19 @@ CLEANFILES+= ipnat.tab.c ipnat.tab.h CLEANFILES+= ippool_y.c ippool_l.c CLEANFILES+= ippool.tab.c ippool.tab.h -ipnat_y.c: ipnat_y.y +ipnat.tab.c ipnat.tab.h: ipnat_y.y ${YACC} -b ipnat -d ${.ALLSRC} + +ipnat_y.c: ipnat.tab.c sed -e 's/yy/ipnat_yy/g' \ -e 's/y.tab.c/ipnat_y.c/' \ -e s/\"ipnat_y.y\"/\"..\\/tools\\/ipnat_y.y\"/ \ ipnat.tab.c > ${.TARGET} + +ipnat_y.h: ipnat.tab.h sed -e 's/yy/ipnat_yy/g' \ -e 's/y.tab.h/ipnat_y.h/' \ - ipnat.tab.h > ${.TARGET:.c=.h} + ipnat.tab.h > ${.TARGET} ipnat_y.h: ipnat_y.c @@ -54,13 +58,17 @@ ipnat_l.h: lexer.h sed -e 's/yy/ipnat_yy/g' \ ${.ALLSRC} > ${.TARGET} -ippool_y.c: ippool_y.y +ippool.tab.c ippool.tab.h: ippool_y.y ${YACC} -b ippool -d ${.ALLSRC} + +ippool_y.c: ippool.tab.c sed -e 's/yy/ippool_yy/g' \ -e 's/"ippool_y.y"/"..\/tools\/ippool_y.y"/' \ ippool.tab.c > ${.TARGET} + +ippool_y.h: ippool.tab.h sed -e 's/yy/ippool_yy/g' \ - ippool.tab.h > ${.TARGET:.c=.h} + ippool.tab.h > ${.TARGET} ippool_y.h: ippool_y.c @@ -74,13 +82,17 @@ ippool_l.h: lexer.h sed -e 's/yy/ippool_yy/g' \ ${.ALLSRC} > ${.TARGET} -ipf_y.c: ipf_y.y +ipf.tab.c ipf.tab.h: ipf_y.y ${YACC} -b ipf -d ${.ALLSRC} + +ipf_y.c: ipf.tab.c sed -e 's/yy/ipf_yy/g' \ -e 's/"ipf_y.y"/"..\/tools\/ipf_y.y"/' \ ipf.tab.c > ${.TARGET} + +ipf_y.h: ipf.tab.h sed -e 's/yy/ipf_yy/g' \ - ipf.tab.h > ${.TARGET:.c=.h} + ipf.tab.h > ${.TARGET} ipf_y.h: ipf_y.c diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 8ad8f90..bc8af9f 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -3625,7 +3625,7 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate) action->opcode = O_NAT; action->len = F_INSN_SIZE(ipfw_insn_nat); CHECK_ACTLEN; - if (_substrcmp(*av, "global") == 0) { + if (*av != NULL && _substrcmp(*av, "global") == 0) { action->arg1 = 0; av++; break; diff --git a/share/dtrace/Makefile b/share/dtrace/Makefile index 11fd1af..c0c3f5e 100644 --- a/share/dtrace/Makefile +++ b/share/dtrace/Makefile @@ -12,7 +12,8 @@ SUBDIR= ${_toolkit} _toolkit= toolkit .endif -SCRIPTS= disklatency \ +SCRIPTS= blocking \ + disklatency \ disklatencycmd \ hotopen \ nfsattrstats \ diff --git a/share/dtrace/blocking b/share/dtrace/blocking new file mode 100755 index 0000000..0065008 --- /dev/null +++ b/share/dtrace/blocking @@ -0,0 +1,57 @@ +#!/usr/sbin/dtrace -s +/*- + * Copyright (c) 2015 Pawel Jakub Dawidek <pawel@dawidek.net> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``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 AUTHORS OR CONTRIBUTORS 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. + * + * $FreeBSD$ + * + * This little script is for use with programs that use event loop and should + * sleep only when waiting for events (eg. via kevent(2)). When a program is + * going to sleep in the kernel, the script will show its name, PID, kernel + * stack trace and userland stack trace. Sleeping in kevent(2) is ignored. + * + * usage: blocking <execname> + */ + +#pragma D option quiet + +syscall::kevent:entry +/execname == $$1/ +{ + self->inkevent = 1; +} + +fbt::sleepq_add:entry +/!self->inkevent && execname == $$1/ +{ + printf("\n%s(%d) is blocking...\n", execname, pid); + stack(); + ustack(); +} + +syscall::kevent:return +/execname == $$1/ +{ + self->inkevent = 0; +} diff --git a/share/man/man7/hier.7 b/share/man/man7/hier.7 index 6d4534b..9def562 100644 --- a/share/man/man7/hier.7 +++ b/share/man/man7/hier.7 @@ -28,7 +28,7 @@ .\" @(#)hier.7 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd January 14, 2015 +.Dd October 2, 2015 .Dt HIER 7 .Os .Sh NAME @@ -685,9 +685,6 @@ source code for contributed cryptography software .It Pa etc/ source code for files in .Pa /etc -.It Pa games/ -source code for files in -.Pa /usr/games .It Pa gnu/ Utilities covered by the GNU General Public License .It Pa include/ diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 411e816..c68e0ab 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -149,7 +149,7 @@ CXXFLAGS.clang+= -Wno-c++11-extensions .if ${MK_SSP} != "no" && \ ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips" # Don't use -Wstack-protector as it breaks world with -Werror. -SSP_CFLAGS?= -fstack-protector +SSP_CFLAGS?= -fstack-protector-strong CFLAGS+= ${SSP_CFLAGS} .endif # SSP && !ARM && !MIPS diff --git a/share/mk/meta.stage.mk b/share/mk/meta.stage.mk index 467e339..7f6c3b3 100644 --- a/share/mk/meta.stage.mk +++ b/share/mk/meta.stage.mk @@ -237,10 +237,11 @@ stage_as.$s: .dirdep CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes # stage_*links usually needs to follow any others. -.for t in ${STAGE_TARGETS:N*links:O:u} -.ORDER: $t stage_links -.ORDER: $t stage_symlinks +.if !empty(STAGE_SETS) && !empty(STAGE_TARGETS:Nstage_links) +.for s in ${STAGE_SETS:O:u} +stage_links.$s: ${STAGE_TARGETS:Nstage_links:O:u} .endfor +.endif # make sure this exists staging: diff --git a/sys/arm/arm/bcopy_page.S b/sys/arm/arm/bcopy_page.S index 92e38cc..0d787b2 100644 --- a/sys/arm/arm/bcopy_page.S +++ b/sys/arm/arm/bcopy_page.S @@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$"); #endif /* ! COPY_CHUNK */ #ifndef SAVE_REGS -#define SAVE_REGS stmfd sp!, {r4-r8, lr} +#define SAVE_REGS stmfd sp!, {r4-r8, lr}; _SAVE({r4-r8, lr}) #define RESTORE_REGS ldmfd sp!, {r4-r8, pc} #endif @@ -134,6 +134,7 @@ END(bcopy_page) ENTRY(bzero_page) stmfd sp!, {r4-r8, lr} + _SAVE({r4-r8, lr}) #ifdef BIG_LOOPS mov r2, #(PAGE_SIZE >> 9) #else @@ -189,6 +190,7 @@ END(bzero_page) ENTRY(bcopy_page) pld [r0] stmfd sp!, {r4, r5} + _SAVE({r4, r5}) mov ip, #32 ldr r2, [r0], #0x04 /* 0x00 */ ldr r3, [r0], #0x04 /* 0x04 */ diff --git a/sys/arm/arm/bcopyinout.S b/sys/arm/arm/bcopyinout.S index c030e24..df0484e 100644 --- a/sys/arm/arm/bcopyinout.S +++ b/sys/arm/arm/bcopyinout.S @@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$"); #endif -#define SAVE_REGS stmfd sp!, {r4-r11} +#define SAVE_REGS stmfd sp!, {r4-r11}; _SAVE({r4-r11}) #define RESTORE_REGS ldmfd sp!, {r4-r11} #if defined(_ARM_ARCH_5E) @@ -341,6 +341,7 @@ ENTRY(copyout) cmp r2, r3 blt .Lnormale stmfd sp!, {r0-r2, r4, lr} + _SAVE({r0-r2, r4, lr}) mov r3, r0 mov r0, r1 mov r1, r3 diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 32bbbc6..1c422f3 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -1069,7 +1069,7 @@ init_proc0(vm_offset_t kstack) (thread0.td_kstack + kstack_pages * PAGE_SIZE) - 1; thread0.td_pcb->pcb_flags = 0; thread0.td_pcb->pcb_vfpcpu = -1; - thread0.td_pcb->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ; + thread0.td_pcb->pcb_vfpstate.fpscr = VFPSCR_DN; thread0.td_frame = &proc0_tf; pcpup->pc_curpcb = thread0.td_pcb; } diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 223ad96..895a14c 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -134,7 +134,7 @@ cpu_fork(register struct thread *td1, register struct proc *p2, pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame); pcb2->pcb_vfpcpu = -1; - pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ; + pcb2->pcb_vfpstate.fpscr = VFPSCR_DN; tf = td2->td_frame; tf->tf_spsr &= ~PSR_C; diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 2f64c37..5958ea3 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -53,10 +53,12 @@ #define STOP_UNWINDING .cantunwind #define _FNSTART .fnstart #define _FNEND .fnend +#define _SAVE(...) .save __VA_ARGS__ #else #define STOP_UNWINDING #define _FNSTART #define _FNEND +#define _SAVE(...) #endif /* diff --git a/sys/arm/include/atomic-v4.h b/sys/arm/include/atomic-v4.h index 7048178..2854655 100644 --- a/sys/arm/include/atomic-v4.h +++ b/sys/arm/include/atomic-v4.h @@ -439,4 +439,37 @@ atomic_subtract_long(volatile u_long *p, u_long v) atomic_subtract_32((volatile uint32_t *)p, v); } +/* + * ARMv5 does not support SMP. For both kernel and user modes, only a + * compiler barrier is needed for fences, since CPU is always + * self-consistent. + */ +static __inline void +atomic_thread_fence_acq(void) +{ + + __compiler_membar(); +} + +static __inline void +atomic_thread_fence_rel(void) +{ + + __compiler_membar(); +} + +static __inline void +atomic_thread_fence_acq_rel(void) +{ + + __compiler_membar(); +} + +static __inline void +atomic_thread_fence_seq_cst(void) +{ + + __compiler_membar(); +} + #endif /* _MACHINE_ATOMIC_H_ */ diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h index 06d8880..d22f7e1 100644 --- a/sys/arm/include/atomic-v6.h +++ b/sys/arm/include/atomic-v6.h @@ -596,4 +596,32 @@ atomic_store_rel_long(volatile u_long *p, u_long v) #undef ATOMIC_ACQ_REL #undef ATOMIC_ACQ_REL_LONG +static __inline void +atomic_thread_fence_acq(void) +{ + + dmb(); +} + +static __inline void +atomic_thread_fence_rel(void) +{ + + dmb(); +} + +static __inline void +atomic_thread_fence_acq_rel(void) +{ + + dmb(); +} + +static __inline void +atomic_thread_fence_seq_cst(void) +{ + + dmb(); +} + #endif /* _MACHINE_ATOMIC_V6_H_ */ diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h index 5379030..039af34 100644 --- a/sys/arm/include/atomic.h +++ b/sys/arm/include/atomic.h @@ -82,34 +82,6 @@ atomic_store_long(volatile u_long *dst, u_long src) *dst = src; } -static __inline void -atomic_thread_fence_acq(void) -{ - - dmb(); -} - -static __inline void -atomic_thread_fence_rel(void) -{ - - dmb(); -} - -static __inline void -atomic_thread_fence_acq_rel(void) -{ - - dmb(); -} - -static __inline void -atomic_thread_fence_seq_cst(void) -{ - - dmb(); -} - #define atomic_clear_ptr atomic_clear_32 #define atomic_set_ptr atomic_set_32 #define atomic_cmpset_ptr atomic_cmpset_32 diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index e54c20e..a29f915 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -275,7 +275,7 @@ do_el1h_sync(struct trapframe *frame) */ KASSERT((esr & ESR_ELx_IL) == ESR_ELx_IL || (exception == EXCP_DATA_ABORT && ((esr & ISS_DATA_ISV) == 0)), - ("Invalid instruction length in exception")); + ("Invalid instruction length in exception, esr %lx", esr)); CTR4(KTR_TRAP, "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", @@ -377,6 +377,11 @@ do_el0_sync(struct trapframe *frame) case EXCP_UNKNOWN: el0_excp_unknown(frame); break; + case EXCP_PC_ALIGN: + td = curthread; + call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr); + userret(td, frame); + break; case EXCP_BRK: td = curthread; call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 326b03e..4ed3f52 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -449,7 +449,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length, } if ((flags & DMU_READ_NO_PREFETCH) == 0 && read && - length < zfetch_array_rd_sz) { + length <= zfetch_array_rd_sz) { dmu_zfetch(&dn->dn_zfetch, blkid, nblks); } rw_exit(&dn->dn_struct_rwlock); diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c index 1ef3d58..5db0ba4 100644 --- a/sys/dev/ath/if_ath_beacon.c +++ b/sys/dev/ath/if_ath_beacon.c @@ -199,7 +199,7 @@ ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni) * we assume the mbuf routines will return us something * with this alignment (perhaps should assert). */ - m = ieee80211_beacon_alloc(ni, &vap->iv_bcn_off); + m = ieee80211_beacon_alloc(ni); if (m == NULL) { device_printf(sc->sc_dev, "%s: cannot get mbuf\n", __func__); sc->sc_stats.ast_be_nombuf++; @@ -713,7 +713,7 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap) /* XXX lock mcastq? */ nmcastq = avp->av_mcastq.axq_depth; - if (ieee80211_beacon_update(bf->bf_node, &vap->iv_bcn_off, m, nmcastq)) { + if (ieee80211_beacon_update(bf->bf_node, m, nmcastq)) { /* XXX too conservative? */ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, @@ -829,7 +829,7 @@ ath_beacon_start_adhoc(struct ath_softc *sc, struct ieee80211vap *vap) */ bf = avp->av_bcbuf; m = bf->bf_m; - if (ieee80211_beacon_update(bf->bf_node, &vap->iv_bcn_off, m, 0)) { + if (ieee80211_beacon_update(bf->bf_node, m, 0)) { /* XXX too conservative? */ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, diff --git a/sys/dev/ath/if_ath_keycache.c b/sys/dev/ath/if_ath_keycache.c index f81785f..ff1df84 100644 --- a/sys/dev/ath/if_ath_keycache.c +++ b/sys/dev/ath/if_ath_keycache.c @@ -527,8 +527,7 @@ ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) * slot(s) must already have been allocated by ath_key_alloc. */ int -ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, - const u_int8_t mac[IEEE80211_ADDR_LEN]) +ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) { struct ath_softc *sc = vap->iv_ic->ic_softc; diff --git a/sys/dev/ath/if_ath_keycache.h b/sys/dev/ath/if_ath_keycache.h index 0b79e6f..c67e555 100644 --- a/sys/dev/ath/if_ath_keycache.h +++ b/sys/dev/ath/if_ath_keycache.h @@ -35,8 +35,7 @@ extern int ath_key_alloc(struct ieee80211vap *, struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); extern int ath_key_delete(struct ieee80211vap *, const struct ieee80211_key *); -extern int ath_key_set(struct ieee80211vap *, const struct ieee80211_key *, - const u_int8_t mac[IEEE80211_ADDR_LEN]); +extern int ath_key_set(struct ieee80211vap *, const struct ieee80211_key *); extern int ath_keyset(struct ath_softc *sc, struct ieee80211vap *vap, const struct ieee80211_key *k, struct ieee80211_node *bss); diff --git a/sys/dev/drm2/drmP.h b/sys/dev/drm2/drmP.h index 32c3fcd..b3633c3 100644 --- a/sys/dev/drm2/drmP.h +++ b/sys/dev/drm2/drmP.h @@ -1782,12 +1782,6 @@ void drm_driver_irq_preinstall(struct drm_device *dev); void drm_driver_irq_postinstall(struct drm_device *dev); void drm_driver_irq_uninstall(struct drm_device *dev); -/* AGP/PCI Express/GART support (drm_agpsupport.c) */ -void *drm_agp_allocate_memory(size_t pages, u32 type); -int drm_agp_free_memory(void *handle); -int drm_agp_bind_memory(void *handle, off_t start); -int drm_agp_unbind_memory(void *handle); - /* sysctl support (drm_sysctl.h) */ extern int drm_sysctl_init(struct drm_device *dev); extern int drm_sysctl_cleanup(struct drm_device *dev); diff --git a/sys/dev/drm2/drm_crtc.c b/sys/dev/drm2/drm_crtc.c index 318a764..79f66aa 100644 --- a/sys/dev/drm2/drm_crtc.c +++ b/sys/dev/drm2/drm_crtc.c @@ -663,7 +663,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, plane->dev = dev; plane->funcs = funcs; plane->format_types = malloc(sizeof(uint32_t) * format_count, - DRM_MEM_KMS, M_WAITOK); + DRM_MEM_KMS, M_NOWAIT); if (!plane->format_types) { DRM_DEBUG_KMS("out of memory when allocating plane\n"); drm_mode_object_put(dev, &plane->base); @@ -1010,7 +1010,7 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) total_objects += dev->mode_config.num_encoder; group->id_list = malloc(total_objects * sizeof(uint32_t), - DRM_MEM_KMS, M_WAITOK | M_ZERO); + DRM_MEM_KMS, M_NOWAIT | M_ZERO); if (!group->id_list) return -ENOMEM; @@ -1998,7 +1998,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, connector_set = malloc(crtc_req->count_connectors * sizeof(struct drm_connector *), - DRM_MEM_KMS, M_WAITOK); + DRM_MEM_KMS, M_NOWAIT); if (!connector_set) { ret = -ENOMEM; goto out; @@ -2523,7 +2523,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, goto out_err1; } clips = malloc(num_clips * sizeof(*clips), DRM_MEM_KMS, - M_WAITOK | M_ZERO); + M_NOWAIT | M_ZERO); if (!clips) { ret = -ENOMEM; goto out_err1; @@ -2774,13 +2774,13 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, int ret; property = malloc(sizeof(struct drm_property), DRM_MEM_KMS, - M_WAITOK | M_ZERO); + M_NOWAIT | M_ZERO); if (!property) return NULL; if (num_values) { property->values = malloc(sizeof(uint64_t)*num_values, DRM_MEM_KMS, - M_WAITOK | M_ZERO); + M_NOWAIT | M_ZERO); if (!property->values) goto fail; } @@ -2908,7 +2908,7 @@ int drm_property_add_enum(struct drm_property *property, int index, } prop_enum = malloc(sizeof(struct drm_property_enum), DRM_MEM_KMS, - M_WAITOK | M_ZERO); + M_NOWAIT | M_ZERO); if (!prop_enum) return -ENOMEM; @@ -3104,7 +3104,7 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev return NULL; blob = malloc(sizeof(struct drm_property_blob)+length, DRM_MEM_KMS, - M_WAITOK | M_ZERO); + M_NOWAIT | M_ZERO); if (!blob) return NULL; @@ -3434,7 +3434,7 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, crtc->gamma_size = gamma_size; crtc->gamma_store = malloc(gamma_size * sizeof(uint16_t) * 3, - DRM_MEM_KMS, M_WAITOK | M_ZERO); + DRM_MEM_KMS, M_NOWAIT | M_ZERO); if (!crtc->gamma_store) { crtc->gamma_size = 0; return -ENOMEM; @@ -3632,7 +3632,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, file_priv->event_space -= sizeof e->event; mtx_unlock(&dev->event_lock); - e = malloc(sizeof *e, DRM_MEM_KMS, M_WAITOK | M_ZERO); + e = malloc(sizeof *e, DRM_MEM_KMS, M_NOWAIT | M_ZERO); if (e == NULL) { mtx_lock(&dev->event_lock); file_priv->event_space += sizeof e->event; diff --git a/sys/dev/drm2/drm_fops.c b/sys/dev/drm2/drm_fops.c index b73cec6..3b3be06 100644 --- a/sys/dev/drm2/drm_fops.c +++ b/sys/dev/drm2/drm_fops.c @@ -136,7 +136,7 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) sx_xlock(&drm_global_mutex); /* - * FIXME Linux<->FreeBSD: On Linux, counter updated outisde + * FIXME Linux<->FreeBSD: On Linux, counter updated outside * global mutex. */ if (!dev->open_count++) diff --git a/sys/dev/drm2/drm_pci.c b/sys/dev/drm2/drm_pci.c index f2c5bbd..ecbfcb7 100644 --- a/sys/dev/drm2/drm_pci.c +++ b/sys/dev/drm2/drm_pci.c @@ -225,7 +225,7 @@ int drm_pci_set_unique(struct drm_device *dev, master->unique_len = u->unique_len; master->unique_size = u->unique_len + 1; - master->unique = malloc(master->unique_size, DRM_MEM_DRIVER, M_WAITOK); + master->unique = malloc(master->unique_size, DRM_MEM_DRIVER, M_NOWAIT); if (!master->unique) { ret = -ENOMEM; goto err; diff --git a/sys/dev/drm2/drm_stub.c b/sys/dev/drm2/drm_stub.c index d7ec6cb..06663ac 100644 --- a/sys/dev/drm2/drm_stub.c +++ b/sys/dev/drm2/drm_stub.c @@ -94,9 +94,9 @@ static int drm_minor_get_id(struct drm_device *dev, int type) if (type == DRM_MINOR_CONTROL) { new_id += 64; - } else if (type == DRM_MINOR_RENDER) { - new_id += 128; - } + } else if (type == DRM_MINOR_RENDER) { + new_id += 128; + } return new_id; } diff --git a/sys/dev/drm2/i915/i915_dma.c b/sys/dev/drm2/i915/i915_dma.c index 2265ac0..dddc03e 100644 --- a/sys/dev/drm2/i915/i915_dma.c +++ b/sys/dev/drm2/i915/i915_dma.c @@ -1452,6 +1452,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } } + pci_enable_busmaster(dev->dev); + intel_opregion_init(dev); callout_init(&dev_priv->hangcheck_timer, 1); diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c index 3109827..e9cf3a4 100644 --- a/sys/dev/drm2/i915/i915_drv.c +++ b/sys/dev/drm2/i915/i915_drv.c @@ -894,6 +894,7 @@ int intel_gpu_reset(struct drm_device *dev) case 4: ret = i965_do_reset(dev); break; + case 3: case 2: ret = i8xx_do_reset(dev); break; diff --git a/sys/dev/drm2/i915/intel_opregion.c b/sys/dev/drm2/i915/intel_opregion.c index 411e530..397c559 100644 --- a/sys/dev/drm2/i915/intel_opregion.c +++ b/sys/dev/drm2/i915/intel_opregion.c @@ -533,11 +533,9 @@ void intel_opregion_fini(struct drm_device *dev) opregion->vbt = NULL; } #else -int +void intel_opregion_init(struct drm_device *dev) { - - return (0); } void diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index c30f31c..bb1f19e 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -194,7 +194,7 @@ static void ndis_media_status (struct ifnet *, struct ifmediareq *); static int ndis_set_cipher (struct ndis_softc *, int); static int ndis_set_wpa (struct ndis_softc *, void *, int); static int ndis_add_key (struct ieee80211vap *, - const struct ieee80211_key *, const u_int8_t []); + const struct ieee80211_key *); static int ndis_del_key (struct ieee80211vap *, const struct ieee80211_key *); static void ndis_setmulti (struct ndis_softc *); @@ -3070,8 +3070,7 @@ ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key) * set after initial authentication with the AP. */ static int -ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key, - const uint8_t mac[IEEE80211_ADDR_LEN]) +ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key) { struct ndis_softc *sc = vap->iv_ic->ic_softc; ndis_80211_key rkey; diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 463b5c9..7f9d8e0 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -111,7 +111,10 @@ static int mwl_key_alloc(struct ieee80211vap *, ieee80211_keyix *, ieee80211_keyix *); static int mwl_key_delete(struct ieee80211vap *, const struct ieee80211_key *); -static int mwl_key_set(struct ieee80211vap *, const struct ieee80211_key *, +static int mwl_key_set(struct ieee80211vap *, + const struct ieee80211_key *); +static int _mwl_key_set(struct ieee80211vap *, + const struct ieee80211_key *, const uint8_t mac[IEEE80211_ADDR_LEN]); static int mwl_mode_init(struct mwl_softc *); static void mwl_update_mcast(struct ieee80211com *); @@ -1604,7 +1607,13 @@ addgroupflags(MWL_HAL_KEYVAL *hk, const struct ieee80211_key *k) * slot(s) must already have been allocated by mwl_key_alloc. */ static int -mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, +mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) +{ + return (_mwl_key_set(vap, k, k->wk_macaddr)); +} + +static int +_mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]) { #define GRPXMIT (IEEE80211_KEY_XMIT | IEEE80211_KEY_GROUP) @@ -1834,10 +1843,9 @@ mwl_beacon_setup(struct ieee80211vap *vap) { struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; struct ieee80211_node *ni = vap->iv_bss; - struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct mbuf *m; - m = ieee80211_beacon_alloc(ni, bo); + m = ieee80211_beacon_alloc(ni); if (m == NULL) return ENOBUFS; mwl_hal_setbeacon(hvap, mtod(m, const void *), m->m_len); @@ -3911,7 +3919,8 @@ mwl_setanywepkey(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN] IEEE80211_F_PRIVACY && vap->iv_def_txkey != IEEE80211_KEYIX_NONE && vap->iv_nw_keys[vap->iv_def_txkey].wk_keyix != IEEE80211_KEYIX_NONE) - (void) mwl_key_set(vap, &vap->iv_nw_keys[vap->iv_def_txkey], mac); + (void) _mwl_key_set(vap, &vap->iv_nw_keys[vap->iv_def_txkey], + mac); } static int @@ -3956,7 +3965,7 @@ mwl_setglobalkeys(struct ieee80211vap *vap) wk = &vap->iv_nw_keys[0]; for (; wk < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; wk++) if (wk->wk_keyix != IEEE80211_KEYIX_NONE) - (void) mwl_key_set(vap, wk, vap->iv_myaddr); + (void) _mwl_key_set(vap, wk, vap->iv_myaddr); } /* diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index ef5a01c..b03e8fa 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -768,7 +768,7 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_IBSS || vap->iv_opmode == IEEE80211_M_MBSS) { - m = ieee80211_beacon_alloc(ni, &vap->iv_bcn_off); + m = ieee80211_beacon_alloc(ni); if (m == NULL) { device_printf(sc->sc_dev, "could not allocate beacon\n"); @@ -1286,7 +1286,6 @@ static void rt2560_beacon_expire(struct rt2560_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct rt2560_tx_data *data; if (ic->ic_opmode != IEEE80211_M_IBSS && @@ -1305,7 +1304,7 @@ rt2560_beacon_expire(struct rt2560_softc *sc) bus_dmamap_unload(sc->bcnq.data_dmat, data->map); /* XXX 1 =>'s mcast frames which means all PS sta's will wakeup! */ - ieee80211_beacon_update(data->ni, &vap->iv_bcn_off, data->m, 1); + ieee80211_beacon_update(data->ni, data->m, 1); rt2560_tx_bcn(sc, data->m, data->ni); diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index 5c73ba0..100b5d6 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -2626,13 +2626,11 @@ static int rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct rt2661_tx_desc desc; struct mbuf *m0; int rate; - m0 = ieee80211_beacon_alloc(vap->iv_bss, bo); - if (m0 == NULL) { + if ((m0 = ieee80211_beacon_alloc(vap->iv_bss))== NULL) { device_printf(sc->sc_dev, "could not allocate beacon frame\n"); return ENOBUFS; } diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c index a6b1e26..9c7fa53 100644 --- a/sys/dev/ral/rt2860.c +++ b/sys/dev/ral/rt2860.c @@ -4268,12 +4268,11 @@ static int rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct rt2860_txwi txwi; struct mbuf *m; int ridx; - if ((m = ieee80211_beacon_alloc(vap->iv_bss, bo)) == NULL) + if ((m = ieee80211_beacon_alloc(vap->iv_bss)) == NULL) return ENOBUFS; memset(&txwi, 0, sizeof txwi); diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 6a558f6..f1c9cdf 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -86,8 +86,6 @@ SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RWTUN, &rum_debug, 0, "Debug level"); #endif -#define N(a) ((int)(sizeof (a) / sizeof ((a)[0]))) - static const STRUCT_USB_HOST_ID rum_devs[] = { #define RUM_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } RUM_DEV(ABOCOM, HWU54DM), @@ -160,14 +158,21 @@ static struct ieee80211vap *rum_vap_create(struct ieee80211com *, int, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void rum_vap_delete(struct ieee80211vap *); +static void rum_cmdq_cb(void *, int); +static int rum_cmd_sleepable(struct rum_softc *, const void *, + size_t, uint8_t, CMD_FUNC_PROTO); static void rum_tx_free(struct rum_tx_data *, int); static void rum_setup_tx_list(struct rum_softc *); static void rum_unsetup_tx_list(struct rum_softc *); static int rum_newstate(struct ieee80211vap *, enum ieee80211_state, int); +static uint8_t rum_crypto_mode(struct rum_softc *, u_int, int); static void rum_setup_tx_desc(struct rum_softc *, - struct rum_tx_desc *, uint32_t, uint16_t, int, - int); + struct rum_tx_desc *, struct ieee80211_key *, + uint32_t, uint8_t, uint8_t, int, int, int); +static uint32_t rum_tx_crypto_flags(struct rum_softc *, + struct ieee80211_node *, + const struct ieee80211_key *); static int rum_tx_mgt(struct rum_softc *, struct mbuf *, struct ieee80211_node *); static int rum_tx_raw(struct rum_softc *, struct mbuf *, @@ -186,6 +191,11 @@ static void rum_read_multi(struct rum_softc *, uint16_t, void *, static usb_error_t rum_write(struct rum_softc *, uint16_t, uint32_t); static usb_error_t rum_write_multi(struct rum_softc *, uint16_t, void *, size_t); +static usb_error_t rum_setbits(struct rum_softc *, uint16_t, uint32_t); +static usb_error_t rum_clrbits(struct rum_softc *, uint16_t, uint32_t); +static usb_error_t rum_modbits(struct rum_softc *, uint16_t, uint32_t, + uint32_t); +static int rum_bbp_busy(struct rum_softc *); static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); @@ -197,9 +207,18 @@ static void rum_select_band(struct rum_softc *, struct ieee80211_channel *); static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); -static void rum_enable_tsf_sync(struct rum_softc *); +static void rum_set_maxretry(struct rum_softc *, + struct ieee80211vap *); +static int rum_enable_tsf_sync(struct rum_softc *); static void rum_enable_tsf(struct rum_softc *); -static void rum_update_slot(struct rum_softc *); +static void rum_abort_tsf_sync(struct rum_softc *); +static void rum_get_tsf(struct rum_softc *, uint64_t *); +static void rum_update_slot_cb(struct rum_softc *, + union sec_param *, uint8_t); +static void rum_update_slot(struct ieee80211com *); +static void rum_wme_update_cb(struct rum_softc *, + union sec_param *, uint8_t); +static int rum_wme_update(struct ieee80211com *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); static void rum_update_mcast(struct ieee80211com *); @@ -207,13 +226,37 @@ static void rum_update_promisc(struct ieee80211com *); static void rum_setpromisc(struct rum_softc *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); +static int rum_bbp_wakeup(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); -static void rum_init(struct rum_softc *); +static void rum_clr_shkey_regs(struct rum_softc *); +static int rum_init(struct rum_softc *); static void rum_stop(struct rum_softc *); static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); -static void rum_prepare_beacon(struct rum_softc *, +static int rum_set_beacon(struct rum_softc *, + struct ieee80211vap *); +static int rum_alloc_beacon(struct rum_softc *, struct ieee80211vap *); +static void rum_update_beacon_cb(struct rum_softc *, + union sec_param *, uint8_t); +static void rum_update_beacon(struct ieee80211vap *, int); +static int rum_common_key_set(struct rum_softc *, + struct ieee80211_key *, uint16_t); +static void rum_group_key_set_cb(struct rum_softc *, + union sec_param *, uint8_t); +static void rum_group_key_del_cb(struct rum_softc *, + union sec_param *, uint8_t); +static void rum_pair_key_set_cb(struct rum_softc *, + union sec_param *, uint8_t); +static void rum_pair_key_del_cb(struct rum_softc *, + union sec_param *, uint8_t); +static int rum_key_alloc(struct ieee80211vap *, + struct ieee80211_key *, ieee80211_keyix *, + ieee80211_keyix *); +static int rum_key_set(struct ieee80211vap *, + const struct ieee80211_key *); +static int rum_key_delete(struct ieee80211vap *, + const struct ieee80211_key *); static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void rum_scan_start(struct ieee80211com *); @@ -242,9 +285,9 @@ static const struct { { RT2573_MAC_CSR10, 0x00000718 }, { RT2573_MAC_CSR12, 0x00000004 }, { RT2573_MAC_CSR13, 0x00007f00 }, - { RT2573_SEC_CSR0, 0x00000000 }, - { RT2573_SEC_CSR1, 0x00000000 }, - { RT2573_SEC_CSR5, 0x00000000 }, + { RT2573_SEC_CSR2, 0x00000000 }, + { RT2573_SEC_CSR3, 0x00000000 }, + { RT2573_SEC_CSR4, 0x00000000 }, { RT2573_PHY_CSR1, 0x000023b0 }, { RT2573_PHY_CSR5, 0x00040a06 }, { RT2573_PHY_CSR6, 0x00080606 }, @@ -434,8 +477,8 @@ rum_attach(device_t self) sc->sc_udev = uaa->device; sc->sc_dev = self; - mtx_init(&sc->sc_mtx, device_get_nameunit(self), - MTX_NETWORK_LOCK, MTX_DEF); + RUM_LOCK_INIT(sc); + RUM_CMDQ_LOCK_INIT(sc); mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RT2573_IFACE_INDEX; @@ -480,13 +523,21 @@ rum_attach(device_t self) | IEEE80211_C_IBSS /* IBSS mode supported */ | IEEE80211_C_MONITOR /* monitor mode supported */ | IEEE80211_C_HOSTAP /* HostAp mode supported */ + | IEEE80211_C_AHDEMO /* adhoc demo mode */ | IEEE80211_C_TXPMGT /* tx power management */ | IEEE80211_C_SHPREAMBLE /* short preamble supported */ | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* bg scanning supported */ | IEEE80211_C_WPA /* 802.11i */ + | IEEE80211_C_WME /* 802.11e */ ; + ic->ic_cryptocaps = + IEEE80211_CRYPTO_WEP | + IEEE80211_CRYPTO_AES_CCM | + IEEE80211_CRYPTO_TKIPMIC | + IEEE80211_CRYPTO_TKIP; + bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); @@ -504,6 +555,8 @@ rum_attach(device_t self) ic->ic_parent = rum_parent; ic->ic_vap_create = rum_vap_create; ic->ic_vap_delete = rum_vap_delete; + ic->ic_updateslot = rum_update_slot; + ic->ic_wme.wme_update = rum_wme_update; ic->ic_update_mcast = rum_update_mcast; ieee80211_radiotap_attach(ic, @@ -512,6 +565,8 @@ rum_attach(device_t self) &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), RT2573_RX_RADIOTAP_PRESENT); + TASK_INIT(&sc->cmdq_task, 0, rum_cmdq_cb, sc); + if (bootverbose) ieee80211_announce(ic); @@ -526,6 +581,7 @@ static int rum_detach(device_t self) { struct rum_softc *sc = device_get_softc(self); + struct ieee80211com *ic = &sc->sc_ic; /* Prevent further ioctls */ RUM_LOCK(sc); @@ -540,10 +596,15 @@ rum_detach(device_t self) rum_unsetup_tx_list(sc); RUM_UNLOCK(sc); - if (sc->sc_ic.ic_softc == sc) - ieee80211_ifdetach(&sc->sc_ic); + if (ic->ic_softc == sc) { + ieee80211_draintask(ic, &sc->cmdq_task); + ieee80211_ifdetach(ic); + } + mbufq_drain(&sc->sc_snd); - mtx_destroy(&sc->sc_mtx); + RUM_CMDQ_LOCK_DESTROY(sc); + RUM_LOCK_DESTROY(sc); + return (0); } @@ -594,6 +655,11 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* override state transition machine */ rvp->newstate = vap->iv_newstate; vap->iv_newstate = rum_newstate; + vap->iv_key_alloc = rum_key_alloc; + vap->iv_key_set = rum_key_set; + vap->iv_key_delete = rum_key_delete; + vap->iv_update_beacon = rum_update_beacon; + vap->iv_max_aid = RT2573_ADDR_MAX; usb_callout_init_mtx(&rvp->ratectl_ch, &sc->sc_mtx, 0); TASK_INIT(&rvp->ratectl_task, 0, rum_ratectl_task, rvp); @@ -612,6 +678,7 @@ rum_vap_delete(struct ieee80211vap *vap) struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211com *ic = vap->iv_ic; + m_freem(rvp->bcn_mbuf); usb_callout_drain(&rvp->ratectl_ch); ieee80211_draintask(ic, &rvp->ratectl_task); ieee80211_ratectl_deinit(vap); @@ -620,6 +687,56 @@ rum_vap_delete(struct ieee80211vap *vap) } static void +rum_cmdq_cb(void *arg, int pending) +{ + struct rum_softc *sc = arg; + struct rum_cmdq *rc; + + RUM_CMDQ_LOCK(sc); + while (sc->cmdq[sc->cmdq_first].func != NULL) { + rc = &sc->cmdq[sc->cmdq_first]; + RUM_CMDQ_UNLOCK(sc); + + RUM_LOCK(sc); + rc->func(sc, &rc->data, rc->rvp_id); + RUM_UNLOCK(sc); + + RUM_CMDQ_LOCK(sc); + memset(rc, 0, sizeof (*rc)); + sc->cmdq_first = (sc->cmdq_first + 1) % RUM_CMDQ_SIZE; + } + RUM_CMDQ_UNLOCK(sc); +} + +static int +rum_cmd_sleepable(struct rum_softc *sc, const void *ptr, size_t len, + uint8_t rvp_id, CMD_FUNC_PROTO) +{ + struct ieee80211com *ic = &sc->sc_ic; + + KASSERT(len <= sizeof(union sec_param), ("buffer overflow")); + + RUM_CMDQ_LOCK(sc); + if (sc->cmdq[sc->cmdq_last].func != NULL) { + device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__); + RUM_CMDQ_UNLOCK(sc); + + return EAGAIN; + } + + if (ptr != NULL) + memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len); + sc->cmdq[sc->cmdq_last].rvp_id = rvp_id; + sc->cmdq[sc->cmdq_last].func = func; + sc->cmdq_last = (sc->cmdq_last + 1) % RUM_CMDQ_SIZE; + RUM_CMDQ_UNLOCK(sc); + + ieee80211_runtask(ic, &sc->cmdq_task); + + return 0; +} + +static void rum_tx_free(struct rum_tx_data *data, int txerr) { struct rum_softc *sc = data->sc; @@ -687,7 +804,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; - uint32_t tmp; + int ret; ostate = vap->iv_state; DPRINTF("%s -> %s\n", @@ -700,38 +817,40 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) switch (nstate) { case IEEE80211_S_INIT: - if (ostate == IEEE80211_S_RUN) { - /* abort TSF synchronization */ - tmp = rum_read(sc, RT2573_TXRX_CSR9); - rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - } + if (ostate == IEEE80211_S_RUN) + rum_abort_tsf_sync(sc); + break; case IEEE80211_S_RUN: ni = ieee80211_ref_node(vap->iv_bss); if (vap->iv_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) { - RUM_UNLOCK(sc); - IEEE80211_LOCK(ic); - ieee80211_free_node(ni); - return (-1); + if (ic->ic_bsschan == IEEE80211_CHAN_ANYC || + ni->ni_chan == IEEE80211_CHAN_ANYC) { + ret = EINVAL; + goto run_fail; } - rum_update_slot(sc); + rum_update_slot_cb(sc, NULL, 0); rum_enable_mrr(sc); rum_set_txpreamble(sc); rum_set_basicrates(sc); - IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); - rum_set_bssid(sc, ic->ic_macaddr); + rum_set_maxretry(sc, vap); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + rum_set_bssid(sc, sc->sc_bssid); } if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS) - rum_prepare_beacon(sc, vap); + vap->iv_opmode == IEEE80211_M_IBSS) { + if ((ret = rum_alloc_beacon(sc, vap)) != 0) + goto run_fail; + } - if (vap->iv_opmode != IEEE80211_M_MONITOR) - rum_enable_tsf_sync(sc); - else + if (vap->iv_opmode != IEEE80211_M_MONITOR && + vap->iv_opmode != IEEE80211_M_AHDEMO) { + if ((ret = rum_enable_tsf_sync(sc)) != 0) + goto run_fail; + } else rum_enable_tsf(sc); /* enable automatic rate adaptation */ @@ -746,6 +865,12 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) RUM_UNLOCK(sc); IEEE80211_LOCK(ic); return (rvp->newstate(vap, nstate, arg)); + +run_fail: + RUM_UNLOCK(sc); + IEEE80211_LOCK(ic); + ieee80211_free_node(ni); + return ret; } static void @@ -794,6 +919,7 @@ tr_setup: tap->wt_flags = 0; tap->wt_rate = data->rate; + rum_get_tsf(sc, &tap->wt_tsf); tap->wt_antenna = sc->tx_ant; ieee80211_radiotap_tx(vap, m); @@ -847,6 +973,7 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct rum_softc *sc = usbd_xfer_softc(xfer); struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_frame_min *wh; struct ieee80211_node *ni; struct mbuf *m = NULL; struct usb_page_cache *pc; @@ -884,6 +1011,21 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } + if ((flags & RT2573_RX_DEC_MASK) != RT2573_RX_DEC_OK) { + switch (flags & RT2573_RX_DEC_MASK) { + case RT2573_RX_IV_ERROR: + DPRINTFN(5, "IV/EIV error\n"); + break; + case RT2573_RX_MIC_ERROR: + DPRINTFN(5, "MIC error\n"); + break; + case RT2573_RX_KEY_ERROR: + DPRINTFN(5, "Key error\n"); + break; + } + counter_u64_add(ic->ic_ierrors, 1); + goto tr_setup; + } m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { @@ -894,17 +1036,26 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) usbd_copy_out(pc, RT2573_RX_DESC_SIZE, mtod(m, uint8_t *), len); + wh = mtod(m, struct ieee80211_frame_min *); + + if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && + (flags & RT2573_RX_CIP_MASK) != + RT2573_RX_CIP_MODE(RT2573_MODE_NOSEC)) { + wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; + m->m_flags |= M_WEP; + } + /* finalize mbuf */ m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; if (ieee80211_radiotap_active(ic)) { struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; - /* XXX read tsf */ tap->wr_flags = 0; tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate, (flags & RT2573_RX_OFDM) ? IEEE80211_T_OFDM : IEEE80211_T_CCK); + rum_get_tsf(sc, &tap->wr_tsf); tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi; tap->wr_antnoise = RT2573_NOISE_FLOOR; tap->wr_antenna = sc->rx_ant; @@ -922,8 +1073,11 @@ tr_setup: */ RUM_UNLOCK(sc); if (m) { - ni = ieee80211_find_rxnode(ic, - mtod(m, struct ieee80211_frame_min *)); + if (m->m_len >= sizeof(struct ieee80211_frame_min)) + ni = ieee80211_find_rxnode(ic, wh); + else + ni = NULL; + if (ni != NULL) { (void) ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR); @@ -969,22 +1123,46 @@ rum_plcp_signal(int rate) return 0xff; /* XXX unsupported/unknown rate */ } +/* + * Map net80211 cipher to RT2573 security mode. + */ +static uint8_t +rum_crypto_mode(struct rum_softc *sc, u_int cipher, int keylen) +{ + switch (cipher) { + case IEEE80211_CIPHER_WEP: + return (keylen < 8 ? RT2573_MODE_WEP40 : RT2573_MODE_WEP104); + case IEEE80211_CIPHER_TKIP: + return RT2573_MODE_TKIP; + case IEEE80211_CIPHER_AES_CCM: + return RT2573_MODE_AES_CCMP; + default: + device_printf(sc->sc_dev, "unknown cipher %d\n", cipher); + return 0; + } +} + static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, - uint32_t flags, uint16_t xflags, int len, int rate) + struct ieee80211_key *k, uint32_t flags, uint8_t xflags, uint8_t qid, + int hdrlen, int len, int rate) { struct ieee80211com *ic = &sc->sc_ic; + struct wmeParams *wmep = &sc->wme_params[qid]; uint16_t plcp_length; int remainder; - desc->flags = htole32(flags); - desc->flags |= htole32(RT2573_TX_VALID); - desc->flags |= htole32(len << 16); + flags |= RT2573_TX_VALID; + flags |= len << 16; + + if (k != NULL && !(k->wk_flags & IEEE80211_KEY_SWCRYPT)) { + const struct ieee80211_cipher *cip = k->wk_cipher; - desc->xflags = htole16(xflags); + len += cip->ic_header + cip->ic_trailer + cip->ic_miclen; - desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) | - RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); + desc->eiv = 0; /* for WEP */ + cip->ic_setiv(k, (uint8_t *)&desc->iv); + } /* setup PLCP fields */ desc->plcp_signal = rum_plcp_signal(rate); @@ -992,7 +1170,7 @@ rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, len += IEEE80211_CRC_LEN; if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM) { - desc->flags |= htole32(RT2573_TX_OFDM); + flags |= RT2573_TX_OFDM; plcp_length = len & 0xfff; desc->plcp_length_hi = plcp_length >> 6; @@ -1012,6 +1190,15 @@ rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) desc->plcp_signal |= 0x08; } + + desc->flags = htole32(flags); + desc->hdrlen = hdrlen; + desc->xflags = xflags; + + desc->wme = htole16(RT2573_QID(qid) | + RT2573_AIFSN(wmep->wmep_aifsn) | + RT2573_LOGCWMIN(wmep->wmep_logcwmin) | + RT2573_LOGCWMAX(wmep->wmep_logcwmax)); } static int @@ -1022,10 +1209,10 @@ rum_sendprot(struct rum_softc *sc, const struct ieee80211_frame *wh; struct rum_tx_data *data; struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort; + int protrate, pktlen, flags, isshort; uint16_t dur; - RUM_LOCK_ASSERT(sc, MA_OWNED); + RUM_LOCK_ASSERT(sc); KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, ("protection %d", prot)); @@ -1033,12 +1220,11 @@ rum_sendprot(struct rum_softc *sc, pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - ackrate = ieee80211_ack_rate(ic->ic_rt, rate); isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = RT2573_TX_MORE_FRAG; + flags = 0; if (prot == IEEE80211_PROT_RTSCTS) { /* NB: CTS is the same size as an ACK */ dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); @@ -1058,7 +1244,8 @@ rum_sendprot(struct rum_softc *sc, data->m = mprot; data->ni = ieee80211_ref_node(ni); data->rate = protrate; - rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate); + rum_setup_tx_desc(sc, &data->desc, NULL, flags, 0, 0, 0, + mprot->m_pkthdr.len, protrate); STAILQ_INSERT_TAIL(&sc->tx_q, data, next); usbd_transfer_start(sc->sc_xfer[RUM_BULK_WR]); @@ -1066,6 +1253,40 @@ rum_sendprot(struct rum_softc *sc, return 0; } +static uint32_t +rum_tx_crypto_flags(struct rum_softc *sc, struct ieee80211_node *ni, + const struct ieee80211_key *k) +{ + struct ieee80211vap *vap = ni->ni_vap; + u_int cipher; + uint32_t flags = 0; + uint8_t mode, pos; + + if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) { + cipher = k->wk_cipher->ic_cipher; + pos = k->wk_keyix; + mode = rum_crypto_mode(sc, cipher, k->wk_keylen); + if (mode == 0) + return 0; + + flags |= RT2573_TX_CIP_MODE(mode); + + /* Do not trust GROUP flag */ + if (!(k >= &vap->iv_nw_keys[0] && + k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) + flags |= RT2573_TX_KEY_PAIR; + else + pos += 0 * RT2573_SKEY_MAX; /* vap id */ + + flags |= RT2573_TX_KEY_ID(pos); + + if (cipher == IEEE80211_CIPHER_TKIP) + flags |= RT2573_TX_TKIPMIC; + } + + return flags; +} + static int rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { @@ -1074,23 +1295,32 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; - struct ieee80211_key *k; + struct ieee80211_key *k = NULL; uint32_t flags = 0; uint16_t dur; + uint8_t ac, type, xflags = 0; + int hdrlen; - RUM_LOCK_ASSERT(sc, MA_OWNED); + RUM_LOCK_ASSERT(sc); data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + hdrlen = ieee80211_anyhdrsize(wh); + ac = M_WME_GETAC(m0); + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return ENOBUFS; - } + k = ieee80211_crypto_get_txkey(ni, m0); + if (k == NULL) + return (ENOENT); + + if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) && + !k->wk_cipher->ic_encap(k, m0)) + return (ENOBUFS); + wh = mtod(m0, struct ieee80211_frame *); } @@ -1104,17 +1334,24 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) USETW(wh->i_dur, dur); /* tell hardware to add timestamp for probe responses */ - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + if (type == IEEE80211_FC0_TYPE_MGT && + (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == + IEEE80211_FC0_SUBTYPE_PROBE_RESP) flags |= RT2573_TX_TIMESTAMP; } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + + if (k != NULL) + flags |= rum_tx_crypto_flags(sc, ni, k); + data->m = m0; data->ni = ni; data->rate = tp->mgmtrate; - rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate); + rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen, + m0->m_pkthdr.len, tp->mgmtrate); DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate); @@ -1130,18 +1367,23 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_frame *wh; struct rum_tx_data *data; uint32_t flags; + uint8_t ac, type, xflags = 0; int rate, error; - RUM_LOCK_ASSERT(sc, MA_OWNED); - KASSERT(params != NULL, ("no raw xmit params")); + RUM_LOCK_ASSERT(sc); + + wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + + ac = params->ibp_pri & 3; rate = params->ibp_rate0; - if (!ieee80211_isratevalid(ic->ic_rt, rate)) { - m_freem(m0); - return EINVAL; - } + if (!ieee80211_isratevalid(ic->ic_rt, rate)) + return (EINVAL); + flags = 0; if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) flags |= RT2573_TX_NEED_ACK; @@ -1150,13 +1392,15 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, params->ibp_flags & IEEE80211_BPF_RTS ? IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, rate); - if (error || sc->tx_nfree == 0) { - m_freem(m0); - return ENOBUFS; - } + if (error || sc->tx_nfree == 0) + return (ENOBUFS); + flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; @@ -1166,7 +1410,8 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, data->rate = rate; /* XXX need to setup descriptor ourself */ - rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate); + rum_setup_tx_desc(sc, &data->desc, NULL, flags, xflags, ac, 0, + m0->m_pkthdr.len, rate); DPRINTFN(10, "sending raw frame len=%u rate=%u\n", m0->m_pkthdr.len, rate); @@ -1185,14 +1430,23 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; - struct ieee80211_key *k; + struct ieee80211_key *k = NULL; uint32_t flags = 0; uint16_t dur; - int error, rate; + uint8_t ac, type, qos, xflags = 0; + int error, hdrlen, rate; - RUM_LOCK_ASSERT(sc, MA_OWNED); + RUM_LOCK_ASSERT(sc); wh = mtod(m0, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + hdrlen = ieee80211_anyhdrsize(wh); + + if (IEEE80211_QOS_HAS_SEQ(wh)) + qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; + else + qos = 0; + ac = M_WME_GETAC(m0); tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; if (IEEE80211_IS_MULTICAST(wh->i_addr1)) @@ -1203,16 +1457,24 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) rate = ni->ni_txrate; if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - k = ieee80211_crypto_encap(ni, m0); + k = ieee80211_crypto_get_txkey(ni, m0); if (k == NULL) { m_freem(m0); - return ENOBUFS; + return (ENOENT); + } + if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) && + !k->wk_cipher->ic_encap(k, m0)) { + m_freem(m0); + return (ENOBUFS); } /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } + if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh)) + xflags |= RT2573_TX_HWSEQ; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { int prot = IEEE80211_PROT_NONE; if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) @@ -1230,6 +1492,9 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } } + if (k != NULL) + flags |= rum_tx_crypto_flags(sc, ni, k); + data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; @@ -1239,15 +1504,18 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) data->rate = rate; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2573_TX_NEED_ACK; - flags |= RT2573_TX_MORE_FRAG; + /* Unicast frame, check if an ACK is expected. */ + if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) != + IEEE80211_QOS_ACKPOLICY_NOACK) + flags |= RT2573_TX_NEED_ACK; - dur = ieee80211_ack_duration(ic->ic_rt, rate, + dur = ieee80211_ack_duration(ic->ic_rt, rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); USETW(wh->i_dur, dur); } - rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate); + rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen, + m0->m_pkthdr.len, rate); DPRINTFN(10, "sending frame len=%d rate=%d\n", m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate); @@ -1286,7 +1554,7 @@ rum_start(struct rum_softc *sc) struct ieee80211_node *ni; struct mbuf *m; - RUM_LOCK_ASSERT(sc, MA_OWNED); + RUM_LOCK_ASSERT(sc); if (!sc->sc_running) return; @@ -1307,24 +1575,22 @@ static void rum_parent(struct ieee80211com *ic) { struct rum_softc *sc = ic->ic_softc; - int startall = 0; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); RUM_LOCK(sc); if (sc->sc_detached) { RUM_UNLOCK(sc); return; } + RUM_UNLOCK(sc); + if (ic->ic_nrunning > 0) { - if (!sc->sc_running) { - rum_init(sc); - startall = 1; - } else - rum_setpromisc(sc); - } else if (sc->sc_running) + if (rum_init(sc) == 0) + ieee80211_start_all(ic); + else + ieee80211_stop(vap); + } else rum_stop(sc); - RUM_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); } static void @@ -1412,13 +1678,28 @@ rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) return (USB_ERR_NORMAL_COMPLETION); } -static void -rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) +static usb_error_t +rum_setbits(struct rum_softc *sc, uint16_t reg, uint32_t mask) { - uint32_t tmp; - int ntries; + return (rum_write(sc, reg, rum_read(sc, reg) | mask)); +} - DPRINTFN(2, "reg=0x%08x\n", reg); +static usb_error_t +rum_clrbits(struct rum_softc *sc, uint16_t reg, uint32_t mask) +{ + return (rum_write(sc, reg, rum_read(sc, reg) & ~mask)); +} + +static usb_error_t +rum_modbits(struct rum_softc *sc, uint16_t reg, uint32_t set, uint32_t unset) +{ + return (rum_write(sc, reg, (rum_read(sc, reg) & ~unset) | set)); +} + +static int +rum_bbp_busy(struct rum_softc *sc) +{ + int ntries; for (ntries = 0; ntries < 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) @@ -1426,7 +1707,20 @@ rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) if (rum_pause(sc, hz / 100)) break; } - if (ntries == 100) { + if (ntries == 100) + return (ETIMEDOUT); + + return (0); +} + +static void +rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) +{ + uint32_t tmp; + + DPRINTFN(2, "reg=0x%08x\n", reg); + + if (rum_bbp_busy(sc) != 0) { device_printf(sc->sc_dev, "could not write to BBP\n"); return; } @@ -1443,13 +1737,7 @@ rum_bbp_read(struct rum_softc *sc, uint8_t reg) DPRINTFN(2, "reg=0x%08x\n", reg); - for (ntries = 0; ntries < 100; ntries++) { - if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) - break; - if (rum_pause(sc, hz / 100)) - break; - } - if (ntries == 100) { + if (rum_bbp_busy(sc) != 0) { device_printf(sc->sc_dev, "could not read BBP\n"); return 0; } @@ -1525,31 +1813,25 @@ static void rum_enable_mrr(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - uint32_t tmp; - tmp = rum_read(sc, RT2573_TXRX_CSR4); - - tmp &= ~RT2573_MRR_CCK_FALLBACK; - if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) - tmp |= RT2573_MRR_CCK_FALLBACK; - tmp |= RT2573_MRR_ENABLED; - - rum_write(sc, RT2573_TXRX_CSR4, tmp); + if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) { + rum_setbits(sc, RT2573_TXRX_CSR4, + RT2573_MRR_ENABLED | RT2573_MRR_CCK_FALLBACK); + } else { + rum_modbits(sc, RT2573_TXRX_CSR4, + RT2573_MRR_ENABLED, RT2573_MRR_CCK_FALLBACK); + } } static void rum_set_txpreamble(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - uint32_t tmp; - - tmp = rum_read(sc, RT2573_TXRX_CSR4); - tmp &= ~RT2573_SHORT_PREAMBLE; if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) - tmp |= RT2573_SHORT_PREAMBLE; - - rum_write(sc, RT2573_TXRX_CSR4, tmp); + rum_setbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_PREAMBLE); + else + rum_clrbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_PREAMBLE); } static void @@ -1578,7 +1860,6 @@ static void rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) { uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; - uint32_t tmp; /* update all BBP registers that depend on the band */ bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; @@ -1608,13 +1889,13 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) rum_bbp_write(sc, 97, bbp97); rum_bbp_write(sc, 98, bbp98); - tmp = rum_read(sc, RT2573_PHY_CSR0); - tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ); - if (IEEE80211_IS_CHAN_2GHZ(c)) - tmp |= RT2573_PA_PE_2GHZ; - else - tmp |= RT2573_PA_PE_5GHZ; - rum_write(sc, RT2573_PHY_CSR0, tmp); + if (IEEE80211_IS_CHAN_2GHZ(c)) { + rum_modbits(sc, RT2573_PHY_CSR0, RT2573_PA_PE_2GHZ, + RT2573_PA_PE_5GHZ); + } else { + rum_modbits(sc, RT2573_PHY_CSR0, RT2573_PA_PE_5GHZ, + RT2573_PA_PE_2GHZ); + } } static void @@ -1689,11 +1970,26 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) rum_pause(sc, hz / 100); } +static void +rum_set_maxretry(struct rum_softc *sc, struct ieee80211vap *vap) +{ + const struct ieee80211_txparam *tp; + struct ieee80211_node *ni = vap->iv_bss; + struct rum_vap *rvp = RUM_VAP(vap); + + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + rvp->maxretry = tp->maxretry < 0xf ? tp->maxretry : 0xf; + + rum_modbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_RETRY(rvp->maxretry) | + RT2573_LONG_RETRY(rvp->maxretry), + RT2573_SHORT_RETRY_MASK | RT2573_LONG_RETRY_MASK); +} + /* * Enable TSF synchronization and tell h/w to start sending beacons for IBSS * and HostAP operating modes. */ -static void +static int rum_enable_tsf_sync(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1705,85 +2001,178 @@ rum_enable_tsf_sync(struct rum_softc *sc) * Change default 16ms TBTT adjustment to 8ms. * Must be done before enabling beacon generation. */ - rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8); + if (rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8) != 0) + return EIO; } tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; /* set beacon interval (in 1/16ms unit) */ tmp |= vap->iv_bss->ni_intval * 16; + tmp |= RT2573_TSF_TIMER_EN | RT2573_TBTT_TIMER_EN; - tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT; - if (vap->iv_opmode == IEEE80211_M_STA) - tmp |= RT2573_TSF_MODE(1); - else - tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; + switch (vap->iv_opmode) { + case IEEE80211_M_STA: + /* + * Local TSF is always updated with remote TSF on beacon + * reception. + */ + tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_STA); + break; + case IEEE80211_M_IBSS: + /* + * Local TSF is updated with remote TSF on beacon reception + * only if the remote TSF is greater than local TSF. + */ + tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_IBSS); + tmp |= RT2573_BCN_TX_EN; + break; + case IEEE80211_M_HOSTAP: + /* SYNC with nobody */ + tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_HOSTAP); + tmp |= RT2573_BCN_TX_EN; + break; + default: + device_printf(sc->sc_dev, + "Enabling TSF failed. undefined opmode %d\n", + vap->iv_opmode); + return EINVAL; + } + + if (rum_write(sc, RT2573_TXRX_CSR9, tmp) != 0) + return EIO; - rum_write(sc, RT2573_TXRX_CSR9, tmp); + return 0; } static void rum_enable_tsf(struct rum_softc *sc) { - rum_write(sc, RT2573_TXRX_CSR9, - (rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000) | - RT2573_TSF_TICKING | RT2573_TSF_MODE(2)); + rum_modbits(sc, RT2573_TXRX_CSR9, RT2573_TSF_TIMER_EN | + RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_DIS), 0x00ffffff); +} + +static void +rum_abort_tsf_sync(struct rum_softc *sc) +{ + rum_clrbits(sc, RT2573_TXRX_CSR9, 0x00ffffff); +} + +static void +rum_get_tsf(struct rum_softc *sc, uint64_t *buf) +{ + rum_read_multi(sc, RT2573_TXRX_CSR12, buf, sizeof (*buf)); } static void -rum_update_slot(struct rum_softc *sc) +rum_update_slot_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id) { struct ieee80211com *ic = &sc->sc_ic; uint8_t slottime; - uint32_t tmp; slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; - tmp = rum_read(sc, RT2573_MAC_CSR9); - tmp = (tmp & ~0xff) | slottime; - rum_write(sc, RT2573_MAC_CSR9, tmp); + rum_modbits(sc, RT2573_MAC_CSR9, slottime, 0xff); DPRINTF("setting slot time to %uus\n", slottime); } static void -rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) +rum_update_slot(struct ieee80211com *ic) { - uint32_t tmp; + rum_cmd_sleepable(ic->ic_softc, NULL, 0, 0, rum_update_slot_cb); +} - tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; - rum_write(sc, RT2573_MAC_CSR4, tmp); +static void +rum_wme_update_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id) +{ + struct ieee80211com *ic = &sc->sc_ic; + const struct wmeParams *chanp = + ic->ic_wme.wme_chanParams.cap_wmeParams; + int error = 0; + + error = rum_write(sc, RT2573_AIFSN_CSR, + chanp[WME_AC_VO].wmep_aifsn << 12 | + chanp[WME_AC_VI].wmep_aifsn << 8 | + chanp[WME_AC_BK].wmep_aifsn << 4 | + chanp[WME_AC_BE].wmep_aifsn); + if (error) + goto print_err; + error = rum_write(sc, RT2573_CWMIN_CSR, + chanp[WME_AC_VO].wmep_logcwmin << 12 | + chanp[WME_AC_VI].wmep_logcwmin << 8 | + chanp[WME_AC_BK].wmep_logcwmin << 4 | + chanp[WME_AC_BE].wmep_logcwmin); + if (error) + goto print_err; + error = rum_write(sc, RT2573_CWMAX_CSR, + chanp[WME_AC_VO].wmep_logcwmax << 12 | + chanp[WME_AC_VI].wmep_logcwmax << 8 | + chanp[WME_AC_BK].wmep_logcwmax << 4 | + chanp[WME_AC_BE].wmep_logcwmax); + if (error) + goto print_err; + error = rum_write(sc, RT2573_TXOP01_CSR, + chanp[WME_AC_BK].wmep_txopLimit << 16 | + chanp[WME_AC_BE].wmep_txopLimit); + if (error) + goto print_err; + error = rum_write(sc, RT2573_TXOP23_CSR, + chanp[WME_AC_VO].wmep_txopLimit << 16 | + chanp[WME_AC_VI].wmep_txopLimit); + if (error) + goto print_err; + + memcpy(sc->wme_params, chanp, sizeof(*chanp) * WME_NUM_AC); - tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16; - rum_write(sc, RT2573_MAC_CSR5, tmp); + return; + +print_err: + device_printf(sc->sc_dev, "%s: WME update failed, error %d\n", + __func__, error); } -static void -rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) +static int +rum_wme_update(struct ieee80211com *ic) { - uint32_t tmp; + struct rum_softc *sc = ic->ic_softc; - tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; - rum_write(sc, RT2573_MAC_CSR2, tmp); + rum_cmd_sleepable(sc, NULL, 0, 0, rum_wme_update_cb); - tmp = addr[4] | addr[5] << 8 | 0xff << 16; - rum_write(sc, RT2573_MAC_CSR3, tmp); + return (0); } static void -rum_setpromisc(struct rum_softc *sc) +rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) { - uint32_t tmp; - tmp = rum_read(sc, RT2573_TXRX_CSR0); + rum_write(sc, RT2573_MAC_CSR4, + bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); + rum_write(sc, RT2573_MAC_CSR5, + bssid[4] | bssid[5] << 8 | RT2573_NUM_BSSID_MSK(1)); +} - tmp &= ~RT2573_DROP_NOT_TO_ME; - if (sc->sc_ic.ic_promisc == 0) - tmp |= RT2573_DROP_NOT_TO_ME; +static void +rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) +{ - rum_write(sc, RT2573_TXRX_CSR0, tmp); + rum_write(sc, RT2573_MAC_CSR2, + addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); + rum_write(sc, RT2573_MAC_CSR3, + addr[4] | addr[5] << 8 | 0xff << 16); +} - DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc > 0 ? +static void +rum_setpromisc(struct rum_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + + if (ic->ic_promisc == 0) + rum_setbits(sc, RT2573_TXRX_CSR0, RT2573_DROP_NOT_TO_ME); + else + rum_clrbits(sc, RT2573_TXRX_CSR0, RT2573_DROP_NOT_TO_ME); + + DPRINTF("%s promiscuous mode\n", ic->ic_promisc > 0 ? "entering" : "leaving"); } @@ -1793,23 +2182,15 @@ rum_update_promisc(struct ieee80211com *ic) struct rum_softc *sc = ic->ic_softc; RUM_LOCK(sc); - if (!sc->sc_running) { - RUM_UNLOCK(sc); - return; - } - rum_setpromisc(sc); + if (sc->sc_running) + rum_setpromisc(sc); RUM_UNLOCK(sc); } static void rum_update_mcast(struct ieee80211com *ic) { - static int warning_printed; - - if (warning_printed == 0) { - ic_printf(ic, "need to implement %s\n", __func__); - warning_printed = 1; - } + /* Ignore. */ } static const char * @@ -1908,6 +2289,27 @@ rum_read_eeprom(struct rum_softc *sc) } static int +rum_bbp_wakeup(struct rum_softc *sc) +{ + unsigned int ntries; + + for (ntries = 0; ntries < 100; ntries++) { + if (rum_read(sc, RT2573_MAC_CSR12) & 8) + break; + rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ + if (rum_pause(sc, hz / 100)) + break; + } + if (ntries == 100) { + device_printf(sc->sc_dev, + "timeout waiting for BBP/RF to wakeup\n"); + return (ETIMEDOUT); + } + + return (0); +} + +static int rum_bbp_init(struct rum_softc *sc) { int i, ntries; @@ -1926,7 +2328,7 @@ rum_bbp_init(struct rum_softc *sc) } /* initialize BBP registers to default values */ - for (i = 0; i < N(rum_def_bbp); i++) + for (i = 0; i < nitems(rum_def_bbp); i++) rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); /* write vendor-specific BBP values (from EEPROM) */ @@ -1940,42 +2342,46 @@ rum_bbp_init(struct rum_softc *sc) } static void +rum_clr_shkey_regs(struct rum_softc *sc) +{ + rum_write(sc, RT2573_SEC_CSR0, 0); + rum_write(sc, RT2573_SEC_CSR1, 0); + rum_write(sc, RT2573_SEC_CSR5, 0); +} + +static int rum_init(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; - usb_error_t error; - int i, ntries; - - RUM_LOCK_ASSERT(sc, MA_OWNED); + int i, ret; - rum_stop(sc); + RUM_LOCK(sc); + if (sc->sc_running) { + ret = 0; + goto end; + } /* initialize MAC registers to default values */ - for (i = 0; i < N(rum_def_mac); i++) + for (i = 0; i < nitems(rum_def_mac); i++) rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); + /* reset some WME parameters to default values */ + sc->wme_params[0].wmep_aifsn = 2; + sc->wme_params[0].wmep_logcwmin = 4; + sc->wme_params[0].wmep_logcwmax = 10; + /* set host ready */ - rum_write(sc, RT2573_MAC_CSR1, 3); + rum_write(sc, RT2573_MAC_CSR1, RT2573_RESET_ASIC | RT2573_RESET_BBP); rum_write(sc, RT2573_MAC_CSR1, 0); /* wait for BBP/RF to wakeup */ - for (ntries = 0; ntries < 100; ntries++) { - if (rum_read(sc, RT2573_MAC_CSR12) & 8) - break; - rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ - if (rum_pause(sc, hz / 100)) - break; - } - if (ntries == 100) { - device_printf(sc->sc_dev, - "timeout waiting for BBP/RF to wakeup\n"); - goto fail; - } + if ((ret = rum_bbp_wakeup(sc)) != 0) + goto end; - if ((error = rum_bbp_init(sc)) != 0) - goto fail; + if ((ret = rum_bbp_init(sc)) != 0) + goto end; /* select default channel */ rum_select_band(sc, ic->ic_curchan); @@ -1985,10 +2391,16 @@ rum_init(struct rum_softc *sc) /* clear STA registers */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + /* clear security registers (if required) */ + if (sc->sc_clr_shkeys == 0) { + rum_clr_shkey_regs(sc); + sc->sc_clr_shkeys = 1; + } + rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* initialize ASIC */ - rum_write(sc, RT2573_MAC_CSR1, 4); + rum_write(sc, RT2573_MAC_CSR1, RT2573_HOST_READY); /* * Allocate Tx and Rx xfer queues. @@ -2012,21 +2424,25 @@ rum_init(struct rum_softc *sc) sc->sc_running = 1; usbd_xfer_set_stall(sc->sc_xfer[RUM_BULK_WR]); usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]); - return; -fail: rum_stop(sc); -#undef N +end: RUM_UNLOCK(sc); + + if (ret != 0) + rum_stop(sc); + + return ret; } static void rum_stop(struct rum_softc *sc) { - uint32_t tmp; - - RUM_LOCK_ASSERT(sc, MA_OWNED); + RUM_LOCK(sc); + if (!sc->sc_running) { + RUM_UNLOCK(sc); + return; + } sc->sc_running = 0; - RUM_UNLOCK(sc); /* @@ -2036,16 +2452,15 @@ rum_stop(struct rum_softc *sc) usbd_transfer_drain(sc->sc_xfer[RUM_BULK_RD]); RUM_LOCK(sc); - rum_unsetup_tx_list(sc); /* disable Rx */ - tmp = rum_read(sc, RT2573_TXRX_CSR0); - rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); + rum_setbits(sc, RT2573_TXRX_CSR0, RT2573_DISABLE_RX); /* reset ASIC */ - rum_write(sc, RT2573_MAC_CSR1, 3); + rum_write(sc, RT2573_MAC_CSR1, RT2573_RESET_ASIC | RT2573_RESET_BBP); rum_write(sc, RT2573_MAC_CSR1, 0); + RUM_UNLOCK(sc); } static void @@ -2082,35 +2497,318 @@ rum_load_microcode(struct rum_softc *sc, const uint8_t *ucode, size_t size) rum_pause(sc, hz / 8); } -static void -rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap) +static int +rum_set_beacon(struct rum_softc *sc, struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; + struct rum_vap *rvp = RUM_VAP(vap); + struct mbuf *m = rvp->bcn_mbuf; const struct ieee80211_txparam *tp; struct rum_tx_desc desc; - struct mbuf *m0; - if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC) - return; - if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) - return; + RUM_LOCK_ASSERT(sc); - m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo); - if (m0 == NULL) - return; + if (m == NULL) + return EINVAL; + if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) + return EINVAL; tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; - rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ, - m0->m_pkthdr.len, tp->mgmtrate); + rum_setup_tx_desc(sc, &desc, NULL, RT2573_TX_TIMESTAMP, + RT2573_TX_HWSEQ, 0, 0, m->m_pkthdr.len, tp->mgmtrate); - /* copy the first 24 bytes of Tx descriptor into NIC memory */ - rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24); + /* copy the Tx descriptor into NIC memory */ + if (rum_write_multi(sc, RT2573_HW_BCN_BASE(0), (uint8_t *)&desc, + RT2573_TX_DESC_SIZE) != 0) + return EIO; /* copy beacon header and payload into NIC memory */ - rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *), - m0->m_pkthdr.len); + if (rum_write_multi(sc, RT2573_HW_BCN_BASE(0) + RT2573_TX_DESC_SIZE, + mtod(m, uint8_t *), m->m_pkthdr.len) != 0) + return EIO; - m_freem(m0); + return 0; +} + +static int +rum_alloc_beacon(struct rum_softc *sc, struct ieee80211vap *vap) +{ + struct rum_vap *rvp = RUM_VAP(vap); + struct ieee80211_node *ni = vap->iv_bss; + struct mbuf *m; + + if (ni->ni_chan == IEEE80211_CHAN_ANYC) + return EINVAL; + + m = ieee80211_beacon_alloc(ni); + if (m == NULL) + return ENOMEM; + + if (rvp->bcn_mbuf != NULL) + m_freem(rvp->bcn_mbuf); + + rvp->bcn_mbuf = m; + + return (rum_set_beacon(sc, vap)); +} + +static void +rum_update_beacon_cb(struct rum_softc *sc, union sec_param *data, + uint8_t rvp_id) +{ + struct ieee80211vap *vap = data->vap; + + rum_set_beacon(sc, vap); +} + +static void +rum_update_beacon(struct ieee80211vap *vap, int item) +{ + struct ieee80211com *ic = vap->iv_ic; + struct rum_softc *sc = ic->ic_softc; + struct rum_vap *rvp = RUM_VAP(vap); + struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; + struct ieee80211_node *ni = vap->iv_bss; + struct mbuf *m = rvp->bcn_mbuf; + int mcast = 0; + + RUM_LOCK(sc); + if (m == NULL) { + m = ieee80211_beacon_alloc(ni); + if (m == NULL) { + device_printf(sc->sc_dev, + "%s: could not allocate beacon frame\n", __func__); + RUM_UNLOCK(sc); + return; + } + rvp->bcn_mbuf = m; + } + + switch (item) { + case IEEE80211_BEACON_ERP: + rum_update_slot(ic); + break; + case IEEE80211_BEACON_TIM: + mcast = 1; /*TODO*/ + break; + default: + break; + } + RUM_UNLOCK(sc); + + setbit(bo->bo_flags, item); + ieee80211_beacon_update(ni, m, mcast); + + rum_cmd_sleepable(sc, &vap, sizeof(vap), 0, rum_update_beacon_cb); +} + +static int +rum_common_key_set(struct rum_softc *sc, struct ieee80211_key *k, + uint16_t base) +{ + + if (rum_write_multi(sc, base, k->wk_key, k->wk_keylen)) + return EIO; + + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) { + if (rum_write_multi(sc, base + IEEE80211_KEYBUF_SIZE, + k->wk_txmic, 8)) + return EIO; + if (rum_write_multi(sc, base + IEEE80211_KEYBUF_SIZE + 8, + k->wk_rxmic, 8)) + return EIO; + } + + return 0; +} + +static void +rum_group_key_set_cb(struct rum_softc *sc, union sec_param *data, + uint8_t rvp_id) +{ + struct ieee80211_key *k = &data->key; + uint8_t mode; + + if (sc->sc_clr_shkeys == 0) { + rum_clr_shkey_regs(sc); + sc->sc_clr_shkeys = 1; + } + + mode = rum_crypto_mode(sc, k->wk_cipher->ic_cipher, k->wk_keylen); + if (mode == 0) + goto print_err; + + DPRINTFN(1, "setting group key %d for vap %d, mode %d " + "(tx %s, rx %s)\n", k->wk_keyix, rvp_id, mode, + (k->wk_flags & IEEE80211_KEY_XMIT) ? "on" : "off", + (k->wk_flags & IEEE80211_KEY_RECV) ? "on" : "off"); + + /* Install the key. */ + if (rum_common_key_set(sc, k, RT2573_SKEY(rvp_id, k->wk_keyix)) != 0) + goto print_err; + + /* Set cipher mode. */ + if (rum_modbits(sc, rvp_id < 2 ? RT2573_SEC_CSR1 : RT2573_SEC_CSR5, + mode << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX, + RT2573_MODE_MASK << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX) + != 0) + goto print_err; + + /* Mark this key as valid. */ + if (rum_setbits(sc, RT2573_SEC_CSR0, + 1 << (rvp_id * RT2573_SKEY_MAX + k->wk_keyix)) != 0) + goto print_err; + + return; + +print_err: + device_printf(sc->sc_dev, "%s: cannot set group key %d for vap %d\n", + __func__, k->wk_keyix, rvp_id); +} + +static void +rum_group_key_del_cb(struct rum_softc *sc, union sec_param *data, + uint8_t rvp_id) +{ + struct ieee80211_key *k = &data->key; + + DPRINTF("%s: removing group key %d for vap %d\n", __func__, + k->wk_keyix, rvp_id); + rum_clrbits(sc, + rvp_id < 2 ? RT2573_SEC_CSR1 : RT2573_SEC_CSR5, + RT2573_MODE_MASK << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX); + rum_clrbits(sc, RT2573_SEC_CSR0, + rvp_id * RT2573_SKEY_MAX + k->wk_keyix); +} + +static void +rum_pair_key_set_cb(struct rum_softc *sc, union sec_param *data, + uint8_t rvp_id) +{ + struct ieee80211_key *k = &data->key; + uint8_t buf[IEEE80211_ADDR_LEN + 1]; + uint8_t mode; + + mode = rum_crypto_mode(sc, k->wk_cipher->ic_cipher, k->wk_keylen); + if (mode == 0) + goto print_err; + + DPRINTFN(1, "setting pairwise key %d for vap %d, mode %d " + "(tx %s, rx %s)\n", k->wk_keyix, rvp_id, mode, + (k->wk_flags & IEEE80211_KEY_XMIT) ? "on" : "off", + (k->wk_flags & IEEE80211_KEY_RECV) ? "on" : "off"); + + /* Install the key. */ + if (rum_common_key_set(sc, k, RT2573_PKEY(k->wk_keyix)) != 0) + goto print_err; + + IEEE80211_ADDR_COPY(buf, k->wk_macaddr); + buf[IEEE80211_ADDR_LEN] = mode; + + /* Set transmitter address and cipher mode. */ + if (rum_write_multi(sc, RT2573_ADDR_ENTRY(k->wk_keyix), + buf, sizeof buf) != 0) + goto print_err; + + /* Enable key table lookup for this vap. */ + if (sc->vap_key_count[rvp_id]++ == 0) + if (rum_setbits(sc, RT2573_SEC_CSR4, 1 << rvp_id) != 0) + goto print_err; + + /* Mark this key as valid. */ + if (rum_setbits(sc, + k->wk_keyix < 32 ? RT2573_SEC_CSR2 : RT2573_SEC_CSR3, + 1 << (k->wk_keyix % 32)) != 0) + goto print_err; + + return; + +print_err: + device_printf(sc->sc_dev, + "%s: cannot set pairwise key %d, vap %d\n", __func__, k->wk_keyix, + rvp_id); +} + +static void +rum_pair_key_del_cb(struct rum_softc *sc, union sec_param *data, + uint8_t rvp_id) +{ + struct ieee80211_key *k = &data->key; + + DPRINTF("%s: removing key %d\n", __func__, k->wk_keyix); + rum_clrbits(sc, (k->wk_keyix < 32) ? RT2573_SEC_CSR2 : RT2573_SEC_CSR3, + 1 << (k->wk_keyix % 32)); + sc->keys_bmap &= ~(1 << k->wk_keyix); + if (--sc->vap_key_count[rvp_id] == 0) + rum_clrbits(sc, RT2573_SEC_CSR4, 1 << rvp_id); +} + +static int +rum_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, + ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) +{ + struct rum_softc *sc = vap->iv_ic->ic_softc; + uint8_t i; + + if (!(&vap->iv_nw_keys[0] <= k && + k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { + if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) { + RUM_LOCK(sc); + for (i = 0; i < RT2573_ADDR_MAX; i++) { + if ((sc->keys_bmap & (1 << i)) == 0) { + sc->keys_bmap |= 1 << i; + *keyix = i; + break; + } + } + RUM_UNLOCK(sc); + if (i == RT2573_ADDR_MAX) { + device_printf(sc->sc_dev, + "%s: no free space in the key table\n", + __func__); + return 0; + } + } else + *keyix = 0; + } else { + *keyix = k - vap->iv_nw_keys; + } + *rxkeyix = *keyix; + return 1; +} + +static int +rum_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) +{ + struct rum_softc *sc = vap->iv_ic->ic_softc; + int group; + + if (k->wk_flags & IEEE80211_KEY_SWCRYPT) { + /* Not for us. */ + return 1; + } + + group = k >= &vap->iv_nw_keys[0] && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; + + return !rum_cmd_sleepable(sc, k, sizeof(*k), 0, + group ? rum_group_key_set_cb : rum_pair_key_set_cb); +} + +static int +rum_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) +{ + struct rum_softc *sc = vap->iv_ic->ic_softc; + int group; + + if (k->wk_flags & IEEE80211_KEY_SWCRYPT) { + /* Not for us. */ + return 1; + } + + group = k >= &vap->iv_nw_keys[0] && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; + + return !rum_cmd_sleepable(sc, k, sizeof(*k), 0, + group ? rum_group_key_del_cb : rum_pair_key_del_cb); } static int @@ -2118,20 +2816,17 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct rum_softc *sc = ni->ni_ic->ic_softc; + int ret; RUM_LOCK(sc); /* prevent management frames from being sent if we're not ready */ if (!sc->sc_running) { - RUM_UNLOCK(sc); - m_freem(m); - ieee80211_free_node(ni); - return ENETDOWN; + ret = ENETDOWN; + goto bad; } if (sc->tx_nfree < RUM_TX_MINFREE) { - RUM_UNLOCK(sc); - m_freem(m); - ieee80211_free_node(ni); - return EIO; + ret = EIO; + goto bad; } if (params == NULL) { @@ -2139,14 +2834,14 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, * Legacy path; interpret frame contents to decide * precisely how to send the frame. */ - if (rum_tx_mgt(sc, m, ni) != 0) + if ((ret = rum_tx_mgt(sc, m, ni)) != 0) goto bad; } else { /* * Caller supplied explicit parameters to use in * sending the frame. */ - if (rum_tx_raw(sc, m, ni, params) != 0) + if ((ret = rum_tx_raw(sc, m, ni, params)) != 0) goto bad; } RUM_UNLOCK(sc); @@ -2154,8 +2849,9 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: RUM_UNLOCK(sc); + m_freem(m); ieee80211_free_node(ni); - return EIO; + return ret; } static void @@ -2185,29 +2881,34 @@ rum_ratectl_task(void *arg, int pending) { struct rum_vap *rvp = arg; struct ieee80211vap *vap = &rvp->vap; - struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = vap->iv_ic->ic_softc; struct ieee80211_node *ni; - int ok, fail; - int sum, retrycnt; + int ok[3], fail; + int sum, success, retrycnt; RUM_LOCK(sc); - /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ + /* read and clear statistic registers (STA_CSR0 to STA_CSR5) */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta)); - ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */ - (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ - fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ - sum = ok+fail; - retrycnt = (le32toh(sc->sta[5]) & 0xffff) + fail; + ok[0] = (le32toh(sc->sta[4]) & 0xffff); /* TX ok w/o retry */ + ok[1] = (le32toh(sc->sta[4]) >> 16); /* TX ok w/ one retry */ + ok[2] = (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ multiple retries */ + fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ - ni = ieee80211_ref_node(vap->iv_bss); - ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); - (void) ieee80211_ratectl_rate(ni, NULL, 0); - ieee80211_free_node(ni); + success = ok[0] + ok[1] + ok[2]; + sum = success + fail; + /* XXX at least */ + retrycnt = ok[1] + ok[2] * 2 + fail * (rvp->maxretry + 1); + + if (sum != 0) { + ni = ieee80211_ref_node(vap->iv_bss); + ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); + (void) ieee80211_ratectl_rate(ni, NULL, 0); + ieee80211_free_node(ni); + } /* count TX retry-fail as Tx errors */ - if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail); + if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, fail); usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); RUM_UNLOCK(sc); @@ -2217,12 +2918,9 @@ static void rum_scan_start(struct ieee80211com *ic) { struct rum_softc *sc = ic->ic_softc; - uint32_t tmp; RUM_LOCK(sc); - /* abort TSF synchronization */ - tmp = rum_read(sc, RT2573_TXRX_CSR9); - rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); + rum_abort_tsf_sync(sc); rum_set_bssid(sc, ieee80211broadcastaddr); RUM_UNLOCK(sc); @@ -2234,8 +2932,11 @@ rum_scan_end(struct ieee80211com *ic) struct rum_softc *sc = ic->ic_softc; RUM_LOCK(sc); - rum_enable_tsf_sync(sc); - rum_set_bssid(sc, ic->ic_macaddr); + if (ic->ic_opmode != IEEE80211_M_AHDEMO) + rum_enable_tsf_sync(sc); + else + rum_enable_tsf(sc); + rum_set_bssid(sc, sc->sc_bssid); RUM_UNLOCK(sc); } diff --git a/sys/dev/usb/wlan/if_rumreg.h b/sys/dev/usb/wlan/if_rumreg.h index 44e627a..c673fd7 100644 --- a/sys/dev/usb/wlan/if_rumreg.h +++ b/sys/dev/usb/wlan/if_rumreg.h @@ -34,13 +34,36 @@ #define RT2573_WRITE_LED 0x0a /* - * Control and status registers. + * WME registers. */ #define RT2573_AIFSN_CSR 0x0400 #define RT2573_CWMIN_CSR 0x0404 #define RT2573_CWMAX_CSR 0x0408 +#define RT2573_TXOP01_CSR 0x040C +#define RT2573_TXOP23_CSR 0x0410 #define RT2573_MCU_CODE_BASE 0x0800 -#define RT2573_HW_BEACON_BASE0 0x2400 + +/* + * H/w encryption/decryption support + */ +#define KEY_SIZE (IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE) +#define RT2573_ADDR_MAX 64 +#define RT2573_SKEY_MAX 4 + +#define RT2573_SKEY(vap, kidx) (0x1000 + ((vap) * RT2573_SKEY_MAX + \ + (kidx)) * KEY_SIZE) +#define RT2573_PKEY(id) (0x1200 + (id) * KEY_SIZE) + +#define RT2573_ADDR_ENTRY(id) (0x1a00 + (id) * 8) + +/* + * Shared memory area + */ +#define RT2573_HW_BCN_BASE(id) (0x2400 + (id) * 0x100) + +/* + * Control and status registers. + */ #define RT2573_MAC_CSR0 0x3000 #define RT2573_MAC_CSR1 0x3004 #define RT2573_MAC_CSR2 0x3008 @@ -95,13 +118,23 @@ #define RT2573_STA_CSR5 0x30d4 +/* possible values for register RT2573_ADDR_MODE */ +#define RT2573_MODE_MASK 0x7 +#define RT2573_MODE_NOSEC 0 +#define RT2573_MODE_WEP40 1 +#define RT2573_MODE_WEP104 2 +#define RT2573_MODE_TKIP 3 +#define RT2573_MODE_AES_CCMP 4 +#define RT2573_MODE_CKIP40 5 +#define RT2573_MODE_CKIP104 6 + /* possible flags for register RT2573_MAC_CSR1 */ #define RT2573_RESET_ASIC (1 << 0) #define RT2573_RESET_BBP (1 << 1) #define RT2573_HOST_READY (1 << 2) /* possible flags for register MAC_CSR5 */ -#define RT2573_ONE_BSSID 3 +#define RT2573_NUM_BSSID_MSK(n) (((n * 3) & 3) << 16) /* possible flags for register TXRX_CSR0 */ /* Tx filter flags are in the low 16 bits */ @@ -122,13 +155,20 @@ #define RT2573_SHORT_PREAMBLE (1 << 18) #define RT2573_MRR_ENABLED (1 << 19) #define RT2573_MRR_CCK_FALLBACK (1 << 22) +#define RT2573_LONG_RETRY(max) ((max) << 24) +#define RT2573_LONG_RETRY_MASK (0xf << 24) +#define RT2573_SHORT_RETRY(max) ((max) << 28) +#define RT2573_SHORT_RETRY_MASK (0xf << 28) /* possible flags for register TXRX_CSR9 */ -#define RT2573_TSF_TICKING (1 << 16) -#define RT2573_TSF_MODE(x) (((x) & 0x3) << 17) -/* TBTT stands for Target Beacon Transmission Time */ -#define RT2573_ENABLE_TBTT (1 << 19) -#define RT2573_GENERATE_BEACON (1 << 20) +#define RT2573_TSF_TIMER_EN (1 << 16) +#define RT2573_TSF_SYNC_MODE(x) (((x) & 0x3) << 17) +#define RT2573_TSF_SYNC_MODE_DIS 0 +#define RT2573_TSF_SYNC_MODE_STA 1 +#define RT2573_TSF_SYNC_MODE_IBSS 2 +#define RT2573_TSF_SYNC_MODE_HOSTAP 3 +#define RT2573_TBTT_TIMER_EN (1 << 19) +#define RT2573_BCN_TX_EN (1 << 20) /* possible flags for register PHY_CSR0 */ #define RT2573_PA_PE_2GHZ (1 << 16) @@ -175,6 +215,10 @@ struct rum_tx_desc { #define RT2573_TX_OFDM (1 << 5) #define RT2573_TX_IFS_SIFS (1 << 6) #define RT2573_TX_LONG_RETRY (1 << 7) +#define RT2573_TX_TKIPMIC (1 << 8) +#define RT2573_TX_KEY_PAIR (1 << 9) +#define RT2573_TX_KEY_ID(id) (((id) & 0x3f) << 10) +#define RT2573_TX_CIP_MODE(m) ((m) << 29) uint16_t wme; #define RT2573_QID(v) (v) @@ -182,8 +226,9 @@ struct rum_tx_desc { #define RT2573_LOGCWMIN(v) ((v) << 8) #define RT2573_LOGCWMAX(v) ((v) << 12) - uint16_t xflags; -#define RT2573_TX_HWSEQ (1 << 12) + uint8_t hdrlen; + uint8_t xflags; +#define RT2573_TX_HWSEQ (1 << 4) uint8_t plcp_signal; uint8_t plcp_service; @@ -207,9 +252,25 @@ struct rum_rx_desc { uint32_t flags; #define RT2573_RX_BUSY (1 << 0) #define RT2573_RX_DROP (1 << 1) +#define RT2573_RX_UC2ME (1 << 2) +#define RT2573_RX_MC (1 << 3) +#define RT2573_RX_BC (1 << 4) +#define RT2573_RX_MYBSS (1 << 5) #define RT2573_RX_CRC_ERROR (1 << 6) #define RT2573_RX_OFDM (1 << 7) +#define RT2573_RX_DEC_MASK (3 << 8) +#define RT2573_RX_DEC_OK (0 << 8) + +#define RT2573_RX_IV_ERROR (1 << 8) +#define RT2573_RX_MIC_ERROR (2 << 8) +#define RT2573_RX_KEY_ERROR (3 << 8) + +#define RT2573_RX_KEY_PAIR (1 << 28) + +#define RT2573_RX_CIP_MASK (7 << 29) +#define RT2573_RX_CIP_MODE(m) ((m) << 29) + uint8_t rate; uint8_t rssi; uint8_t reserved1; diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h index 35da6d3..9fa733e 100644 --- a/sys/dev/usb/wlan/if_rumvar.h +++ b/sys/dev/usb/wlan/if_rumvar.h @@ -22,6 +22,7 @@ struct rum_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; + uint64_t wr_tsf; uint8_t wr_flags; uint8_t wr_rate; uint16_t wr_chan_freq; @@ -32,7 +33,8 @@ struct rum_rx_radiotap_header { } __packed __aligned(8); #define RT2573_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + ((1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ @@ -42,6 +44,7 @@ struct rum_rx_radiotap_header { struct rum_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; + uint64_t wt_tsf; uint8_t wt_flags; uint8_t wt_rate; uint16_t wt_chan_freq; @@ -50,7 +53,8 @@ struct rum_tx_radiotap_header { } __packed __aligned(8); #define RT2573_TX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + ((1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_ANTENNA)) @@ -67,11 +71,29 @@ struct rum_tx_data { }; typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead; +union sec_param { + struct ieee80211_key key; + struct wmeParams wme_params[WME_NUM_AC]; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + struct ieee80211vap *vap; +}; +#define CMD_FUNC_PROTO void (*func)(struct rum_softc *, \ + union sec_param *, uint8_t) + +struct rum_cmdq { + union sec_param data; + uint8_t rvp_id; + + CMD_FUNC_PROTO; +}; +#define RUM_CMDQ_SIZE 16 + struct rum_vap { struct ieee80211vap vap; - struct ieee80211_beacon_offsets bo; + struct mbuf *bcn_mbuf; struct usb_callout ratectl_ch; struct task ratectl_task; + uint8_t maxretry; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); @@ -90,7 +112,7 @@ struct rum_softc { device_t sc_dev; struct usb_device *sc_udev; - struct usb_xfer *sc_xfer[RUM_N_TRANSFER]; + struct usb_xfer *sc_xfer[RUM_N_TRANSFER]; uint8_t rf_rev; uint8_t rffreq; @@ -103,11 +125,24 @@ struct rum_softc { struct mtx sc_mtx; + struct rum_cmdq cmdq[RUM_CMDQ_SIZE]; + struct mtx cmdq_mtx; + struct task cmdq_task; + uint8_t cmdq_first; + uint8_t cmdq_last; + uint32_t sta[6]; uint32_t rf_regs[4]; uint8_t txpow[44]; u_int sc_detached:1, - sc_running:1; + sc_running:1, + sc_clr_shkeys:1; + + uint8_t sc_bssid[IEEE80211_ADDR_LEN]; + struct wmeParams wme_params[WME_NUM_AC]; + + uint8_t vap_key_count[1]; + uint64_t keys_bmap; struct { uint8_t val; @@ -125,12 +160,19 @@ struct rum_softc { uint8_t bbp17; struct rum_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - struct rum_tx_radiotap_header sc_txtap; - int sc_txtap_len; }; -#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) -#define RUM_LOCK_ASSERT(sc, t) mtx_assert(&(sc)->sc_mtx, t) +#define RUM_LOCK_INIT(sc) \ + mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ + MTX_NETWORK_LOCK, MTX_DEF); +#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define RUM_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RUM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) + +#define RUM_CMDQ_LOCK_INIT(sc) \ + mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF) +#define RUM_CMDQ_LOCK(sc) mtx_lock(&(sc)->cmdq_mtx) +#define RUM_CMDQ_UNLOCK(sc) mtx_unlock(&(sc)->cmdq_mtx) +#define RUM_CMDQ_LOCK_DESTROY(sc) mtx_destroy(&(sc)->cmdq_mtx) diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index c8707c4..83d4a88 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -382,8 +382,7 @@ static int run_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int run_wme_update(struct ieee80211com *); static void run_wme_update_cb(void *); static void run_key_set_cb(void *); -static int run_key_set(struct ieee80211vap *, struct ieee80211_key *, - const uint8_t mac[IEEE80211_ADDR_LEN]); +static int run_key_set(struct ieee80211vap *, struct ieee80211_key *); static void run_key_delete_cb(void *); static int run_key_delete(struct ieee80211vap *, struct ieee80211_key *); static void run_ratectl_to(void *); @@ -392,6 +391,8 @@ static void run_drain_fifo(void *); static void run_iter_func(void *, struct ieee80211_node *); static void run_newassoc_cb(void *); static void run_newassoc(struct ieee80211_node *, int); +static void run_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, + const struct ieee80211_rx_stats *, int, int); static void run_rx_frame(struct run_softc *, struct mbuf *, uint32_t); static void run_tx_free(struct run_endpoint_queue *pq, struct run_tx_data *, int); @@ -830,6 +831,21 @@ detach: return (ENXIO); } +static void +run_drain_mbufq(struct run_softc *sc) +{ + struct mbuf *m; + struct ieee80211_node *ni; + + RUN_LOCK_ASSERT(sc, MA_OWNED); + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + ieee80211_free_node(ni); + m_freem(m); + } +} + static int run_detach(device_t self) { @@ -851,6 +867,9 @@ run_detach(device_t self) /* free TX list, if any */ for (i = 0; i != RUN_EP_QUEUES; i++) run_unsetup_tx_list(sc, &sc->sc_epq[i]); + + /* Free TX queue */ + run_drain_mbufq(sc); RUN_UNLOCK(sc); if (sc->sc_ic.ic_softc == sc) { @@ -861,7 +880,6 @@ run_detach(device_t self) ieee80211_ifdetach(ic); } - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -939,6 +957,10 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* override state transition machine */ rvp->newstate = vap->iv_newstate; vap->iv_newstate = run_newstate; + if (opmode == IEEE80211_M_IBSS) { + rvp->recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = run_recv_mgmt; + } ieee80211_ratectl_init(vap); ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); @@ -1670,14 +1692,14 @@ run_get_txpower(struct run_softc *sc) /* Fix broken Tx power entries. */ for (i = 0; i < 14; i++) { if (sc->mac_ver >= 0x5390) { - if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27) + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 39) sc->txpow1[i] = 5; } else { if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) sc->txpow1[i] = 5; } if (sc->mac_ver > 0x5390) { - if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27) + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 39) sc->txpow2[i] = 5; } else if (sc->mac_ver < 0x5390) { if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) @@ -2157,7 +2179,8 @@ run_wme_update_cb(void *arg) { struct ieee80211com *ic = arg; struct run_softc *sc = ic->ic_softc; - struct ieee80211_wme_state *wmesp = &ic->ic_wme; + const struct wmeParams *ac = + ic->ic_wme.wme_chanParams.cap_wmeParams; int aci, error = 0; RUN_LOCK_ASSERT(sc, MA_OWNED); @@ -2165,39 +2188,39 @@ run_wme_update_cb(void *arg) /* update MAC TX configuration registers */ for (aci = 0; aci < WME_NUM_AC; aci++) { error = run_write(sc, RT2860_EDCA_AC_CFG(aci), - wmesp->wme_params[aci].wmep_logcwmax << 16 | - wmesp->wme_params[aci].wmep_logcwmin << 12 | - wmesp->wme_params[aci].wmep_aifsn << 8 | - wmesp->wme_params[aci].wmep_txopLimit); + ac[aci].wmep_logcwmax << 16 | + ac[aci].wmep_logcwmin << 12 | + ac[aci].wmep_aifsn << 8 | + ac[aci].wmep_txopLimit); if (error) goto err; } /* update SCH/DMA registers too */ error = run_write(sc, RT2860_WMM_AIFSN_CFG, - wmesp->wme_params[WME_AC_VO].wmep_aifsn << 12 | - wmesp->wme_params[WME_AC_VI].wmep_aifsn << 8 | - wmesp->wme_params[WME_AC_BK].wmep_aifsn << 4 | - wmesp->wme_params[WME_AC_BE].wmep_aifsn); + ac[WME_AC_VO].wmep_aifsn << 12 | + ac[WME_AC_VI].wmep_aifsn << 8 | + ac[WME_AC_BK].wmep_aifsn << 4 | + ac[WME_AC_BE].wmep_aifsn); if (error) goto err; error = run_write(sc, RT2860_WMM_CWMIN_CFG, - wmesp->wme_params[WME_AC_VO].wmep_logcwmin << 12 | - wmesp->wme_params[WME_AC_VI].wmep_logcwmin << 8 | - wmesp->wme_params[WME_AC_BK].wmep_logcwmin << 4 | - wmesp->wme_params[WME_AC_BE].wmep_logcwmin); + ac[WME_AC_VO].wmep_logcwmin << 12 | + ac[WME_AC_VI].wmep_logcwmin << 8 | + ac[WME_AC_BK].wmep_logcwmin << 4 | + ac[WME_AC_BE].wmep_logcwmin); if (error) goto err; error = run_write(sc, RT2860_WMM_CWMAX_CFG, - wmesp->wme_params[WME_AC_VO].wmep_logcwmax << 12 | - wmesp->wme_params[WME_AC_VI].wmep_logcwmax << 8 | - wmesp->wme_params[WME_AC_BK].wmep_logcwmax << 4 | - wmesp->wme_params[WME_AC_BE].wmep_logcwmax); + ac[WME_AC_VO].wmep_logcwmax << 12 | + ac[WME_AC_VI].wmep_logcwmax << 8 | + ac[WME_AC_BK].wmep_logcwmax << 4 | + ac[WME_AC_BE].wmep_logcwmax); if (error) goto err; error = run_write(sc, RT2860_WMM_TXOP0_CFG, - wmesp->wme_params[WME_AC_BK].wmep_txopLimit << 16 | - wmesp->wme_params[WME_AC_BE].wmep_txopLimit); + ac[WME_AC_BK].wmep_txopLimit << 16 | + ac[WME_AC_BE].wmep_txopLimit); if (error) goto err; error = run_write(sc, RT2860_WMM_TXOP1_CFG, - wmesp->wme_params[WME_AC_VO].wmep_txopLimit << 16 | - wmesp->wme_params[WME_AC_VI].wmep_txopLimit); + ac[WME_AC_VO].wmep_txopLimit << 16 | + ac[WME_AC_VI].wmep_txopLimit); err: if (error) @@ -2355,8 +2378,7 @@ run_key_set_cb(void *arg) * return 0 on error */ static int -run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, - const uint8_t mac[IEEE80211_ADDR_LEN]) +run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k) { struct ieee80211com *ic = vap->iv_ic; struct run_softc *sc = ic->ic_softc; @@ -2368,7 +2390,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, sc->cmdq[i].arg0 = NULL; sc->cmdq[i].arg1 = vap; sc->cmdq[i].k = k; - IEEE80211_ADDR_COPY(sc->cmdq[i].mac, mac); + IEEE80211_ADDR_COPY(sc->cmdq[i].mac, k->wk_macaddr); ieee80211_runtask(ic, &sc->cmdq_task); /* @@ -2725,6 +2747,34 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi) } static void +run_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, + const struct ieee80211_rx_stats *rxs, int rssi, int nf) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct run_softc *sc = vap->iv_ic->ic_softc; + struct run_vap *rvp = RUN_VAP(vap); + uint64_t ni_tstamp, rx_tstamp; + + rvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf); + + if (vap->iv_state == IEEE80211_S_RUN && + (subtype == IEEE80211_FC0_SUBTYPE_BEACON || + subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) { + ni_tstamp = le64toh(ni->ni_tstamp.tsf); + RUN_LOCK(sc); + run_get_tsf(sc, &rx_tstamp); + RUN_UNLOCK(sc); + rx_tstamp = le64toh(rx_tstamp); + + if (ni_tstamp >= rx_tstamp) { + DPRINTF("ibss merge, tsf %ju tstamp %ju\n", + (uintmax_t)rx_tstamp, (uintmax_t)ni_tstamp); + (void) ieee80211_ibss_merge(ni); + } + } +} + +static void run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) { struct ieee80211com *ic = &sc->sc_ic; @@ -4834,11 +4884,11 @@ run_update_beacon(struct ieee80211vap *vap, int item) setbit(bo->bo_flags, item); if (rvp->beacon_mbuf == NULL) { - rvp->beacon_mbuf = ieee80211_beacon_alloc(ni, bo); + rvp->beacon_mbuf = ieee80211_beacon_alloc(ni); if (rvp->beacon_mbuf == NULL) return; } - ieee80211_beacon_update(ni, bo, rvp->beacon_mbuf, mcast); + ieee80211_beacon_update(ni, rvp->beacon_mbuf, mcast); i = RUN_CMDQ_GET(&sc->cmdq_store); DPRINTF("cmdq_store=%d\n", i); @@ -4872,8 +4922,7 @@ run_update_beacon_cb(void *arg) * is taking care of apropriate calls. */ if (rvp->beacon_mbuf == NULL) { - rvp->beacon_mbuf = ieee80211_beacon_alloc(ni, - &vap->iv_bcn_off); + rvp->beacon_mbuf = ieee80211_beacon_alloc(ni); if (rvp->beacon_mbuf == NULL) return; } @@ -6140,6 +6189,8 @@ run_stop(void *arg) RUN_LOCK(sc); + run_drain_mbufq(sc); + if (sc->rx_m != NULL) { m_free(sc->rx_m); sc->rx_m = NULL; diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h index aa54a72..de71d5a 100644 --- a/sys/dev/usb/wlan/if_runreg.h +++ b/sys/dev/usb/wlan/if_runreg.h @@ -274,7 +274,6 @@ #define RT2860_USB_TXOP_HALT (1 << 20) #define RT2860_USB_TX_CLEAR (1 << 19) #define RT2860_USB_PHY_WD_EN (1 << 16) -#define RT2860_USB_PHY_MAN_RST (1 << 15) #define RT2860_USB_RX_AGG_LMT(x) ((x) << 8) /* in unit of 1KB */ #define RT2860_USB_RX_AGG_TO(x) ((x) & 0xff) /* in unit of 33ns */ diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h index bbefbb0..3af5b22 100644 --- a/sys/dev/usb/wlan/if_runvar.h +++ b/sys/dev/usb/wlan/if_runvar.h @@ -123,6 +123,10 @@ struct run_vap { int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); + void (*recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, + const struct ieee80211_rx_stats *, + int, int); uint8_t rvp_id; }; diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index b882fe3..516caf0 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -956,10 +956,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - uvp = (struct upgt_vap *) malloc(sizeof(struct upgt_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return NULL; + uvp = malloc(sizeof(struct upgt_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; /* enable s/w bmiss handling for sta mode */ diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index bff4de5..6f6686f 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -698,12 +698,9 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ni = ieee80211_ref_node(vap->iv_bss); if (vap->iv_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) { - RAL_UNLOCK(sc); - IEEE80211_LOCK(ic); - ieee80211_free_node(ni); - return (-1); - } + if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) + goto fail; + ural_update_slot(sc); ural_set_txpreamble(sc); ural_set_basicrates(sc, ic->ic_bsschan); @@ -713,23 +710,17 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_IBSS) { - m = ieee80211_beacon_alloc(ni, &vap->iv_bcn_off); + m = ieee80211_beacon_alloc(ni); if (m == NULL) { device_printf(sc->sc_dev, "could not allocate beacon\n"); - RAL_UNLOCK(sc); - IEEE80211_LOCK(ic); - ieee80211_free_node(ni); - return (-1); + goto fail; } ieee80211_ref_node(ni); if (ural_tx_bcn(sc, m, ni) != 0) { device_printf(sc->sc_dev, "could not send beacon\n"); - RAL_UNLOCK(sc); - IEEE80211_LOCK(ic); - ieee80211_free_node(ni); - return (-1); + goto fail; } } @@ -755,6 +746,12 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) RAL_UNLOCK(sc); IEEE80211_LOCK(ic); return (uvp->newstate(vap, nstate, arg)); + +fail: + RAL_UNLOCK(sc); + IEEE80211_LOCK(ic); + ieee80211_free_node(ni); + return (-1); } diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c index b1e3804..eb11f7b 100644 --- a/sys/dev/usb/wlan/if_urtwn.c +++ b/sys/dev/usb/wlan/if_urtwn.c @@ -1775,7 +1775,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, struct r92c_tx_desc *txd; uint8_t raid, type; uint16_t sum; - int i, hasqos, xferlen; + int i, xferlen; struct usb_xfer *urtwn_pipes[4] = { sc->sc_xfer[URTWN_BULK_TX_BE], sc->sc_xfer[URTWN_BULK_TX_BK], @@ -1816,8 +1816,6 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, break; } - hasqos = 0; - /* Fill Tx descriptor. */ txd = (struct r92c_tx_desc *)data->buf; memset(txd, 0, sizeof(*txd)); @@ -1873,7 +1871,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, /* Set sequence number (already little endian). */ txd->txdseq |= *(uint16_t *)wh->i_seq; - if (!hasqos) { + if (!IEEE80211_QOS_HAS_SEQ(wh)) { /* Use HW sequence numbering for non-QoS frames. */ txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ); txd->txdseq |= htole16(0x8000); diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 5a59d37..ed70d19 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -420,6 +420,22 @@ detach: return (ENXIO); /* failure */ } +static void +zyd_drain_mbufq(struct zyd_softc *sc) +{ + struct mbuf *m; + struct ieee80211_node *ni; + + ZYD_LOCK_ASSERT(sc, MA_OWNED); + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + ieee80211_free_node(ni); + m_freem(m); + } +} + + static int zyd_detach(device_t dev) { @@ -433,6 +449,7 @@ zyd_detach(device_t dev) */ ZYD_LOCK(sc); sc->sc_flags |= ZYD_FLAG_DETACHED; + zyd_drain_mbufq(sc); STAILQ_INIT(&sc->tx_q); STAILQ_INIT(&sc->tx_free); ZYD_UNLOCK(sc); @@ -451,7 +468,6 @@ zyd_detach(device_t dev) if (ic->ic_softc == sc) ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -2443,7 +2459,6 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { - m_freem(m0); return (ENOBUFS); } /* packet header may have moved, reset our local pointer */ @@ -2555,6 +2570,7 @@ zyd_start(struct zyd_softc *sc) ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (zyd_tx_start(sc, m, ni) != 0) { ieee80211_free_node(ni); + m_freem(m); if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); break; @@ -2592,6 +2608,7 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (zyd_tx_start(sc, m, ni) != 0) { ZYD_UNLOCK(sc); ieee80211_free_node(ni); + m_freem(m); return (EIO); } ZYD_UNLOCK(sc); @@ -2738,6 +2755,7 @@ zyd_stop(struct zyd_softc *sc) ZYD_LOCK_ASSERT(sc, MA_OWNED); sc->sc_flags &= ~ZYD_FLAG_RUNNING; + zyd_drain_mbufq(sc); /* * Drain all the transfers, if not already drained: diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index abb3bd5..0d7c1c1 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -254,8 +254,7 @@ static void wpi_del_key_cb(void *, struct ieee80211_node *); static int wpi_process_key(struct ieee80211vap *, const struct ieee80211_key *, int); static int wpi_key_set(struct ieee80211vap *, - const struct ieee80211_key *, - const uint8_t mac[IEEE80211_ADDR_LEN]); + const struct ieee80211_key *); static int wpi_key_delete(struct ieee80211vap *, const struct ieee80211_key *); static int wpi_post_alive(struct wpi_softc *); @@ -4355,7 +4354,6 @@ static int wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct wpi_vap *wvp = WPI_VAP(vap); struct wpi_buf *bcn = &wvp->wv_bcbuf; struct mbuf *m; @@ -4366,7 +4364,7 @@ wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) if (ni->ni_chan == IEEE80211_CHAN_ANYC) return EINVAL; - m = ieee80211_beacon_alloc(ni, bo); + m = ieee80211_beacon_alloc(ni); if (m == NULL) { device_printf(sc->sc_dev, "%s: could not allocate beacon frame\n", __func__); @@ -4399,7 +4397,7 @@ wpi_update_beacon(struct ieee80211vap *vap, int item) WPI_VAP_LOCK(wvp); if (bcn->m == NULL) { - bcn->m = ieee80211_beacon_alloc(ni, bo); + bcn->m = ieee80211_beacon_alloc(ni); if (bcn->m == NULL) { device_printf(sc->sc_dev, "%s: could not allocate beacon frame\n", __func__); @@ -4417,7 +4415,7 @@ wpi_update_beacon(struct ieee80211vap *vap, int item) mcast = 1; /* TODO */ setbit(bo->bo_flags, item); - ieee80211_beacon_update(ni, bo, bcn->m, mcast); + ieee80211_beacon_update(ni, bcn->m, mcast); WPI_VAP_LOCK(wvp); wpi_config_beacon(wvp); @@ -4799,8 +4797,7 @@ wpi_process_key(struct ieee80211vap *vap, const struct ieee80211_key *k, } static int -wpi_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, - const uint8_t mac[IEEE80211_ADDR_LEN]) +wpi_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) { return wpi_process_key(vap, k, 1); } diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c index 7c15c35..847ffcb 100644 --- a/sys/dev/wtap/if_wtap.c +++ b/sys/dev/wtap/if_wtap.c @@ -205,7 +205,7 @@ wtap_beacon_alloc(struct wtap_softc *sc, struct ieee80211_node *ni) * we assume the mbuf routines will return us something * with this alignment (perhaps should assert). */ - avp->beacon = ieee80211_beacon_alloc(ni, &vap->iv_bcn_off); + avp->beacon = ieee80211_beacon_alloc(ni); if (avp->beacon == NULL) { printf("%s: cannot get mbuf\n", __func__); return ENOMEM; @@ -242,7 +242,7 @@ wtap_beacon_intrp(void *arg) * of the TIM bitmap). */ m = m_dup(avp->beacon, M_NOWAIT); - if (ieee80211_beacon_update(avp->bf_node, &vap->iv_bcn_off, m, 0)) { + if (ieee80211_beacon_update(avp->bf_node, m, 0)) { printf("%s, need to remap the memory because the beacon frame" " changed size.\n",__func__); } diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c index 3c36b28..5314590 100644 --- a/sys/kern/subr_sbuf.c +++ b/sys/kern/subr_sbuf.c @@ -623,6 +623,10 @@ sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap) va_copy(ap_copy, ap); len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1, fmt, ap_copy); + if (len < 0) { + s->s_error = errno; + return (-1); + } va_end(ap_copy); if (SBUF_FREESPACE(s) >= len) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 0fab000..70dc565 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2050,11 +2050,10 @@ vfs_vmio_iodone(struct buf *bp) (intmax_t)foff, (uintmax_t)m->pindex)); vm_page_sunbusy(m); - vm_object_pip_subtract(obj, 1); foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; iosize -= resid; } - vm_object_pip_wakeupn(obj, 0); + vm_object_pip_wakeupn(obj, bp->b_npages); VM_OBJECT_WUNLOCK(obj); if (bogus && buf_mapped(bp)) { BUF_CHECK_MAPPED(bp); @@ -3923,10 +3922,9 @@ vfs_unbusy_pages(struct buf *bp) } else BUF_CHECK_UNMAPPED(bp); } - vm_object_pip_subtract(obj, 1); vm_page_sunbusy(m); } - vm_object_pip_wakeupn(obj, 0); + vm_object_pip_wakeupn(obj, bp->b_npages); VM_OBJECT_WUNLOCK(obj); } diff --git a/sys/mips/conf/WZR-300HP b/sys/mips/conf/WZR-300HP index 8f84776..c8280cc 100644 --- a/sys/mips/conf/WZR-300HP +++ b/sys/mips/conf/WZR-300HP @@ -28,9 +28,6 @@ device geom_uncompress # compressed in-memory filesystem hackery! options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\" -# options MD_ROOT -# options MD_ROOT_SIZE="6144" - options AR71XX_ATH_EEPROM # Fetch EEPROM/PCI config from flash options ATH_EEPROM_FIRMWARE # Use EEPROM from flash device firmware # Used by the above @@ -42,10 +39,11 @@ device miiproxy # MDIO bus <-> MII PHY rendezvous device etherswitch device arswitch -# Enable GPIO -device gpio -device gpioled - # hwpmc device hwpmc_mips24k device hwpmc + +# load these via modules, shrink kernel +nodevice if_bridge +nodevice bridgestp +nodevice random diff --git a/sys/mips/conf/WZR-300HP.hints b/sys/mips/conf/WZR-300HP.hints index 07d8a71..2f22198 100644 --- a/sys/mips/conf/WZR-300HP.hints +++ b/sys/mips/conf/WZR-300HP.hints @@ -5,11 +5,11 @@ # arge1 MDIO bus hint.argemdio.0.at="nexus0" -hint.argemdio.0.maddr=0x1a000000 +hint.argemdio.0.maddr=0x19000000 hint.argemdio.0.msize=0x1000 hint.argemdio.0.order=0 -hint.arge.0.phymask=0x0 +hint.arge.0.phymask=0x1 hint.arge.0.media=1000 hint.arge.0.fduplex=1 hint.arge.0.eeprommac=0x1f05120c @@ -17,9 +17,9 @@ hint.arge.0.mdio=mdioproxy1 # .. off of the switch mdiobus # arge1: nail to 1000/full, RMII - connected to the switch -hint.arge.1.media=1000 # Map to 1000/full -hint.arge.1.fduplex=1 # -hint.arge.1.phymask=0x0 # no directly mapped PHYs +#hint.arge.1.media=1000 # Map to 1000/full +#hint.arge.1.fduplex=1 # +#hint.arge.1.phymask=0x0 # no directly mapped PHYs # # AR7240 switch config @@ -28,7 +28,7 @@ hint.arswitch.0.at="mdio0" hint.arswitch.0.is_7240=1 # We need to be explicitly told this hint.arswitch.0.numphys=4 # 4 active switch PHYs (PHY 0 -> 3) hint.arswitch.0.phy4cpu=1 # Yes, PHY 4 == dedicated PHY -hint.arswitch.0.is_rgmii=0 # No, not RGMII +hint.arswitch.0.is_rgmii=1 # No, not RGMII hint.arswitch.0.is_gmii=0 # No, not GMII # ath0 - slot 0 diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 5903abd..33d583c 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -197,6 +197,8 @@ gif_clone_create(struct if_clone *ifc, int unit, caddr_t params) GIF2IFP(sc)->if_transmit = gif_transmit; GIF2IFP(sc)->if_qflush = gif_qflush; GIF2IFP(sc)->if_output = gif_output; + GIF2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + GIF2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(GIF2IFP(sc)); bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int32_t)); if (ng_gif_attach_p != NULL) @@ -1040,10 +1042,13 @@ gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) #if defined(INET) || defined(INET6) bad: #endif - if (error == 0 && sc->gif_family != 0) + if (error == 0 && sc->gif_family != 0) { ifp->if_drv_flags |= IFF_DRV_RUNNING; - else + if_link_state_change(ifp, LINK_STATE_UP); + } else { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); + } return (error); } @@ -1065,4 +1070,5 @@ gif_delete_tunnel(struct ifnet *ifp) free(sc->gif_hdr, M_GIF); } ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index c38ec3a..ffd94d8 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -179,6 +179,8 @@ gre_clone_create(struct if_clone *ifc, int unit, caddr_t params) GRE2IFP(sc)->if_ioctl = gre_ioctl; GRE2IFP(sc)->if_transmit = gre_transmit; GRE2IFP(sc)->if_qflush = gre_qflush; + GRE2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + GRE2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(GRE2IFP(sc)); bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t)); GRE_LIST_LOCK(); @@ -623,7 +625,7 @@ gre_set_tunnel(struct ifnet *ifp, struct sockaddr *src, default: return (EAFNOSUPPORT); } - if (sc->gre_family != src->sa_family) + if (sc->gre_family != 0) gre_detach(sc); GRE_WLOCK(sc); if (sc->gre_family != 0) @@ -648,8 +650,10 @@ gre_set_tunnel(struct ifnet *ifp, struct sockaddr *src, break; #endif } - if (error == 0) + if (error == 0) { ifp->if_drv_flags |= IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_UP); + } return (error); } @@ -668,6 +672,7 @@ gre_delete_tunnel(struct ifnet *ifp) free(sc->gre_hdr, M_GRE); } ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } int diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index b623493..ab67b93 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -221,13 +221,6 @@ static const struct lagg_proto { .pr_portreq = lacp_portreq, }, { - .pr_num = LAGG_PROTO_ETHERCHANNEL, - .pr_attach = lagg_lb_attach, - .pr_detach = lagg_lb_detach, - .pr_start = lagg_lb_start, - .pr_input = lagg_lb_input, - }, - { .pr_num = LAGG_PROTO_BROADCAST, .pr_start = lagg_bcast_start, .pr_input = lagg_bcast_input, @@ -1125,7 +1118,6 @@ lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp) case LAGG_PROTO_ROUNDROBIN: case LAGG_PROTO_LOADBALANCE: - case LAGG_PROTO_ETHERCHANNEL: case LAGG_PROTO_BROADCAST: if (LAGG_PORTACTIVE(lp)) rp->rp_flags |= LAGG_PORT_ACTIVE; @@ -1759,7 +1751,6 @@ lagg_linkstate(struct lagg_softc *sc) break; case LAGG_PROTO_ROUNDROBIN: case LAGG_PROTO_LOADBALANCE: - case LAGG_PROTO_ETHERCHANNEL: case LAGG_PROTO_BROADCAST: speed = 0; SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h index bb5ea23..956c238 100644 --- a/sys/net/if_lagg.h +++ b/sys/net/if_lagg.h @@ -53,7 +53,6 @@ typedef enum { LAGG_PROTO_FAILOVER, /* active failover */ LAGG_PROTO_LOADBALANCE, /* loadbalance */ LAGG_PROTO_LACP, /* 802.3ad lacp */ - LAGG_PROTO_ETHERCHANNEL,/* Cisco FEC */ LAGG_PROTO_BROADCAST, /* broadcast */ LAGG_PROTO_MAX, } lagg_proto; @@ -66,7 +65,6 @@ struct lagg_protos { #define LAGG_PROTO_DEFAULT LAGG_PROTO_FAILOVER #define LAGG_PROTOS { \ { "failover", LAGG_PROTO_FAILOVER }, \ - { "fec", LAGG_PROTO_ETHERCHANNEL }, \ { "lacp", LAGG_PROTO_LACP }, \ { "loadbalance", LAGG_PROTO_LOADBALANCE }, \ { "roundrobin", LAGG_PROTO_ROUNDROBIN }, \ diff --git a/sys/net/if_me.c b/sys/net/if_me.c index ff79713..7a09222 100644 --- a/sys/net/if_me.c +++ b/sys/net/if_me.c @@ -192,6 +192,8 @@ me_clone_create(struct if_clone *ifc, int unit, caddr_t params) ME2IFP(sc)->if_ioctl = me_ioctl; ME2IFP(sc)->if_transmit = me_transmit; ME2IFP(sc)->if_qflush = me_qflush; + ME2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + ME2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(ME2IFP(sc)); bpfattach(ME2IFP(sc), DLT_NULL, sizeof(u_int32_t)); ME_LIST_LOCK(); @@ -376,8 +378,10 @@ me_set_tunnel(struct ifnet *ifp, struct sockaddr_in *src, if (sc->me_ecookie == NULL) sc->me_ecookie = encap_attach_func(AF_INET, IPPROTO_MOBILE, me_encapcheck, &in_mobile_protosw, sc); - if (sc->me_ecookie != NULL) + if (sc->me_ecookie != NULL) { ifp->if_drv_flags |= IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_UP); + } return (0); } @@ -395,6 +399,7 @@ me_delete_tunnel(struct ifnet *ifp) sc->me_dst.s_addr = 0; ME_WUNLOCK(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } static uint16_t diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c index d338506..6e55847 100644 --- a/sys/net80211/ieee80211_crypto.c +++ b/sys/net80211/ieee80211_crypto.c @@ -89,8 +89,7 @@ null_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) return 1; } static int -null_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, - const uint8_t mac[IEEE80211_ADDR_LEN]) +null_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) { return 1; } @@ -132,7 +131,7 @@ dev_key_delete(struct ieee80211vap *vap, static __inline int dev_key_set(struct ieee80211vap *vap, const struct ieee80211_key *key) { - return vap->iv_key_set(vap, key, key->wk_macaddr); + return vap->iv_key_set(vap, key); } /* @@ -521,17 +520,21 @@ ieee80211_crypto_setkey(struct ieee80211vap *vap, struct ieee80211_key *key) return dev_key_set(vap, key); } -/* - * Add privacy headers appropriate for the specified key. - */ +uint8_t +ieee80211_crypto_get_keyid(struct ieee80211vap *vap, struct ieee80211_key *k) +{ + if (k >= &vap->iv_nw_keys[0] && + k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) + return (k - vap->iv_nw_keys); + else + return (0); +} + struct ieee80211_key * -ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m) +ieee80211_crypto_get_txkey(struct ieee80211_node *ni, struct mbuf *m) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_key *k; struct ieee80211_frame *wh; - const struct ieee80211_cipher *cip; - uint8_t keyid; /* * Multicast traffic always uses the multicast key. @@ -550,14 +553,27 @@ ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m) vap->iv_stats.is_tx_nodefkey++; return NULL; } - keyid = vap->iv_def_txkey; - k = &vap->iv_nw_keys[vap->iv_def_txkey]; - } else { - keyid = 0; - k = &ni->ni_ucastkey; + return &vap->iv_nw_keys[vap->iv_def_txkey]; } - cip = k->wk_cipher; - return (cip->ic_encap(k, m, keyid<<6) ? k : NULL); + + return &ni->ni_ucastkey; +} + +/* + * Add privacy headers appropriate for the specified key. + */ +struct ieee80211_key * +ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m) +{ + struct ieee80211_key *k; + const struct ieee80211_cipher *cip; + + if ((k = ieee80211_crypto_get_txkey(ni, m)) != NULL) { + cip = k->wk_cipher; + return (cip->ic_encap(k, m) ? k : NULL); + } + + return NULL; } /* diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h index d7ac436..cca166d 100644 --- a/sys/net80211/ieee80211_crypto.h +++ b/sys/net80211/ieee80211_crypto.h @@ -178,8 +178,8 @@ struct ieee80211_cipher { void* (*ic_attach)(struct ieee80211vap *, struct ieee80211_key *); void (*ic_detach)(struct ieee80211_key *); int (*ic_setkey)(struct ieee80211_key *); - int (*ic_encap)(struct ieee80211_key *, struct mbuf *, - uint8_t keyid); + void (*ic_setiv)(struct ieee80211_key *, uint8_t *); + int (*ic_encap)(struct ieee80211_key *, struct mbuf *); int (*ic_decap)(struct ieee80211_key *, struct mbuf *, int); int (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int); int (*ic_demic)(struct ieee80211_key *, struct mbuf *, int); @@ -193,6 +193,10 @@ void ieee80211_crypto_register(const struct ieee80211_cipher *); void ieee80211_crypto_unregister(const struct ieee80211_cipher *); int ieee80211_crypto_available(u_int cipher); +uint8_t ieee80211_crypto_get_keyid(struct ieee80211vap *vap, + struct ieee80211_key *k); +struct ieee80211_key *ieee80211_crypto_get_txkey(struct ieee80211_node *, + struct mbuf *); struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *, struct mbuf *); struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *, diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c index 485a9cd..9fdd5e0 100644 --- a/sys/net80211/ieee80211_crypto_ccmp.c +++ b/sys/net80211/ieee80211_crypto_ccmp.c @@ -63,7 +63,8 @@ struct ccmp_ctx { static void *ccmp_attach(struct ieee80211vap *, struct ieee80211_key *); static void ccmp_detach(struct ieee80211_key *); static int ccmp_setkey(struct ieee80211_key *); -static int ccmp_encap(struct ieee80211_key *k, struct mbuf *, uint8_t keyid); +static void ccmp_setiv(struct ieee80211_key *, uint8_t *); +static int ccmp_encap(struct ieee80211_key *, struct mbuf *); static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int); static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int); static int ccmp_demic(struct ieee80211_key *, struct mbuf *, int); @@ -78,6 +79,7 @@ static const struct ieee80211_cipher ccmp = { .ic_attach = ccmp_attach, .ic_detach = ccmp_detach, .ic_setkey = ccmp_setkey, + .ic_setiv = ccmp_setiv, .ic_encap = ccmp_encap, .ic_decap = ccmp_decap, .ic_enmic = ccmp_enmic, @@ -134,11 +136,31 @@ ccmp_setkey(struct ieee80211_key *k) return 1; } +static void +ccmp_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ + struct ccmp_ctx *ctx = k->wk_private; + struct ieee80211vap *vap = ctx->cc_vap; + uint8_t keyid; + + keyid = ieee80211_crypto_get_keyid(vap, k) << 6; + + k->wk_keytsc++; + ivp[0] = k->wk_keytsc >> 0; /* PN0 */ + ivp[1] = k->wk_keytsc >> 8; /* PN1 */ + ivp[2] = 0; /* Reserved */ + ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ + ivp[4] = k->wk_keytsc >> 16; /* PN2 */ + ivp[5] = k->wk_keytsc >> 24; /* PN3 */ + ivp[6] = k->wk_keytsc >> 32; /* PN4 */ + ivp[7] = k->wk_keytsc >> 40; /* PN5 */ +} + /* * Add privacy headers appropriate for the specified key. */ static int -ccmp_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) +ccmp_encap(struct ieee80211_key *k, struct mbuf *m) { struct ccmp_ctx *ctx = k->wk_private; struct ieee80211com *ic = ctx->cc_ic; @@ -157,15 +179,7 @@ ccmp_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen); ivp += hdrlen; - k->wk_keytsc++; /* XXX wrap at 48 bits */ - ivp[0] = k->wk_keytsc >> 0; /* PN0 */ - ivp[1] = k->wk_keytsc >> 8; /* PN1 */ - ivp[2] = 0; /* Reserved */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* PN2 */ - ivp[5] = k->wk_keytsc >> 24; /* PN3 */ - ivp[6] = k->wk_keytsc >> 32; /* PN4 */ - ivp[7] = k->wk_keytsc >> 40; /* PN5 */ + ccmp_setiv(k, ivp); /* * Finally, do software encrypt if needed. diff --git a/sys/net80211/ieee80211_crypto_none.c b/sys/net80211/ieee80211_crypto_none.c index b1ffbb4..30f2fc3 100644 --- a/sys/net80211/ieee80211_crypto_none.c +++ b/sys/net80211/ieee80211_crypto_none.c @@ -48,7 +48,8 @@ __FBSDID("$FreeBSD$"); static void *none_attach(struct ieee80211vap *, struct ieee80211_key *); static void none_detach(struct ieee80211_key *); static int none_setkey(struct ieee80211_key *); -static int none_encap(struct ieee80211_key *, struct mbuf *, uint8_t); +static void none_setiv(struct ieee80211_key *, uint8_t *); +static int none_encap(struct ieee80211_key *, struct mbuf *); static int none_decap(struct ieee80211_key *, struct mbuf *, int); static int none_enmic(struct ieee80211_key *, struct mbuf *, int); static int none_demic(struct ieee80211_key *, struct mbuf *, int); @@ -62,6 +63,7 @@ const struct ieee80211_cipher ieee80211_cipher_none = { .ic_attach = none_attach, .ic_detach = none_detach, .ic_setkey = none_setkey, + .ic_setiv = none_setiv, .ic_encap = none_encap, .ic_decap = none_decap, .ic_enmic = none_enmic, @@ -87,20 +89,28 @@ none_setkey(struct ieee80211_key *k) return 1; } +static void +none_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ +} + static int -none_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) +none_encap(struct ieee80211_key *k, struct mbuf *m) { struct ieee80211vap *vap = k->wk_private; #ifdef IEEE80211_DEBUG struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); #endif + uint8_t keyid; + + keyid = ieee80211_crypto_get_keyid(vap, k); /* * The specified key is not setup; this can * happen, at least, when changing keys. */ IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr1, - "key id %u is not set (encap)", keyid>>6); + "key id %u is not set (encap)", keyid); vap->iv_stats.is_tx_badcipher++; return 0; } diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c index 16673de..8b33a79 100644 --- a/sys/net80211/ieee80211_crypto_tkip.c +++ b/sys/net80211/ieee80211_crypto_tkip.c @@ -54,7 +54,8 @@ __FBSDID("$FreeBSD$"); static void *tkip_attach(struct ieee80211vap *, struct ieee80211_key *); static void tkip_detach(struct ieee80211_key *); static int tkip_setkey(struct ieee80211_key *); -static int tkip_encap(struct ieee80211_key *, struct mbuf *m, uint8_t keyid); +static void tkip_setiv(struct ieee80211_key *, uint8_t *); +static int tkip_encap(struct ieee80211_key *, struct mbuf *); static int tkip_enmic(struct ieee80211_key *, struct mbuf *, int); static int tkip_decap(struct ieee80211_key *, struct mbuf *, int); static int tkip_demic(struct ieee80211_key *, struct mbuf *, int); @@ -69,6 +70,7 @@ static const struct ieee80211_cipher tkip = { .ic_attach = tkip_attach, .ic_detach = tkip_detach, .ic_setkey = tkip_setkey, + .ic_setiv = tkip_setiv, .ic_encap = tkip_encap, .ic_decap = tkip_decap, .ic_enmic = tkip_enmic, @@ -84,7 +86,6 @@ struct tkip_ctx { struct ieee80211vap *tc_vap; /* for diagnostics+statistics */ u16 tx_ttak[5]; - int tx_phase1_done; u8 tx_rc4key[16]; /* XXX for test module; make locals? */ u16 rx_ttak[5]; @@ -143,16 +144,35 @@ tkip_setkey(struct ieee80211_key *k) __func__, k->wk_keylen, 128/NBBY); return 0; } - k->wk_keytsc = 1; /* TSC starts at 1 */ ctx->rx_phase1_done = 0; return 1; } +static void +tkip_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ + struct tkip_ctx *ctx = k->wk_private; + struct ieee80211vap *vap = ctx->tc_vap; + uint8_t keyid; + + keyid = ieee80211_crypto_get_keyid(vap, k) << 6; + + k->wk_keytsc++; + ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ + ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ + ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ + ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ + ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ + ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ + ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ + ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ +} + /* * Add privacy headers and do any s/w encryption required. */ static int -tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) +tkip_encap(struct ieee80211_key *k, struct mbuf *m) { struct tkip_ctx *ctx = k->wk_private; struct ieee80211vap *vap = ctx->tc_vap; @@ -185,24 +205,14 @@ tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) memmove(ivp, ivp + tkip.ic_header, hdrlen); ivp += hdrlen; - ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ - ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ - ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ - ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ - ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ - ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ + tkip_setiv(k, ivp); /* * Finally, do software encrypt if needed. */ - if (k->wk_flags & IEEE80211_KEY_SWENCRYPT) { - if (!tkip_encrypt(ctx, k, m, hdrlen)) - return 0; - /* NB: tkip_encrypt handles wk_keytsc */ - } else - k->wk_keytsc++; + if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) && + !tkip_encrypt(ctx, k, m, hdrlen)) + return 0; return 1; } @@ -931,10 +941,9 @@ tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key, ctx->tc_vap->iv_stats.is_crypto_tkip++; wh = mtod(m, struct ieee80211_frame *); - if (!ctx->tx_phase1_done) { + if ((u16)(key->wk_keytsc) == 0 || key->wk_keytsc == 1) { tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2, (u32)(key->wk_keytsc >> 16)); - ctx->tx_phase1_done = 1; } tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak, (u16) key->wk_keytsc); @@ -945,9 +954,6 @@ tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key, icv); (void) m_append(m, IEEE80211_WEP_CRCLEN, icv); /* XXX check return */ - key->wk_keytsc++; - if ((u16)(key->wk_keytsc) == 0) - ctx->tx_phase1_done = 0; return 1; } diff --git a/sys/net80211/ieee80211_crypto_wep.c b/sys/net80211/ieee80211_crypto_wep.c index 2e84dd0..dbcf765 100644 --- a/sys/net80211/ieee80211_crypto_wep.c +++ b/sys/net80211/ieee80211_crypto_wep.c @@ -50,8 +50,9 @@ __FBSDID("$FreeBSD$"); static void *wep_attach(struct ieee80211vap *, struct ieee80211_key *); static void wep_detach(struct ieee80211_key *); static int wep_setkey(struct ieee80211_key *); -static int wep_encap(struct ieee80211_key *, struct mbuf *, uint8_t keyid); -static int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen); +static void wep_setiv(struct ieee80211_key *, uint8_t *); +static int wep_encap(struct ieee80211_key *, struct mbuf *); +static int wep_decap(struct ieee80211_key *, struct mbuf *, int); static int wep_enmic(struct ieee80211_key *, struct mbuf *, int); static int wep_demic(struct ieee80211_key *, struct mbuf *, int); @@ -64,6 +65,7 @@ static const struct ieee80211_cipher wep = { .ic_attach = wep_attach, .ic_detach = wep_detach, .ic_setkey = wep_setkey, + .ic_setiv = wep_setiv, .ic_encap = wep_encap, .ic_decap = wep_decap, .ic_enmic = wep_enmic, @@ -117,29 +119,15 @@ wep_setkey(struct ieee80211_key *k) return k->wk_keylen >= 40/NBBY; } -/* - * Add privacy headers appropriate for the specified key. - */ -static int -wep_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) +static void +wep_setiv(struct ieee80211_key *k, uint8_t *ivp) { struct wep_ctx *ctx = k->wk_private; - struct ieee80211com *ic = ctx->wc_ic; + struct ieee80211vap *vap = ctx->wc_vap; uint32_t iv; - uint8_t *ivp; - int hdrlen; - - hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); + uint8_t keyid; - /* - * Copy down 802.11 header and add the IV + KeyID. - */ - M_PREPEND(m, wep.ic_header, M_NOWAIT); - if (m == NULL) - return 0; - ivp = mtod(m, uint8_t *); - ovbcopy(ivp + wep.ic_header, ivp, hdrlen); - ivp += hdrlen; + keyid = ieee80211_crypto_get_keyid(vap, k) << 6; /* * XXX @@ -182,6 +170,32 @@ wep_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid) ivp[0] = iv >> 16; #endif ivp[3] = keyid; +} + +/* + * Add privacy headers appropriate for the specified key. + */ +static int +wep_encap(struct ieee80211_key *k, struct mbuf *m) +{ + struct wep_ctx *ctx = k->wk_private; + struct ieee80211com *ic = ctx->wc_ic; + uint8_t *ivp; + int hdrlen; + + hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); + + /* + * Copy down 802.11 header and add the IV + KeyID. + */ + M_PREPEND(m, wep.ic_header, M_NOWAIT); + if (m == NULL) + return 0; + ivp = mtod(m, uint8_t *); + ovbcopy(ivp + wep.ic_header, ivp, hdrlen); + ivp += hdrlen; + + wep_setiv(k, ivp); /* * Finally, do software encrypt if needed. diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 1c7ddb9..6388dac 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -957,7 +957,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ + case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only) */ error = ieee80211_ioctl_getwmeparam(vap, ireq); break; case IEEE80211_IOC_DTIM_PERIOD: @@ -1757,13 +1757,14 @@ ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) struct ieee80211com *ic = vap->iv_ic; struct ieee80211_wme_state *wme = &ic->ic_wme; struct wmeParams *wmep, *chanp; - int isbss, ac; + int isbss, ac, aggrmode; if ((ic->ic_caps & IEEE80211_C_WME) == 0) return EOPNOTSUPP; isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); + aggrmode = (wme->wme_flags & WME_F_AGGRMODE); if (ac >= WME_NUM_AC) ac = WME_AC_BE; if (isbss) { @@ -1775,47 +1776,28 @@ ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) } switch (ireq->i_type) { case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ - if (isbss) { - wmep->wmep_logcwmin = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_logcwmin = ireq->i_val; - } else { - wmep->wmep_logcwmin = chanp->wmep_logcwmin = - ireq->i_val; - } + wmep->wmep_logcwmin = ireq->i_val; + if (!isbss || !aggrmode) + chanp->wmep_logcwmin = ireq->i_val; break; case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ - if (isbss) { - wmep->wmep_logcwmax = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_logcwmax = ireq->i_val; - } else { - wmep->wmep_logcwmax = chanp->wmep_logcwmax = - ireq->i_val; - } + wmep->wmep_logcwmax = ireq->i_val; + if (!isbss || !aggrmode) + chanp->wmep_logcwmax = ireq->i_val; break; case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ - if (isbss) { - wmep->wmep_aifsn = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_aifsn = ireq->i_val; - } else { - wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; - } + wmep->wmep_aifsn = ireq->i_val; + if (!isbss || !aggrmode) + chanp->wmep_aifsn = ireq->i_val; break; case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ - if (isbss) { - wmep->wmep_txopLimit = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) - chanp->wmep_txopLimit = ireq->i_val; - } else { - wmep->wmep_txopLimit = chanp->wmep_txopLimit = - ireq->i_val; - } + wmep->wmep_txopLimit = ireq->i_val; + if (!isbss || !aggrmode) + chanp->wmep_txopLimit = ireq->i_val; break; case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ wmep->wmep_acm = ireq->i_val; - if ((wme->wme_flags & WME_F_AGGRMODE) == 0) + if (!aggrmode) chanp->wmep_acm = ireq->i_val; break; case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ @@ -2945,7 +2927,7 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ - case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ + case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only) */ error = ieee80211_ioctl_setwmeparam(vap, ireq); break; case IEEE80211_IOC_DTIM_PERIOD: diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 27fe929..19af613 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -2860,9 +2860,10 @@ ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status) static void ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm, - struct ieee80211_beacon_offsets *bo, struct ieee80211_node *ni) + struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_rateset *rs = &ni->ni_rates; uint16_t capinfo; @@ -3021,8 +3022,7 @@ ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm, * Allocate a beacon frame and fillin the appropriate bits. */ struct mbuf * -ieee80211_beacon_alloc(struct ieee80211_node *ni, - struct ieee80211_beacon_offsets *bo) +ieee80211_beacon_alloc(struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -3104,7 +3104,7 @@ ieee80211_beacon_alloc(struct ieee80211_node *ni, vap->iv_stats.is_tx_nobuf++; return NULL; } - ieee80211_beacon_construct(m, frm, bo, ni); + ieee80211_beacon_construct(m, frm, ni); M_PREPEND(m, sizeof(struct ieee80211_frame), M_NOWAIT); KASSERT(m != NULL, ("no space for 802.11 header?")); @@ -3125,10 +3125,10 @@ ieee80211_beacon_alloc(struct ieee80211_node *ni, * Update the dynamic parts of a beacon frame based on the current state. */ int -ieee80211_beacon_update(struct ieee80211_node *ni, - struct ieee80211_beacon_offsets *bo, struct mbuf *m, int mcast) +ieee80211_beacon_update(struct ieee80211_node *ni, struct mbuf *m, int mcast) { struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; struct ieee80211com *ic = ni->ni_ic; int len_changed = 0; uint16_t capinfo; @@ -3158,7 +3158,7 @@ ieee80211_beacon_update(struct ieee80211_node *ni, * clear IEEE80211_BEACON_CSA. */ ieee80211_beacon_construct(m, - mtod(m, uint8_t*) + sizeof(struct ieee80211_frame), bo, ni); + mtod(m, uint8_t*) + sizeof(struct ieee80211_frame), ni); /* XXX do WME aggressive mode processing? */ IEEE80211_UNLOCK(ic); diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 273e759..4305863 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -346,8 +346,7 @@ struct ieee80211_beacon_offsets { uint8_t *bo_meshconf; /* start of MESHCONF element */ uint8_t *bo_spare[3]; }; -struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *, - struct ieee80211_beacon_offsets *); +struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *); /* * Beacon frame updates are signaled through calls to iv_update_beacon @@ -375,7 +374,7 @@ enum { IEEE80211_BEACON_MESHCONF = 11, /* Mesh Configuration */ }; int ieee80211_beacon_update(struct ieee80211_node *, - struct ieee80211_beacon_offsets *, struct mbuf *, int mcast); + struct mbuf *, int mcast); void ieee80211_csa_startswitch(struct ieee80211com *, struct ieee80211_channel *, int mode, int count); diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 17f37d3..5c5b1c9 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -461,8 +461,7 @@ struct ieee80211vap { int (*iv_key_delete)(struct ieee80211vap *, const struct ieee80211_key *); int (*iv_key_set)(struct ieee80211vap *, - const struct ieee80211_key *, - const uint8_t mac[IEEE80211_ADDR_LEN]); + const struct ieee80211_key *); void (*iv_key_update_begin)(struct ieee80211vap *); void (*iv_key_update_end)(struct ieee80211vap *); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 4098ffb..23e7a9b 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -134,6 +134,7 @@ static int regen_tmpaddr(struct in6_ifaddr *); static void nd6_free(struct llentry *, int); static void nd6_free_redirect(const struct llentry *); static void nd6_llinfo_timer(void *); +static void nd6_llinfo_settimer_locked(struct llentry *, long); static void clear_llinfo_pqueue(struct llentry *); static void nd6_rtrequest(int, struct rtentry *, struct rt_addrinfo *); static int nd6_resolve_slow(struct ifnet *, struct mbuf *, @@ -483,7 +484,7 @@ skip1: /* * ND6 timer routine to handle ND6 entries */ -void +static void nd6_llinfo_settimer_locked(struct llentry *ln, long tick) { int canceled; @@ -512,12 +513,13 @@ nd6_llinfo_settimer_locked(struct llentry *ln, long tick) } /* -* Gets source address of the first packet in hold queue -* and stores it in @src. -* Returns pointer to @src (if hold queue is not empty) or NULL. -* -*/ -static struct in6_addr * + * Gets source address of the first packet in hold queue + * and stores it in @src. + * Returns pointer to @src (if hold queue is not empty) or NULL. + * + * Set noinline to be dtrace-friendly + */ +static __noinline struct in6_addr * nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src) { struct ip6_hdr hdr; @@ -530,7 +532,7 @@ nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src) * assume every packet in la_hold has the same IP header */ m = ln->la_hold; - if (sizeof(hdr) < m->m_len) + if (sizeof(hdr) > m->m_len) return (NULL); m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr); @@ -541,8 +543,10 @@ nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src) /* * Switch @lle state to new state optionally arming timers. + * + * Set noinline to be dtrace-friendly */ -void +__noinline void nd6_llinfo_setstate(struct llentry *lle, int newstate) { struct ifnet *ifp; @@ -576,17 +580,12 @@ nd6_llinfo_setstate(struct llentry *lle, int newstate) lle->ln_state = newstate; } - -void -nd6_llinfo_settimer(struct llentry *ln, long tick) -{ - - LLE_WLOCK(ln); - nd6_llinfo_settimer_locked(ln, tick); - LLE_WUNLOCK(ln); -} - -static void +/* + * Timer-dependent part of nd state machine. + * + * Set noinline to be dtrace-friendly + */ +static __noinline void nd6_llinfo_timer(void *arg) { struct llentry *ln; @@ -810,8 +809,31 @@ nd6_timer(void *arg) goto addrloop; } } + } else if ((ia6->ia6_flags & IN6_IFF_TENTATIVE) != 0) { + /* + * Schedule DAD for a tentative address. This happens + * if the interface was down or not running + * when the address was configured. + */ + int delay; + + delay = arc4random() % + (MAX_RTR_SOLICITATION_DELAY * hz); + nd6_dad_start((struct ifaddr *)ia6, delay); } else { /* + * Check status of the interface. If it is down, + * mark the address as tentative for future DAD. + */ + if ((ia6->ia_ifp->if_flags & IFF_UP) == 0 || + (ia6->ia_ifp->if_drv_flags & IFF_DRV_RUNNING) + == 0 || + (ND_IFINFO(ia6->ia_ifp)->flags & + ND6_IFF_IFDISABLED) != 0) { + ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; + ia6->ia6_flags |= IN6_IFF_TENTATIVE; + } + /* * A new RA might have made a deprecated address * preferred. */ @@ -1156,8 +1178,10 @@ nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) * Since the function would cause significant changes in the kernel, DO NOT * make it global, unless you have a strong reason for the change, and are sure * that the change is safe. + * + * Set noinline to be dtrace-friendly */ -static void +static __noinline void nd6_free(struct llentry *ln, int gc) { struct nd_defrouter *dr; @@ -1452,7 +1476,8 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) /* Mark all IPv6 address as tentative. */ ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; - if ((ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) { + if (V_ip6_dad_count > 0 && + (ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) { IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1725,9 +1750,12 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, lltable_link_entry(LLTABLE6(ifp), ln); IF_AFDATA_WUNLOCK(ifp); if (ln_tmp == NULL) { - /* No existing lle, mark as new entry */ + /* No existing lle, mark as new entry (6,7) */ is_newentry = 1; nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); + if (lladdr != NULL) /* (7) */ + EVENTHANDLER_INVOKE(lle_event, ln, + LLENTRY_RESOLVED); } else { lltable_free_entry(LLTABLE6(ifp), ln); ln = ln_tmp; @@ -1764,10 +1792,9 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, */ do_update = 0; - if (!is_newentry && llchange != 0) + if (is_newentry == 0 && llchange != 0) { do_update = 1; /* (3,5) */ - if (lladdr) { /* (3-5) and (7) */ /* * Record source link-layer address * XXX is it dependent to ifp->if_type? @@ -1778,10 +1805,8 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); - if (do_update) { - if (ln->la_hold != NULL) - nd6_grab_holdchain(ln, &chain, &sin6); - } + if (ln->la_hold != NULL) + nd6_grab_holdchain(ln, &chain, &sin6); } /* Calculates new router status */ @@ -2011,8 +2036,10 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m, * Heavy version. * Function assume that destination LLE does not exist, * is invalid or stale, so LLE_EXCLUSIVE lock needs to be acquired. + * + * Set noinline to be dtrace-friendly */ -static int +static __noinline int nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m, const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags) { diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index c5f0eea..4c39a09 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -408,8 +408,6 @@ struct llentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *); struct llentry *nd6_alloc(const struct in6_addr *, int, struct ifnet *); void nd6_setmtu(struct ifnet *); void nd6_llinfo_setstate(struct llentry *lle, int newstate); -void nd6_llinfo_settimer(struct llentry *, long); -void nd6_llinfo_settimer_locked(struct llentry *, long); void nd6_timer(void *); void nd6_purge(struct ifnet *); int nd6_resolve(struct ifnet *, int, struct mbuf *, diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 7c3c87c..199dbee 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -85,11 +85,11 @@ static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *); static void nd6_dad_add(struct dadq *dp); static void nd6_dad_del(struct dadq *dp); static void nd6_dad_rele(struct dadq *); -static void nd6_dad_starttimer(struct dadq *, int); +static void nd6_dad_starttimer(struct dadq *, int, int); static void nd6_dad_stoptimer(struct dadq *); static void nd6_dad_timer(struct dadq *); static void nd6_dad_duplicated(struct ifaddr *, struct dadq *); -static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); +static void nd6_dad_ns_output(struct dadq *); static void nd6_dad_ns_input(struct ifaddr *, struct nd_opt_nonce *); static void nd6_dad_na_input(struct ifaddr *); static void nd6_na_output_fib(struct ifnet *, const struct in6_addr *, @@ -1199,9 +1199,11 @@ nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *n) } static void -nd6_dad_starttimer(struct dadq *dp, int ticks) +nd6_dad_starttimer(struct dadq *dp, int ticks, int send_ns) { + if (send_ns != 0) + nd6_dad_ns_output(dp); callout_reset(&dp->dad_timer_ch, ticks, (void (*)(void *))nd6_dad_timer, (void *)dp); } @@ -1240,6 +1242,7 @@ nd6_dad_start(struct ifaddr *ifa, int delay) struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; struct dadq *dp; char ip6buf[INET6_ADDRSTRLEN]; + int send_ns; /* * If we don't need DAD, don't do it. @@ -1276,8 +1279,10 @@ nd6_dad_start(struct ifaddr *ifa, int delay) return; } if ((dp = nd6_dad_find(ifa, NULL)) != NULL) { - /* DAD already in progress */ - nd6_dad_rele(dp); + /* + * DAD already in progress. Let the existing entry + * to finish it. + */ return; } @@ -1310,13 +1315,12 @@ nd6_dad_start(struct ifaddr *ifa, int delay) dp->dad_ns_lcount = dp->dad_loopbackprobe = 0; refcount_init(&dp->dad_refcnt, 1); nd6_dad_add(dp); + send_ns = 0; if (delay == 0) { - nd6_dad_ns_output(dp, ifa); - nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); - } else { - nd6_dad_starttimer(dp, delay); + send_ns = 1; + delay = (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000; } + nd6_dad_starttimer(dp, delay, send_ns); } /* @@ -1386,7 +1390,8 @@ nd6_dad_timer(struct dadq *dp) if ((dp->dad_ns_tcount > V_dad_maxtry) && (((ifp->if_flags & IFF_UP) == 0) || ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))) { - nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", + nd6log((LOG_INFO, "%s: could not run DAD " + "because the interface was down or not running.\n", if_name(ifa->ifa_ifp))); goto err; } @@ -1396,9 +1401,8 @@ nd6_dad_timer(struct dadq *dp) /* * We have more NS to go. Send NS packet for DAD. */ - nd6_dad_ns_output(dp, ifa); nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000, 1); goto done; } else { /* @@ -1426,11 +1430,11 @@ nd6_dad_timer(struct dadq *dp) * Send an NS immediately and increase dad_count by * V_nd6_mmaxtries - 1. */ - nd6_dad_ns_output(dp, ifa); dp->dad_count = dp->dad_ns_ocount + V_nd6_mmaxtries - 1; nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000, + 1); goto done; } else { /* @@ -1517,10 +1521,10 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) } static void -nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) +nd6_dad_ns_output(struct dadq *dp) { - struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; - struct ifnet *ifp = ifa->ifa_ifp; + struct in6_ifaddr *ia = (struct in6_ifaddr *)dp->dad_ifa; + struct ifnet *ifp = dp->dad_ifa->ifa_ifp; int i; dp->dad_ns_tcount++; diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c index 107c4b8..7ed4c1d 100644 --- a/sys/netpfil/ipfw/ip_fw_sockopt.c +++ b/sys/netpfil/ipfw/ip_fw_sockopt.c @@ -1531,7 +1531,7 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci) case O_IP_SRC_MASK: case O_IP_DST_MASK: /* only odd command lengths */ - if ( !(cmdlen & 1) || cmdlen > 31) + if ((cmdlen & 1) == 0) goto bad_size; break; diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index a3a9a10..8492f2e 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -149,6 +149,8 @@ static int sysctl_vm_page_blacklist(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_vm, OID_AUTO, page_blacklist, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_page_blacklist, "A", "Blacklist pages"); +/* Is the page daemon waiting for free pages? */ +static int vm_pageout_pages_needed; static uma_zone_t fakepg_zone; diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 0a18e6d..e0d00f5 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -157,7 +157,6 @@ SYSINIT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, &vm_kp); int vm_pages_needed; /* Event on which pageout daemon sleeps */ int vm_pageout_deficit; /* Estimated number of pages deficit */ -int vm_pageout_pages_needed; /* flag saying that the pageout daemon needs pages */ int vm_pageout_wakeup_thresh; #if !defined(NO_SWAPPING) diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h index c7b4e90..9c8da8b 100644 --- a/sys/vm/vm_pageout.h +++ b/sys/vm/vm_pageout.h @@ -73,7 +73,6 @@ extern int vm_page_max_wired; extern int vm_pages_needed; /* should be some "event" structure */ -extern int vm_pageout_pages_needed; extern int vm_pageout_deficit; extern int vm_pageout_page_count; diff --git a/targets/pseudo/userland/games/Makefile.depend b/targets/pseudo/userland/games/Makefile.depend index a9ac340..151a368 100644 --- a/targets/pseudo/userland/games/Makefile.depend +++ b/targets/pseudo/userland/games/Makefile.depend @@ -3,20 +3,18 @@ # This file is not autogenerated - take care! DIRDEPS = \ - games/bcd \ - games/caesar \ - games/factor \ - games/fortune/fortune \ - games/fortune/strfile \ - games/fortune/datfiles \ - games/fortune/unstr \ - games/grdc \ - games/morse \ - games/number \ - games/pom \ - games/ppt \ - games/primes \ - games/random \ + usr.bin/caesar \ + usr.bin/factor \ + usr.bin/fortune/fortune \ + usr.bin/fortune/strfile \ + usr.bin/fortune/datfiles \ + usr.bin/fortune/unstr \ + usr.bin/grdc \ + usr.bin/morse \ + usr.bin/number \ + usr.bin/pom \ + usr.bin/primes \ + usr.bin/random \ .include <dirdeps.mk> diff --git a/usr.bin/Makefile b/usr.bin/Makefile index faabe67..03f8864 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -230,6 +230,18 @@ SUBDIR+= finger SUBDIR+= ftp .endif +.if ${MK_GAMES} != "no" +SUBDIR+= caesar +SUBDIR+= factor +SUBDIR+= fortune +SUBDIR+= grdc +SUBDIR+= morse +SUBDIR+= number +SUBDIR+= pom +SUBDIR+= primes +SUBDIR+= random +.endif + .if ${MK_GPL_DTC} != "yes" SUBDIR+= dtc .endif @@ -254,10 +266,8 @@ SUBDIR+= iscsictl .if ${MK_KDUMP} != "no" SUBDIR+= kdump -.if ${MACHINE_ARCH} != "aarch64" # ARM64TODO truss does not build SUBDIR+= truss .endif -.endif .if ${MK_KERBEROS_SUPPORT} != "no" SUBDIR+= compile_et diff --git a/games/caesar/Makefile b/usr.bin/caesar/Makefile index 88b79ee..88b79ee 100644 --- a/games/caesar/Makefile +++ b/usr.bin/caesar/Makefile diff --git a/games/caesar/Makefile.depend b/usr.bin/caesar/Makefile.depend index c9f9d52..c9f9d52 100644 --- a/games/caesar/Makefile.depend +++ b/usr.bin/caesar/Makefile.depend diff --git a/games/caesar/caesar.6 b/usr.bin/caesar/caesar.6 index 91e9af8..91e9af8 100644 --- a/games/caesar/caesar.6 +++ b/usr.bin/caesar/caesar.6 diff --git a/games/caesar/caesar.c b/usr.bin/caesar/caesar.c index b1f9920..b1f9920 100644 --- a/games/caesar/caesar.c +++ b/usr.bin/caesar/caesar.c diff --git a/games/caesar/rot13.sh b/usr.bin/caesar/rot13.sh index 7dcef74..7dcef74 100644 --- a/games/caesar/rot13.sh +++ b/usr.bin/caesar/rot13.sh diff --git a/games/factor/Makefile b/usr.bin/factor/Makefile index afc9510..afc9510 100644 --- a/games/factor/Makefile +++ b/usr.bin/factor/Makefile diff --git a/games/factor/Makefile.depend b/usr.bin/factor/Makefile.depend index fc0b633..fc0b633 100644 --- a/games/factor/Makefile.depend +++ b/usr.bin/factor/Makefile.depend diff --git a/games/factor/factor.6 b/usr.bin/factor/factor.6 index ba82f14..ba82f14 100644 --- a/games/factor/factor.6 +++ b/usr.bin/factor/factor.6 diff --git a/games/factor/factor.c b/usr.bin/factor/factor.c index 19fe830..19fe830 100644 --- a/games/factor/factor.c +++ b/usr.bin/factor/factor.c diff --git a/games/fortune/Makefile b/usr.bin/fortune/Makefile index b8b4ff1..b8b4ff1 100644 --- a/games/fortune/Makefile +++ b/usr.bin/fortune/Makefile diff --git a/games/fortune/Makefile.inc b/usr.bin/fortune/Makefile.inc index 63751fb..63751fb 100644 --- a/games/fortune/Makefile.inc +++ b/usr.bin/fortune/Makefile.inc diff --git a/games/fortune/Notes b/usr.bin/fortune/Notes index f049391..f049391 100644 --- a/games/fortune/Notes +++ b/usr.bin/fortune/Notes diff --git a/games/fortune/README b/usr.bin/fortune/README index 31b96a2..31b96a2 100644 --- a/games/fortune/README +++ b/usr.bin/fortune/README diff --git a/games/fortune/datfiles/Makefile b/usr.bin/fortune/datfiles/Makefile index 1eabaa4..1eabaa4 100644 --- a/games/fortune/datfiles/Makefile +++ b/usr.bin/fortune/datfiles/Makefile diff --git a/games/fortune/datfiles/Makefile.depend b/usr.bin/fortune/datfiles/Makefile.depend index f80275d..f80275d 100644 --- a/games/fortune/datfiles/Makefile.depend +++ b/usr.bin/fortune/datfiles/Makefile.depend diff --git a/games/fortune/datfiles/fortunes b/usr.bin/fortune/datfiles/fortunes index 1aa54b5..1aa54b5 100644 --- a/games/fortune/datfiles/fortunes +++ b/usr.bin/fortune/datfiles/fortunes diff --git a/games/fortune/datfiles/fortunes.sp.ok b/usr.bin/fortune/datfiles/fortunes.sp.ok index 02229cd..02229cd 100644 --- a/games/fortune/datfiles/fortunes.sp.ok +++ b/usr.bin/fortune/datfiles/fortunes.sp.ok diff --git a/games/fortune/datfiles/freebsd-tips b/usr.bin/fortune/datfiles/freebsd-tips index 9767586..9767586 100644 --- a/games/fortune/datfiles/freebsd-tips +++ b/usr.bin/fortune/datfiles/freebsd-tips diff --git a/games/fortune/datfiles/freebsd-tips.sp.ok b/usr.bin/fortune/datfiles/freebsd-tips.sp.ok index 968f318..968f318 100644 --- a/games/fortune/datfiles/freebsd-tips.sp.ok +++ b/usr.bin/fortune/datfiles/freebsd-tips.sp.ok diff --git a/games/fortune/datfiles/gerrold.limerick b/usr.bin/fortune/datfiles/gerrold.limerick index f0bbce6..f0bbce6 100644 --- a/games/fortune/datfiles/gerrold.limerick +++ b/usr.bin/fortune/datfiles/gerrold.limerick diff --git a/games/fortune/datfiles/limerick b/usr.bin/fortune/datfiles/limerick index 5a92c78..5a92c78 100644 --- a/games/fortune/datfiles/limerick +++ b/usr.bin/fortune/datfiles/limerick diff --git a/games/fortune/datfiles/limerick.sp.ok b/usr.bin/fortune/datfiles/limerick.sp.ok index be7135d..be7135d 100644 --- a/games/fortune/datfiles/limerick.sp.ok +++ b/usr.bin/fortune/datfiles/limerick.sp.ok diff --git a/games/fortune/datfiles/murphy b/usr.bin/fortune/datfiles/murphy index 949d944..949d944 100644 --- a/games/fortune/datfiles/murphy +++ b/usr.bin/fortune/datfiles/murphy diff --git a/games/fortune/datfiles/murphy-o b/usr.bin/fortune/datfiles/murphy-o index 94c9cc2..94c9cc2 100644 --- a/games/fortune/datfiles/murphy-o +++ b/usr.bin/fortune/datfiles/murphy-o diff --git a/games/fortune/datfiles/murphy.sp.ok b/usr.bin/fortune/datfiles/murphy.sp.ok index 0287e6a..0287e6a 100644 --- a/games/fortune/datfiles/murphy.sp.ok +++ b/usr.bin/fortune/datfiles/murphy.sp.ok diff --git a/games/fortune/datfiles/startrek b/usr.bin/fortune/datfiles/startrek index af3f9d4..af3f9d4 100644 --- a/games/fortune/datfiles/startrek +++ b/usr.bin/fortune/datfiles/startrek diff --git a/games/fortune/datfiles/startrek.sp.ok b/usr.bin/fortune/datfiles/startrek.sp.ok index ccca709..ccca709 100644 --- a/games/fortune/datfiles/startrek.sp.ok +++ b/usr.bin/fortune/datfiles/startrek.sp.ok diff --git a/games/fortune/datfiles/zippy b/usr.bin/fortune/datfiles/zippy index 7c43436..7c43436 100644 --- a/games/fortune/datfiles/zippy +++ b/usr.bin/fortune/datfiles/zippy diff --git a/games/fortune/datfiles/zippy.sp.ok b/usr.bin/fortune/datfiles/zippy.sp.ok index b2f3fff..b2f3fff 100644 --- a/games/fortune/datfiles/zippy.sp.ok +++ b/usr.bin/fortune/datfiles/zippy.sp.ok diff --git a/games/fortune/fortune/Makefile b/usr.bin/fortune/fortune/Makefile index c18ead9..c18ead9 100644 --- a/games/fortune/fortune/Makefile +++ b/usr.bin/fortune/fortune/Makefile diff --git a/games/fortune/fortune/Makefile.depend b/usr.bin/fortune/fortune/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/fortune/fortune/Makefile.depend +++ b/usr.bin/fortune/fortune/Makefile.depend diff --git a/games/fortune/fortune/fortune.6 b/usr.bin/fortune/fortune/fortune.6 index d8f6bad..d8f6bad 100644 --- a/games/fortune/fortune/fortune.6 +++ b/usr.bin/fortune/fortune/fortune.6 diff --git a/games/fortune/fortune/fortune.c b/usr.bin/fortune/fortune/fortune.c index 2fb2be0..2fb2be0 100644 --- a/games/fortune/fortune/fortune.c +++ b/usr.bin/fortune/fortune/fortune.c diff --git a/games/fortune/fortune/pathnames.h b/usr.bin/fortune/fortune/pathnames.h index 149b3e8..149b3e8 100644 --- a/games/fortune/fortune/pathnames.h +++ b/usr.bin/fortune/fortune/pathnames.h diff --git a/games/fortune/strfile/Makefile b/usr.bin/fortune/strfile/Makefile index a43e8ea..a43e8ea 100644 --- a/games/fortune/strfile/Makefile +++ b/usr.bin/fortune/strfile/Makefile diff --git a/games/fortune/strfile/Makefile.depend b/usr.bin/fortune/strfile/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/fortune/strfile/Makefile.depend +++ b/usr.bin/fortune/strfile/Makefile.depend diff --git a/games/fortune/strfile/strfile.8 b/usr.bin/fortune/strfile/strfile.8 index 26de0d7..26de0d7 100644 --- a/games/fortune/strfile/strfile.8 +++ b/usr.bin/fortune/strfile/strfile.8 diff --git a/games/fortune/strfile/strfile.c b/usr.bin/fortune/strfile/strfile.c index c88d997..c88d997 100644 --- a/games/fortune/strfile/strfile.c +++ b/usr.bin/fortune/strfile/strfile.c diff --git a/games/fortune/strfile/strfile.h b/usr.bin/fortune/strfile/strfile.h index 5d4f875..5d4f875 100644 --- a/games/fortune/strfile/strfile.h +++ b/usr.bin/fortune/strfile/strfile.h diff --git a/games/fortune/tools/Do_spell b/usr.bin/fortune/tools/Do_spell index d997392..d997392 100644 --- a/games/fortune/tools/Do_spell +++ b/usr.bin/fortune/tools/Do_spell diff --git a/games/fortune/tools/Do_troff b/usr.bin/fortune/tools/Do_troff index 52cb282..52cb282 100644 --- a/games/fortune/tools/Do_troff +++ b/usr.bin/fortune/tools/Do_troff diff --git a/games/fortune/tools/Troff.mac b/usr.bin/fortune/tools/Troff.mac index c2b433e..c2b433e 100644 --- a/games/fortune/tools/Troff.mac +++ b/usr.bin/fortune/tools/Troff.mac diff --git a/games/fortune/tools/Troff.sed b/usr.bin/fortune/tools/Troff.sed index 3216681..3216681 100644 --- a/games/fortune/tools/Troff.sed +++ b/usr.bin/fortune/tools/Troff.sed diff --git a/games/fortune/tools/do_sort b/usr.bin/fortune/tools/do_sort index 07e301b..07e301b 100644 --- a/games/fortune/tools/do_sort +++ b/usr.bin/fortune/tools/do_sort diff --git a/games/fortune/tools/do_uniq.py b/usr.bin/fortune/tools/do_uniq.py index bd62676..bd62676 100644 --- a/games/fortune/tools/do_uniq.py +++ b/usr.bin/fortune/tools/do_uniq.py diff --git a/games/fortune/unstr/Makefile b/usr.bin/fortune/unstr/Makefile index e943d97..e943d97 100644 --- a/games/fortune/unstr/Makefile +++ b/usr.bin/fortune/unstr/Makefile diff --git a/games/fortune/unstr/Makefile.depend b/usr.bin/fortune/unstr/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/fortune/unstr/Makefile.depend +++ b/usr.bin/fortune/unstr/Makefile.depend diff --git a/games/fortune/unstr/unstr.c b/usr.bin/fortune/unstr/unstr.c index f79a0ec..f79a0ec 100644 --- a/games/fortune/unstr/unstr.c +++ b/usr.bin/fortune/unstr/unstr.c diff --git a/games/grdc/Makefile b/usr.bin/grdc/Makefile index 73d395a..73d395a 100644 --- a/games/grdc/Makefile +++ b/usr.bin/grdc/Makefile diff --git a/games/grdc/Makefile.depend b/usr.bin/grdc/Makefile.depend index 59bc828..59bc828 100644 --- a/games/grdc/Makefile.depend +++ b/usr.bin/grdc/Makefile.depend diff --git a/games/grdc/grdc.6 b/usr.bin/grdc/grdc.6 index 5226a6b..5226a6b 100644 --- a/games/grdc/grdc.6 +++ b/usr.bin/grdc/grdc.6 diff --git a/games/grdc/grdc.c b/usr.bin/grdc/grdc.c index 04cc00b..04cc00b 100644 --- a/games/grdc/grdc.c +++ b/usr.bin/grdc/grdc.c diff --git a/games/morse/Makefile b/usr.bin/morse/Makefile index 4435422..4435422 100644 --- a/games/morse/Makefile +++ b/usr.bin/morse/Makefile diff --git a/games/morse/Makefile.depend b/usr.bin/morse/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/morse/Makefile.depend +++ b/usr.bin/morse/Makefile.depend diff --git a/games/morse/morse.6 b/usr.bin/morse/morse.6 index 94645bb..94645bb 100644 --- a/games/morse/morse.6 +++ b/usr.bin/morse/morse.6 diff --git a/games/morse/morse.c b/usr.bin/morse/morse.c index 03a09a6..03a09a6 100644 --- a/games/morse/morse.c +++ b/usr.bin/morse/morse.c diff --git a/games/number/Makefile b/usr.bin/number/Makefile index 8e75f71..8e75f71 100644 --- a/games/number/Makefile +++ b/usr.bin/number/Makefile diff --git a/games/number/Makefile.depend b/usr.bin/number/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/number/Makefile.depend +++ b/usr.bin/number/Makefile.depend diff --git a/games/number/number.6 b/usr.bin/number/number.6 index a8be9ff..a8be9ff 100644 --- a/games/number/number.6 +++ b/usr.bin/number/number.6 diff --git a/games/number/number.c b/usr.bin/number/number.c index e8cf181..e8cf181 100644 --- a/games/number/number.c +++ b/usr.bin/number/number.c diff --git a/games/pom/Makefile b/usr.bin/pom/Makefile index 9a74204..9a74204 100644 --- a/games/pom/Makefile +++ b/usr.bin/pom/Makefile diff --git a/games/pom/Makefile.depend b/usr.bin/pom/Makefile.depend index c9f9d52..c9f9d52 100644 --- a/games/pom/Makefile.depend +++ b/usr.bin/pom/Makefile.depend diff --git a/games/pom/pom.6 b/usr.bin/pom/pom.6 index a38a920..a38a920 100644 --- a/games/pom/pom.6 +++ b/usr.bin/pom/pom.6 diff --git a/games/pom/pom.c b/usr.bin/pom/pom.c index 5f18bb3..5f18bb3 100644 --- a/games/pom/pom.c +++ b/usr.bin/pom/pom.c diff --git a/games/primes/Makefile b/usr.bin/primes/Makefile index bfc4147..bfc4147 100644 --- a/games/primes/Makefile +++ b/usr.bin/primes/Makefile diff --git a/games/primes/Makefile.depend b/usr.bin/primes/Makefile.depend index c9f9d52..c9f9d52 100644 --- a/games/primes/Makefile.depend +++ b/usr.bin/primes/Makefile.depend diff --git a/games/primes/pattern.c b/usr.bin/primes/pattern.c index 2b30678..2b30678 100644 --- a/games/primes/pattern.c +++ b/usr.bin/primes/pattern.c diff --git a/games/primes/pr_tbl.c b/usr.bin/primes/pr_tbl.c index 5bb7093..5bb7093 100644 --- a/games/primes/pr_tbl.c +++ b/usr.bin/primes/pr_tbl.c diff --git a/games/primes/primes.c b/usr.bin/primes/primes.c index a1c95c2..a1c95c2 100644 --- a/games/primes/primes.c +++ b/usr.bin/primes/primes.c diff --git a/games/primes/primes.h b/usr.bin/primes/primes.h index 3a18fc7..3a18fc7 100644 --- a/games/primes/primes.h +++ b/usr.bin/primes/primes.h diff --git a/games/primes/spsp.c b/usr.bin/primes/spsp.c index f61acd6..f61acd6 100644 --- a/games/primes/spsp.c +++ b/usr.bin/primes/spsp.c diff --git a/games/random/Makefile b/usr.bin/random/Makefile index 9136c98..9136c98 100644 --- a/games/random/Makefile +++ b/usr.bin/random/Makefile diff --git a/games/random/Makefile.depend b/usr.bin/random/Makefile.depend index 3646e2e..3646e2e 100644 --- a/games/random/Makefile.depend +++ b/usr.bin/random/Makefile.depend diff --git a/games/random/random.6 b/usr.bin/random/random.6 index bd38ba6..bd38ba6 100644 --- a/games/random/random.6 +++ b/usr.bin/random/random.6 diff --git a/games/random/random.c b/usr.bin/random/random.c index 99f9d90..99f9d90 100644 --- a/games/random/random.c +++ b/usr.bin/random/random.c diff --git a/games/random/randomize_fd.c b/usr.bin/random/randomize_fd.c index f66b965..f66b965 100644 --- a/games/random/randomize_fd.c +++ b/usr.bin/random/randomize_fd.c diff --git a/games/random/randomize_fd.h b/usr.bin/random/randomize_fd.h index de3f873..de3f873 100644 --- a/games/random/randomize_fd.h +++ b/usr.bin/random/randomize_fd.h diff --git a/usr.bin/truss/Makefile b/usr.bin/truss/Makefile index 34a6ef4..1cd0a9c 100644 --- a/usr.bin/truss/Makefile +++ b/usr.bin/truss/Makefile @@ -58,6 +58,16 @@ fbsd32-syscalls.master: ${.CURDIR}/../../sys/compat/freebsd32/syscalls.master freebsd32_syscalls.h: fbsd32-syscalls.master /bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \ ${.CURDIR}/fbsd32.conf + +SRCS+= amd64-cloudabi64.c cloudabi64_syscalls.h +CLEANFILES+=amd64cloudabi64-syscalls.master cloudabi64_syscalls.h + +amd64cloudabi64-syscalls.master: ${.CURDIR}/../../sys/compat/cloudabi64/syscalls.master + cat ${.ALLSRC} > ${.TARGET} + +cloudabi64_syscalls.h: amd64cloudabi64-syscalls.master + /bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \ + ${.CURDIR}/amd64cloudabi64.conf .endif .if ${MACHINE_ARCH} == "powerpc64" diff --git a/usr.bin/truss/aarch64-fbsd.c b/usr.bin/truss/aarch64-fbsd.c new file mode 100644 index 0000000..85819f6 --- /dev/null +++ b/usr.bin/truss/aarch64-fbsd.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015 The FreeBSD Foundation + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* FreeBSD/arm64-specific system call handling. */ + +#include <sys/ptrace.h> +#include <sys/syscall.h> + +#include <machine/reg.h> +#include <machine/armreg.h> +#include <machine/ucontext.h> + +#include <stdio.h> + +#include "truss.h" + +extern const char *syscallnames[]; /* silence compiler */ +#include "syscalls.h" + +static int +aarch64_fetch_args(struct trussinfo *trussinfo, u_int narg) +{ + struct reg regs; + struct current_syscall *cs; + lwpid_t tid; + u_int i, reg, syscall_num; + + tid = trussinfo->curthread->tid; + cs = &trussinfo->curthread->cs; + if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + /* + * FreeBSD has two special kinds of system call redirections -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + * + * The system call argument count and code from ptrace() already + * account for these, but we need to skip over the first argument. + */ + syscall_num = regs.x[8]; + if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { + reg = 1; + syscall_num = regs.x[0]; + } else { + reg = 0; + } + + for (i = 0; i < narg && reg < 8; i++, reg++) + cs->args[i] = regs.x[reg]; + return (0); +} + +static int +aarch64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) +{ + struct reg regs; + lwpid_t tid; + + tid = trussinfo->curthread->tid; + if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval[0] = regs.x[0]; + retval[1] = regs.x[1]; + *errorp = !!(regs.spsr & PSR_C); + return (0); +} + +static struct procabi aarch64_fbsd = { + "FreeBSD ELF64", + syscallnames, + nitems(syscallnames), + aarch64_fetch_args, + aarch64_fetch_retval +}; + +PROCABI(aarch64_fbsd); diff --git a/usr.bin/truss/amd64-cloudabi64.c b/usr.bin/truss/amd64-cloudabi64.c new file mode 100644 index 0000000..797c62a --- /dev/null +++ b/usr.bin/truss/amd64-cloudabi64.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2015 Nuxi, https://nuxi.nl/ + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/ptrace.h> + +#include <machine/psl.h> + +#include <errno.h> +#include <stdio.h> + +#include "cloudabi64_syscalls.h" +#include "truss.h" + +static int +amd64_cloudabi64_fetch_args(struct trussinfo *trussinfo, unsigned int narg) +{ + struct current_syscall *cs; + struct reg regs; + lwpid_t tid; + + tid = trussinfo->curthread->tid; + if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) == -1) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + cs = &trussinfo->curthread->cs; + if (narg >= 1) + cs->args[0] = regs.r_rdi; + if (narg >= 2) + cs->args[1] = regs.r_rsi; + if (narg >= 3) + cs->args[2] = regs.r_rdx; + if (narg >= 4) + cs->args[3] = regs.r_rcx; + if (narg >= 5) + cs->args[4] = regs.r_r8; + if (narg >= 6) + cs->args[5] = regs.r_r9; + return (0); +} + +static const int cloudabi_errno_table[] = { + 0, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL, EAFNOSUPPORT, + EAGAIN, EALREADY, EBADF, EBADMSG, EBUSY, ECANCELED, ECHILD, + ECONNABORTED, ECONNREFUSED, ECONNRESET, EDEADLK, EDESTADDRREQ, + EDOM, EDQUOT, EEXIST, EFAULT, EFBIG, EHOSTUNREACH, EIDRM, + EILSEQ, EINPROGRESS, EINTR, EINVAL, EIO, EISCONN, EISDIR, ELOOP, + EMFILE, EMLINK, EMSGSIZE, EMULTIHOP, ENAMETOOLONG, ENETDOWN, + ENETRESET, ENETUNREACH, ENFILE, ENOBUFS, ENODEV, ENOENT, + ENOEXEC, ENOLCK, ENOLINK, ENOMEM, ENOMSG, ENOPROTOOPT, ENOSPC, + ENOSYS, ENOTCONN, ENOTDIR, ENOTEMPTY, ENOTRECOVERABLE, ENOTSOCK, + ENOTSUP, ENOTTY, ENXIO, EOVERFLOW, EOWNERDEAD, EPERM, EPIPE, + EPROTO, EPROTONOSUPPORT, EPROTOTYPE, ERANGE, EROFS, ESPIPE, + ESRCH, ESTALE, ETIMEDOUT, ETXTBSY, EXDEV, ENOTCAPABLE, +}; + +static int +amd64_cloudabi64_fetch_retval(struct trussinfo *trussinfo, long *retval, + int *errorp) +{ + struct reg regs; + lwpid_t tid; + + tid = trussinfo->curthread->tid; + if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) == -1) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval[0] = regs.r_rax; + retval[1] = regs.r_rdx; + *errorp = (regs.r_rflags & PSL_C) != 0; + if (*errorp && *retval >= 0 && *retval < nitems(cloudabi_errno_table)) + *retval = cloudabi_errno_table[*retval]; + return (0); +} + +static struct procabi amd64_cloudabi64 = { + "CloudABI ELF64", + cloudabi64_syscallnames, + nitems(cloudabi64_syscallnames), + amd64_cloudabi64_fetch_args, + amd64_cloudabi64_fetch_retval +}; + +PROCABI(amd64_cloudabi64); diff --git a/usr.bin/truss/amd64cloudabi64.conf b/usr.bin/truss/amd64cloudabi64.conf new file mode 100644 index 0000000..e68906e --- /dev/null +++ b/usr.bin/truss/amd64cloudabi64.conf @@ -0,0 +1,13 @@ +# $FreeBSD$ + +sysnames="cloudabi64_syscalls.h" +sysproto="/dev/null" +sysproto_h="/dev/null" +syshdr="/dev/null" +sysmk="/dev/null" +syssw="/dev/null" +syshide="/dev/null" +syscallprefix="SYS_" +switchname="sysent" +namesname="cloudabi64_syscallnames" +systrace="/dev/null" diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index ee35214..18dd33f 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -10,6 +10,7 @@ * BinString -- pointer to an array of chars, printed via strvisx(). * Ptr -- pointer to some unspecified structure. Just print as hex for now. * Stat -- a pointer to a stat buffer. Prints a couple fields. + * StatFs -- a pointer to a statfs buffer. Prints a few fields. * Ioctl -- an ioctl command. Woefully limited. * Quad -- a double-word value. e.g., lseek(int, offset_t, int) * Signal -- a signal number. Prints the signal name (SIGxxx) @@ -38,7 +39,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad, Signal, Sockaddr, StringArray, Timespec, Timeval, Itimerval, Pollfd, Fd_set, Sigaction, Fcntl, Mprot, Mmapflags, Whence, Readlinkres, - Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open, + Sigset, Sigprocmask, StatFs, Kevent, Sockdomain, Socktype, Open, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long, diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index ab163d8..6211bae 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <sys/event.h> #include <sys/ioccom.h> #include <sys/mman.h> +#include <sys/mount.h> #include <sys/procctl.h> #include <sys/ptrace.h> #include <sys/resource.h> @@ -182,6 +183,10 @@ static struct syscall syscalls[] = { { Atflags, 3 } } }, { .name = "stat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, + { .name = "statfs", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { StatFs | OUT, 1 } } }, + { .name = "fstatfs", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { StatFs | OUT, 1 } } }, { .name = "lstat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, { .name = "linux_newstat", .ret_type = 1, .nargs = 2, @@ -1444,6 +1449,30 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval, } break; } + case StatFs: { + unsigned int i; + struct statfs buf; + + if (get_struct(pid, (void *)args[sc->offset], &buf, + sizeof(buf)) != -1) { + char fsid[17]; + + bzero(fsid, sizeof(fsid)); + if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) { + for (i = 0; i < sizeof(buf.f_fsid); i++) + snprintf(&fsid[i*2], + sizeof(fsid) - (i*2), "%02x", + ((u_char *)&buf.f_fsid)[i]); + } + fprintf(fp, + "{ fstypename=%s,mntonname=%s,mntfromname=%s," + "fsid=%s }", buf.f_fstypename, buf.f_mntonname, + buf.f_mntfromname, fsid); + } else + fprintf(fp, "0x%lx", args[sc->offset]); + break; + } + case Rusage: { struct rusage ru; diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index be5cb33..0e1a85e 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -16,6 +16,7 @@ SRCS= \ bootrom.c \ consport.c \ dbgport.c \ + fwctl.c \ inout.c \ ioapic.c \ mem.c \ diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index cfb3fe4..bc49c57 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include "acpi.h" #include "inout.h" #include "dbgport.h" +#include "fwctl.h" #include "ioapic.h" #include "mem.h" #include "mevent.h" @@ -950,6 +951,9 @@ main(int argc, char *argv[]) assert(error == 0); } + if (lpc_bootrom()) + fwctl_init(); + /* * Change the proc title to include the VM name. */ diff --git a/usr.sbin/bhyve/fwctl.c b/usr.sbin/bhyve/fwctl.c new file mode 100644 index 0000000..4b6164b --- /dev/null +++ b/usr.sbin/bhyve/fwctl.c @@ -0,0 +1,549 @@ +/*- + * Copyright (c) 2015 Peter Grehan <grehan@freebsd.org> + * 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. + * + * 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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +/* + * Guest firmware interface. Uses i/o ports x510/x511 as Qemu does, + * but with a request/response messaging protocol. + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/uio.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "bhyverun.h" +#include "inout.h" +#include "fwctl.h" + +/* + * Messaging protocol base operations + */ +#define OP_NULL 1 +#define OP_ECHO 2 +#define OP_GET 3 +#define OP_GET_LEN 4 +#define OP_SET 5 +#define OP_MAX OP_SET + +/* I/O ports */ +#define FWCTL_OUT 0x510 +#define FWCTL_IN 0x511 + +/* + * Back-end state-machine + */ +enum state { + DORMANT, + IDENT_WAIT, + IDENT_SEND, + REQ, + RESP +} be_state = DORMANT; + +static uint8_t sig[] = { 'B', 'H', 'Y', 'V' }; +static u_int ident_idx; + +struct op_info { + int op; + int (*op_start)(int len); + void (*op_data)(uint32_t data, int len); + int (*op_result)(struct iovec **data); + void (*op_done)(struct iovec *data); +}; +static struct op_info *ops[OP_MAX+1]; + +/* Return 0-padded uint32_t */ +static uint32_t +fwctl_send_rest(uint32_t *data, size_t len) +{ + union { + uint8_t c[4]; + uint32_t w; + } u; + uint8_t *cdata; + int i; + + cdata = (uint8_t *) data; + u.w = 0; + + for (i = 0, u.w = 0; i < len; i++) + u.c[i] = *cdata++; + + return (u.w); +} + +/* + * error op dummy proto - drop all data sent and return an error +*/ +static int errop_code; + +static void +errop_set(int err) +{ + + errop_code = err; +} + +static int +errop_start(int len) +{ + errop_code = ENOENT; + + /* accept any length */ + return (errop_code); +} + +static void +errop_data(uint32_t data, int len) +{ + + /* ignore */ +} + +static int +errop_result(struct iovec **data) +{ + + /* no data to send back; always successful */ + *data = NULL; + return (errop_code); +} + +static void +errop_done(struct iovec *data) +{ + + /* assert data is NULL */ +} + +static struct op_info errop_info = { + .op_start = errop_start, + .op_data = errop_data, + .op_result = errop_result, + .op_done = errop_done +}; + +/* OID search */ +SET_DECLARE(ctl_set, struct ctl); + +CTL_NODE("hw.ncpu", &guest_ncpus, sizeof(guest_ncpus)); + +static struct ctl * +ctl_locate(const char *str, int maxlen) +{ + struct ctl *cp, **cpp; + + SET_FOREACH(cpp, ctl_set) { + cp = *cpp; + if (!strncmp(str, cp->c_oid, maxlen)) + return (cp); + } + + return (NULL); +} + +/* uefi-sysctl get-len */ +#define FGET_STRSZ 80 +static struct iovec fget_biov[2]; +static char fget_str[FGET_STRSZ]; +static struct { + size_t f_sz; + uint32_t f_data[1024]; +} fget_buf; +static int fget_cnt; +static size_t fget_size; + +static int +fget_start(int len) +{ + + if (len > FGET_STRSZ) + return(E2BIG); + + fget_cnt = 0; + + return (0); +} + +static void +fget_data(uint32_t data, int len) +{ + + *((uint32_t *) &fget_str[fget_cnt]) = data; + fget_cnt += sizeof(uint32_t); +} + +static int +fget_result(struct iovec **data, int val) +{ + struct ctl *cp; + int err; + + err = 0; + + /* Locate the OID */ + cp = ctl_locate(fget_str, fget_cnt); + if (cp == NULL) { + *data = NULL; + err = ENOENT; + } else { + if (val) { + /* For now, copy the len/data into a buffer */ + memset(&fget_buf, 0, sizeof(fget_buf)); + fget_buf.f_sz = cp->c_len; + memcpy(fget_buf.f_data, cp->c_data, cp->c_len); + fget_biov[0].iov_base = (char *)&fget_buf; + fget_biov[0].iov_len = sizeof(fget_buf.f_sz) + + cp->c_len; + } else { + fget_size = cp->c_len; + fget_biov[0].iov_base = (char *)&fget_size; + fget_biov[0].iov_len = sizeof(fget_size); + } + + fget_biov[1].iov_base = NULL; + fget_biov[1].iov_len = 0; + *data = fget_biov; + } + + return (err); +} + +static void +fget_done(struct iovec *data) +{ + + /* nothing needs to be freed */ +} + +static int +fget_len_result(struct iovec **data) +{ + return (fget_result(data, 0)); +} + +static int +fget_val_result(struct iovec **data) +{ + return (fget_result(data, 1)); +} + +static struct op_info fgetlen_info = { + .op_start = fget_start, + .op_data = fget_data, + .op_result = fget_len_result, + .op_done = fget_done +}; + +static struct op_info fgetval_info = { + .op_start = fget_start, + .op_data = fget_data, + .op_result = fget_val_result, + .op_done = fget_done +}; + +static struct req_info { + int req_error; + u_int req_count; + uint32_t req_size; + uint32_t req_type; + uint32_t req_txid; + struct op_info *req_op; + int resp_error; + int resp_count; + int resp_size; + int resp_off; + struct iovec *resp_biov; +} rinfo; + +static void +fwctl_response_done(void) +{ + + (*rinfo.req_op->op_done)(rinfo.resp_biov); + + /* reinit the req data struct */ + memset(&rinfo, 0, sizeof(rinfo)); +} + +static void +fwctl_request_done(void) +{ + + rinfo.resp_error = (*rinfo.req_op->op_result)(&rinfo.resp_biov); + + /* XXX only a single vector supported at the moment */ + rinfo.resp_off = 0; + if (rinfo.resp_biov == NULL) { + rinfo.resp_size = 0; + } else { + rinfo.resp_size = rinfo.resp_biov[0].iov_len; + } +} + +static int +fwctl_request_start(void) +{ + int err; + + /* Data size doesn't include header */ + rinfo.req_size -= 12; + + rinfo.req_op = &errop_info; + if (rinfo.req_type <= OP_MAX && ops[rinfo.req_type] != NULL) + rinfo.req_op = ops[rinfo.req_type]; + + err = (*rinfo.req_op->op_start)(rinfo.req_size); + + if (err) { + errop_set(err); + rinfo.req_op = &errop_info; + } + + /* Catch case of zero-length message here */ + if (rinfo.req_size == 0) { + fwctl_request_done(); + return (1); + } + + return (0); +} + +static int +fwctl_request_data(uint32_t value) +{ + int remlen; + + /* Make sure remaining size is >= 0 */ + rinfo.req_size -= sizeof(uint32_t); + remlen = (rinfo.req_size > 0) ? rinfo.req_size: 0; + + (*rinfo.req_op->op_data)(value, remlen); + + if (rinfo.req_size < sizeof(uint32_t)) { + fwctl_request_done(); + return (1); + } + + return (0); +} + +static int +fwctl_request(uint32_t value) +{ + + int ret; + + ret = 0; + + switch (rinfo.req_count) { + case 0: + /* Verify size */ + if (value < 12) { + printf("msg size error"); + exit(1); + } + rinfo.req_size = value; + rinfo.req_count = 1; + break; + case 1: + rinfo.req_type = value; + rinfo.req_count++; + break; + case 2: + rinfo.req_txid = value; + rinfo.req_count++; + ret = fwctl_request_start(); + break; + default: + ret = fwctl_request_data(value); + break; + } + + return (ret); +} + +static int +fwctl_response(uint32_t *retval) +{ + uint32_t *dp; + int remlen; + + switch(rinfo.resp_count) { + case 0: + /* 4 x u32 header len + data */ + *retval = 4*sizeof(uint32_t) + + roundup(rinfo.resp_size, sizeof(uint32_t)); + rinfo.resp_count++; + break; + case 1: + *retval = rinfo.req_type; + rinfo.resp_count++; + break; + case 2: + *retval = rinfo.req_txid; + rinfo.resp_count++; + break; + case 3: + *retval = rinfo.resp_error; + rinfo.resp_count++; + break; + default: + remlen = rinfo.resp_size - rinfo.resp_off; + dp = (uint32_t *) + ((uint8_t *)rinfo.resp_biov->iov_base + rinfo.resp_off); + if (remlen >= sizeof(uint32_t)) { + *retval = *dp; + } else if (remlen > 0) { + *retval = fwctl_send_rest(dp, remlen); + } + rinfo.resp_off += sizeof(uint32_t); + break; + } + + if (rinfo.resp_count > 3 && + rinfo.resp_size - rinfo.resp_off <= 0) { + fwctl_response_done(); + return (1); + } + + return (0); +} + + +/* + * i/o port handling. + */ +static uint8_t +fwctl_inb(void) +{ + uint8_t retval; + + retval = 0xff; + + switch (be_state) { + case IDENT_SEND: + retval = sig[ident_idx++]; + if (ident_idx >= sizeof(sig)) + be_state = REQ; + break; + default: + break; + } + + return (retval); +} + +static void +fwctl_outw(uint16_t val) +{ + switch (be_state) { + case IDENT_WAIT: + if (val == 0) { + be_state = IDENT_SEND; + ident_idx = 0; + } + break; + default: + /* ignore */ + break; + } +} + +static uint32_t +fwctl_inl(void) +{ + uint32_t retval; + + switch (be_state) { + case RESP: + if (fwctl_response(&retval)) + be_state = REQ; + break; + default: + retval = 0xffffffff; + break; + } + + return (retval); +} + +static void +fwctl_outl(uint32_t val) +{ + + switch (be_state) { + case REQ: + if (fwctl_request(val)) + be_state = RESP; + default: + break; + } + +} + +static int +fwctl_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + + if (in) { + if (bytes == 1) + *eax = fwctl_inb(); + else if (bytes == 4) + *eax = fwctl_inl(); + else + *eax = 0xffff; + } else { + if (bytes == 2) + fwctl_outw(*eax); + else if (bytes == 4) + fwctl_outl(*eax); + } + + return (0); +} +INOUT_PORT(fwctl_wreg, FWCTL_OUT, IOPORT_F_INOUT, fwctl_handler); +INOUT_PORT(fwctl_rreg, FWCTL_IN, IOPORT_F_IN, fwctl_handler); + +void +fwctl_init(void) +{ + + ops[OP_GET_LEN] = &fgetlen_info; + ops[OP_GET] = &fgetval_info; + + be_state = IDENT_WAIT; +} diff --git a/usr.sbin/bhyve/fwctl.h b/usr.sbin/bhyve/fwctl.h new file mode 100644 index 0000000..f5f8d13 --- /dev/null +++ b/usr.sbin/bhyve/fwctl.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2015 Peter Grehan <grehan@freebsd.org> + * 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. + * + * 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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +#ifndef _FWCTL_H_ +#define _FWCTL_H_ + +#include <sys/linker_set.h> + +/* + * Linker set api for export of information to guest firmware via + * a sysctl-like OID interface + */ +struct ctl { + const char *c_oid; + const void *c_data; + const int c_len; +}; + +#define CTL_NODE(oid, data, len) \ + static struct ctl __CONCAT(__ctl, __LINE__) = { \ + oid, \ + (data), \ + (len), \ + }; \ + DATA_SET(ctl_set, __CONCAT(__ctl, __LINE__)) + +void fwctl_init(void); + +#endif /* _FWCTL_H_ */ diff --git a/usr.sbin/ctld/ctl.conf.5 b/usr.sbin/ctld/ctl.conf.5 index 24c4c85..538699e 100644 --- a/usr.sbin/ctld/ctl.conf.5 +++ b/usr.sbin/ctld/ctl.conf.5 @@ -387,7 +387,7 @@ testing. The default backend is block. .It Ic blocksize Ar size The blocksize visible to the initiator. -The default blocksize is 512. +The default blocksize is 512 for disks, and 2048 for CD/DVDs. .It Ic ctl-lun Ar lun_id Global numeric identifier to use for a given LUN inside CTL. By default CTL allocates those IDs dynamically, but explicit specification diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index 12474ea..4813ae0 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -1661,7 +1661,10 @@ conf_verify_lun(struct lun *lun) } } if (lun->l_blocksize == 0) { - lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); + if (lun->l_device_type == 5) + lun_set_blocksize(lun, DEFAULT_CD_BLOCKSIZE); + else + lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); } else if (lun->l_blocksize < 0) { log_warnx("invalid blocksize for lun \"%s\"; " "must be larger than 0", lun->l_name); diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 6eb878c..51775d7 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -43,6 +43,7 @@ #define DEFAULT_CONFIG_PATH "/etc/ctl.conf" #define DEFAULT_PIDFILE "/var/run/ctld.pid" #define DEFAULT_BLOCKSIZE 512 +#define DEFAULT_CD_BLOCKSIZE 2048 #define MAX_LUNS 1024 #define MAX_NAME_LEN 223 diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index c3784ef..1e81801 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -360,9 +360,12 @@ main(int argc, char *argv[]) fwrite(&ival, sizeof(ival), 1, fxref); reccnt = 0; } - /* skip non-files or .symbols entries */ + /* skip non-files and separate debug files */ if (p->fts_info != FTS_F) continue; + if (p->fts_namelen >= 6 && + strcmp(p->fts_name + p->fts_namelen - 6, ".debug") == 0) + continue; if (p->fts_namelen >= 8 && strcmp(p->fts_name + p->fts_namelen - 8, ".symbols") == 0) continue; diff --git a/usr.sbin/rpc.yppasswdd/yppasswdd_server.c b/usr.sbin/rpc.yppasswdd/yppasswdd_server.c index 0260e4c..9eb874b 100644 --- a/usr.sbin/rpc.yppasswdd/yppasswdd_server.c +++ b/usr.sbin/rpc.yppasswdd/yppasswdd_server.c @@ -212,12 +212,12 @@ validate(struct passwd *opw, struct x_passwd *npw) * Don't allow the user to shoot himself in the foot, * even on purpose. */ - if (!ok_shell(npw->pw_shell)) { + if (!no_chsh && !ok_shell(npw->pw_shell)) { yp_error("%s is not a valid shell", npw->pw_shell); return(1); } - if (validchars(npw->pw_shell)) { + if (!no_chsh && validchars(npw->pw_shell)) { yp_error("specified shell contains invalid characters"); return(1); } diff --git a/usr.sbin/rpcbind/rpcb_svc_com.c b/usr.sbin/rpcbind/rpcb_svc_com.c index a88f619..326224a 100644 --- a/usr.sbin/rpcbind/rpcb_svc_com.c +++ b/usr.sbin/rpcbind/rpcb_svc_com.c @@ -1052,12 +1052,15 @@ static bool_t netbuf_copybuf(struct netbuf *dst, const struct netbuf *src) { - assert(dst->buf == NULL); + if (dst->len != src->len || dst->buf == NULL) { + if (dst->buf != NULL) + free(dst->buf); + if ((dst->buf = malloc(src->len)) == NULL) + return (FALSE); - if ((dst->buf = malloc(src->len)) == NULL) - return (FALSE); + dst->maxlen = dst->len = src->len; + } - dst->maxlen = dst->len = src->len; memcpy(dst->buf, src->buf, src->len); return (TRUE); } |