summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-10-05 00:11:49 +0000
committerngie <ngie@FreeBSD.org>2015-10-05 00:11:49 +0000
commite3bac3a30a41f56ac36f4791a7df260f2155c8db (patch)
treeac20948d4aa368300bc16ece67336a1bed25e992
parentca6cf0ba737487849f2ee102afce74545600850c (diff)
parent85fa330dc74592563cea8d7cf0e628fd30683993 (diff)
downloadFreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.zip
FreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.tar.gz
MFhead @ r281414
-rw-r--r--Makefile.inc15
-rw-r--r--bin/cat/cat.c43
-rw-r--r--games/Makefile21
-rw-r--r--games/Makefile.inc6
-rw-r--r--games/tests/Makefile10
-rw-r--r--include/Makefile8
-rw-r--r--lib/libc/net/getaddrinfo.c16
-rw-r--r--lib/libc/sys/posix_fadvise.212
-rw-r--r--lib/libohash/ohash.h2
-rw-r--r--lib/libusb/Makefile4
-rw-r--r--lib/libz/Makefile2
-rw-r--r--sbin/ipf/ipftest/Makefile24
-rw-r--r--sbin/ipfw/ipfw2.c2
-rw-r--r--share/dtrace/Makefile3
-rwxr-xr-xshare/dtrace/blocking57
-rw-r--r--share/man/man7/hier.75
-rw-r--r--share/mk/bsd.sys.mk2
-rw-r--r--share/mk/meta.stage.mk7
-rw-r--r--sys/arm/arm/bcopy_page.S4
-rw-r--r--sys/arm/arm/bcopyinout.S3
-rw-r--r--sys/arm/arm/machdep.c2
-rw-r--r--sys/arm/arm/vm_machdep.c2
-rw-r--r--sys/arm/include/asm.h2
-rw-r--r--sys/arm/include/atomic-v4.h33
-rw-r--r--sys/arm/include/atomic-v6.h28
-rw-r--r--sys/arm/include/atomic.h28
-rw-r--r--sys/arm64/arm64/trap.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c2
-rw-r--r--sys/dev/ath/if_ath_beacon.c6
-rw-r--r--sys/dev/ath/if_ath_keycache.c3
-rw-r--r--sys/dev/ath/if_ath_keycache.h3
-rw-r--r--sys/dev/drm2/drmP.h6
-rw-r--r--sys/dev/drm2/drm_crtc.c20
-rw-r--r--sys/dev/drm2/drm_fops.c2
-rw-r--r--sys/dev/drm2/drm_pci.c2
-rw-r--r--sys/dev/drm2/drm_stub.c6
-rw-r--r--sys/dev/drm2/i915/i915_dma.c2
-rw-r--r--sys/dev/drm2/i915/i915_drv.c1
-rw-r--r--sys/dev/drm2/i915/intel_opregion.c4
-rw-r--r--sys/dev/if_ndis/if_ndis.c5
-rw-r--r--sys/dev/mwl/if_mwl.c21
-rw-r--r--sys/dev/ral/rt2560.c5
-rw-r--r--sys/dev/ral/rt2661.c4
-rw-r--r--sys/dev/ral/rt2860.c3
-rw-r--r--sys/dev/usb/wlan/if_rum.c1223
-rw-r--r--sys/dev/usb/wlan/if_rumreg.h81
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h64
-rw-r--r--sys/dev/usb/wlan/if_run.c117
-rw-r--r--sys/dev/usb/wlan/if_runreg.h1
-rw-r--r--sys/dev/usb/wlan/if_runvar.h4
-rw-r--r--sys/dev/usb/wlan/if_upgt.c5
-rw-r--r--sys/dev/usb/wlan/if_ural.c27
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c6
-rw-r--r--sys/dev/usb/wlan/if_zyd.c22
-rw-r--r--sys/dev/wpi/if_wpi.c13
-rw-r--r--sys/dev/wtap/if_wtap.c4
-rw-r--r--sys/kern/subr_sbuf.c4
-rw-r--r--sys/kern/vfs_bio.c6
-rw-r--r--sys/mips/conf/WZR-300HP12
-rw-r--r--sys/mips/conf/WZR-300HP.hints12
-rw-r--r--sys/net/if_gif.c10
-rw-r--r--sys/net/if_gre.c9
-rw-r--r--sys/net/if_lagg.c9
-rw-r--r--sys/net/if_lagg.h2
-rw-r--r--sys/net/if_me.c7
-rw-r--r--sys/net80211/ieee80211_crypto.c50
-rw-r--r--sys/net80211/ieee80211_crypto.h8
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c36
-rw-r--r--sys/net80211/ieee80211_crypto_none.c16
-rw-r--r--sys/net80211/ieee80211_crypto_tkip.c52
-rw-r--r--sys/net80211/ieee80211_crypto_wep.c56
-rw-r--r--sys/net80211/ieee80211_ioctl.c52
-rw-r--r--sys/net80211/ieee80211_output.c14
-rw-r--r--sys/net80211/ieee80211_proto.h5
-rw-r--r--sys/net80211/ieee80211_var.h3
-rw-r--r--sys/netinet6/nd6.c87
-rw-r--r--sys/netinet6/nd6.h2
-rw-r--r--sys/netinet6/nd6_nbr.c40
-rw-r--r--sys/netpfil/ipfw/ip_fw_sockopt.c2
-rw-r--r--sys/vm/vm_page.c2
-rw-r--r--sys/vm/vm_pageout.c1
-rw-r--r--sys/vm/vm_pageout.h1
-rw-r--r--targets/pseudo/userland/games/Makefile.depend26
-rw-r--r--usr.bin/Makefile14
-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/Makefile10
-rw-r--r--usr.bin/truss/aarch64-fbsd.c110
-rw-r--r--usr.bin/truss/amd64-cloudabi64.c113
-rw-r--r--usr.bin/truss/amd64cloudabi64.conf13
-rw-r--r--usr.bin/truss/syscall.h3
-rw-r--r--usr.bin/truss/syscalls.c29
-rw-r--r--usr.sbin/bhyve/Makefile1
-rw-r--r--usr.sbin/bhyve/bhyverun.c4
-rw-r--r--usr.sbin/bhyve/fwctl.c549
-rw-r--r--usr.sbin/bhyve/fwctl.h54
-rw-r--r--usr.sbin/ctld/ctl.conf.52
-rw-r--r--usr.sbin/ctld/ctld.c5
-rw-r--r--usr.sbin/ctld/ctld.h1
-rw-r--r--usr.sbin/kldxref/kldxref.c5
-rw-r--r--usr.sbin/rpc.yppasswdd/yppasswdd_server.c4
-rw-r--r--usr.sbin/rpcbind/rpcb_svc_com.c11
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)&regs, 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)&regs, 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)&regs, 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)&regs, 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);
}
OpenPOWER on IntegriCloud