summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-26 17:38:00 +0000
committerattilio <attilio@FreeBSD.org>2011-05-26 17:38:00 +0000
commit867c6223e7e4f6682389d40926782fd537ffc3ad (patch)
tree87423ad4498424494102d7b58615c0df44019d32
parentc0038ec50d088a2152d05e1da7d5b4cec45e8d27 (diff)
parentd7214daa609442aa65fdbb054db56a3ffc1ee75a (diff)
downloadFreeBSD-src-867c6223e7e4f6682389d40926782fd537ffc3ad.zip
FreeBSD-src-867c6223e7e4f6682389d40926782fd537ffc3ad.tar.gz
MFC
-rw-r--r--bin/sh/cd.c5
-rw-r--r--cddl/compat/opensolaris/misc/fsshare.c1
-rw-r--r--contrib/openbsm/libbsm/audit_submit.32
-rw-r--r--gnu/usr.bin/Makefile2
-rw-r--r--gnu/usr.bin/grep/Makefile15
-rw-r--r--lib/libc/gen/feature_present.32
-rw-r--r--sbin/geom/class/part/geom_part.c4
-rw-r--r--share/man/man4/atrtc.42
-rw-r--r--share/man/man4/attimer.42
-rw-r--r--share/man/man4/cc.42
-rw-r--r--share/man/man4/h_ertt.42
-rw-r--r--share/man/man4/nvram2env.42
-rw-r--r--share/man/man7/eventtimers.72
-rw-r--r--share/man/man7/ports.74
-rw-r--r--share/man/man9/devfs_set_cdevpriv.92
-rw-r--r--share/man/man9/hhook.92
-rw-r--r--share/man/man9/khelp.92
-rw-r--r--share/misc/committers-src.dot3
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c5
-rw-r--r--sys/cddl/compat/opensolaris/sys/taskq.h1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c31
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c14
-rw-r--r--sys/conf/kern.mk7
-rw-r--r--sys/dev/ahci/ahci.c101
-rw-r--r--sys/dev/ath/ath_hal/ah.c2
-rw-r--r--sys/dev/ath/ath_hal/ah.h35
-rw-r--r--sys/dev/ath/ath_hal/ah_devid.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom.h4
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_9287.c42
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h12
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.h3
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_attach.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_misc.c20
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_ani.c17
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c7
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_reset.c54
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c43
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416desc.h23
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416reg.h60
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9160_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9280_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_phy.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.c392
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.h62
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.ini783
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_attach.c468
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_cal.c73
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_cal.h33
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_olc.c171
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_olc.h31
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.c570
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.h27
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287an.h49
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287phy.h26
-rw-r--r--sys/dev/ath/if_athvar.h6
-rw-r--r--sys/dev/msk/if_msk.c33
-rw-r--r--sys/dev/mvs/mvs.c44
-rw-r--r--sys/dev/siis/siis.c25
-rw-r--r--sys/dev/sound/pci/hda/hdac.c26
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c8
-rw-r--r--sys/fs/nfs/nfs_var.h2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c15
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c14
-rw-r--r--sys/geom/part/g_part_ebr.c3
-rw-r--r--sys/geom/part/g_part_mbr.c10
-rw-r--r--sys/geom/part/g_part_pc98.c13
-rw-r--r--sys/geom/vinum/geom_vinum_drive.c4
-rw-r--r--sys/geom/vinum/geom_vinum_events.c6
-rw-r--r--sys/kern/device_if.m20
-rw-r--r--sys/kern/kern_synch.c4
-rw-r--r--sys/kern/subr_smp.c50
-rw-r--r--sys/net/if_epair.c41
-rw-r--r--sys/net/netisr.c282
-rw-r--r--sys/net/netisr.h19
-rw-r--r--sys/net/netisr_internal.h3
-rw-r--r--sys/netgraph/ng_eiface.c71
-rw-r--r--sys/netgraph/ng_pipe.c31
-rw-r--r--sys/netinet/in_pcb.c2
-rw-r--r--sys/netinet/in_proto.c2
-rw-r--r--sys/netinet6/in6_proto.c1
-rw-r--r--sys/powerpc/aim/trap_subr64.S1
-rw-r--r--sys/powerpc/ps3/ps3bus.c34
-rw-r--r--tools/build/make_check/Makefile21
-rw-r--r--tools/build/options/WITH_BSD_GREP2
-rw-r--r--tools/tools/ether_reflect/ether_reflect.12
-rw-r--r--usr.bin/Makefile6
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd1
-rw-r--r--usr.bin/grep/Makefile11
-rw-r--r--usr.bin/gzip/gzip.c3
-rw-r--r--usr.bin/mkcsmapper/mkcsmapper.12
-rw-r--r--usr.bin/mkesdb/mkesdb.12
-rw-r--r--usr.bin/netstat/netisr.c65
-rw-r--r--usr.bin/showmount/showmount.c2
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.32
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.32
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.32
-rw-r--r--usr.sbin/gpioctl/gpioctl.810
-rw-r--r--usr.sbin/usbdump/usbdump.82
102 files changed, 3760 insertions, 389 deletions
diff --git a/bin/sh/cd.c b/bin/sh/cd.c
index 776bdba..2cd9daf 100644
--- a/bin/sh/cd.c
+++ b/bin/sh/cd.c
@@ -86,6 +86,7 @@ cdcmd(int argc, char **argv)
struct stat statb;
int ch, phys, print = 0, getcwderr = 0;
int rc;
+ int errno1 = ENOENT;
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
phys = Pflag;
@@ -138,9 +139,11 @@ cdcmd(int argc, char **argv)
rc = docd(p, print, phys);
if (rc >= 0)
return getcwderr ? rc : 0;
+ if (errno != ENOENT)
+ errno1 = errno;
}
}
- error("can't cd to %s", dest);
+ error("%s: %s", dest, strerror(errno1));
/*NOTREACHED*/
return 0;
}
diff --git a/cddl/compat/opensolaris/misc/fsshare.c b/cddl/compat/opensolaris/misc/fsshare.c
index e8faa92..c3247f9 100644
--- a/cddl/compat/opensolaris/misc/fsshare.c
+++ b/cddl/compat/opensolaris/misc/fsshare.c
@@ -223,6 +223,7 @@ out:
error = errno;
unlink(tmpfile);
} else {
+ fflush(newfd);
/*
* Send SIGHUP to mountd, but unlock exports file later.
*/
diff --git a/contrib/openbsm/libbsm/audit_submit.3 b/contrib/openbsm/libbsm/audit_submit.3
index b6c28a7..c77e1d4 100644
--- a/contrib/openbsm/libbsm/audit_submit.3
+++ b/contrib/openbsm/libbsm/audit_submit.3
@@ -30,7 +30,7 @@
.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#17 $
.\"
.Dd January 18, 2008
-.Dt audit_submit 3
+.Dt AUDIT_SUBMIT 3
.Os
.Sh NAME
.Nm audit_submit
diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile
index 0ee257f..95eeeb8 100644
--- a/gnu/usr.bin/Makefile
+++ b/gnu/usr.bin/Makefile
@@ -27,9 +27,7 @@ _groff= groff
.endif
.endif
-.if ${MK_BSD_GREP} != "yes"
_grep= grep
-.endif
.if ${MK_CVS} != "no"
_cvs= cvs
diff --git a/gnu/usr.bin/grep/Makefile b/gnu/usr.bin/grep/Makefile
index b0c3988..7d3b607 100644
--- a/gnu/usr.bin/grep/Makefile
+++ b/gnu/usr.bin/grep/Makefile
@@ -1,35 +1,50 @@
# $FreeBSD$
+.include <bsd.own.mk>
+
GREP_LIBZ=YES
+.if ${MK_BSD_GREP} != "yes"
PROG= grep
+.else
+PROG= gnugrep
+.endif
SRCS= closeout.c dfa.c error.c exclude.c grep.c grepmat.c hard-locale.c \
isdir.c kwset.c obstack.c quotearg.c savedir.c search.c xmalloc.c \
xstrtoumax.c
CFLAGS+=-I${.CURDIR} -I${DESTDIR}/usr/include/gnu -DHAVE_CONFIG_H
+.if ${MK_BSD_GREP} != "yes"
LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \
${BINDIR}/grep ${BINDIR}/fgrep
MLINKS= grep.1 egrep.1 grep.1 fgrep.1
+.endif
DPADD= ${LIBGNUREGEX} ${LIBBZ2}
LDADD= -lgnuregex -lbz2
+.if ${MK_BSD_GREP} != "yes"
LINKS+= ${BINDIR}/grep ${BINDIR}/bzgrep \
${BINDIR}/grep ${BINDIR}/bzegrep \
${BINDIR}/grep ${BINDIR}/bzfgrep
MLINKS+=grep.1 bzgrep.1 grep.1 bzegrep.1 grep.1 bzfgrep.1
+.endif
.if defined(GREP_LIBZ) && !empty(GREP_LIBZ)
LDADD+= -lz
DPADD+= ${LIBZ}
CFLAGS+=-DHAVE_LIBZ=1
+.if ${MK_BSD_GREP} != "yes"
LINKS+= ${BINDIR}/grep ${BINDIR}/zgrep \
${BINDIR}/grep ${BINDIR}/zegrep \
${BINDIR}/grep ${BINDIR}/zfgrep
MLINKS+=grep.1 zgrep.1 grep.1 zegrep.1 grep.1 zfgrep.1
.endif
+.endif
+
+gnugrep.1: grep.1
+ cp ${.ALLSRC} ${.TARGET}
SUBDIR+=doc
diff --git a/lib/libc/gen/feature_present.3 b/lib/libc/gen/feature_present.3
index 9a4269e..3a702d4 100644
--- a/lib/libc/gen/feature_present.3
+++ b/lib/libc/gen/feature_present.3
@@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd January 8, 2008
-.Dt feature_present 3
+.Dt FEATURE_PRESENT 3
.Os
.Sh NAME
.Nm feature_present
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c
index 19d1502..278030d 100644
--- a/sbin/geom/class/part/geom_part.c
+++ b/sbin/geom/class/part/geom_part.c
@@ -295,8 +295,8 @@ fmtattrib(struct gprovider *pp)
return (buf);
}
-#define ALIGNDOWN(d, a) (-(a) & (d))
-#define ALIGNUP(d, a) (-(-(a) & -(d)))
+#define ALIGNDOWN(d, a) ((d) - (d) % (a))
+#define ALIGNUP(d, a) ((d) % (a) ? (d) - (d) % (a) + (a): (d))
static int
gpart_autofill_resize(struct gctl_req *req)
diff --git a/share/man/man4/atrtc.4 b/share/man/man4/atrtc.4
index 35e770d..51d6f05 100644
--- a/share/man/man4/atrtc.4
+++ b/share/man/man4/atrtc.4
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 17, 2010
-.Dt atrtc 4
+.Dt ATRTC 4
.Os
.Sh NAME
.Nm atrtc
diff --git a/share/man/man4/attimer.4 b/share/man/man4/attimer.4
index d5bfaf9..67d001e 100644
--- a/share/man/man4/attimer.4
+++ b/share/man/man4/attimer.4
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 14, 2010
-.Dt attimer 4
+.Dt ATTIMER 4
.Os
.Sh NAME
.Nm attimer
diff --git a/share/man/man4/cc.4 b/share/man/man4/cc.4
index 32da741..c518f45 100644
--- a/share/man/man4/cc.4
+++ b/share/man/man4/cc.4
@@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
-.Dt cc 4
+.Dt CC 4
.Os
.Sh NAME
.Nm cc
diff --git a/share/man/man4/h_ertt.4 b/share/man/man4/h_ertt.4
index ed7461e..b04efaa 100644
--- a/share/man/man4/h_ertt.4
+++ b/share/man/man4/h_ertt.4
@@ -30,7 +30,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
-.Dt h_ertt 9
+.Dt H_ERTT 9
.Os
.Sh NAME
.Nm h_ertt
diff --git a/share/man/man4/nvram2env.4 b/share/man/man4/nvram2env.4
index c0ee0cf..5176097 100644
--- a/share/man/man4/nvram2env.4
+++ b/share/man/man4/nvram2env.4
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd April 3, 2011
-.Dt nvram2env 4
+.Dt NVRAM2ENV 4
.Os
.Sh NAME
.Nm nvram2env
diff --git a/share/man/man7/eventtimers.7 b/share/man/man7/eventtimers.7
index 6c9552a..37d5fc8 100644
--- a/share/man/man7/eventtimers.7
+++ b/share/man/man7/eventtimers.7
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 15, 2010
-.Dt eventtimers 4
+.Dt EVENTTIMERS 4
.Os
.Sh NAME
.Nm eventtimers
diff --git a/share/man/man7/ports.7 b/share/man/man7/ports.7
index 54afe0a..2344a4d 100644
--- a/share/man/man7/ports.7
+++ b/share/man/man7/ports.7
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2009
+.Dd May 25, 2011
.Dt PORTS 7
.Os
.Sh NAME
@@ -124,6 +124,8 @@ and
.It Cm checksum
Verify that the fetched distfile's checksum matches the one the port was
tested against.
+If the distfile's checksum does not match, it also fetches the distfiles
+which are missing or failed the checksum calculation.
Defining
.Va NO_CHECKSUM
will skip this step.
diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9
index fcdc5c4..a2b0279 100644
--- a/share/man/man9/devfs_set_cdevpriv.9
+++ b/share/man/man9/devfs_set_cdevpriv.9
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 8, 2008
-.Dt DEVFS_CDEVPRIV
+.Dt DEVFS_CDEVPRIV 9
.Os
.Sh NAME
.Nm devfs_set_cdevpriv ,
diff --git a/share/man/man9/hhook.9 b/share/man/man9/hhook.9
index 1dd391f..df74543 100644
--- a/share/man/man9/hhook.9
+++ b/share/man/man9/hhook.9
@@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
-.Dt hhook 9
+.Dt HHOOK 9
.Os
.Sh NAME
.Nm hhook ,
diff --git a/share/man/man9/khelp.9 b/share/man/man9/khelp.9
index 25125c0..2f3f0e1 100644
--- a/share/man/man9/khelp.9
+++ b/share/man/man9/khelp.9
@@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
-.Dt khelp 9
+.Dt KHELP 9
.Os
.Sh NAME
.Nm khelp ,
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index d450c8a..2fce08f 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -206,6 +206,7 @@ ps [label="Paul Saab\nps@FreeBSD.org\n2000/02/23"]
qingli [label="Qing Li\nqingli@FreeBSD.org\n2005/04/13"]
rafan [label="Rong-En Fan\nrafan@FreeBSD.org\n2007/01/31"]
randi [label="Randi Harper\nrandi@FreeBSD.org\n2010/04/20"]
+ray [label="Aleksandr Rybalko\nray@FreeBSD.org\n2011/05/25"]
rdivacky [label="Roman Divacky\nrdivacky@FreeBSD.org\n2008/03/13"]
remko [label="Remko Lodder\nremko@FreeBSD.org\n2007/02/23"]
rik [label="Roman Kurakin\nrik@FreeBSD.org\n2003/12/18"]
@@ -268,6 +269,8 @@ day1 -> rgrimes
day1 -> alm
day1 -> dg
+adrian -> ray
+
andre -> qingli
anholt -> jkim
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
index 5a20488..a74f795 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
@@ -147,9 +147,7 @@ taskq_run_safe(void *arg, int pending __unused)
{
struct ostask *task = arg;
- ASSERT(task->ost_magic == TASKQ_MAGIC);
task->ost_func(task->ost_arg);
- task->ost_magic = 0;
}
taskqid_t
@@ -158,15 +156,12 @@ taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg, u_int flags,
{
int prio;
- ASSERT(task->ost_magic != TASKQ_MAGIC);
-
/*
* If TQ_FRONT is given, we want higher priority for this task, so it
* can go at the front of the queue.
*/
prio = !!(flags & TQ_FRONT);
- task->ost_magic = TASKQ_MAGIC;
task->ost_func = func;
task->ost_arg = arg;
diff --git a/sys/cddl/compat/opensolaris/sys/taskq.h b/sys/cddl/compat/opensolaris/sys/taskq.h
index eedc4da..ffe70ca 100644
--- a/sys/cddl/compat/opensolaris/sys/taskq.h
+++ b/sys/cddl/compat/opensolaris/sys/taskq.h
@@ -35,7 +35,6 @@ struct ostask {
struct task ost_task;
task_func_t *ost_func;
void *ost_arg;
- int ost_magic;
};
taskqid_t taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
index 355f560..e8372f7 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
@@ -421,8 +421,7 @@ struct zio {
#ifdef _KERNEL
/* FreeBSD only. */
- struct ostask io_task_issue;
- struct ostask io_task_interrupt;
+ struct ostask io_task;
#endif
};
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
index bae9071..6ff9339 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
@@ -239,15 +239,20 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
return (ENOENT);
}
if (dl == NULL) {
+ size_t namesize;
+
/*
* Allocate a new dirlock and add it to the list.
*/
- dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP);
+ namesize = strlen(name) + 1;
+ dl = kmem_alloc(sizeof (zfs_dirlock_t) + namesize,
+ KM_SLEEP);
cv_init(&dl->dl_cv, NULL, CV_DEFAULT, NULL);
- dl->dl_name = name;
+ dl->dl_name = (char *)(dl + 1);
+ bcopy(name, dl->dl_name, namesize);
dl->dl_sharecnt = 0;
dl->dl_namelock = 0;
- dl->dl_namesize = 0;
+ dl->dl_namesize = namesize;
dl->dl_dzp = dzp;
dl->dl_next = dzp->z_dirlocks;
dzp->z_dirlocks = dl;
@@ -264,20 +269,8 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
if (flag & ZHAVELOCK)
dl->dl_namelock = 1;
- if ((flag & ZSHARED) && ++dl->dl_sharecnt > 1 && dl->dl_namesize == 0) {
- /*
- * We're the second shared reference to dl. Make a copy of
- * dl_name in case the first thread goes away before we do.
- * Note that we initialize the new name before storing its
- * pointer into dl_name, because the first thread may load
- * dl->dl_name at any time. He'll either see the old value,
- * which is his, or the new shared copy; either is OK.
- */
- dl->dl_namesize = strlen(dl->dl_name) + 1;
- name = kmem_alloc(dl->dl_namesize, KM_SLEEP);
- bcopy(dl->dl_name, name, dl->dl_namesize);
- dl->dl_name = name;
- }
+ if (flag & ZSHARED)
+ dl->dl_sharecnt++;
mutex_exit(&dzp->z_lock);
@@ -361,10 +354,8 @@ zfs_dirent_unlock(zfs_dirlock_t *dl)
cv_broadcast(&dl->dl_cv);
mutex_exit(&dzp->z_lock);
- if (dl->dl_namesize != 0)
- kmem_free(dl->dl_name, dl->dl_namesize);
cv_destroy(&dl->dl_cv);
- kmem_free(dl, sizeof (*dl));
+ kmem_free(dl, sizeof (*dl) + dl->dl_namesize);
}
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index 5e968b5..9a04344 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -1068,19 +1068,9 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline)
spa_t *spa = zio->io_spa;
zio_type_t t = zio->io_type;
int flags = TQ_SLEEP | (cutinline ? TQ_FRONT : 0);
-#ifdef _KERNEL
- struct ostask *task;
-#endif
ASSERT(q == ZIO_TASKQ_ISSUE || q == ZIO_TASKQ_INTERRUPT);
-#ifdef _KERNEL
- if (q == ZIO_TASKQ_ISSUE)
- task = &zio->io_task_issue;
- else /* if (q == ZIO_TASKQ_INTERRUPT) */
- task = &zio->io_task_interrupt;
-#endif
-
/*
* If we're a config writer or a probe, the normal issue and
* interrupt threads may all be blocked waiting for the config lock.
@@ -1105,7 +1095,7 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline)
ASSERT3U(q, <, ZIO_TASKQ_TYPES);
#ifdef _KERNEL
(void) taskq_dispatch_safe(spa->spa_zio_taskq[t][q],
- (task_func_t *)zio_execute, zio, flags, task);
+ (task_func_t *)zio_execute, zio, flags, &zio->io_task);
#else
(void) taskq_dispatch(spa->spa_zio_taskq[t][q],
(task_func_t *)zio_execute, zio, flags);
@@ -2904,7 +2894,7 @@ zio_done(zio_t *zio)
(void) taskq_dispatch_safe(
spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE],
(task_func_t *)zio_reexecute, zio, TQ_SLEEP,
- &zio->io_task_issue);
+ &zio->io_task);
#else
(void) taskq_dispatch(
spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE],
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index 58ab6ee..a0a595f 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -1,15 +1,12 @@
# $FreeBSD$
#
-# Warning flags for compiling the kernel and components of the kernel.
+# Warning flags for compiling the kernel and components of the kernel:
#
-# Note that the newly added -Wcast-qual is responsible for generating
-# most of the remaining warnings. Warnings introduced with -Wall will
-# also pop up, but are easier to fix.
CWARNFLAGS?= -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes \
-Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual \
-Wundef -Wno-pointer-sign -fformat-extensions \
- -Wmissing-include-dirs
+ -Wmissing-include-dirs -fdiagnostics-show-option
#
# The following flags are next up for working on:
# -Wextra
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 2a06492..136011c 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -119,6 +119,7 @@ static struct {
#define AHCI_Q_NOBSYRES 256
#define AHCI_Q_NOAA 512
#define AHCI_Q_NOCOUNT 1024
+#define AHCI_Q_ALTSIG 2048
} ahci_ids[] = {
{0x43801002, 0x00, "ATI IXP600", 0},
{0x43901002, 0x00, "ATI IXP700", 0},
@@ -192,8 +193,9 @@ static struct {
{0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE | AHCI_Q_4CH |
AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
{0x91201b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_NOBSYRES},
- {0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES},
+ {0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES|AHCI_Q_ALTSIG},
{0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES},
+ {0x91721b4b, 0x00, "Marvell 88SE9172", AHCI_Q_NOBSYRES},
{0x91821b4b, 0x00, "Marvell 88SE9182", AHCI_Q_NOBSYRES},
{0x06201103, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
{0x06201b4b, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
@@ -398,6 +400,13 @@ ahci_attach(device_t dev)
if (ctlr->caps & AHCI_CAP_EMS)
ctlr->capsem = ATA_INL(ctlr->r_mem, AHCI_EM_CTL);
ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI);
+
+ /* Identify and set separate quirks for HBA and RAID f/w Marvells. */
+ if ((ctlr->quirks & AHCI_Q_NOBSYRES) &&
+ (ctlr->quirks & AHCI_Q_ALTSIG) &&
+ (ctlr->caps & AHCI_CAP_SPM) == 0)
+ ctlr->quirks &= ~AHCI_Q_NOBSYRES;
+
if (ctlr->quirks & AHCI_Q_1CH) {
ctlr->caps &= ~AHCI_CAP_NPMASK;
ctlr->ichannels &= 0x01;
@@ -1764,7 +1773,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
struct ahci_cmd_list *clp;
union ccb *ccb = slot->ccb;
int port = ccb->ccb_h.target_id & 0x0f;
- int fis_size, i;
+ int fis_size, i, softreset;
uint8_t *fis = ch->dma.rfis + 0x40;
uint8_t val;
@@ -1791,17 +1800,20 @@ ahci_execute_transaction(struct ahci_slot *slot)
if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
(ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
if (ccb->ataio.cmd.control & ATA_A_RESET) {
+ softreset = 1;
/* Kick controller into sane state */
ahci_stop(dev);
ahci_clo(dev);
ahci_start(dev, 0);
clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY;
} else {
+ softreset = 2;
/* Prepare FIS receive area for check. */
for (i = 0; i < 20; i++)
fis[i] = 0xff;
}
- }
+ } else
+ softreset = 0;
clp->bytecount = 0;
clp->cmd_table_phys = htole64(ch->dma.work_bus + AHCI_CT_OFFSET +
(AHCI_CT_SIZE * slot->slot));
@@ -1825,8 +1837,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
ATA_OUTL(ch->r_mem, AHCI_P_CI, (1 << slot->slot));
/* Device reset commands doesn't interrupt. Poll them. */
if (ccb->ccb_h.func_code == XPT_ATA_IO &&
- (ccb->ataio.cmd.command == ATA_DEVICE_RESET ||
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL))) {
+ (ccb->ataio.cmd.command == ATA_DEVICE_RESET || softreset)) {
int count, timeout = ccb->ccb_h.timeout * 100;
enum ahci_err_type et = AHCI_ERR_NONE;
@@ -1834,10 +1845,13 @@ ahci_execute_transaction(struct ahci_slot *slot)
DELAY(10);
if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot)))
break;
- if (ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) {
+ if ((ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) &&
+ softreset != 1) {
+#if 0
device_printf(ch->dev,
"Poll error on slot %d, TFD: %04x\n",
slot->slot, ATA_INL(ch->r_mem, AHCI_P_TFD));
+#endif
et = AHCI_ERR_TFE;
break;
}
@@ -1849,9 +1863,20 @@ ahci_execute_transaction(struct ahci_slot *slot)
break;
}
}
+
+ /* Marvell controllers do not wait for readyness. */
+ if ((ch->quirks & AHCI_Q_NOBSYRES) && softreset == 2 &&
+ et == AHCI_ERR_NONE) {
+ while ((val = fis[2]) & ATA_S_BUSY) {
+ DELAY(10);
+ if (count++ >= timeout)
+ break;
+ }
+ }
+
if (timeout && (count >= timeout)) {
- device_printf(ch->dev,
- "Poll timeout on slot %d\n", slot->slot);
+ device_printf(dev, "Poll timeout on slot %d port %d\n",
+ slot->slot, port);
device_printf(dev, "is %08x cs %08x ss %08x "
"rs %08x tfd %02x serr %08x\n",
ATA_INL(ch->r_mem, AHCI_P_IS),
@@ -1861,30 +1886,11 @@ ahci_execute_transaction(struct ahci_slot *slot)
ATA_INL(ch->r_mem, AHCI_P_SERR));
et = AHCI_ERR_TIMEOUT;
}
- /* Marvell controllers do not wait for readyness. */
- if ((ch->quirks & AHCI_Q_NOBSYRES) &&
- (ccb->ccb_h.func_code == XPT_ATA_IO) &&
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
- (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
- while ((val = fis[2]) & (ATA_S_BUSY | ATA_S_DRQ)) {
- DELAY(10);
- if (count++ >= timeout) {
- device_printf(dev, "device is not "
- "ready after soft-reset: "
- "tfd = %08x\n", val);
- et = AHCI_ERR_TIMEOUT;
- break;
- }
- }
- }
- ahci_end_transaction(slot, et);
+
/* Kick controller into sane state and enable FBS. */
- if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
- (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
- ahci_stop(ch->dev);
- ahci_start(ch->dev, 1);
- }
+ if (softreset == 2)
+ ch->eslots |= (1 << slot->slot);
+ ahci_end_transaction(slot, et);
return;
}
/* Start command execution timeout */
@@ -1962,7 +1968,8 @@ ahci_timeout(struct ahci_slot *slot)
return;
}
- device_printf(dev, "Timeout on slot %d\n", slot->slot);
+ device_printf(dev, "Timeout on slot %d port %d\n",
+ slot->slot, slot->ccb->ccb_h.target_id & 0x0f);
device_printf(dev, "is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
ATA_INL(ch->r_mem, AHCI_P_IS), ATA_INL(ch->r_mem, AHCI_P_CI),
ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots,
@@ -2013,6 +2020,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
union ccb *ccb = slot->ccb;
struct ahci_cmd_list *clp;
int lastto;
+ uint32_t sig;
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -2050,6 +2058,20 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
res->lba_high_exp = fis[10];
res->sector_count = fis[12];
res->sector_count_exp = fis[13];
+
+ /*
+ * Some weird controllers do not return signature in
+ * FIS receive area. Read it from PxSIG register.
+ */
+ if ((ch->quirks & AHCI_Q_ALTSIG) &&
+ (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
+ (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
+ sig = ATA_INL(ch->r_mem, AHCI_P_SIG);
+ res->lba_high = sig >> 24;
+ res->lba_mid = sig >> 16;
+ res->lba_low = sig >> 8;
+ res->sector_count = sig;
+ }
} else
bzero(res, sizeof(*res));
if ((ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) == 0 &&
@@ -2169,13 +2191,6 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- ahci_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there was fatal error - reset port. */
@@ -2185,6 +2200,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
/* if we have slots in error, we can reinit port. */
if (ch->eslots != 0) {
ahci_stop(dev);
+ ahci_clo(dev);
ahci_start(dev, 1);
}
/* if there commands on hold, we can do READ LOG. */
@@ -2195,6 +2211,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != AHCI_ERR_TIMEOUT)
ahci_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ ahci_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
/* Start PM timer. */
if (ch->numrslots == 0 && ch->pm_level > 3 &&
(ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 13a59f1..e84f9b3 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -117,6 +117,8 @@ ath_hal_mac_name(struct ath_hal *ah)
return "9280";
case AR_XSREV_VERSION_KITE:
return "9285";
+ case AR_XSREV_VERSION_KIWI:
+ return "9287";
}
return "????";
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index 85790e1..7bf2843 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -669,6 +669,41 @@ typedef struct {
} HAL_CHANNEL_SURVEY;
/*
+ * ANI commands.
+ *
+ * These are used both internally and externally via the diagnostic
+ * API.
+ *
+ * Note that this is NOT the ANI commands being used via the INTMIT
+ * capability - that has a different mapping for some reason.
+ */
+typedef enum {
+ HAL_ANI_PRESENT = 0, /* is ANI support present */
+ HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level */
+ HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 2, /* enable/disable */
+ HAL_ANI_CCK_WEAK_SIGNAL_THR = 3, /* enable/disable */
+ HAL_ANI_FIRSTEP_LEVEL = 4, /* set level */
+ HAL_ANI_SPUR_IMMUNITY_LEVEL = 5, /* set level */
+ HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */
+ HAL_ANI_PHYERR_RESET = 7, /* reset phy error stats */
+} HAL_ANI_CMD;
+
+/*
+ * This is the layout of the ANI INTMIT capability.
+ *
+ * Notice that the command values differ to HAL_ANI_CMD.
+ */
+typedef enum {
+ HAL_CAP_INTMIT_PRESENT = 0,
+ HAL_CAP_INTMIT_ENABLE = 1,
+ HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL = 2,
+ HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL = 3,
+ HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR = 4,
+ HAL_CAP_INTMIT_FIRSTEP_LEVEL = 5,
+ HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL = 6
+} HAL_CAP_INTMIT_CMD;
+
+/*
* Hardware Access Layer (HAL) API.
*
* Clients of the HAL call ath_hal_attach to obtain a reference to an
diff --git a/sys/dev/ath/ath_hal/ah_devid.h b/sys/dev/ath/ath_hal/ah_devid.h
index 64033f3..c7a98dd 100644
--- a/sys/dev/ath/ath_hal/ah_devid.h
+++ b/sys/dev/ath/ath_hal/ah_devid.h
@@ -80,6 +80,8 @@
#define AR9280_DEVID_PCIE 0x002a /* AR9280 PCI-E Merlin */
#define AR9285_DEVID_PCIE 0x002b /* AR9285 PCI-E Kite */
#define AR2427_DEVID_PCIE 0x002c /* AR2427 PCI-E w/ 802.11n bonded out */
+#define AR9287_DEVID_PCI 0x002d /* AR9227 PCI Kiwi */
+#define AR9287_DEVID_PCIE 0x002e /* AR9287 PCI-E Kiwi */
#define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */
#define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */
diff --git a/sys/dev/ath/ath_hal/ah_eeprom.h b/sys/dev/ath/ath_hal/ah_eeprom.h
index c7fe385..2ca0589 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom.h
@@ -101,7 +101,9 @@ enum {
AR_EEP_ANTGAINMAX_2, /* int8_t* */
AR_EEP_WRITEPROTECT, /* use ath_hal_eepromGetFlag */
AR_EEP_PWR_TABLE_OFFSET,/* int8_t* */
- AR_EEP_PWDCLKIND /* uint8_t* */
+ AR_EEP_PWDCLKIND, /* uint8_t* */
+ AR_EEP_TEMPSENSE_SLOPE, /* int8_t* */
+ AR_EEP_TEMPSENSE_SLOPE_PAL_ON, /* int8_t* */
};
typedef struct {
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.c b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
index e8c5e54..4055093 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_9287.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
@@ -63,28 +63,10 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val)
return pBase->opCapFlags;
case AR_EEP_RFSILENT:
return pBase->rfSilent;
-#if 0
- case AR_EEP_OB_5:
- return pModal[CHAN_A_IDX].ob;
- case AR_EEP_DB_5:
- return pModal[CHAN_A_IDX].db;
- case AR_EEP_OB_2:
- return pModal[CHAN_B_IDX].ob;
- case AR_EEP_DB_2:
- return pModal[CHAN_B_IDX].db;
-#endif
case AR_EEP_TXMASK:
return pBase->txMask;
case AR_EEP_RXMASK:
return pBase->rxMask;
-#if 0
- case AR_EEP_RXGAIN_TYPE:
- return IS_VERS(>=, AR5416_EEP_MINOR_VER_17) ?
- pBase->rxGainType : AR5416_EEP_RXGAIN_ORIG;
- case AR_EEP_TXGAIN_TYPE:
- return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ?
- pBase->txGainType : AR5416_EEP_TXGAIN_ORIG;
-#endif
case AR_EEP_OL_PWRCTRL:
HALASSERT(val == AH_NULL);
return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO;
@@ -117,6 +99,18 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val)
case AR_EEP_PWR_TABLE_OFFSET:
*(int8_t *) val = pBase->pwrTableOffset;
return HAL_OK;
+ case AR_EEP_TEMPSENSE_SLOPE:
+ if (IS_VERS(>=, AR9287_EEP_MINOR_VER_2))
+ *(int8_t *)val = pBase->tempSensSlope;
+ else
+ *(int8_t *)val = 0;
+ return HAL_OK;
+ case AR_EEP_TEMPSENSE_SLOPE_PAL_ON:
+ if (IS_VERS(>=, AR9287_EEP_MINOR_VER_3))
+ *(int8_t *)val = pBase->tempSensSlopePalOn;
+ else
+ *(int8_t *)val = 0;
+ return HAL_OK;
default:
HALASSERT(0);
return HAL_EINVAL;
@@ -132,14 +126,12 @@ v9287EepromSet(struct ath_hal *ah, int param, int v)
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (param) {
- case AR_EEP_ANTGAINMAX_2:
- ee->ee_antennaGainMax[1] = (int8_t) v;
- return HAL_OK;
- case AR_EEP_ANTGAINMAX_5:
- ee->ee_antennaGainMax[0] = (int8_t) v;
- return HAL_OK;
+ case AR_EEP_ANTGAINMAX_2:
+ ee->ee_antennaGainMax[1] = (int8_t) v;
+ return HAL_OK;
+ default:
+ return HAL_EINVAL;
}
- return HAL_EINVAL;
}
static HAL_BOOL
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index b4cc817..b994eab 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -418,18 +418,6 @@ extern HAL_BOOL ath_hal_setTxQProps(struct ath_hal *ah,
extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah,
HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi);
-typedef enum {
- HAL_ANI_PRESENT = 0x1, /* is ANI support present */
- HAL_ANI_NOISE_IMMUNITY_LEVEL = 0x2, /* set level */
- HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, /* enable/disable */
- HAL_ANI_CCK_WEAK_SIGNAL_THR = 0x8, /* enable/disable */
- HAL_ANI_FIRSTEP_LEVEL = 0x10, /* set level */
- HAL_ANI_SPUR_IMMUNITY_LEVEL = 0x20, /* set level */
- HAL_ANI_MODE = 0x40, /* 0 => manual, 1 => auto (XXX do not change) */
- HAL_ANI_PHYERR_RESET =0x80, /* reset phy error stats */
- HAL_ANI_ALL = 0xff
-} HAL_ANI_CMD;
-
#define HAL_SPUR_VAL_MASK 0x3FFF
#define HAL_SPUR_CHAN_WIDTH 87
#define HAL_BIN_WIDTH_BASE_100HZ 3125
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
index e226816..5bdfcb4 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
@@ -320,6 +320,9 @@ struct ath_hal_5212 {
struct ar5212AniState *ah_curani; /* cached last reference */
struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */
+ /* AR5416 uses some of the AR5212 ANI code; these are the ANI methods */
+ HAL_BOOL (*ah_aniControl) (struct ath_hal *, HAL_ANI_CMD cmd, int param);
+
/*
* Transmit power state. Note these are maintained
* here so they can be retrieved by diagnostic tools.
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
index 4b0fcbe..5f85522 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
@@ -203,6 +203,9 @@ ar5212AniSetup(struct ath_hal *ah)
ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE);
} else
ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
+
+ /* Set overridable ANI methods */
+ AH5212(ah)->ah_aniControl = ar5212AniControl;
}
/*
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
index 0d6adc1..518d079 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
@@ -880,16 +880,16 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
return HAL_OK;
case HAL_CAP_INTMIT: /* interference mitigation */
switch (capability) {
- case 0: /* hardware capability */
+ case HAL_CAP_INTMIT_PRESENT: /* hardware capability */
return HAL_OK;
- case 1:
+ case HAL_CAP_INTMIT_ENABLE:
return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
HAL_OK : HAL_ENXIO;
- case 2: /* HAL_ANI_NOISE_IMMUNITY_LEVEL */
- case 3: /* HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION */
- case 4: /* HAL_ANI_CCK_WEAK_SIGNAL_THR */
- case 5: /* HAL_ANI_FIRSTEP_LEVEL */
- case 6: /* HAL_ANI_SPUR_IMMUNITY_LEVEL */
+ case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL:
+ case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL:
+ case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR:
+ case HAL_CAP_INTMIT_FIRSTEP_LEVEL:
+ case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL:
ani = ar5212AniGetCurrentState(ah);
if (ani == AH_NULL)
return HAL_ENXIO;
@@ -980,6 +980,8 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
return AH_TRUE;
case HAL_CAP_INTMIT: { /* interference mitigation */
+ /* This maps the public ANI commands to the internal ANI commands */
+ /* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */
static const HAL_ANI_CMD cmds[] = {
HAL_ANI_PRESENT,
HAL_ANI_MODE,
@@ -990,7 +992,7 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
HAL_ANI_SPUR_IMMUNITY_LEVEL,
};
return capability < N(cmds) ?
- ar5212AniControl(ah, cmds[capability], setting) :
+ AH5212(ah)->ah_aniControl(ah, cmds[capability], setting) :
AH_FALSE;
}
case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
@@ -1053,7 +1055,7 @@ ar5212GetDiagState(struct ath_hal *ah, int request,
case HAL_DIAG_ANI_CMD:
if (argsize != 2*sizeof(uint32_t))
return AH_FALSE;
- ar5212AniControl(ah, ((const uint32_t *)args)[0],
+ AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0],
((const uint32_t *)args)[1]);
return AH_TRUE;
case HAL_DIAG_ANI_PARAMS:
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
index 3a8f785..e2c8592 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
@@ -175,9 +175,17 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params = aniState->params;
+ /* Check whether the particular function is enabled */
+ if (((1 << cmd) & AH5416(ah)->ah_ani_function) == 0) {
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: command %d disabled\n",
+ __func__, cmd);
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd %d; mask %x\n", __func__, cmd, AH5416(ah)->ah_ani_function);
+ return AH_FALSE;
+ }
+
OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd);
- switch (cmd & AH5416(ah)->ah_ani_function) {
+ switch (cmd) {
case HAL_ANI_NOISE_IMMUNITY_LEVEL: {
u_int level = param;
@@ -356,14 +364,14 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah)
aniState = ahp->ah_curani;
params = aniState->params;
/* First, raise noise immunity level, up to max */
- if ((AH5416(ah)->ah_ani_function & HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL)) &&
(aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1);
return;
}
/* then, raise spur immunity level, up to max */
- if ((AH5416(ah)->ah_ani_function & HAL_ANI_SPUR_IMMUNITY_LEVEL) &&
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL)) &&
(aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
aniState->spurImmunityLevel + 1);
@@ -443,7 +451,8 @@ ar5416AniCckErrTrigger(struct ath_hal *ah)
/* first, raise noise immunity level, up to max */
aniState = ahp->ah_curani;
params = aniState->params;
- if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
+ aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1);
return;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index 6779bf9..dc1a5ff 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -58,7 +58,7 @@ ar5416AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
@@ -199,7 +199,10 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
/* Enable all ANI functions to begin with */
- AH5416(ah)->ah_ani_function = HAL_ANI_ALL;
+ AH5416(ah)->ah_ani_function = 0xffffffff;
+
+ /* Set overridable ANI methods */
+ AH5212(ah)->ah_aniControl = ar5416AniControl;
}
uint32_t
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
index ee61c30..1356c7d 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
@@ -594,8 +594,8 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
if (AR_SREV_KITE(ah)) {
/* Kite has only one chain */
chainmask = 0x9;
- } else if (AR_SREV_MERLIN(ah)) {
- /* Merlin has only two chains */
+ } else if (AR_SREV_MERLIN(ah) || AR_SREV_KIWI(ah)) {
+ /* Merlin/Kiwi has only two chains */
chainmask = 0x1B;
} else {
chainmask = 0x3F;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
index d2ae351..1da686a 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
@@ -167,6 +167,17 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AH5416(ah)->ah_writeIni(ah, chan);
+ if(AR_SREV_KIWI_13_OR_LATER(ah) ) {
+ /* Enable ASYNC FIFO */
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+ OS_REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+ OS_REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ }
+
/* Override ini values (that can be overriden in this fashion) */
ar5416OverrideIni(ah, chan);
@@ -258,6 +269,12 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) |
saveLedState);
+ /* Start TSF2 for generic timer 8-15 */
+#ifdef NOTYET
+ if (AR_SREV_KIWI(ah))
+ ar5416StartTsf2(ah);
+#endif
+
/* Restore previous antenna */
OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
@@ -292,6 +309,41 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* This may override the AR_DIAG_SW register */
ar5416InitUserSettings(ah);
+ if (AR_SREV_KIWI_13_OR_LATER(ah)) {
+ /*
+ * Enable ASYNC FIFO
+ *
+ * If Async FIFO is enabled, the following counters change
+ * as MAC now runs at 117 Mhz instead of 88/44MHz when
+ * async FIFO is disabled.
+ *
+ * Overwrite the delay/timeouts initialized in ProcessIni()
+ * above.
+ */
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+ AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+ AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+ AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+ OS_REG_WRITE(ah, AR_TIME_OUT,
+ AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+ AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+ OS_REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+ AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+ }
+
+ if (AR_SREV_KIWI_13_OR_LATER(ah)) {
+ /* Enable AGGWEP to accelerate encryption engine */
+ OS_REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+ }
+
+
/*
* disable seq number generation in hw
*/
@@ -2576,7 +2628,7 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
if (!AR_SREV_9271(ah))
val &= ~AR_PCU_MISC_MODE2_HWWAR1;
- if (AR_SREV_9287_11_OR_LATER(ah))
+ if (AR_SREV_KIWI_11_OR_LATER(ah))
val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
index 3cf7da9..48956c5 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
@@ -208,10 +208,11 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(ahp->ah_tx_chainmask, AR_ChainSel2)
| SM(ahp->ah_tx_chainmask, AR_ChainSel3)
;
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = (txPower << 24); /* XXX? */
- ads->ds_ctl10 = (txPower << 24); /* XXX? */
- ads->ds_ctl11 = (txPower << 24); /* XXX? */
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
+
if (keyIx != HAL_TXKEYIX_INVALID) {
/* XXX validate key index */
ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
@@ -232,11 +233,16 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
}
+ /*
+ * Set the TX antenna to 0 for Kite
+ * To preserve existing behaviour, also set the TPC bits to 0;
+ * when TPC is enabled these should be filled in appropriately.
+ */
if (AR_SREV_KITE(ah)) {
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = 0;
- ads->ds_ctl10 = 0;
- ads->ds_ctl11 = 0;
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
return AH_TRUE;
#undef RTSCTS
@@ -410,10 +416,10 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
/* NB: no V1 WAR */
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = (txPower << 24);
- ads->ds_ctl10 = (txPower << 24);
- ads->ds_ctl11 = (txPower << 24);
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
ads->ds_ctl6 &= ~(0xffff);
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
@@ -424,11 +430,16 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
}
+ /*
+ * Set the TX antenna to 0 for Kite
+ * To preserve existing behaviour, also set the TPC bits to 0;
+ * when TPC is enabled these should be filled in appropriately.
+ */
if (AR_SREV_KITE(ah)) {
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = 0;
- ads->ds_ctl10 = 0;
- ads->ds_ctl11 = 0;
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
return AH_TRUE;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
index 76f5080..105c5d6 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
@@ -205,6 +205,29 @@ struct ar5416_desc {
#define AR_STBC2 0x40000000
#define AR_STBC3 0x80000000
+/* ds_ctl8 */
+#define AR_AntCtl0 0x00ffffff
+#define AR_AntCtl0_S 0
+/* Xmit 0 TPC is AR_XmitPower in ctl0 */
+
+/* ds_ctl9 */
+#define AR_AntCtl1 0x00ffffff
+#define AR_AntCtl1_S 0
+#define AR_XmitPower1 0xff000000
+#define AR_XmitPower1_S 24
+
+/* ds_ctl10 */
+#define AR_AntCtl2 0x00ffffff
+#define AR_AntCtl2_S 0
+#define AR_XmitPower2 0xff000000
+#define AR_XmitPower2_S 24
+
+/* ds_ctl11 */
+#define AR_AntCtl3 0x00ffffff
+#define AR_AntCtl3_S 0
+#define AR_XmitPower3 0xff000000
+#define AR_XmitPower3_S 24
+
/*************
* TX Status *
*************/
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
index 86643f0..2c419d7 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
@@ -301,4 +301,6 @@
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+#define AR_PHY_MODE_ASYNCFIFO 0x80 /* Enable async fifo */
+
#endif /* _DEV_ATH_AR5416PHY_H_ */
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
index 9921366..561c5b4 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
@@ -219,6 +219,10 @@
#define AR_AHB_PAGE_SIZE_1K 0x00000000 /* set page-size as 1k */
#define AR_AHB_PAGE_SIZE_2K 0x00000008 /* set page-size as 2k */
#define AR_AHB_PAGE_SIZE_4K 0x00000010 /* set page-size as 4k */
+/* Kiwi */
+#define AR_AHB_CUSTOM_BURST_EN 0x000000C0 /* set Custom Burst Mode */
+#define AR_AHB_CUSTOM_BURST_EN_S 6 /* set Custom Burst Mode */
+#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3 /* set both bits in Async FIFO mode */
/* MAC PCU Registers */
#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 /* Don't replace seq num */
@@ -451,9 +455,23 @@
* For Merlin and above only.
*/
#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040
+#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000 /* Kiwi or later? */
#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000
#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
+/* For Kiwi */
+#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
+
+/* TSF2. For Kiwi only */
+#define AR_TSF2_L32 0x8390
+#define AR_TSF2_U32 0x8394
+
+/* MAC Direct Connect Control. For Kiwi only */
+#define AR_DIRECT_CONNECT 0x83A0
+#define AR_DC_AP_STA_EN 0x00000001
+
/* GPIO Interrupt */
#define AR_INTR_GPIO 0x3FF00000 /* gpio interrupted */
#define AR_INTR_GPIO_S 20
@@ -488,6 +506,17 @@
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
+/* IFS, SIFS, slot, etc for Async FIFO mode (Kiwi) */
+#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
+#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56
+#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074
+#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420
+#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB
+
+/* Used by Kiwi Async FIFO */
+#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264
+#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000
+
/* Eeprom defines */
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0
@@ -566,6 +595,11 @@
#define AR_XSREV_REVISION_KITE_10 0 /* Kite 1.0 */
#define AR_XSREV_REVISION_KITE_11 1 /* Kite 1.1 */
#define AR_XSREV_REVISION_KITE_12 2 /* Kite 1.2 */
+#define AR_XSREV_VERSION_KIWI 0x180 /* Kiwi (AR9287) */
+#define AR_XSREV_REVISION_KIWI_10 0
+#define AR_XSREV_REVISION_KIWI_11 1
+#define AR_XSREV_REVISION_KIWI_12 2
+#define AR_XSREV_REVISION_KIWI_13 3
/* Owl (AR5416) */
#define AR_SREV_OWL(_ah) \
@@ -648,9 +682,31 @@
(AR_SREV_KITE_12_OR_LATER(_ah) && \
((OS_REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
+#define AR_SREV_KIWI(_ah) \
+ (AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KIWI)
+
+#define AR_SREV_KIWI_11_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_11)
+
+#define AR_SREV_KIWI_11(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_11)
+
+#define AR_SREV_KIWI_12(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_12)
+
+#define AR_SREV_KIWI_12_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_12)
+
+#define AR_SREV_KIWI_13_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_13)
+
+
/* Not yet implemented chips */
#define AR_SREV_9271(_ah) 0
-#define AR_SREV_9287_11_OR_LATER(_ah) 0
-#define AR_SREV_KIWI_10_OR_LATER(_ah) 0
#endif /* _DEV_ATH_AR5416REG_H */
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
index 0b6472b..0d950d2 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
@@ -82,7 +82,7 @@ ar9160AniSetup(struct ath_hal *ah)
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
index 3351edb..77b9f58 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
@@ -93,7 +93,7 @@ ar9280AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
/* NB: ANI is not enabled yet */
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
index b7ed27d..111bea2 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
@@ -98,7 +98,7 @@ ar9285AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
index e4e73d4..b28b97f 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
@@ -87,8 +87,10 @@ ar9285_check_div_comb(struct ath_hal *ah)
HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader;
+#if 0
/* For now, simply disable this until it's better debugged. -adrian */
return AH_FALSE;
+#endif
if (! AR_SREV_KITE(ah))
return AH_FALSE;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.c b/sys/dev/ath/ath_hal/ar9002/ar9287.c
new file mode 100644
index 0000000..92501ca
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+/*
+ * NB: Merlin and later have a simpler RF backend.
+ */
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v14.h"
+
+#include "ar9002/ar9287.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+struct ar9287State {
+ RF_HAL_FUNCS base; /* public state, must be first */
+ uint16_t pcdacTable[1]; /* XXX */
+};
+#define AR9280(ah) ((struct ar9287State *) AH5212(ah)->ah_rfHal)
+
+static HAL_BOOL ar9287GetChannelMaxMinPower(struct ath_hal *,
+ const struct ieee80211_channel *, int16_t *maxPow,int16_t *minPow);
+int16_t ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c);
+
+static void
+ar9287WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
+ int writes)
+{
+ (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain,
+ freqIndex, writes);
+}
+
+/*
+ * Take the MHz channel value and set the Channel value
+ *
+ * ASSUMES: Writes enabled to analog bus
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ *
+ * For 5GHz channels which are 5MHz spaced,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ */
+static HAL_BOOL
+ar9287SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ uint16_t bMode, fracMode, aModeRefSel = 0;
+ uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+ CHAN_CENTERS centers;
+ uint32_t refDivA = 24;
+
+ OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq);
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+ freq = centers.synth_center;
+
+ reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+ reg32 &= 0xc0000000;
+
+ if (freq < 4800) { /* 2 GHz, fractional mode */
+ uint32_t txctl;
+ int regWrites = 0;
+
+ bMode = 1;
+ fracMode = 1;
+ aModeRefSel = 0;
+ channelSel = (freq * 0x10000)/15;
+
+ if (AR_SREV_KIWI_11_OR_LATER(ah)) {
+ if (freq == 2484) {
+ ath_hal_ini_write(ah,
+ &AH9287(ah)->ah_ini_cckFirJapan2484, 1,
+ regWrites);
+ } else {
+ ath_hal_ini_write(ah,
+ &AH9287(ah)->ah_ini_cckFirNormal, 1,
+ regWrites);
+ }
+ }
+
+ txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+ if (freq == 2484) {
+ /* Enable channel spreading for channel 14 */
+ OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+ txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+ } else {
+ OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+ txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
+ }
+ } else {
+ bMode = 0;
+ fracMode = 0;
+
+ if ((freq % 20) == 0) {
+ aModeRefSel = 3;
+ } else if ((freq % 10) == 0) {
+ aModeRefSel = 2;
+ } else {
+ aModeRefSel = 0;
+ /*
+ * Enable 2G (fractional) mode for channels which
+ * are 5MHz spaced
+ */
+ fracMode = 1;
+ refDivA = 1;
+ channelSel = (freq * 0x8000)/15;
+
+ /* RefDivA setting */
+ OS_A_REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+ AR_AN_SYNTH9_REFDIVA, refDivA);
+ }
+ if (!fracMode) {
+ ndiv = (freq * (refDivA >> aModeRefSel))/60;
+ channelSel = ndiv & 0x1ff;
+ channelFrac = (ndiv & 0xfffffe00) * 2;
+ channelSel = (channelSel << 17) | channelFrac;
+ }
+ }
+
+ reg32 = reg32 | (bMode << 29) | (fracMode << 28) |
+ (aModeRefSel << 26) | (channelSel);
+
+ OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+ AH_PRIVATE(ah)->ah_curchan = chan;
+
+ return AH_TRUE;
+}
+
+/*
+ * Return a reference to the requested RF Bank.
+ */
+static uint32_t *
+ar9287GetRfBank(struct ath_hal *ah, int bank)
+{
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n",
+ __func__, bank);
+ return AH_NULL;
+}
+
+/*
+ * Reads EEPROM header info from device structure and programs
+ * all rf registers
+ */
+static HAL_BOOL
+ar9287SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
+{
+ return AH_TRUE; /* nothing to do */
+}
+
+/*
+ * Read the transmit power levels from the structures taken from EEPROM
+ * Interpolate read transmit power values for this channel
+ * Organize the transmit power values into a table for writing into the hardware
+ */
+
+static HAL_BOOL
+ar9287SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
+{
+ return AH_TRUE;
+}
+
+#if 0
+static int16_t
+ar9287GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data)
+{
+ int i, minIndex;
+ int16_t minGain,minPwr,minPcdac,retVal;
+
+ /* Assume NUM_POINTS_XPD0 > 0 */
+ minGain = data->pDataPerXPD[0].xpd_gain;
+ for (minIndex=0,i=1; i<NUM_XPD_PER_CHANNEL; i++) {
+ if (data->pDataPerXPD[i].xpd_gain < minGain) {
+ minIndex = i;
+ minGain = data->pDataPerXPD[i].xpd_gain;
+ }
+ }
+ minPwr = data->pDataPerXPD[minIndex].pwr_t4[0];
+ minPcdac = data->pDataPerXPD[minIndex].pcdac[0];
+ for (i=1; i<NUM_POINTS_XPD0; i++) {
+ if (data->pDataPerXPD[minIndex].pwr_t4[i] < minPwr) {
+ minPwr = data->pDataPerXPD[minIndex].pwr_t4[i];
+ minPcdac = data->pDataPerXPD[minIndex].pcdac[i];
+ }
+ }
+ retVal = minPwr - (minPcdac*2);
+ return(retVal);
+}
+#endif
+
+static HAL_BOOL
+ar9287GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ int16_t *maxPow, int16_t *minPow)
+{
+#if 0
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ int numChannels=0,i,last;
+ int totalD, totalF,totalMin;
+ EXPN_DATA_PER_CHANNEL_5112 *data=AH_NULL;
+ EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL;
+
+ *maxPow = 0;
+ if (IS_CHAN_A(chan)) {
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11A].pDataPerChannel;
+ numChannels = powerArray[headerInfo11A].numChannels;
+ } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) {
+ /* XXX - is this correct? Should we also use the same power for turbo G? */
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11G].pDataPerChannel;
+ numChannels = powerArray[headerInfo11G].numChannels;
+ } else if (IS_CHAN_B(chan)) {
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11B].pDataPerChannel;
+ numChannels = powerArray[headerInfo11B].numChannels;
+ } else {
+ return (AH_TRUE);
+ }
+ /* Make sure the channel is in the range of the TP values
+ * (freq piers)
+ */
+ if ((numChannels < 1) ||
+ (chan->channel < data[0].channelValue) ||
+ (chan->channel > data[numChannels-1].channelValue))
+ return(AH_FALSE);
+
+ /* Linearly interpolate the power value now */
+ for (last=0,i=0;
+ (i<numChannels) && (chan->channel > data[i].channelValue);
+ last=i++);
+ totalD = data[i].channelValue - data[last].channelValue;
+ if (totalD > 0) {
+ totalF = data[i].maxPower_t4 - data[last].maxPower_t4;
+ *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
+
+ totalMin = ar9287GetMinPower(ah,&data[i]) - ar9287GetMinPower(ah, &data[last]);
+ *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar9287GetMinPower(ah, &data[last])*totalD)/totalD);
+ return (AH_TRUE);
+ } else {
+ if (chan->channel == data[i].channelValue) {
+ *maxPow = data[i].maxPower_t4;
+ *minPow = ar9287GetMinPower(ah, &data[i]);
+ return(AH_TRUE);
+ } else
+ return(AH_FALSE);
+ }
+#else
+ *maxPow = *minPow = 0;
+ return AH_FALSE;
+#endif
+}
+
+/*
+ * The ordering of nfarray is thus:
+ *
+ * nfarray[0]: Chain 0 ctl
+ * nfarray[1]: Chain 1 ctl
+ * nfarray[2]: Chain 2 ctl
+ * nfarray[3]: Chain 0 ext
+ * nfarray[4]: Chain 1 ext
+ * nfarray[5]: Chain 2 ext
+ */
+static void
+ar9287GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
+{
+ int16_t nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ctl] [chain 0] is %d\n", nf);
+ nfarray[0] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ctl] [chain 1] is %d\n", nf);
+ nfarray[1] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ext] [chain 0] is %d\n", nf);
+ nfarray[3] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ext] [chain 1] is %d\n", nf);
+ nfarray[4] = nf;
+
+ /* Chain 2 - invalid */
+ nfarray[2] = 0;
+ nfarray[5] = 0;
+
+}
+
+/*
+ * Adjust NF based on statistical values for 5GHz frequencies.
+ * Stubbed:Not used by Fowl
+ */
+int16_t
+ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
+{
+ return 0;
+}
+
+/*
+ * Free memory for analog bank scratch buffers
+ */
+static void
+ar9287RfDetach(struct ath_hal *ah)
+{
+ struct ath_hal_5212 *ahp = AH5212(ah);
+
+ HALASSERT(ahp->ah_rfHal != AH_NULL);
+ ath_hal_free(ahp->ah_rfHal);
+ ahp->ah_rfHal = AH_NULL;
+}
+
+HAL_BOOL
+ar9287RfAttach(struct ath_hal *ah, HAL_STATUS *status)
+{
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ struct ar9287State *priv;
+
+ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: attach AR9280 radio\n", __func__);
+
+ HALASSERT(ahp->ah_rfHal == AH_NULL);
+ priv = ath_hal_malloc(sizeof(struct ar9287State));
+ if (priv == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: cannot allocate private state\n", __func__);
+ *status = HAL_ENOMEM; /* XXX */
+ return AH_FALSE;
+ }
+ priv->base.rfDetach = ar9287RfDetach;
+ priv->base.writeRegs = ar9287WriteRegs;
+ priv->base.getRfBank = ar9287GetRfBank;
+ priv->base.setChannel = ar9287SetChannel;
+ priv->base.setRfRegs = ar9287SetRfRegs;
+ priv->base.setPowerTable = ar9287SetPowerTable;
+ priv->base.getChannelMaxMinPower = ar9287GetChannelMaxMinPower;
+ priv->base.getNfAdjust = ar9287GetNfAdjust;
+
+ ahp->ah_pcdacTable = priv->pcdacTable;
+ ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable);
+ ahp->ah_rfHal = &priv->base;
+ /*
+ * Set noise floor adjust method; we arrange a
+ * direct call instead of thunking.
+ */
+ AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust;
+ AH_PRIVATE(ah)->ah_getNoiseFloor = ar9287GetNoiseFloor;
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.h b/sys/dev/ath/ath_hal/ar9002/ar9287.h
new file mode 100644
index 0000000..90d25ed
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ATH_AR9287_H_
+#define _ATH_AR9287_H_
+
+#include "ar5416/ar5416.h"
+
+/*
+ * This is a chip thing, but it's used here as part of the
+ * ath_hal_9287 struct; so it's convienent to locate the
+ * define here.
+ */
+#define AR9287_TX_GAIN_TABLE_SIZE 22
+
+struct ath_hal_9287 {
+ struct ath_hal_5416 ah_5416;
+
+ HAL_INI_ARRAY ah_ini_xmodes;
+ HAL_INI_ARRAY ah_ini_rxgain;
+ HAL_INI_ARRAY ah_ini_txgain;
+
+ HAL_INI_ARRAY ah_ini_cckFirNormal;
+ HAL_INI_ARRAY ah_ini_cckFirJapan2484;
+
+ int PDADCdelta;
+
+ uint32_t originalGain[AR9287_TX_GAIN_TABLE_SIZE];
+};
+#define AH9287(_ah) ((struct ath_hal_9287 *)(_ah))
+
+#define AR9287_DEFAULT_RXCHAINMASK 3
+#define AR9285_DEFAULT_RXCHAINMASK 1
+#define AR9287_DEFAULT_TXCHAINMASK 3
+#define AR9285_DEFAULT_TXCHAINMASK 1
+
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -112
+#define AR_PHY_CCA_NOM_VAL_9287_5GHZ -112
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ -122
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -97
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ -102
+
+extern HAL_BOOL ar9287RfAttach(struct ath_hal *, HAL_STATUS *);
+extern HAL_BOOL ar9287SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
+
+#endif /* _ATH_AR9287_H_ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.ini b/sys/dev/ath/ath_hal/ar9002/ar9287.ini
new file mode 100644
index 0000000..7f4ca05
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.ini
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+static const uint32_t ar9287Modes_9287_1_1[][6] = {
+ {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0},
+ {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0},
+ {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180},
+ {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+ {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0},
+ {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f},
+ {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
+ {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a},
+ {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880},
+ {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303},
+ {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200},
+ {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+ {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001},
+ {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+ {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007},
+ {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e},
+ {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0},
+ {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2},
+ {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+ {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e},
+ {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18},
+ {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+ {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881},
+ {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0},
+ {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016},
+ {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
+ {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010},
+ {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+ {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+ {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210},
+ {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce},
+ {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c},
+ {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00},
+ {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444},
+ {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a},
+ {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+ {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000},
+ {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+ {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const uint32_t ar9287Common_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000000c, 0x00000000},
+ {0x00000030, 0x00020015},
+ {0x00000034, 0x00000005},
+ {0x00000040, 0x00000000},
+ {0x00000044, 0x00000008},
+ {0x00000048, 0x00000008},
+ {0x0000004c, 0x00000010},
+ {0x00000050, 0x00000000},
+ {0x00000054, 0x0000001f},
+ {0x00000800, 0x00000000},
+ {0x00000804, 0x00000000},
+ {0x00000808, 0x00000000},
+ {0x0000080c, 0x00000000},
+ {0x00000810, 0x00000000},
+ {0x00000814, 0x00000000},
+ {0x00000818, 0x00000000},
+ {0x0000081c, 0x00000000},
+ {0x00000820, 0x00000000},
+ {0x00000824, 0x00000000},
+ {0x00001040, 0x002ffc0f},
+ {0x00001044, 0x002ffc0f},
+ {0x00001048, 0x002ffc0f},
+ {0x0000104c, 0x002ffc0f},
+ {0x00001050, 0x002ffc0f},
+ {0x00001054, 0x002ffc0f},
+ {0x00001058, 0x002ffc0f},
+ {0x0000105c, 0x002ffc0f},
+ {0x00001060, 0x002ffc0f},
+ {0x00001064, 0x002ffc0f},
+ {0x00001230, 0x00000000},
+ {0x00001270, 0x00000000},
+ {0x00001038, 0x00000000},
+ {0x00001078, 0x00000000},
+ {0x000010b8, 0x00000000},
+ {0x000010f8, 0x00000000},
+ {0x00001138, 0x00000000},
+ {0x00001178, 0x00000000},
+ {0x000011b8, 0x00000000},
+ {0x000011f8, 0x00000000},
+ {0x00001238, 0x00000000},
+ {0x00001278, 0x00000000},
+ {0x000012b8, 0x00000000},
+ {0x000012f8, 0x00000000},
+ {0x00001338, 0x00000000},
+ {0x00001378, 0x00000000},
+ {0x000013b8, 0x00000000},
+ {0x000013f8, 0x00000000},
+ {0x00001438, 0x00000000},
+ {0x00001478, 0x00000000},
+ {0x000014b8, 0x00000000},
+ {0x000014f8, 0x00000000},
+ {0x00001538, 0x00000000},
+ {0x00001578, 0x00000000},
+ {0x000015b8, 0x00000000},
+ {0x000015f8, 0x00000000},
+ {0x00001638, 0x00000000},
+ {0x00001678, 0x00000000},
+ {0x000016b8, 0x00000000},
+ {0x000016f8, 0x00000000},
+ {0x00001738, 0x00000000},
+ {0x00001778, 0x00000000},
+ {0x000017b8, 0x00000000},
+ {0x000017f8, 0x00000000},
+ {0x0000103c, 0x00000000},
+ {0x0000107c, 0x00000000},
+ {0x000010bc, 0x00000000},
+ {0x000010fc, 0x00000000},
+ {0x0000113c, 0x00000000},
+ {0x0000117c, 0x00000000},
+ {0x000011bc, 0x00000000},
+ {0x000011fc, 0x00000000},
+ {0x0000123c, 0x00000000},
+ {0x0000127c, 0x00000000},
+ {0x000012bc, 0x00000000},
+ {0x000012fc, 0x00000000},
+ {0x0000133c, 0x00000000},
+ {0x0000137c, 0x00000000},
+ {0x000013bc, 0x00000000},
+ {0x000013fc, 0x00000000},
+ {0x0000143c, 0x00000000},
+ {0x0000147c, 0x00000000},
+ {0x00004030, 0x00000002},
+ {0x0000403c, 0x00000002},
+ {0x00004024, 0x0000001f},
+ {0x00004060, 0x00000000},
+ {0x00004064, 0x00000000},
+ {0x00007010, 0x00000033},
+ {0x00007020, 0x00000000},
+ {0x00007034, 0x00000002},
+ {0x00007038, 0x000004c2},
+ {0x00008004, 0x00000000},
+ {0x00008008, 0x00000000},
+ {0x0000800c, 0x00000000},
+ {0x00008018, 0x00000700},
+ {0x00008020, 0x00000000},
+ {0x00008038, 0x00000000},
+ {0x0000803c, 0x00000000},
+ {0x00008048, 0x40000000},
+ {0x00008054, 0x00000000},
+ {0x00008058, 0x00000000},
+ {0x0000805c, 0x000fc78f},
+ {0x00008060, 0x0000000f},
+ {0x00008064, 0x00000000},
+ {0x00008070, 0x00000000},
+ {0x000080c0, 0x2a80001a},
+ {0x000080c4, 0x05dc01e0},
+ {0x000080c8, 0x1f402710},
+ {0x000080cc, 0x01f40000},
+ {0x000080d0, 0x00001e00},
+ {0x000080d4, 0x00000000},
+ {0x000080d8, 0x00400000},
+ {0x000080e0, 0xffffffff},
+ {0x000080e4, 0x0000ffff},
+ {0x000080e8, 0x003f3f3f},
+ {0x000080ec, 0x00000000},
+ {0x000080f0, 0x00000000},
+ {0x000080f4, 0x00000000},
+ {0x000080f8, 0x00000000},
+ {0x000080fc, 0x00020000},
+ {0x00008100, 0x00020000},
+ {0x00008104, 0x00000001},
+ {0x00008108, 0x00000052},
+ {0x0000810c, 0x00000000},
+ {0x00008110, 0x00000168},
+ {0x00008118, 0x000100aa},
+ {0x0000811c, 0x00003210},
+ {0x00008124, 0x00000000},
+ {0x00008128, 0x00000000},
+ {0x0000812c, 0x00000000},
+ {0x00008130, 0x00000000},
+ {0x00008134, 0x00000000},
+ {0x00008138, 0x00000000},
+ {0x0000813c, 0x00000000},
+ {0x00008144, 0xffffffff},
+ {0x00008168, 0x00000000},
+ {0x0000816c, 0x00000000},
+ {0x00008170, 0x18487320},
+ {0x00008174, 0xfaa4fa50},
+ {0x00008178, 0x00000100},
+ {0x0000817c, 0x00000000},
+ {0x000081c0, 0x00000000},
+ {0x000081c4, 0x00000000},
+ {0x000081d4, 0x00000000},
+ {0x000081ec, 0x00000000},
+ {0x000081f0, 0x00000000},
+ {0x000081f4, 0x00000000},
+ {0x000081f8, 0x00000000},
+ {0x000081fc, 0x00000000},
+ {0x00008200, 0x00000000},
+ {0x00008204, 0x00000000},
+ {0x00008208, 0x00000000},
+ {0x0000820c, 0x00000000},
+ {0x00008210, 0x00000000},
+ {0x00008214, 0x00000000},
+ {0x00008218, 0x00000000},
+ {0x0000821c, 0x00000000},
+ {0x00008220, 0x00000000},
+ {0x00008224, 0x00000000},
+ {0x00008228, 0x00000000},
+ {0x0000822c, 0x00000000},
+ {0x00008230, 0x00000000},
+ {0x00008234, 0x00000000},
+ {0x00008238, 0x00000000},
+ {0x0000823c, 0x00000000},
+ {0x00008240, 0x00100000},
+ {0x00008244, 0x0010f400},
+ {0x00008248, 0x00000100},
+ {0x0000824c, 0x0001e800},
+ {0x00008250, 0x00000000},
+ {0x00008254, 0x00000000},
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x400000ff},
+ {0x00008260, 0x00080922},
+ {0x00008264, 0x88a00010},
+ {0x00008270, 0x00000000},
+ {0x00008274, 0x40000000},
+ {0x00008278, 0x003e4180},
+ {0x0000827c, 0x00000000},
+ {0x00008284, 0x0000002c},
+ {0x00008288, 0x0000002c},
+ {0x0000828c, 0x000000ff},
+ {0x00008294, 0x00000000},
+ {0x00008298, 0x00000000},
+ {0x0000829c, 0x00000000},
+ {0x00008300, 0x00000040},
+ {0x00008314, 0x00000000},
+ {0x00008328, 0x00000000},
+ {0x0000832c, 0x00000007},
+ {0x00008330, 0x00000302},
+ {0x00008334, 0x00000e00},
+ {0x00008338, 0x00ff0000},
+ {0x0000833c, 0x00000000},
+ {0x00008340, 0x000107ff},
+ {0x00008344, 0x01c81043},
+ {0x00008360, 0xffffffff},
+ {0x00008364, 0xffffffff},
+ {0x00008368, 0x00000000},
+ {0x00008370, 0x00000000},
+ {0x00008374, 0x000000ff},
+ {0x00008378, 0x00000000},
+ {0x0000837c, 0x00000000},
+ {0x00008380, 0xffffffff},
+ {0x00008384, 0xffffffff},
+ {0x00008390, 0x0fffffff},
+ {0x00008394, 0x0fffffff},
+ {0x00008398, 0x00000000},
+ {0x0000839c, 0x00000000},
+ {0x000083a0, 0x00000000},
+ {0x00009808, 0x00000000},
+ {0x0000980c, 0xafe68e30},
+ {0x00009810, 0xfd14e000},
+ {0x00009814, 0x9c0a9f6b},
+ {0x0000981c, 0x00000000},
+ {0x0000982c, 0x0000a000},
+ {0x00009830, 0x00000000},
+ {0x0000983c, 0x00200400},
+ {0x0000984c, 0x0040233c},
+ {0x0000a84c, 0x0040233c},
+ {0x00009854, 0x00000044},
+ {0x00009900, 0x00000000},
+ {0x00009904, 0x00000000},
+ {0x00009908, 0x00000000},
+ {0x0000990c, 0x00000000},
+ {0x00009910, 0x10002310},
+ {0x0000991c, 0x10000fff},
+ {0x00009920, 0x04900000},
+ {0x0000a920, 0x04900000},
+ {0x00009928, 0x00000001},
+ {0x0000992c, 0x00000004},
+ {0x00009930, 0x00000000},
+ {0x0000a930, 0x00000000},
+ {0x00009934, 0x1e1f2022},
+ {0x00009938, 0x0a0b0c0d},
+ {0x0000993c, 0x00000000},
+ {0x00009948, 0x9280c00a},
+ {0x0000994c, 0x00020028},
+ {0x00009954, 0x5f3ca3de},
+ {0x00009958, 0x0108ecff},
+ {0x00009940, 0x14750604},
+ {0x0000c95c, 0x004b6a8e},
+ {0x00009970, 0x990bb514},
+ {0x00009974, 0x00000000},
+ {0x00009978, 0x00000001},
+ {0x0000997c, 0x00000000},
+ {0x000099a0, 0x00000000},
+ {0x000099a4, 0x00000001},
+ {0x000099a8, 0x201fff00},
+ {0x000099ac, 0x0c6f0000},
+ {0x000099b0, 0x03051000},
+ {0x000099b4, 0x00000820},
+ {0x000099c4, 0x06336f77},
+ {0x000099c8, 0x6af6532f},
+ {0x000099cc, 0x08f186c8},
+ {0x000099d0, 0x00046384},
+ {0x000099dc, 0x00000000},
+ {0x000099e0, 0x00000000},
+ {0x000099e4, 0xaaaaaaaa},
+ {0x000099e8, 0x3c466478},
+ {0x000099ec, 0x0cc80caa},
+ {0x000099f0, 0x00000000},
+ {0x000099fc, 0x00001042},
+ {0x0000a208, 0x803e4788},
+ {0x0000a210, 0x4080a333},
+ {0x0000a214, 0x40206c10},
+ {0x0000a218, 0x009c4060},
+ {0x0000a220, 0x01834061},
+ {0x0000a224, 0x00000400},
+ {0x0000a228, 0x000003b5},
+ {0x0000a22c, 0x233f7180},
+ {0x0000a234, 0x20202020},
+ {0x0000a238, 0x20202020},
+ {0x0000a23c, 0x13c889af},
+ {0x0000a240, 0x38490a20},
+ {0x0000a244, 0x00000000},
+ {0x0000a248, 0xfffffffc},
+ {0x0000a24c, 0x00000000},
+ {0x0000a254, 0x00000000},
+ {0x0000a258, 0x0cdbd380},
+ {0x0000a25c, 0x0f0f0f01},
+ {0x0000a260, 0xdfa91f01},
+ {0x0000a264, 0x00418a11},
+ {0x0000b264, 0x00418a11},
+ {0x0000a268, 0x00000000},
+ {0x0000a26c, 0x0e79e5c6},
+ {0x0000b26c, 0x0e79e5c6},
+ {0x0000d270, 0x00820820},
+ {0x0000a278, 0x1ce739ce},
+ {0x0000a27c, 0x050701ce},
+ {0x0000d35c, 0x07ffffef},
+ {0x0000d360, 0x0fffffe7},
+ {0x0000d364, 0x17ffffe5},
+ {0x0000d368, 0x1fffffe4},
+ {0x0000d36c, 0x37ffffe3},
+ {0x0000d370, 0x3fffffe3},
+ {0x0000d374, 0x57ffffe3},
+ {0x0000d378, 0x5fffffe2},
+ {0x0000d37c, 0x7fffffe2},
+ {0x0000d380, 0x7f3c7bba},
+ {0x0000d384, 0xf3307ff0},
+ {0x0000a388, 0x0c000000},
+ {0x0000a38c, 0x20202020},
+ {0x0000a390, 0x20202020},
+ {0x0000a394, 0x1ce739ce},
+ {0x0000a398, 0x000001ce},
+ {0x0000b398, 0x000001ce},
+ {0x0000a39c, 0x00000001},
+ {0x0000a3c8, 0x00000246},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3dc, 0x1ce739ce},
+ {0x0000a3e0, 0x000001ce},
+ {0x0000a3e4, 0x00000000},
+ {0x0000a3e8, 0x18c43433},
+ {0x0000a3ec, 0x00f70081},
+ {0x0000a3f0, 0x01036a1e},
+ {0x0000a3f4, 0x00000000},
+ {0x0000b3f4, 0x00000000},
+ {0x0000a7d8, 0x000003f1},
+ {0x00007800, 0x00000800},
+ {0x00007804, 0x6c35ffd2},
+ {0x00007808, 0x6db6c000},
+ {0x0000780c, 0x6db6cb30},
+ {0x00007810, 0x6db6cb6c},
+ {0x00007814, 0x0501e200},
+ {0x00007818, 0x0094128d},
+ {0x0000781c, 0x976ee392},
+ {0x00007820, 0xf75ff6fc},
+ {0x00007824, 0x00040000},
+ {0x00007828, 0xdb003012},
+ {0x0000782c, 0x04924914},
+ {0x00007830, 0x21084210},
+ {0x00007834, 0x00140000},
+ {0x00007838, 0x0e4548d8},
+ {0x0000783c, 0x54214514},
+ {0x00007840, 0x02025830},
+ {0x00007844, 0x71c0d388},
+ {0x00007848, 0x934934a8},
+ {0x00007850, 0x00000000},
+ {0x00007854, 0x00000800},
+ {0x00007858, 0x6c35ffd2},
+ {0x0000785c, 0x6db6c000},
+ {0x00007860, 0x6db6cb30},
+ {0x00007864, 0x6db6cb6c},
+ {0x00007868, 0x0501e200},
+ {0x0000786c, 0x0094128d},
+ {0x00007870, 0x976ee392},
+ {0x00007874, 0xf75ff6fc},
+ {0x00007878, 0x00040000},
+ {0x0000787c, 0xdb003012},
+ {0x00007880, 0x04924914},
+ {0x00007884, 0x21084210},
+ {0x00007888, 0x001b6db0},
+ {0x0000788c, 0x00376b63},
+ {0x00007890, 0x06db6db6},
+ {0x00007894, 0x006d8000},
+ {0x00007898, 0x48100000},
+ {0x0000789c, 0x00000000},
+ {0x000078a0, 0x08000000},
+ {0x000078a4, 0x0007ffd8},
+ {0x000078a8, 0x0007ffd8},
+ {0x000078ac, 0x001c0020},
+ {0x000078b0, 0x00060aeb},
+ {0x000078b4, 0x40008080},
+ {0x000078b8, 0x2a850160},
+};
+
+static const uint32_t ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000a1f4, 0x00fffeff},
+ {0x0000a1f8, 0x00f5f9ff},
+ {0x0000a1fc, 0xb79f6427},
+};
+
+static const uint32_t ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000a1f4, 0x00000000},
+ {0x0000a1f8, 0xefff0301},
+ {0x0000a1fc, 0xca9228ee},
+};
+
+static const uint32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
+ {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002},
+ {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004},
+ {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a},
+ {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c},
+ {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b},
+ {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a},
+ {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a},
+ {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a},
+ {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a},
+ {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a},
+ {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a},
+ {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a},
+ {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a},
+ {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c},
+ {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc},
+ {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4},
+ {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc},
+ {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede},
+ {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e},
+ {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e},
+ {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e},
+ {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062},
+ {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064},
+ {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4},
+ {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa},
+ {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac},
+ {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4},
+ {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4},
+ {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134},
+ {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174},
+ {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c},
+ {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e},
+ {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be},
+ {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000},
+};
+
+static const uint32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
+ {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+ {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+ {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+ {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+ {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+ {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+ {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+ {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+ {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+ {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+ {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+ {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+ {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+ {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+ {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+ {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+ {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+ {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+ {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+ {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+ {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+ {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+ {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+ {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+ {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+ {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+ {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+ {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+ {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+ {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+ {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+ {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+ {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+ {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+ {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+ {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+ {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+ {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+ {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+ {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+ {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+ {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+ {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+ {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+ {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+ {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+ {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+ {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+ {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+ {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+ {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+ {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+ {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+ {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+ {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+ {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+ {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+ {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+ {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+ {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+ {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+ {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+ {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+ {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+ {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+ {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+ {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+ {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+ {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+ {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+ {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+ {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+ {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+ {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+ {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+ {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+ {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+ {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+ {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+ {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+ {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+ {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+ {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+ {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+ {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+ {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+ {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+ {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+ {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+ {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+ {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+ {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+ {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+ {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+ {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+ {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+ {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+ {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+ {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+ {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+ {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+ {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+ {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+ {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+ {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+ {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+ {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+ {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+ {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+ {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+ {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+ {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+ {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+ {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+ {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+ {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+ {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+ {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+ {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+ {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+ {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+ {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+ {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+ {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+ {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+ {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+ {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+ {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+ {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+ {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+ {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+ {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+ {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+ {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+ {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+ {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+ {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+ {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+ {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+ {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+ {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+ {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+ {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+ {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+ {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+ {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+ {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+ {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+ {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+ {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+ {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+ {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+ {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+ {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+ {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+ {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+ {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+ {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+ {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+ {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+ {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+ {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+ {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+ {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+ {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+ {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+ {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+ {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+ {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+ {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+ {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+ {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+ {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+ {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+ {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+ {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+ {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+ {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+ {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+ {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+ {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+ {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+ {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+ {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+ {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+ {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+ {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+ {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+ {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+ {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+ {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+ {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+ {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+ {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+ {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+ {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+ {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+ {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+ {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+ {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+ {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+ {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+ {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+ {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+ {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+ {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+ {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+ {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+};
+
+static const uint32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x00004040, 0x9248fd00},
+ {0x00004040, 0x24924924},
+ {0x00004040, 0xa8000019},
+ {0x00004040, 0x13160820},
+ {0x00004040, 0xe5980560},
+ {0x00004040, 0xc01dcffd},
+ {0x00004040, 0x1aaabe41},
+ {0x00004040, 0xbe105554},
+ {0x00004040, 0x00043007},
+ {0x00004044, 0x00000000},
+};
+
+static const uint32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x00004040, 0x9248fd00},
+ {0x00004040, 0x24924924},
+ {0x00004040, 0xa8000019},
+ {0x00004040, 0x13160820},
+ {0x00004040, 0xe5980560},
+ {0x00004040, 0xc01dcffc},
+ {0x00004040, 0x1aaabe41},
+ {0x00004040, 0xbe105554},
+ {0x00004040, 0x00043007},
+ {0x00004044, 0x00000000},
+};
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
new file mode 100644
index 0000000..daee414
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+
+#include "ah_eeprom_v14.h" /* XXX for tx/rx gain */
+#include "ah_eeprom_9287.h"
+
+#include "ar9002/ar9280.h"
+#include "ar9002/ar9287.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "ar9002/ar9287_cal.h"
+#include "ar9002/ar9287_reset.h"
+#include "ar9002/ar9287_olc.h"
+
+#include "ar9002/ar9287.ini"
+
+static const HAL_PERCAL_DATA ar9287_iq_cal = { /* single sample */
+ .calName = "IQ", .calType = IQ_MISMATCH_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MAX_LOG_COUNT,
+ .calCollect = ar5416IQCalCollect,
+ .calPostProc = ar5416IQCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_gain_cal = { /* single sample */
+ .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MIN_LOG_COUNT,
+ .calCollect = ar5416AdcGainCalCollect,
+ .calPostProc = ar5416AdcGainCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_dc_cal = { /* single sample */
+ .calName = "ADC DC", .calType = ADC_DC_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MIN_LOG_COUNT,
+ .calCollect = ar5416AdcDcCalCollect,
+ .calPostProc = ar5416AdcDcCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_init_dc_cal = {
+ .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = INIT_LOG_COUNT,
+ .calCollect = ar5416AdcDcCalCollect,
+ .calPostProc = ar5416AdcDcCalibration
+};
+
+static void ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
+static HAL_BOOL ar9287FillCapabilityInfo(struct ath_hal *ah);
+static void ar9287WriteIni(struct ath_hal *ah,
+ const struct ieee80211_channel *chan);
+
+static void
+ar9287AniSetup(struct ath_hal *ah)
+{
+ /*
+ * These are the parameters from the AR5416 ANI code;
+ * they likely need quite a bit of adjustment for the
+ * AR9280.
+ */
+ static const struct ar5212AniParams aniparams = {
+ .maxNoiseImmunityLevel = 4, /* levels 0..4 */
+ .totalSizeDesired = { -55, -55, -55, -55, -62 },
+ .coarseHigh = { -14, -14, -14, -14, -12 },
+ .coarseLow = { -64, -64, -64, -64, -70 },
+ .firpwr = { -78, -78, -78, -78, -80 },
+ .maxSpurImmunityLevel = 2,
+ .cycPwrThr1 = { 2, 4, 6 },
+ .maxFirstepLevel = 2, /* levels 0..2 */
+ .firstep = { 0, 4, 8 },
+ .ofdmTrigHigh = 500,
+ .ofdmTrigLow = 200,
+ .cckTrigHigh = 200,
+ .cckTrigLow = 100,
+ .rssiThrHigh = 40,
+ .rssiThrLow = 7,
+ .period = 100,
+ };
+ /* NB: disable ANI noise immmunity for reliable RIFS rx */
+ AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+
+ /* NB: ANI is not enabled yet */
+ ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
+}
+
+/*
+ * Attach for an AR9287 part.
+ */
+static struct ath_hal *
+ar9287Attach(uint16_t devid, HAL_SOFTC sc,
+ HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_STATUS *status)
+{
+ struct ath_hal_9287 *ahp9287;
+ struct ath_hal_5212 *ahp;
+ struct ath_hal *ah;
+ uint32_t val;
+ HAL_STATUS ecode;
+ HAL_BOOL rfStatus;
+ int8_t pwr_table_offset;
+
+ HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
+ __func__, sc, (void*) st, (void*) sh);
+
+ /* NB: memory is returned zero'd */
+ ahp9287 = ath_hal_malloc(sizeof (struct ath_hal_9287));
+ if (ahp9287 == AH_NULL) {
+ HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
+ "%s: cannot allocate memory for state block\n", __func__);
+ *status = HAL_ENOMEM;
+ return AH_NULL;
+ }
+ ahp = AH5212(ahp9287);
+ ah = &ahp->ah_priv.h;
+
+ ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
+
+ /* XXX override with 9280 specific state */
+ /* override 5416 methods for our needs */
+ ah->ah_setAntennaSwitch = ar9287SetAntennaSwitch;
+ ah->ah_configPCIE = ar9287ConfigPCIE;
+
+ AH5416(ah)->ah_cal.iqCalData.calData = &ar9287_iq_cal;
+ AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9287_adc_gain_cal;
+ AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9287_adc_dc_cal;
+ AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9287_adc_init_dc_cal;
+ /* Better performance without ADC Gain Calibration */
+ AH5416(ah)->ah_cal.suppCals = ADC_DC_CAL | IQ_MISMATCH_CAL;
+
+ AH5416(ah)->ah_spurMitigate = ar9280SpurMitigate;
+ AH5416(ah)->ah_writeIni = ar9287WriteIni;
+
+ ah->ah_setTxPower = ar9287SetTransmitPower;
+ ah->ah_setBoardValues = ar9287SetBoardValues;
+
+ AH5416(ah)->ah_olcInit = ar9287olcInit;
+ AH5416(ah)->ah_olcTempCompensation = ar9287olcTemperatureCompensation;
+ //AH5416(ah)->ah_setPowerCalTable = ar9287SetPowerCalTable;
+ AH5416(ah)->ah_cal_initcal = ar9287InitCalHardware;
+ AH5416(ah)->ah_cal_pacal = ar9287PACal;
+
+ /* XXX NF calibration */
+ /* XXX Ini override? (IFS vars - since the kiwi mac clock is faster?) */
+ /* XXX what else is kiwi-specific in the radio/calibration pathway? */
+
+ AH5416(ah)->ah_rx_chainmask = AR9287_DEFAULT_RXCHAINMASK;
+ AH5416(ah)->ah_tx_chainmask = AR9287_DEFAULT_TXCHAINMASK;
+
+ if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
+ /* reset chip */
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
+ __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
+ __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+ /* Read Revisions from Chips before taking out of reset */
+ val = OS_REG_READ(ah, AR_SREV);
+ HALDEBUG(ah, HAL_DEBUG_ATTACH,
+ "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
+ __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
+ MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
+ /* NB: include chip type to differentiate from pre-Sowl versions */
+ AH_PRIVATE(ah)->ah_macVersion =
+ (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
+ AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
+ AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
+
+ /* Don't support Kiwi < 1.2; those are pre-release chips */
+ if (! AR_SREV_KIWI_12_OR_LATER(ah)) {
+ ath_hal_printf(ah, "[ath]: Kiwi < 1.2 is not supported\n");
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ /* setup common ini data; rf backends handle remainder */
+ HAL_INI_INIT(&ahp->ah_ini_modes, ar9287Modes_9287_1_1, 6);
+ HAL_INI_INIT(&ahp->ah_ini_common, ar9287Common_9287_1_1, 2);
+
+ /* If pcie_clock_req */
+ HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
+ ar9287PciePhy_clkreq_always_on_L1_9287_1_1, 2);
+
+ /* XXX WoW ini values */
+
+ /* Else */
+#if 0
+ HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
+ ar9287PciePhy_clkreq_off_L1_9287_1_1, 2);
+#endif
+
+ /* Initialise Japan arrays */
+ HAL_INI_INIT(&ahp9287->ah_ini_cckFirNormal,
+ ar9287Common_normal_cck_fir_coeff_9287_1_1, 2);
+ HAL_INI_INIT(&ahp9287->ah_ini_cckFirJapan2484,
+ ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, 2);
+
+ ar5416AttachPCIE(ah);
+
+ ecode = ath_hal_9287EepromAttach(ah);
+ if (ecode != HAL_OK)
+ goto bad;
+
+ if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
+
+ if (!ar5212ChipTest(ah)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
+ __func__);
+ ecode = HAL_ESELFTEST;
+ goto bad;
+ }
+
+ /*
+ * Set correct Baseband to analog shift
+ * setting to access analog chips.
+ */
+ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+ /* Read Radio Chip Rev Extract */
+ AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
+ switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
+ case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */
+ case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */
+ break;
+ default:
+ if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
+ AH_PRIVATE(ah)->ah_analog5GhzRev =
+ AR_RAD5133_SREV_MAJOR;
+ break;
+ }
+#ifdef AH_DEBUG
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: 5G Radio Chip Rev 0x%02X is not supported by "
+ "this driver\n", __func__,
+ AH_PRIVATE(ah)->ah_analog5GhzRev);
+ ecode = HAL_ENOTSUPP;
+ goto bad;
+#endif
+ }
+ rfStatus = ar9287RfAttach(ah, &ecode);
+ if (!rfStatus) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
+ __func__, ecode);
+ goto bad;
+ }
+
+ /*
+ * We only implement open-loop TX power control
+ * for the AR9287 in this codebase.
+ */
+ if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
+ ath_hal_printf(ah, "[ath] AR9287 w/ closed-loop TX power control"
+ " isn't supported.\n");
+ ecode = HAL_ENOTSUPP;
+ goto bad;
+ }
+
+ /*
+ * Check whether the power table offset isn't the default.
+ * This can occur with eeprom minor V21 or greater on Merlin.
+ */
+ (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
+ if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB)
+ ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n",
+ AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset);
+
+ /* setup rxgain table */
+ HAL_INI_INIT(&ahp9287->ah_ini_rxgain, ar9287Modes_rx_gain_9287_1_1, 6);
+
+ /* setup txgain table */
+ HAL_INI_INIT(&ahp9287->ah_ini_txgain, ar9287Modes_tx_gain_9287_1_1, 6);
+
+ /*
+ * Got everything we need now to setup the capabilities.
+ */
+ if (!ar9287FillCapabilityInfo(ah)) {
+ ecode = HAL_EEREAD;
+ goto bad;
+ }
+
+ ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
+ if (ecode != HAL_OK) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: error getting mac address from EEPROM\n", __func__);
+ goto bad;
+ }
+ /* XXX How about the serial number ? */
+ /* Read Reg Domain */
+ AH_PRIVATE(ah)->ah_currentRD =
+ ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
+
+ /*
+ * ah_miscMode is populated by ar5416FillCapabilityInfo()
+ * starting from griffin. Set here to make sure that
+ * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
+ * placed into hardware.
+ */
+ if (ahp->ah_miscMode != 0)
+ OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
+
+ ar9287AniSetup(ah); /* Anti Noise Immunity */
+
+ /* Setup noise floor min/max/nominal values */
+ AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
+ AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
+ AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
+ AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ;
+ AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ;
+ AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9287_5GHZ;
+
+ ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
+
+ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
+
+ return ah;
+bad:
+ if (ah != AH_NULL)
+ ah->ah_detach(ah);
+ if (status)
+ *status = ecode;
+ return AH_NULL;
+}
+
+static void
+ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
+{
+ if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
+ ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
+ OS_DELAY(1000);
+ OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+ OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); /* Yes, Kiwi uses the Kite PCIe PHY WA */
+ }
+}
+
+static void
+ar9287WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ u_int modesIndex, freqIndex;
+ int regWrites = 0;
+
+ /* Setup the indices for the next set of register array writes */
+ /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
+ freqIndex = 2;
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ modesIndex = 3;
+ else if (IEEE80211_IS_CHAN_108G(chan))
+ modesIndex = 5;
+ else
+ modesIndex = 4;
+ } else {
+ freqIndex = 1;
+ if (IEEE80211_IS_CHAN_HT40(chan) ||
+ IEEE80211_IS_CHAN_TURBO(chan))
+ modesIndex = 2;
+ else
+ modesIndex = 1;
+ }
+
+ /* Set correct Baseband to analog shift setting to access analog chips. */
+ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
+ OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_rxgain, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_txgain, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites);
+}
+
+#define AR_BASE_FREQ_2GHZ 2300
+#define AR_BASE_FREQ_5GHZ 4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+
+
+
+/*
+ * Fill all software cached or static hardware state information.
+ * Return failure if capabilities are to come from EEPROM and
+ * cannot be read.
+ */
+static HAL_BOOL
+ar9287FillCapabilityInfo(struct ath_hal *ah)
+{
+ HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
+
+ if (!ar5416FillCapabilityInfo(ah))
+ return AH_FALSE;
+ pCap->halNumGpioPins = 10;
+ pCap->halWowSupport = AH_TRUE;
+ pCap->halWowMatchPatternExact = AH_TRUE;
+#if 0
+ pCap->halWowMatchPatternDword = AH_TRUE;
+#endif
+
+ pCap->halCSTSupport = AH_TRUE;
+ pCap->halRifsRxSupport = AH_TRUE;
+ pCap->halRifsTxSupport = AH_TRUE;
+ pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */
+ pCap->halExtChanDfsSupport = AH_TRUE;
+#if 0
+ /* XXX bluetooth */
+ pCap->halBtCoexSupport = AH_TRUE;
+#endif
+ pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */
+ pCap->hal4kbSplitTransSupport = AH_FALSE;
+ /* Disable this so Block-ACK works correctly */
+ pCap->halHasRxSelfLinkedTail = AH_FALSE;
+ pCap->halPSPollBroken = AH_FALSE;
+ pCap->halRxStbcSupport = 1;
+ pCap->halTxStbcSupport = 1;
+
+ return AH_TRUE;
+}
+
+/*
+ * This has been disabled - having the HAL flip chainmasks on/off
+ * when attempting to implement 11n disrupts things. For now, just
+ * leave this flipped off and worry about implementing TX diversity
+ * for legacy and MCS0-7 when 11n is fully functioning.
+ */
+HAL_BOOL
+ar9287SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
+{
+ return AH_TRUE;
+}
+
+static const char*
+ar9287Probe(uint16_t vendorid, uint16_t devid)
+{
+ if (vendorid == ATHEROS_VENDOR_ID &&
+ (devid == AR9287_DEVID_PCI || devid == AR9287_DEVID_PCIE))
+ return "Atheros 9287";
+ return AH_NULL;
+}
+AH_CHIP(AR9287, ar9287Probe, ar9287Attach);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
new file mode 100644
index 0000000..d5024b0
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v4k.h"
+
+#include "ar9002/ar9285.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+#include "ar9002/ar9002phy.h"
+//#include "ar9002/ar9287phy.h"
+
+#include "ar9002/ar9287_cal.h"
+
+
+void
+ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset)
+{
+ /* XXX not required */
+}
+
+/*
+ * This is like Merlin but without ADC disable
+ */
+HAL_BOOL
+ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ /* Calibrate the AGC */
+ OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+ OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
+
+ /* Poll for offset calibration complete */
+ if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0)) {
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "%s: offset calibration failed to complete in 1ms; "
+ "noisy environment?\n", __func__);
+ return AH_FALSE;
+ }
+
+ OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h
new file mode 100644
index 0000000..1a7cda2
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef __AR9287_CAL_H__
+#define __AR9287_CAL_H__
+
+extern void ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset);
+extern HAL_BOOL ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan);
+
+#endif /* __AR9287_CAL_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c
new file mode 100644
index 0000000..cbbe017
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v14.h"
+#include "ah_eeprom_9287.h"
+
+#include "ar9002/ar9280.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+#include "ar9002/ar9002phy.h"
+
+#include "ar9002/ar9287phy.h"
+#include "ar9002/ar9287an.h"
+#include "ar9002/ar9287_olc.h"
+
+void
+ar9287olcInit(struct ath_hal *ah)
+{
+ OS_REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
+ AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
+ OS_A_REG_RMW_FIELD(ah, AR9287_AN_TXPC0,
+ AR9287_AN_TXPC0_TXPCMODE,
+ AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
+ OS_DELAY(100);
+}
+
+/*
+ * Run temperature compensation calibration.
+ *
+ * The TX gain table is adjusted depending upon the difference
+ * between the initial PDADC value and the currently read
+ * average TX power sample value. This value is only valid if
+ * frames have been transmitted, so currPDADC will be 0 if
+ * no frames have yet been transmitted.
+ */
+void
+ar9287olcTemperatureCompensation(struct ath_hal *ah)
+{
+ uint32_t rddata;
+ int32_t delta, currPDADC, slope;
+
+ rddata = OS_REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+ currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+ HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: initPDADC=%d, currPDADC=%d\n",
+ __func__, AH5416(ah)->initPDADC, currPDADC);
+
+ if (AH5416(ah)->initPDADC == 0 || currPDADC == 0) {
+ /*
+ * Zero value indicates that no frames have been transmitted
+ * yet, can't do temperature compensation until frames are
+ * transmitted.
+ */
+ return;
+ } else {
+ int8_t val;
+ (void) (ath_hal_eepromGet(ah, AR_EEP_TEMPSENSE_SLOPE, &val));
+ slope = val;
+
+ if (slope == 0) { /* to avoid divide by zero case */
+ delta = 0;
+ } else {
+ delta = ((currPDADC - AH5416(ah)->initPDADC)*4) / slope;
+ }
+ OS_REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+ AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+ OS_REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+ AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+
+ HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: delta=%d\n", __func__, delta);
+ }
+}
+
+void
+ar9287olcGetTxGainIndex(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+ uint8_t *pCalChans, uint16_t availPiers, int8_t *pPwr)
+{
+ uint16_t idxL = 0, idxR = 0, numPiers;
+ HAL_BOOL match;
+ CHAN_CENTERS centers;
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
+
+ match = ath_ee_getLowerUpperIndex(
+ (uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
+ pCalChans, numPiers, &idxL, &idxR);
+
+ if (match) {
+ *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
+ } else {
+ *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
+ (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+ }
+}
+
+void
+ar9287olcSetPDADCs(struct ath_hal *ah, int32_t txPower,
+ uint16_t chain)
+{
+ uint32_t tmpVal;
+ uint32_t a;
+
+ /* Enable OLPC for chain 0 */
+
+ tmpVal = OS_REG_READ(ah, 0xa270);
+ tmpVal = tmpVal & 0xFCFFFFFF;
+ tmpVal = tmpVal | (0x3 << 24);
+ OS_REG_WRITE(ah, 0xa270, tmpVal);
+
+ /* Enable OLPC for chain 1 */
+
+ tmpVal = OS_REG_READ(ah, 0xb270);
+ tmpVal = tmpVal & 0xFCFFFFFF;
+ tmpVal = tmpVal | (0x3 << 24);
+ OS_REG_WRITE(ah, 0xb270, tmpVal);
+
+ /* Write the OLPC ref power for chain 0 */
+
+ if (chain == 0) {
+ tmpVal = OS_REG_READ(ah, 0xa398);
+ tmpVal = tmpVal & 0xff00ffff;
+ a = (txPower)&0xff;
+ tmpVal = tmpVal | (a << 16);
+ OS_REG_WRITE(ah, 0xa398, tmpVal);
+ }
+
+ /* Write the OLPC ref power for chain 1 */
+
+ if (chain == 1) {
+ tmpVal = OS_REG_READ(ah, 0xb398);
+ tmpVal = tmpVal & 0xff00ffff;
+ a = (txPower)&0xff;
+ tmpVal = tmpVal | (a << 16);
+ OS_REG_WRITE(ah, 0xb398, tmpVal);
+ }
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h
new file mode 100644
index 0000000..ff21ce6
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287_OLC_H__
+#define __AR9287_OLC_H__
+
+extern void ar9287olcInit(struct ath_hal *ah);
+extern void ar9287olcTemperatureCompensation(struct ath_hal *ah);
+extern void ar9287olcGetTxGainIndex(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+ uint8_t *pCalChans, uint16_t availPiers, int8_t *pPwr);
+extern void ar9287olcSetPDADCs(struct ath_hal *ah,
+ int32_t txPower, uint16_t chain);
+
+#endif /* __AR9287_OLC_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
new file mode 100644
index 0000000..34a723a
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+
+#include "ah_eeprom_v14.h"
+#include "ah_eeprom_9287.h"
+
+#include "ar5416/ar5416.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "ar9002/ar9287phy.h"
+#include "ar9002/ar9287an.h"
+
+#include "ar9002/ar9287_olc.h"
+#include "ar9002/ar9287_reset.h"
+
+/*
+ * Set the TX power calibration table per-chain.
+ *
+ * This only supports open-loop TX power control for the AR9287.
+ */
+static void
+ar9287SetPowerCalTable(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
+{
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
+ uint8_t *pCalBChans = NULL;
+ uint16_t pdGainOverlap_t2;
+ uint16_t numPiers = 0, i;
+ uint16_t numXpdGain, xpdMask;
+ uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
+ uint32_t regChainOffset;
+ HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ struct ar9287_eeprom *pEepData = &ee->ee_base;
+
+ xpdMask = pEepData->modalHeader.xpdGain;
+
+ if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+ AR9287_EEP_MINOR_VER_2)
+ pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
+ else
+ pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+
+ /* Note: Kiwi should only be 2ghz.. */
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR9287_NUM_2G_CAL_PIERS;
+ pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0];
+ AH5416(ah)->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
+ }
+ numXpdGain = 0;
+
+ /* Calculate the value of xpdgains from the xpdGain Mask */
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (uint16_t)(AR5416_PD_GAINS_IN_MASK-i);
+ numXpdGain++;
+ }
+ }
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ regChainOffset = i * 0x1000;
+
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ int8_t txPower;
+ pRawDatasetOpenLoop =
+ (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i];
+ ar9287olcGetTxGainIndex(ah, chan,
+ pRawDatasetOpenLoop,
+ pCalBChans, numPiers,
+ &txPower);
+ ar9287olcSetPDADCs(ah, txPower, i);
+ }
+ }
+
+ *pTxPowerIndexOffset = 0;
+}
+
+
+/* XXX hard-coded values? */
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
+
+/*
+ * ar9287SetPowerPerRateTable
+ *
+ * Sets the transmit power in the baseband for the given
+ * operating channel and mode.
+ *
+ * This is like the v14 EEPROM table except the 5GHz code.
+ */
+static HAL_BOOL
+ar9287SetPowerPerRateTable(struct ath_hal *ah,
+ struct ar9287_eeprom *pEepData,
+ const struct ieee80211_channel *chan,
+ int16_t *ratesArray, uint16_t cfgCtl,
+ uint16_t AntennaReduction,
+ uint16_t twiceMaxRegulatoryPower,
+ uint16_t powerLimit)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+/* Local defines to distinguish between extension and control CTL's */
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+ uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ int i;
+ int16_t twiceLargestAntenna;
+ struct cal_ctl_data_ar9287 *rep;
+ CAL_TARGET_POWER_LEG targetPowerOfdm;
+ CAL_TARGET_POWER_LEG targetPowerCck = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_LEG targetPowerCckExt = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_HT targetPowerHt20;
+ CAL_TARGET_POWER_HT targetPowerHt40 = {0, {0, 0, 0, 0}};
+ int16_t scaledPower, minCtlPower;
+
+#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
+ static const uint16_t ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ const uint16_t *pCtlMode;
+ uint16_t numCtlModes, ctlMode, freq;
+ CHAN_CENTERS centers;
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+
+ /* Compute TxPower reduction due to Antenna Gain */
+
+ twiceLargestAntenna = AH_MAX(
+ pEepData->modalHeader.antennaGainCh[0],
+ pEepData->modalHeader.antennaGainCh[1]);
+
+ twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
+
+ /* XXX setup for 5212 use (really used?) */
+ ath_hal_eepromSet(ah, AR_EEP_ANTGAINMAX_2, twiceLargestAntenna);
+
+ /*
+ * scaledPower is the minimum of the user input power level and
+ * the regulatory allowed power level
+ */
+ scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna);
+
+ /* Reduce scaled Power by number of chains active to get to per chain tx power level */
+ /* TODO: better value than these? */
+ switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) {
+ case 1:
+ break;
+ case 2:
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ default:
+ return AH_FALSE; /* Unsupported number of chains */
+ }
+
+ scaledPower = AH_MAX(0, scaledPower);
+
+ /* Get target powers from EEPROM - our baseline for TX Power */
+ /* XXX assume channel is 2ghz */
+ if (1) {
+ /* Setup for CTL modes */
+ numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
+ pCtlMode = ctlModesFor11g;
+
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck,
+ AR9287_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE);
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
+ ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
+
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
+ numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */
+
+ ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40,
+ AR9287_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
+ /* Get target powers for extension channels */
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck,
+ AR9287_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE);
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
+ }
+ }
+
+ /*
+ * For MIMO, need to apply regulatory caps individually across dynamically
+ * running modes: CCK, OFDM, HT20, HT40
+ *
+ * The outer loop walks through each possible applicable runtime mode.
+ * The inner loop walks through each ctlIndex entry in EEPROM.
+ * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
+ *
+ */
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode) {
+ freq = centers.ctl_center;
+ } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
+ freq = centers.ext_center;
+ } else {
+ freq = centers.ctl_center;
+ }
+
+ /* walk through each CTL index stored in EEPROM */
+ for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+ uint16_t twiceMinEdgePower;
+
+ /* compare test group from regulatory channel list with test mode from pCtlMode list */
+ if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+ rep = &(pEepData->ctlData[i]);
+ twiceMinEdgePower = ar5416GetMaxEdgePower(freq,
+ rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1],
+ IEEE80211_IS_CHAN_2GHZ(chan));
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+ /* Find the minimum of all CTL edge powers that apply to this channel */
+ twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
+ } else {
+ /* specific */
+ twiceMaxEdgePower = twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+ minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower);
+ /* Apply ctl mode to correct target power set */
+ switch(pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = 0; i < N(targetPowerCck.tPow2x); i++) {
+ targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_11A:
+ case CTL_11G:
+ for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) {
+ targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_5GHT20:
+ case CTL_2GHT20:
+ for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
+ targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_11B_EXT:
+ targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower);
+ break;
+ case CTL_11A_EXT:
+ case CTL_11G_EXT:
+ targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower);
+ break;
+ case CTL_5GHT40:
+ case CTL_2GHT40:
+ for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
+ targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower);
+ }
+ break;
+ default:
+ return AH_FALSE;
+ break;
+ }
+ } /* end ctl mode checking */
+
+ /* Set rates Array from collected data */
+ ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray,
+ &targetPowerCck,
+ &targetPowerCckExt,
+ &targetPowerOfdm,
+ &targetPowerOfdmExt,
+ &targetPowerHt20,
+ &targetPowerHt40);
+ return AH_TRUE;
+#undef EXT_ADDITIVE
+#undef CTL_11A_EXT
+#undef CTL_11G_EXT
+#undef CTL_11B_EXT
+#undef SUB_NUM_CTL_MODES_AT_5G_40
+#undef SUB_NUM_CTL_MODES_AT_2G_40
+#undef N
+}
+
+#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
+
+/*
+ * This is based off of the AR5416/AR9285 code and likely could
+ * be unified in the future.
+ */
+HAL_BOOL
+ar9287SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
+{
+#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
+#define N(a) (sizeof (a) / sizeof (a[0]))
+
+ const struct modal_eep_ar9287_header *pModal;
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ uint8_t ht40PowerIncForPdadc = 2;
+ int i;
+
+ uint16_t cfgCtl;
+ uint16_t powerLimit;
+ uint16_t twiceAntennaReduction;
+ uint16_t twiceMaxRegulatoryPower;
+ int16_t maxPower;
+ HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ struct ar9287_eeprom *pEepData = &ee->ee_base;
+
+ /* Setup info for the actual eeprom */
+ OS_MEMZERO(ratesArray, sizeof(ratesArray));
+ cfgCtl = ath_hal_getctl(ah, chan);
+ powerLimit = chan->ic_maxregpower * 2;
+ twiceAntennaReduction = chan->ic_maxantgain;
+ twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
+ pModal = &pEepData->modalHeader;
+ HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
+ __func__,chan->ic_freq, cfgCtl );
+
+ /* XXX Assume Minor is v2 or later */
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+
+ /* Fetch per-rate power table for the given channel */
+ if (! ar9287SetPowerPerRateTable(ah, pEepData, chan,
+ &ratesArray[0],cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower, powerLimit)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: unable to set tx power per rate table\n", __func__);
+ return AH_FALSE;
+ }
+
+ /* Set TX power control calibration curves for each TX chain */
+ ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset);
+
+ /* Calculate maximum power level */
+ maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
+ maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
+
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
+
+ ahp->ah_tx6PowerInHalfDbm = maxPower;
+ AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower;
+ ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
+
+ /*
+ * txPowerIndexOffset is set by the SetPowerTable() call -
+ * adjust the rate table (0 offset if rates EEPROM not loaded)
+ */
+ /* XXX what about the pwrTableOffset? */
+ for (i = 0; i < N(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ /* -5 dBm offset for Merlin and later; this includes Kiwi */
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
+ if (ratesArray[i] < 0)
+ ratesArray[i] = 0;
+ }
+
+#ifdef AH_EEPROM_DUMP
+ ar5416PrintPowerPerRate(ah, ratesArray);
+#endif
+
+ /*
+ * Adjust the HT40 power to meet the correct target TX power
+ * for 40MHz mode, based on TX power curves that are established
+ * for 20MHz mode.
+ *
+ * XXX handle overflow/too high power level?
+ */
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
+ ratesArray[rateHt40_0] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_1] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_2] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_3] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_4] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_5] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_6] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_7] += ht40PowerIncForPdadc;
+ }
+
+ /* Write the TX power rate registers */
+ ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray);
+
+ return AH_TRUE;
+#undef POW_SM
+#undef N
+}
+
+/*
+ * Read EEPROM header info and program the device for correct operation
+ * given the channel value.
+ */
+HAL_BOOL
+ar9287SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ const HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ const struct ar9287_eeprom *eep = &ee->ee_base;
+ const struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+ uint16_t antWrites[AR9287_ANT_16S];
+ uint32_t regChainOffset, regval;
+ uint8_t txRxAttenLocal;
+ int i, j, offset_num;
+
+ pModal = &eep->modalHeader;
+
+ antWrites[0] = (uint16_t)((pModal->antCtrlCommon >> 28) & 0xF);
+ antWrites[1] = (uint16_t)((pModal->antCtrlCommon >> 24) & 0xF);
+ antWrites[2] = (uint16_t)((pModal->antCtrlCommon >> 20) & 0xF);
+ antWrites[3] = (uint16_t)((pModal->antCtrlCommon >> 16) & 0xF);
+ antWrites[4] = (uint16_t)((pModal->antCtrlCommon >> 12) & 0xF);
+ antWrites[5] = (uint16_t)((pModal->antCtrlCommon >> 8) & 0xF);
+ antWrites[6] = (uint16_t)((pModal->antCtrlCommon >> 4) & 0xF);
+ antWrites[7] = (uint16_t)(pModal->antCtrlCommon & 0xF);
+
+ offset_num = 8;
+
+ for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 28) & 0xf);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 10) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 8) & 0x3);
+ antWrites[j++] = 0;
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 6) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 4) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 2) & 0x3);
+ antWrites[j++] = (uint16_t)(pModal->antCtrlChain[i] & 0x3);
+ }
+
+ OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ regChainOffset = i * 0x1000;
+
+ OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+ pModal->antCtrlChain[i]);
+
+ OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset,
+ (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset)
+ & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+ SM(pModal->iqCalICh[i],
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+ SM(pModal->iqCalQCh[i],
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+ txRxAttenLocal = pModal->txRxAttenCh[i];
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ pModal->bswMargin[i]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ pModal->bswAtten[i]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN,
+ txRxAttenLocal);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN,
+ pModal->rxTxMarginCh[i]);
+ }
+
+
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
+ else
+ OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+ AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
+
+ OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+ | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+ | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+ | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
+ AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_CCA,
+ AR9280_PHY_CCA_THRESH62, pModal->thresh62);
+ OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+ AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
+
+ regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH0);
+ regval &= ~(AR9287_AN_RF2G3_DB1 |
+ AR9287_AN_RF2G3_DB2 |
+ AR9287_AN_RF2G3_OB_CCK |
+ AR9287_AN_RF2G3_OB_PSK |
+ AR9287_AN_RF2G3_OB_QAM |
+ AR9287_AN_RF2G3_OB_PAL_OFF);
+ regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+ SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+ SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+ SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+ SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+ SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+ OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH0, regval);
+ OS_DELAY(100); /* analog write */
+
+ regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH1);
+ regval &= ~(AR9287_AN_RF2G3_DB1 |
+ AR9287_AN_RF2G3_DB2 |
+ AR9287_AN_RF2G3_OB_CCK |
+ AR9287_AN_RF2G3_OB_PSK |
+ AR9287_AN_RF2G3_OB_QAM |
+ AR9287_AN_RF2G3_OB_PAL_OFF);
+ regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+ SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+ SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+ SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+ SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+ SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+ OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH1, regval);
+ OS_DELAY(100); /* analog write */
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+ AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+ AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn);
+
+ OS_A_REG_RMW_FIELD(ah, AR9287_AN_TOP2,
+ AR9287_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl);
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h
new file mode 100644
index 0000000..679fb8c
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287_RESET_H__
+#define __AR9287_RESET_H__
+
+extern HAL_BOOL ar9287SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
+extern HAL_BOOL ar9287SetBoardValues(struct ath_hal *ah,
+ const struct ieee80211_channel *chan);
+
+#endif /* __AR9287_RESET_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287an.h b/sys/dev/ath/ath_hal/ar9002/ar9287an.h
new file mode 100644
index 0000000..ba7a92c
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287an.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287AN_H__
+#define __AR9287AN_H__
+
+#define AR9287_AN_RF2G3_CH0 0x7808
+#define AR9287_AN_RF2G3_CH1 0x785c
+#define AR9287_AN_RF2G3_DB1 0xE0000000
+#define AR9287_AN_RF2G3_DB1_S 29
+#define AR9287_AN_RF2G3_DB2 0x1C000000
+#define AR9287_AN_RF2G3_DB2_S 26
+#define AR9287_AN_RF2G3_OB_CCK 0x03800000
+#define AR9287_AN_RF2G3_OB_CCK_S 23
+#define AR9287_AN_RF2G3_OB_PSK 0x00700000
+#define AR9287_AN_RF2G3_OB_PSK_S 20
+#define AR9287_AN_RF2G3_OB_QAM 0x000E0000
+#define AR9287_AN_RF2G3_OB_QAM_S 17
+#define AR9287_AN_RF2G3_OB_PAL_OFF 0x0001C000
+#define AR9287_AN_RF2G3_OB_PAL_OFF_S 14
+
+#define AR9287_AN_TXPC0 0x7898
+#define AR9287_AN_TXPC0_TXPCMODE 0x0000C000
+#define AR9287_AN_TXPC0_TXPCMODE_S 14
+#define AR9287_AN_TXPC0_TXPCMODE_NORMAL 0
+#define AR9287_AN_TXPC0_TXPCMODE_TEST 1
+#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
+#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST 3
+
+#define AR9287_AN_TOP2 0x78b4
+#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000
+#define AR9287_AN_TOP2_XPABIAS_LVL_S 30
+
+#endif
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287phy.h b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h
new file mode 100644
index 0000000..8f28194
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287PHY_H__
+#define __AR9287PHY_H__
+
+/* AR_PHY_CH0_TX_PWRCTRL11, AR_PHY_CH1_TX_PWRCTRL11 */
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#endif
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 26a50bc..6353847 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -634,11 +634,11 @@ void ath_intr(void *);
#define ath_hal_settpcts(_ah, _tpcts) \
ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL)
#define ath_hal_hasintmit(_ah) \
- (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 0, NULL) == HAL_OK)
+ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_PRESENT, NULL) == HAL_OK)
#define ath_hal_getintmit(_ah) \
- (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK)
+ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, NULL) == HAL_OK)
#define ath_hal_setintmit(_ah, _v) \
- ath_hal_setcapability(_ah, HAL_CAP_INTMIT, 1, _v, NULL)
+ ath_hal_setcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, _v, NULL)
#define ath_hal_getchannoise(_ah, _c) \
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
#define ath_hal_getrxchainmask(_ah, _prxchainmask) \
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 2adbf1c..23538f7 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -1018,7 +1018,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN)
error = EINVAL;
else if (ifp->if_mtu != ifr->ifr_mtu) {
- if (ifr->ifr_mtu > ETHERMTU) {
+ if (ifr->ifr_mtu > ETHERMTU) {
if ((sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) {
error = EINVAL;
MSK_IF_UNLOCK(sc_if);
@@ -1636,7 +1636,7 @@ msk_attach(device_t dev)
* this workaround does not work so disable checksum offload
* for VLAN interface.
*/
- ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
/*
* Enable Rx checksum offloading for VLAN tagged frames
* if controller support new descriptor format.
@@ -1921,7 +1921,8 @@ mskc_attach(device_t dev)
error = ENXIO;
goto fail;
}
- mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO);
+ mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK |
+ M_ZERO);
if (mmd == NULL) {
device_printf(dev, "failed to allocate memory for "
"ivars of PORT_B\n");
@@ -1930,9 +1931,9 @@ mskc_attach(device_t dev)
}
mmd->port = MSK_PORT_B;
mmd->pmd = sc->msk_pmd;
- if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
+ if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
mmd->mii_flags |= MIIF_HAVEFIBER;
- if (sc->msk_pmd == 'P')
+ if (sc->msk_pmd == 'P')
mmd->mii_flags |= MIIF_HAVEFIBER | MIIF_MACPRIV0;
device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd);
}
@@ -3741,10 +3742,10 @@ msk_init_locked(struct msk_if_softc *sc_if)
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
}
- /* GMAC Control reset. */
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
+ /* GMAC Control reset. */
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
@@ -3854,13 +3855,13 @@ msk_init_locked(struct msk_if_softc *sc_if)
msk_set_tx_stfwd(sc_if);
}
- if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
- sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
- /* Disable dynamic watermark - from Linux. */
- reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
- reg &= ~0x03;
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
- }
+ if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
+ sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
+ /* Disable dynamic watermark - from Linux. */
+ reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
+ reg &= ~0x03;
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
+ }
/*
* Disable Force Sync bit and Alloc bit in Tx RAM interface
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 5dbe30c..54808c5 100644
--- a/sys/dev/mvs/mvs.c
+++ b/sys/dev/mvs/mvs.c
@@ -1738,13 +1738,6 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- mvs_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there was fatal error - reset port. */
@@ -1764,6 +1757,13 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != MVS_ERR_TIMEOUT)
mvs_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ mvs_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
/* Start PM timer. */
if (ch->numrslots == 0 && ch->pm_level > 3 &&
(ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
@@ -2080,7 +2080,8 @@ mvs_softreset(device_t dev, union ccb *ccb)
{
struct mvs_channel *ch = device_get_softc(dev);
int port = ccb->ccb_h.target_id & 0x0f;
- int i;
+ int i, stuck;
+ uint8_t status;
mvs_set_edma_mode(dev, MVS_EDMA_OFF);
ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT);
@@ -2089,12 +2090,35 @@ mvs_softreset(device_t dev, union ccb *ccb)
ATA_OUTB(ch->r_mem, ATA_CONTROL, 0);
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
/* Wait for clearing busy status. */
- if ((i = mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout)) < 0) {
+ if ((i = mvs_wait(dev, 0, ATA_S_BUSY, ccb->ccb_h.timeout)) < 0) {
ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
+ stuck = 1;
} else {
- ccb->ccb_h.status |= CAM_REQ_CMP;
+ status = mvs_getstatus(dev, 0);
+ if (status & ATA_S_ERROR)
+ ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
+ else
+ ccb->ccb_h.status |= CAM_REQ_CMP;
+ if (status & ATA_S_DRQ)
+ stuck = 1;
+ else
+ stuck = 0;
}
mvs_tfd_read(dev, ccb);
+
+ /*
+ * XXX: If some device on PMP failed to soft-reset,
+ * try to recover by sending dummy soft-reset to PMP.
+ */
+ if (stuck && ch->pm_present && port != 15) {
+ ATA_OUTB(ch->r_mem, SATA_SATAICTL,
+ 15 << SATA_SATAICTL_PMPTX_SHIFT);
+ ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET);
+ DELAY(10000);
+ ATA_OUTB(ch->r_mem, ATA_CONTROL, 0);
+ mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout);
+ }
+
xpt_done(ccb);
}
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 01edae3..a7b018a 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1178,11 +1178,22 @@ siis_timeout(struct siis_slot *slot)
{
device_t dev = slot->dev;
struct siis_channel *ch = device_get_softc(dev);
+ union ccb *ccb = slot->ccb;
mtx_assert(&ch->mtx, MA_OWNED);
/* Check for stale timeout. */
if (slot->state < SIIS_SLOT_RUNNING)
return;
+
+ /* Handle soft-reset timeouts without doing hard-reset. */
+ if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
+ (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
+ (ccb->ataio.cmd.control & ATA_A_RESET)) {
+ xpt_freeze_simq(ch->sim, ch->numrslots);
+ siis_end_transaction(slot, SIIS_ERR_TFE);
+ return;
+ }
+
device_printf(dev, "Timeout on slot %d\n", slot->slot);
device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n",
__func__, ATA_INL(ch->r_mem, SIIS_P_IS),
@@ -1331,13 +1342,6 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !siis_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- siis_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there were timeouts or fatal error - reset port. */
@@ -1355,6 +1359,13 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != SIIS_ERR_TIMEOUT)
siis_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !siis_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ siis_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
}
static void
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 7af5303..5bec624 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -826,12 +826,13 @@ static const struct {
#define HDA_CODEC_NVIDIAXXXX HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff)
/* INTEL */
-#define HDA_CODEC_INTELG45_1 HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
-#define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
-#define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
-#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
-#define HDA_CODEC_INTELG45_5 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
-#define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
+#define HDA_CODEC_INTELIP HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
+#define HDA_CODEC_INTELBL HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
+#define HDA_CODEC_INTELCA HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
+#define HDA_CODEC_INTELEL HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
+#define HDA_CODEC_INTELIP2 HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
+#define HDA_CODEC_INTELCPT HDA_CODEC_CONSTRUCT(INTEL, 0x2805)
+#define HDA_CODEC_INTELCL HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
#define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
/* Codecs */
@@ -998,12 +999,13 @@ static const struct {
{ HDA_CODEC_NVIDIAGT21X, "NVidia GT21x HDMI" },
{ HDA_CODEC_NVIDIAMCP89, "NVidia MCP89 HDMI" },
{ HDA_CODEC_NVIDIAGT240, "NVidia GT240 HDMI" },
- { HDA_CODEC_INTELG45_1, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_5, "Intel G45 HDMI" },
- { HDA_CODEC_INTELQ57, "Intel Q57 HDMI" },
+ { HDA_CODEC_INTELIP, "Intel Ibex Peak HDMI" },
+ { HDA_CODEC_INTELBL, "Intel Bearlake HDMI" },
+ { HDA_CODEC_INTELCA, "Intel Cantiga HDMI" },
+ { HDA_CODEC_INTELEL, "Intel Eaglelake HDMI" },
+ { HDA_CODEC_INTELIP2, "Intel Ibex Peak HDMI" },
+ { HDA_CODEC_INTELCPT, "Intel Cougar Point HDMI" },
+ { HDA_CODEC_INTELCL, "Intel Crestline HDMI" },
{ HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" },
{ HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" },
/* Unknown codec */
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 3cdd5ad..489be29 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -242,8 +242,14 @@ ns8250_probe(struct uart_bas *bas)
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
+ /*
+ * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699
+ * chip, but otherwise doesn't seem to have a function. In
+ * other words, uart(4) works regardless. Ignore that bit so
+ * the probe succeeds.
+ */
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 6182ee8..d83d523 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -370,7 +370,7 @@ int nfsrpc_readlink(vnode_t, struct uio *, struct ucred *,
NFSPROC_T *, struct nfsvattr *, int *, void *);
int nfsrpc_read(vnode_t, struct uio *, struct ucred *, NFSPROC_T *,
struct nfsvattr *, int *, void *);
-int nfsrpc_write(vnode_t, struct uio *, int *, u_char *,
+int nfsrpc_write(vnode_t, struct uio *, int *, int *,
struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *, int);
int nfsrpc_mknod(vnode_t, char *, int, struct vattr *, u_int32_t,
enum vtype, struct ucred *, NFSPROC_T *, struct nfsvattr *,
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 7af0852..0fc9bfd 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -68,7 +68,7 @@ static int nfsrpc_setattrrpc(vnode_t , struct vattr *, nfsv4stateid_t *,
struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *);
static int nfsrpc_readrpc(vnode_t , struct uio *, struct ucred *,
nfsv4stateid_t *, NFSPROC_T *, struct nfsvattr *, int *, void *);
-static int nfsrpc_writerpc(vnode_t , struct uio *, int *, u_char *,
+static int nfsrpc_writerpc(vnode_t , struct uio *, int *, int *,
struct ucred *, nfsv4stateid_t *, NFSPROC_T *, struct nfsvattr *, int *,
void *);
static int nfsrpc_createv23(vnode_t , char *, int, struct vattr *,
@@ -1369,7 +1369,7 @@ nfsmout:
* will then deadlock.
*/
APPLESTATIC int
-nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
+nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp,
void *stuff, int called_from_strategy)
{
@@ -1382,6 +1382,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
nfsv4stateid_t stateid;
void *lckp;
+ *must_commit = 0;
if (nmp->nm_clp != NULL)
clidrev = nmp->nm_clp->nfsc_clientidrev;
newcred = cred;
@@ -1412,7 +1413,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
if (nostateid)
error = 0;
else
- error = nfsrpc_writerpc(vp, uiop, iomode, verfp,
+ error = nfsrpc_writerpc(vp, uiop, iomode, must_commit,
newcred, &stateid, p, nap, attrflagp, stuff);
if (error == NFSERR_STALESTATEID)
nfscl_initiate_recovery(nmp->nm_clp);
@@ -1447,7 +1448,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp,
*/
static int
nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode,
- u_char *verfp, struct ucred *cred, nfsv4stateid_t *stateidp,
+ int *must_commit, struct ucred *cred, nfsv4stateid_t *stateidp,
NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp, void *stuff)
{
u_int32_t *tl;
@@ -1585,14 +1586,16 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode,
else if (committed == NFSWRITE_DATASYNC &&
commit == NFSWRITE_UNSTABLE)
committed = commit;
- if (verfp != NULL)
- NFSBCOPY((caddr_t)tl, verfp, NFSX_VERF);
NFSLOCKMNT(nmp);
if (!NFSHASWRITEVERF(nmp)) {
NFSBCOPY((caddr_t)tl,
(caddr_t)&nmp->nm_verf[0],
NFSX_VERF);
NFSSETWRITEVERF(nmp);
+ } else if (NFSBCMP(tl, nmp->nm_verf,
+ NFSX_VERF)) {
+ *must_commit = 1;
+ NFSBCOPY(tl, nmp->nm_verf, NFSX_VERF);
}
NFSUNLOCKMNT(nmp);
}
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 1b08582..3ec12ca 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1332,19 +1332,9 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
{
struct nfsvattr nfsva;
int error = 0, attrflag, ret;
- u_char verf[NFSX_VERF];
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- *must_commit = 0;
- error = nfsrpc_write(vp, uiop, iomode, verf, cred,
+ error = nfsrpc_write(vp, uiop, iomode, must_commit, cred,
uiop->uio_td, &nfsva, &attrflag, NULL, called_from_strategy);
- NFSLOCKMNT(nmp);
- if (!error && NFSHASWRITEVERF(nmp) &&
- NFSBCMP(verf, nmp->nm_verf, NFSX_VERF)) {
- *must_commit = 1;
- NFSBCOPY(verf, nmp->nm_verf, NFSX_VERF);
- }
- NFSUNLOCKMNT(nmp);
if (attrflag) {
if (VTONFS(vp)->n_flag & ND_NFSV4)
ret = nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 1,
@@ -2480,10 +2470,12 @@ ncl_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
error = nfsrpc_commit(vp, offset, cnt, cred, td, verf, &nfsva,
&attrflag, NULL);
if (!error) {
+ mtx_lock(&nmp->nm_mtx);
if (NFSBCMP((caddr_t)nmp->nm_verf, verf, NFSX_VERF)) {
NFSBCOPY(verf, (caddr_t)nmp->nm_verf, NFSX_VERF);
error = NFSERR_STALEWRITEVERF;
}
+ mtx_unlock(&nmp->nm_mtx);
if (!error && attrflag)
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL,
0, 1);
diff --git a/sys/geom/part/g_part_ebr.c b/sys/geom/part/g_part_ebr.c
index f6278cc..8ea9b47 100644
--- a/sys/geom/part/g_part_ebr.c
+++ b/sys/geom/part/g_part_ebr.c
@@ -289,7 +289,6 @@ g_part_ebr_create(struct g_part_table *basetable, struct g_part_parms *gpp)
return (ENXIO);
msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
- msize -= msize % basetable->gpt_sectors;
basetable->gpt_first = 0;
basetable->gpt_last = msize - 1;
basetable->gpt_entries = msize / basetable->gpt_sectors;
@@ -523,7 +522,7 @@ g_part_ebr_read(struct g_part_table *basetable, struct g_consumer *cp)
basetable->gpt_entries = msize / basetable->gpt_sectors;
basetable->gpt_first = 0;
- basetable->gpt_last = msize - (msize % basetable->gpt_sectors) - 1;
+ basetable->gpt_last = msize - 1;
return (0);
}
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 4fa829a..0b40366 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -251,20 +251,16 @@ g_part_mbr_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
static int
g_part_mbr_create(struct g_part_table *basetable, struct g_part_parms *gpp)
{
- struct g_consumer *cp;
struct g_provider *pp;
struct g_part_mbr_table *table;
- uint32_t msize;
pp = gpp->gpp_provider;
- cp = LIST_FIRST(&pp->consumers);
-
if (pp->sectorsize < MBRSIZE)
return (ENOSPC);
- msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
basetable->gpt_first = basetable->gpt_sectors;
- basetable->gpt_last = msize - (msize % basetable->gpt_sectors) - 1;
+ basetable->gpt_last = MIN(pp->mediasize / pp->sectorsize,
+ UINT32_MAX) - 1;
table = (struct g_part_mbr_table *)basetable;
le16enc(table->mbr + DOSMAGICOFFSET, DOSMAGIC);
@@ -473,7 +469,7 @@ g_part_mbr_read(struct g_part_table *basetable, struct g_consumer *cp)
basetable->gpt_entries = NDOSPART;
basetable->gpt_first = basetable->gpt_sectors;
- basetable->gpt_last = msize - (msize % basetable->gpt_sectors) - 1;
+ basetable->gpt_last = msize - 1;
g_free(buf);
return (0);
diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c
index 693fad8..0d81a0e 100644
--- a/sys/geom/part/g_part_pc98.c
+++ b/sys/geom/part/g_part_pc98.c
@@ -246,24 +246,17 @@ g_part_pc98_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
static int
g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp)
{
- struct g_consumer *cp;
struct g_provider *pp;
struct g_part_pc98_table *table;
- uint32_t cyl, msize;
pp = gpp->gpp_provider;
- cp = LIST_FIRST(&pp->consumers);
-
if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE)
return (ENOSPC);
if (pp->sectorsize > SECSIZE)
return (ENXIO);
- cyl = basetable->gpt_heads * basetable->gpt_sectors;
-
- msize = MIN(pp->mediasize / SECSIZE, UINT32_MAX);
- basetable->gpt_first = cyl;
- basetable->gpt_last = msize - (msize % cyl) - 1;
+ basetable->gpt_first = basetable->gpt_heads * basetable->gpt_sectors;
+ basetable->gpt_last = MIN(pp->mediasize / SECSIZE, UINT32_MAX) - 1;
table = (struct g_part_pc98_table *)basetable;
le16enc(table->boot + DOSMAGICOFFSET, DOSMAGIC);
@@ -491,7 +484,7 @@ g_part_pc98_read(struct g_part_table *basetable, struct g_consumer *cp)
basetable->gpt_entries = NDOSPART;
basetable->gpt_first = cyl;
- basetable->gpt_last = msize - (msize % cyl) - 1;
+ basetable->gpt_last = msize - 1;
g_free(buf);
return (0);
diff --git a/sys/geom/vinum/geom_vinum_drive.c b/sys/geom/vinum/geom_vinum_drive.c
index 5ab68f3..f782fd0 100644
--- a/sys/geom/vinum/geom_vinum_drive.c
+++ b/sys/geom/vinum/geom_vinum_drive.c
@@ -126,6 +126,10 @@ gv_read_header(struct g_consumer *cp, struct gv_hdr *m_hdr)
pp = cp->provider;
KASSERT(pp != NULL, ("gv_read_header: null pp"));
+ if ((GV_HDR_OFFSET % pp->sectorsize) != 0 ||
+ (GV_HDR_LEN % pp->sectorsize) != 0)
+ return (ENODEV);
+
d_hdr = g_read_data(cp, GV_HDR_OFFSET, pp->sectorsize, NULL);
if (d_hdr == NULL)
return (-1);
diff --git a/sys/geom/vinum/geom_vinum_events.c b/sys/geom/vinum/geom_vinum_events.c
index fcd45f1..db4e543 100644
--- a/sys/geom/vinum/geom_vinum_events.c
+++ b/sys/geom/vinum/geom_vinum_events.c
@@ -109,6 +109,12 @@ gv_drive_tasted(struct gv_softc *sc, struct g_provider *pp)
buf = NULL;
G_VINUM_DEBUG(2, "tasted drive on '%s'", pp->name);
+ if ((GV_CFG_OFFSET % pp->sectorsize) != 0 ||
+ (GV_CFG_LEN % pp->sectorsize) != 0) {
+ G_VINUM_DEBUG(0, "provider %s has unsupported sectorsize.",
+ pp->name);
+ return;
+ }
gp = sc->geom;
g_topology_lock();
diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m
index 2931c0a..eb720eb 100644
--- a/sys/kern/device_if.m
+++ b/sys/kern/device_if.m
@@ -89,28 +89,29 @@ CODE {
* the probe before returning. The return value of DEVICE_PROBE()
* is used to elect which driver is used - the driver which returns
* the largest non-error value wins the election and attaches to
- * the device.
+ * the device. Common non-error values are described in the
+ * DEVICE_PROBE(9) manual page.
*
* If a driver matches the hardware, it should set the device
* description string using device_set_desc() or
- * device_set_desc_copy(). This string is
- * used to generate an informative message when DEVICE_ATTACH()
- * is called.
+ * device_set_desc_copy(). This string is used to generate an
+ * informative message when DEVICE_ATTACH() is called.
*
* As a special case, if a driver returns zero, the driver election
* is cut short and that driver will attach to the device
- * immediately.
+ * immediately. This should rarely be used.
*
- * For example, a probe method for a pci device driver might look
+ * For example, a probe method for a PCI device driver might look
* like this:
*
* @code
- * int foo_probe(device_t dev)
+ * int
+ * foo_probe(device_t dev)
* {
* if (pci_get_vendor(dev) == FOOVENDOR &&
* pci_get_device(dev) == FOODEVICE) {
* device_set_desc(dev, "Foo device");
- * return (0);
+ * return (BUS_PROBE_DEFAULT);
* }
* return (ENXIO);
* }
@@ -125,7 +126,8 @@ CODE {
*
* @param dev the device to probe
*
- * @retval 0 if the driver strongly matches this device
+ * @retval 0 if this is the only possible driver for this
+ * device
* @retval negative if the driver can match this device - the
* least negative value is used to select the
* driver
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index d3aef76..05fb4a1 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -400,9 +400,7 @@ mi_switch(int flags, struct thread *newtd)
if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
mtx_assert(&Giant, MA_NOTOWNED);
#endif
- KASSERT(td->td_critnest == 1 || (td->td_critnest == 2 &&
- (td->td_owepreempt) && (flags & SW_INVOL) != 0 &&
- newtd == NULL) || panicstr,
+ KASSERT(td->td_critnest == 1 || panicstr,
("mi_switch: switch in a critical section"));
KASSERT((flags & (SW_INVOL | SW_VOL)) != 0,
("mi_switch: switch must be voluntary or involuntary"));
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index ce66f44..c38177b 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -318,11 +318,15 @@ restart_cpus(cpuset_t map)
void
smp_rendezvous_action(void)
{
+ struct thread *td;
void *local_func_arg;
void (*local_setup_func)(void*);
void (*local_action_func)(void*);
void (*local_teardown_func)(void*);
int generation;
+#ifdef INVARIANTS
+ int owepreempt;
+#endif
/* Ensure we have up-to-date values. */
atomic_add_acq_int(&smp_rv_waiters[0], 1);
@@ -337,6 +341,34 @@ smp_rendezvous_action(void)
generation = smp_rv_generation;
/*
+ * Use a nested critical section to prevent any preemptions
+ * from occurring during a rendezvous action routine.
+ * Specifically, if a rendezvous handler is invoked via an IPI
+ * and the interrupted thread was in the critical_exit()
+ * function after setting td_critnest to 0 but before
+ * performing a deferred preemption, this routine can be
+ * invoked with td_critnest set to 0 and td_owepreempt true.
+ * In that case, a critical_exit() during the rendezvous
+ * action would trigger a preemption which is not permitted in
+ * a rendezvous action. To fix this, wrap all of the
+ * rendezvous action handlers in a critical section. We
+ * cannot use a regular critical section however as having
+ * critical_exit() preempt from this routine would also be
+ * problematic (the preemption must not occur before the IPI
+ * has been acknowledged via an EOI). Instead, we
+ * intentionally ignore td_owepreempt when leaving the
+ * critical section. This should be harmless because we do
+ * not permit rendezvous action routines to schedule threads,
+ * and thus td_owepreempt should never transition from 0 to 1
+ * during this routine.
+ */
+ td = curthread;
+ td->td_critnest++;
+#ifdef INVARIANTS
+ owepreempt = td->td_owepreempt;
+#endif
+
+ /*
* If requested, run a setup function before the main action
* function. Ensure all CPUs have completed the setup
* function before moving on to the action function.
@@ -369,14 +401,18 @@ smp_rendezvous_action(void)
*/
MPASS(generation == smp_rv_generation);
atomic_add_int(&smp_rv_waiters[2], 1);
- if (local_teardown_func == smp_no_rendevous_barrier)
- return;
- while (smp_rv_waiters[2] < smp_rv_ncpus &&
- generation == smp_rv_generation)
- cpu_spinwait();
+ if (local_teardown_func != smp_no_rendevous_barrier) {
+ while (smp_rv_waiters[2] < smp_rv_ncpus &&
+ generation == smp_rv_generation)
+ cpu_spinwait();
+
+ if (local_teardown_func != NULL)
+ local_teardown_func(local_func_arg);
+ }
- if (local_teardown_func != NULL)
- local_teardown_func(local_func_arg);
+ td->td_critnest--;
+ KASSERT(owepreempt == td->td_owepreempt,
+ ("rendezvous action changed td_owepreempt"));
}
void
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 8775e6f..dff9efc 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_clone.h>
+#include <net/if_media.h>
#include <net/if_var.h>
#include <net/if_types.h>
#include <net/netisr.h>
@@ -92,6 +93,8 @@ static struct mbuf *epair_nh_m2cpuid(struct mbuf *, uintptr_t, u_int *);
static void epair_nh_drainedcpu(u_int);
static void epair_start_locked(struct ifnet *);
+static int epair_media_change(struct ifnet *);
+static void epair_media_status(struct ifnet *, struct ifmediareq *);
static int epair_clone_match(struct if_clone *, const char *);
static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t);
@@ -127,6 +130,7 @@ SYSCTL_PROC(_net_link_epair, OID_AUTO, netisr_maxqlen, CTLTYPE_INT|CTLFLAG_RW,
struct epair_softc {
struct ifnet *ifp; /* This ifp. */
struct ifnet *oifp; /* other ifp of pair. */
+ struct ifmedia media; /* Media config (fake). */
u_int refcount; /* # of mbufs in flight. */
u_int cpuid; /* CPU ID assigned upon creation. */
void (*if_qflush)(struct ifnet *);
@@ -611,8 +615,25 @@ epair_qflush(struct ifnet *ifp)
}
static int
+epair_media_change(struct ifnet *ifp __unused)
+{
+
+ /* Do nothing. */
+ return (0);
+}
+
+static void
+epair_media_status(struct ifnet *ifp __unused, struct ifmediareq *imr)
+{
+
+ imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+ imr->ifm_active = IFM_ETHER | IFM_10G_T | IFM_FDX;
+}
+
+static int
epair_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
+ struct epair_softc *sc;
struct ifreq *ifr;
int error;
@@ -624,6 +645,12 @@ epair_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = 0;
break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ sc = ifp->if_softc;
+ error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
+ break;
+
case SIOCSIFMTU:
/* We basically allow all kinds of MTUs. */
ifp->if_mtu = ifr->ifr_mtu;
@@ -783,6 +810,8 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
ifp->if_dname = ifc->ifc_name;
ifp->if_dunit = unit;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_capabilities = IFCAP_VLAN_MTU;
+ ifp->if_capenable = IFCAP_VLAN_MTU;
ifp->if_start = epair_start;
ifp->if_ioctl = epair_ioctl;
ifp->if_init = epair_init;
@@ -807,6 +836,8 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
ifp->if_dname = ifc->ifc_name;
ifp->if_dunit = unit;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_capabilities = IFCAP_VLAN_MTU;
+ ifp->if_capenable = IFCAP_VLAN_MTU;
ifp->if_start = epair_start;
ifp->if_ioctl = epair_ioctl;
ifp->if_init = epair_init;
@@ -829,6 +860,14 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
strlcpy(name, sca->ifp->if_xname, len);
DPRINTF("name='%s/%db' created sca=%p scb=%p\n", name, unit, sca, scb);
+ /* Initialise pseudo media types. */
+ ifmedia_init(&sca->media, 0, epair_media_change, epair_media_status);
+ ifmedia_add(&sca->media, IFM_ETHER | IFM_10G_T, 0, NULL);
+ ifmedia_set(&sca->media, IFM_ETHER | IFM_10G_T);
+ ifmedia_init(&scb->media, 0, epair_media_change, epair_media_status);
+ ifmedia_add(&scb->media, IFM_ETHER | IFM_10G_T, 0, NULL);
+ ifmedia_set(&scb->media, IFM_ETHER | IFM_10G_T);
+
/* Tell the world, that we are ready to rock. */
sca->ifp->if_drv_flags |= IFF_DRV_RUNNING;
scb->ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -895,6 +934,8 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
if_free(oifp);
CURVNET_RESTORE();
if_free(ifp);
+ ifmedia_removeall(&sca->media);
+ ifmedia_removeall(&scb->media);
free(scb, M_EPAIR);
free(sca, M_EPAIR);
ifc_free_unit(ifc, unit);
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index 952b463..67ec160 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007-2009 Robert N. M. Watson
- * Copyright (c) 2010 Juniper Networks, Inc.
+ * Copyright (c) 2010-2011 Juniper Networks, Inc.
* All rights reserved.
*
* This software was developed by Robert N. M. Watson under contract
@@ -127,32 +127,44 @@ static struct rmlock netisr_rmlock;
SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr");
/*-
- * Three direct dispatch policies are supported:
+ * Three global direct dispatch policies are supported:
*
- * - Always defer: all work is scheduled for a netisr, regardless of context.
- * (!direct)
+ * NETISR_DISPATCH_QUEUED: All work is deferred for a netisr, regardless of
+ * context (may be overriden by protocols).
*
- * - Hybrid: if the executing context allows direct dispatch, and we're
- * running on the CPU the work would be done on, then direct dispatch if it
- * wouldn't violate ordering constraints on the workstream.
- * (direct && !direct_force)
+ * NETISR_DISPATCH_HYBRID: If the executing context allows direct dispatch,
+ * and we're running on the CPU the work would be performed on, then direct
+ * dispatch it if it wouldn't violate ordering constraints on the workstream.
*
- * - Always direct: if the executing context allows direct dispatch, always
- * direct dispatch. (direct && direct_force)
+ * NETISR_DISPATCH_DIRECT: If the executing context allows direct dispatch,
+ * always direct dispatch. (The default.)
*
* Notice that changing the global policy could lead to short periods of
* misordered processing, but this is considered acceptable as compared to
- * the complexity of enforcing ordering during policy changes.
+ * the complexity of enforcing ordering during policy changes. Protocols can
+ * override the global policy (when they're not doing that, they select
+ * NETISR_DISPATCH_DEFAULT).
*/
-static int netisr_direct_force = 1; /* Always direct dispatch. */
-TUNABLE_INT("net.isr.direct_force", &netisr_direct_force);
-SYSCTL_INT(_net_isr, OID_AUTO, direct_force, CTLFLAG_RW,
- &netisr_direct_force, 0, "Force direct dispatch");
+#define NETISR_DISPATCH_POLICY_DEFAULT NETISR_DISPATCH_DIRECT
+#define NETISR_DISPATCH_POLICY_MAXSTR 20 /* Used for temporary buffers. */
+static u_int netisr_dispatch_policy = NETISR_DISPATCH_POLICY_DEFAULT;
+static int sysctl_netisr_dispatch_policy(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_isr, OID_AUTO, dispatch, CTLTYPE_STRING | CTLFLAG_RW |
+ CTLFLAG_TUN, 0, 0, sysctl_netisr_dispatch_policy, "A",
+ "netisr dispatch policy");
-static int netisr_direct = 1; /* Enable direct dispatch. */
-TUNABLE_INT("net.isr.direct", &netisr_direct);
-SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RW,
- &netisr_direct, 0, "Enable direct dispatch");
+/*
+ * These sysctls were used in previous versions to control and export
+ * dispatch policy state. Now, we provide read-only export via them so that
+ * older netstat binaries work. At some point they can be garbage collected.
+ */
+static int netisr_direct_force;
+SYSCTL_INT(_net_isr, OID_AUTO, direct_force, CTLFLAG_RD,
+ &netisr_direct_force, 0, "compat: force direct dispatch");
+
+static int netisr_direct;
+SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RD, &netisr_direct, 0,
+ "compat: enable direct dispatch");
/*
* Allow the administrator to limit the number of threads (CPUs) to use for
@@ -276,6 +288,106 @@ netisr_default_flow2cpu(u_int flowid)
}
/*
+ * Dispatch tunable and sysctl configuration.
+ */
+struct netisr_dispatch_table_entry {
+ u_int ndte_policy;
+ const char *ndte_policy_str;
+};
+static const struct netisr_dispatch_table_entry netisr_dispatch_table[] = {
+ { NETISR_DISPATCH_DEFAULT, "default" },
+ { NETISR_DISPATCH_DEFERRED, "deferred" },
+ { NETISR_DISPATCH_HYBRID, "hybrid" },
+ { NETISR_DISPATCH_DIRECT, "direct" },
+};
+static const u_int netisr_dispatch_table_len =
+ (sizeof(netisr_dispatch_table) / sizeof(netisr_dispatch_table[0]));
+
+static void
+netisr_dispatch_policy_to_str(u_int dispatch_policy, char *buffer,
+ u_int buflen)
+{
+ const struct netisr_dispatch_table_entry *ndtep;
+ const char *str;
+ u_int i;
+
+ str = "unknown";
+ for (i = 0; i < netisr_dispatch_table_len; i++) {
+ ndtep = &netisr_dispatch_table[i];
+ if (ndtep->ndte_policy == dispatch_policy) {
+ str = ndtep->ndte_policy_str;
+ break;
+ }
+ }
+ snprintf(buffer, buflen, "%s", str);
+}
+
+static int
+netisr_dispatch_policy_from_str(const char *str, u_int *dispatch_policyp)
+{
+ const struct netisr_dispatch_table_entry *ndtep;
+ u_int i;
+
+ for (i = 0; i < netisr_dispatch_table_len; i++) {
+ ndtep = &netisr_dispatch_table[i];
+ if (strcmp(ndtep->ndte_policy_str, str) == 0) {
+ *dispatch_policyp = ndtep->ndte_policy;
+ return (0);
+ }
+ }
+ return (EINVAL);
+}
+
+static void
+netisr_dispatch_policy_compat(void)
+{
+
+ switch (netisr_dispatch_policy) {
+ case NETISR_DISPATCH_DEFERRED:
+ netisr_direct_force = 0;
+ netisr_direct = 0;
+ break;
+
+ case NETISR_DISPATCH_HYBRID:
+ netisr_direct_force = 0;
+ netisr_direct = 1;
+ break;
+
+ case NETISR_DISPATCH_DIRECT:
+ netisr_direct_force = 1;
+ netisr_direct = 1;
+ break;
+
+ default:
+ panic("%s: unknown policy %u", __func__,
+ netisr_dispatch_policy);
+ }
+}
+
+static int
+sysctl_netisr_dispatch_policy(SYSCTL_HANDLER_ARGS)
+{
+ char tmp[NETISR_DISPATCH_POLICY_MAXSTR];
+ u_int dispatch_policy;
+ int error;
+
+ netisr_dispatch_policy_to_str(netisr_dispatch_policy, tmp,
+ sizeof(tmp));
+ error = sysctl_handle_string(oidp, tmp, sizeof(tmp), req);
+ if (error == 0 && req->newptr != NULL) {
+ error = netisr_dispatch_policy_from_str(tmp,
+ &dispatch_policy);
+ if (error == 0 && dispatch_policy == NETISR_DISPATCH_DEFAULT)
+ error = EINVAL;
+ if (error == 0) {
+ netisr_dispatch_policy = dispatch_policy;
+ netisr_dispatch_policy_compat();
+ }
+ }
+ return (error);
+}
+
+/*
* Register a new netisr handler, which requires initializing per-protocol
* fields for each workstream. All netisr work is briefly suspended while
* the protocol is installed.
@@ -312,6 +424,12 @@ netisr_register(const struct netisr_handler *nhp)
KASSERT(nhp->nh_policy != NETISR_POLICY_CPU || nhp->nh_m2cpuid != NULL,
("%s: nh_policy == CPU but m2cpuid not defined for %s", __func__,
name));
+ KASSERT(nhp->nh_dispatch == NETISR_DISPATCH_DEFAULT ||
+ nhp->nh_dispatch == NETISR_DISPATCH_DEFERRED ||
+ nhp->nh_dispatch == NETISR_DISPATCH_HYBRID ||
+ nhp->nh_dispatch == NETISR_DISPATCH_DIRECT,
+ ("%s: invalid nh_dispatch (%u)", __func__, nhp->nh_dispatch));
+
KASSERT(proto < NETISR_MAXPROT,
("%s(%u, %s): protocol too big", __func__, proto, name));
@@ -339,6 +457,7 @@ netisr_register(const struct netisr_handler *nhp)
} else
netisr_proto[proto].np_qlimit = nhp->nh_qlimit;
netisr_proto[proto].np_policy = nhp->nh_policy;
+ netisr_proto[proto].np_dispatch = nhp->nh_dispatch;
CPU_FOREACH(i) {
npwp = &(DPCPU_ID_PTR(i, nws))->nws_work[proto];
bzero(npwp, sizeof(*npwp));
@@ -541,15 +660,32 @@ netisr_unregister(const struct netisr_handler *nhp)
}
/*
+ * Compose the global and per-protocol policies on dispatch, and return the
+ * dispatch policy to use.
+ */
+static u_int
+netisr_get_dispatch(struct netisr_proto *npp)
+{
+
+ /*
+ * Protocol-specific configuration overrides the global default.
+ */
+ if (npp->np_dispatch != NETISR_DISPATCH_DEFAULT)
+ return (npp->np_dispatch);
+ return (netisr_dispatch_policy);
+}
+
+/*
* Look up the workstream given a packet and source identifier. Do this by
* checking the protocol's policy, and optionally call out to the protocol
* for assistance if required.
*/
static struct mbuf *
-netisr_select_cpuid(struct netisr_proto *npp, uintptr_t source,
- struct mbuf *m, u_int *cpuidp)
+netisr_select_cpuid(struct netisr_proto *npp, u_int dispatch_policy,
+ uintptr_t source, struct mbuf *m, u_int *cpuidp)
{
struct ifnet *ifp;
+ u_int policy;
NETISR_LOCK_ASSERT();
@@ -567,11 +703,30 @@ netisr_select_cpuid(struct netisr_proto *npp, uintptr_t source,
* If we want to support per-interface policies, we should do that
* here first.
*/
- switch (npp->np_policy) {
- case NETISR_POLICY_CPU:
- return (npp->np_m2cpuid(m, source, cpuidp));
+ policy = npp->np_policy;
+ if (policy == NETISR_POLICY_CPU) {
+ m = npp->np_m2cpuid(m, source, cpuidp);
+ if (m == NULL)
+ return (NULL);
+
+ /*
+ * It's possible for a protocol not to have a good idea about
+ * where to process a packet, in which case we fall back on
+ * the netisr code to decide. In the hybrid case, return the
+ * current CPU ID, which will force an immediate direct
+ * dispatch. In the queued case, fall back on the SOURCE
+ * policy.
+ */
+ if (*cpuidp != NETISR_CPUID_NONE)
+ return (m);
+ if (dispatch_policy == NETISR_DISPATCH_HYBRID) {
+ *cpuidp = curcpu;
+ return (m);
+ }
+ policy = NETISR_POLICY_SOURCE;
+ }
- case NETISR_POLICY_FLOW:
+ if (policy == NETISR_POLICY_FLOW) {
if (!(m->m_flags & M_FLOWID) && npp->np_m2flow != NULL) {
m = npp->np_m2flow(m, source);
if (m == NULL)
@@ -582,21 +737,19 @@ netisr_select_cpuid(struct netisr_proto *npp, uintptr_t source,
netisr_default_flow2cpu(m->m_pkthdr.flowid);
return (m);
}
- /* FALLTHROUGH */
-
- case NETISR_POLICY_SOURCE:
- ifp = m->m_pkthdr.rcvif;
- if (ifp != NULL)
- *cpuidp = nws_array[(ifp->if_index + source) %
- nws_count];
- else
- *cpuidp = nws_array[source % nws_count];
- return (m);
-
- default:
- panic("%s: invalid policy %u for %s", __func__,
- npp->np_policy, npp->np_name);
+ policy = NETISR_POLICY_SOURCE;
}
+
+ KASSERT(policy == NETISR_POLICY_SOURCE,
+ ("%s: invalid policy %u for %s", __func__, npp->np_policy,
+ npp->np_name));
+
+ ifp = m->m_pkthdr.rcvif;
+ if (ifp != NULL)
+ *cpuidp = nws_array[(ifp->if_index + source) % nws_count];
+ else
+ *cpuidp = nws_array[source % nws_count];
+ return (m);
}
/*
@@ -795,7 +948,8 @@ netisr_queue_src(u_int proto, uintptr_t source, struct mbuf *m)
KASSERT(netisr_proto[proto].np_handler != NULL,
("%s: invalid proto %u", __func__, proto));
- m = netisr_select_cpuid(&netisr_proto[proto], source, m, &cpuid);
+ m = netisr_select_cpuid(&netisr_proto[proto], NETISR_DISPATCH_DEFERRED,
+ source, m, &cpuid);
if (m != NULL) {
KASSERT(!CPU_ABSENT(cpuid), ("%s: CPU %u absent", __func__,
cpuid));
@@ -826,23 +980,23 @@ netisr_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m)
struct rm_priotracker tracker;
#endif
struct netisr_workstream *nwsp;
+ struct netisr_proto *npp;
struct netisr_work *npwp;
int dosignal, error;
- u_int cpuid;
-
- /*
- * If direct dispatch is entirely disabled, fall back on queueing.
- */
- if (!netisr_direct)
- return (netisr_queue_src(proto, source, m));
+ u_int cpuid, dispatch_policy;
KASSERT(proto < NETISR_MAXPROT,
("%s: invalid proto %u", __func__, proto));
#ifdef NETISR_LOCKING
NETISR_RLOCK(&tracker);
#endif
- KASSERT(netisr_proto[proto].np_handler != NULL,
- ("%s: invalid proto %u", __func__, proto));
+ npp = &netisr_proto[proto];
+ KASSERT(npp->np_handler != NULL, ("%s: invalid proto %u", __func__,
+ proto));
+
+ dispatch_policy = netisr_get_dispatch(npp);
+ if (dispatch_policy == NETISR_DISPATCH_DEFERRED)
+ return (netisr_queue_src(proto, source, m));
/*
* If direct dispatch is forced, then unconditionally dispatch
@@ -851,7 +1005,7 @@ netisr_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m)
* nws_flags because all netisr processing will be source ordered due
* to always being forced to directly dispatch.
*/
- if (netisr_direct_force) {
+ if (dispatch_policy == NETISR_DISPATCH_DIRECT) {
nwsp = DPCPU_PTR(nws);
npwp = &nwsp->nws_work[proto];
npwp->nw_dispatched++;
@@ -861,18 +1015,22 @@ netisr_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m)
goto out_unlock;
}
+ KASSERT(dispatch_policy == NETISR_DISPATCH_HYBRID,
+ ("%s: unknown dispatch policy (%u)", __func__, dispatch_policy));
+
/*
* Otherwise, we execute in a hybrid mode where we will try to direct
* dispatch if we're on the right CPU and the netisr worker isn't
* already running.
*/
- m = netisr_select_cpuid(&netisr_proto[proto], source, m, &cpuid);
+ sched_pin();
+ m = netisr_select_cpuid(&netisr_proto[proto], NETISR_DISPATCH_HYBRID,
+ source, m, &cpuid);
if (m == NULL) {
error = ENOBUFS;
- goto out_unlock;
+ goto out_unpin;
}
KASSERT(!CPU_ABSENT(cpuid), ("%s: CPU %u absent", __func__, cpuid));
- sched_pin();
if (cpuid != curcpu)
goto queue_fallback;
nwsp = DPCPU_PTR(nws);
@@ -1003,6 +1161,9 @@ netisr_start_swi(u_int cpuid, struct pcpu *pc)
static void
netisr_init(void *arg)
{
+ char tmp[NETISR_DISPATCH_POLICY_MAXSTR];
+ u_int dispatch_policy;
+ int error;
KASSERT(curcpu == 0, ("%s: not on CPU 0", __func__));
@@ -1033,6 +1194,20 @@ netisr_init(void *arg)
}
#endif
+ if (TUNABLE_STR_FETCH("net.isr.dispatch", tmp, sizeof(tmp))) {
+ error = netisr_dispatch_policy_from_str(tmp,
+ &dispatch_policy);
+ if (error == 0 && dispatch_policy == NETISR_DISPATCH_DEFAULT)
+ error = EINVAL;
+ if (error == 0) {
+ netisr_dispatch_policy = dispatch_policy;
+ netisr_dispatch_policy_compat();
+ } else
+ printf(
+ "%s: invalid dispatch policy %s, using default\n",
+ __func__, tmp);
+ }
+
netisr_start_swi(curcpu, pcpu_find(curcpu));
}
SYSINIT(netisr_init, SI_SUB_SOFTINTR, SI_ORDER_FIRST, netisr_init, NULL);
@@ -1088,6 +1263,7 @@ sysctl_netisr_proto(SYSCTL_HANDLER_ARGS)
snpp->snp_proto = proto;
snpp->snp_qlimit = npp->np_qlimit;
snpp->snp_policy = npp->np_policy;
+ snpp->snp_dispatch = npp->np_dispatch;
if (npp->np_m2flow != NULL)
snpp->snp_flags |= NETISR_SNP_FLAGS_M2FLOW;
if (npp->np_m2cpuid != NULL)
diff --git a/sys/net/netisr.h b/sys/net/netisr.h
index cd692f6..83bf9ce 100644
--- a/sys/net/netisr.h
+++ b/sys/net/netisr.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007-2009 Robert N. M. Watson
- * Copyright (c) 2010 Juniper Networks, Inc.
+ * Copyright (c) 2010-2011 Juniper Networks, Inc.
* All rights reserved.
*
* This software was developed by Robert N. M. Watson under contract
@@ -71,6 +71,15 @@
#define NETISR_POLICY_CPU 3 /* Protocol determines CPU placement. */
/*
+ * Protocol dispatch policy constants; selects whether and when direct
+ * dispatch is permitted.
+ */
+#define NETISR_DISPATCH_DEFAULT 0 /* Use global default. */
+#define NETISR_DISPATCH_DEFERRED 1 /* Always defer dispatch. */
+#define NETISR_DISPATCH_HYBRID 2 /* Allow hybrid dispatch. */
+#define NETISR_DISPATCH_DIRECT 3 /* Always direct dispatch. */
+
+/*
* Monitoring data structures, exported by sysctl(2).
*
* Three sysctls are defined. First, a per-protocol structure exported by
@@ -84,7 +93,8 @@ struct sysctl_netisr_proto {
u_int snp_qlimit; /* nh_qlimit */
u_int snp_policy; /* nh_policy */
u_int snp_flags; /* Various flags. */
- u_int _snp_ispare[7];
+ u_int snp_dispatch; /* Dispatch policy. */
+ u_int _snp_ispare[6];
};
/*
@@ -173,6 +183,8 @@ typedef struct mbuf *netisr_m2cpuid_t(struct mbuf *m, uintptr_t source,
typedef struct mbuf *netisr_m2flow_t(struct mbuf *m, uintptr_t source);
typedef void netisr_drainedcpu_t(u_int cpuid);
+#define NETISR_CPUID_NONE ((u_int)-1) /* No affinity returned. */
+
/*
* Data structure describing a protocol handler.
*/
@@ -185,7 +197,8 @@ struct netisr_handler {
u_int nh_proto; /* Integer protocol ID. */
u_int nh_qlimit; /* Maximum per-CPU queue depth. */
u_int nh_policy; /* Work placement policy. */
- u_int nh_ispare[5]; /* For future use. */
+ u_int nh_dispatch; /* Dispatch policy. */
+ u_int nh_ispare[4]; /* For future use. */
void *nh_pspare[4]; /* For future use. */
};
diff --git a/sys/net/netisr_internal.h b/sys/net/netisr_internal.h
index 40afaf1..ac3ed0f 100644
--- a/sys/net/netisr_internal.h
+++ b/sys/net/netisr_internal.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007-2009 Robert N. M. Watson
- * Copyright (c) 2010 Juniper Networks, Inc.
+ * Copyright (c) 2010-2011 Juniper Networks, Inc.
* All rights reserved.
*
* This software was developed by Robert N. M. Watson under contract
@@ -64,6 +64,7 @@ struct netisr_proto {
netisr_drainedcpu_t *np_drainedcpu; /* Callback when drained a queue. */
u_int np_qlimit; /* Maximum per-CPU queue depth. */
u_int np_policy; /* Work placement policy. */
+ u_int np_dispatch; /* Work dispatch policy. */
};
#define NETISR_MAXPROT 16 /* Compile-time limit. */
diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c
index cbae38f..d761a6c 100644
--- a/sys/netgraph/ng_eiface.c
+++ b/sys/netgraph/ng_eiface.c
@@ -41,6 +41,7 @@
#include <sys/syslog.h>
#include <net/if.h>
+#include <net/if_media.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
@@ -76,6 +77,8 @@ static const struct ng_cmdlist ng_eiface_cmdlist[] = {
/* Node private data */
struct ng_eiface_private {
struct ifnet *ifp; /* per-interface network data */
+ struct ifmedia media; /* (fake) media information */
+ int link_status; /* fake */
int unit; /* Interface unit number */
node_p node; /* Our netgraph node */
hook_p ether; /* Hook for ethernet stream */
@@ -127,6 +130,7 @@ static VNET_DEFINE(struct unrhdr *, ng_eiface_unit);
static int
ng_eiface_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
+ const priv_p priv = (priv_p)ifp->if_softc;
struct ifreq *const ifr = (struct ifreq *)data;
int s, error = 0;
@@ -170,6 +174,12 @@ ng_eiface_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_mtu = ifr->ifr_mtu;
break;
+ /* (Fake) media type manipulation */
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &priv->media, command);
+ break;
+
/* Stuff that's not supported */
case SIOCADDMULTI:
case SIOCDELMULTI:
@@ -280,7 +290,6 @@ ng_eiface_start2(node_p node, hook_p hook, void *arg1, int arg2)
static void
ng_eiface_start(struct ifnet *ifp)
{
-
const priv_p priv = (priv_p)ifp->if_softc;
/* Don't do anything if output is active */
@@ -328,6 +337,41 @@ ng_eiface_print_ioctl(struct ifnet *ifp, int command, caddr_t data)
}
#endif /* DEBUG */
+/*
+ * ifmedia stuff
+ */
+static int
+ng_eiface_mediachange(struct ifnet *ifp)
+{
+ const priv_p priv = (priv_p)ifp->if_softc;
+ struct ifmedia *ifm = &priv->media;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+ if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
+ ifp->if_baudrate = ifmedia_baudrate(IFM_ETHER | IFM_1000_T);
+ else
+ ifp->if_baudrate = ifmedia_baudrate(ifm->ifm_media);
+
+ return (0);
+}
+
+static void
+ng_eiface_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ const priv_p priv = (priv_p)ifp->if_softc;
+ struct ifmedia *ifm = &priv->media;
+
+ if (ifm->ifm_cur->ifm_media == (IFM_ETHER | IFM_AUTO) &&
+ (priv->link_status & IFM_ACTIVE))
+ ifmr->ifm_active = IFM_ETHER | IFM_1000_T | IFM_FDX;
+ else
+ ifmr->ifm_active = ifm->ifm_cur->ifm_media;
+ ifmr->ifm_status = priv->link_status;
+
+ return;
+}
+
/************************************************************************
NETGRAPH NODE STUFF
************************************************************************/
@@ -371,6 +415,18 @@ ng_eiface_constructor(node_p node)
ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
+ ifmedia_init(&priv->media, 0, ng_eiface_mediachange,
+ ng_eiface_mediastatus);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_10_T, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_100_TX, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_1000_T, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_10G_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO);
+ priv->link_status = IFM_AVALID;
/* Give this node the same name as the interface (if possible) */
if (ng_name_node(node, ifp->if_xname) != 0)
@@ -379,6 +435,7 @@ ng_eiface_constructor(node_p node)
/* Attach the interface */
ether_ifattach(ifp, eaddr);
+ ifp->if_baudrate = ifmedia_baudrate(IFM_ETHER | IFM_1000_T);
/* Done */
return (0);
@@ -401,7 +458,10 @@ ng_eiface_newhook(node_p node, hook_p hook, const char *name)
NG_HOOK_SET_PRIVATE(hook, &priv->ether);
NG_HOOK_SET_TO_INBOUND(hook);
+ priv->link_status |= IFM_ACTIVE;
+ CURVNET_SET_QUIET(ifp->if_vnet);
if_link_state_change(ifp, LINK_STATE_UP);
+ CURVNET_RESTORE();
return (0);
}
@@ -486,16 +546,20 @@ ng_eiface_rcvmsg(node_p node, item_p item, hook_p lasthook)
} /* end of inner switch() */
break;
case NGM_FLOW_COOKIE:
+ CURVNET_SET_QUIET(ifp->if_vnet);
switch (msg->header.cmd) {
case NGM_LINK_IS_UP:
+ priv->link_status |= IFM_ACTIVE;
if_link_state_change(ifp, LINK_STATE_UP);
break;
case NGM_LINK_IS_DOWN:
+ priv->link_status &= ~IFM_ACTIVE;
if_link_state_change(ifp, LINK_STATE_DOWN);
break;
default:
break;
}
+ CURVNET_RESTORE();
break;
default:
error = EINVAL;
@@ -557,6 +621,7 @@ ng_eiface_rmnode(node_p node)
* hence we have to change the current vnet context here.
*/
CURVNET_SET_QUIET(ifp->if_vnet);
+ ifmedia_removeall(&priv->media);
ether_ifdetach(ifp);
if_free(ifp);
CURVNET_RESTORE();
@@ -576,6 +641,10 @@ ng_eiface_disconnect(hook_p hook)
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
priv->ether = NULL;
+ priv->link_status &= ~IFM_ACTIVE;
+ CURVNET_SET_QUIET(priv->ifp->if_vnet);
+ if_link_state_change(priv->ifp, LINK_STATE_DOWN);
+ CURVNET_RESTORE();
return (0);
}
diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c
index b5bab3c..11ea814 100644
--- a/sys/netgraph/ng_pipe.c
+++ b/sys/netgraph/ng_pipe.c
@@ -298,11 +298,12 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
{
const priv_p priv = NG_NODE_PRIVATE(node);
struct ng_mesg *resp = NULL;
- struct ng_mesg *msg;
+ struct ng_mesg *msg, *flow_msg;
struct ng_pipe_stats *stats;
struct ng_pipe_run *run;
struct ng_pipe_cfg *cfg;
int error = 0;
+ int prev_down, now_down, cmd;
NGI_GET_MSG(item, msg);
switch (msg->header.typecookie) {
@@ -403,10 +404,38 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
cfg->header_offset < 64)
priv->header_offset = cfg->header_offset;
+ prev_down = priv->upper.cfg.ber == 1 ||
+ priv->lower.cfg.ber == 1;
parse_cfg(&priv->upper.cfg, &cfg->downstream,
&priv->upper, priv);
parse_cfg(&priv->lower.cfg, &cfg->upstream,
&priv->lower, priv);
+ now_down = priv->upper.cfg.ber == 1 ||
+ priv->lower.cfg.ber == 1;
+
+ if (prev_down != now_down) {
+ if (now_down)
+ cmd = NGM_LINK_IS_DOWN;
+ else
+ cmd = NGM_LINK_IS_UP;
+
+ if (priv->lower.hook != NULL) {
+ NG_MKMESSAGE(flow_msg, NGM_FLOW_COOKIE,
+ cmd, 0, M_NOWAIT);
+ if (flow_msg != NULL)
+ NG_SEND_MSG_HOOK(error, node,
+ flow_msg, priv->lower.hook,
+ 0);
+ }
+ if (priv->upper.hook != NULL) {
+ NG_MKMESSAGE(flow_msg, NGM_FLOW_COOKIE,
+ cmd, 0, M_NOWAIT);
+ if (flow_msg != NULL)
+ NG_SEND_MSG_HOOK(error, node,
+ flow_msg, priv->upper.hook,
+ 0);
+ }
+ }
break;
default:
error = EINVAL;
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 9bde3c8..85e31dc 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1054,8 +1054,6 @@ void
in_pcbref(struct inpcb *inp)
{
- INP_WLOCK_ASSERT(inp);
-
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
refcount_acquire(&inp->inp_refcount);
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 2827c22..d2a772f 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -106,6 +106,8 @@ static struct pr_usrreqs nousrreqs;
#include <net/if_pfsync.h>
#endif
+FEATURE(inet, "Internet Protocol version 4");
+
extern struct domain inetdomain;
/* Spacer for loadable protocols. */
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index acd1569..ab54755 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -133,6 +133,7 @@ __FBSDID("$FreeBSD$");
/*
* TCP/IP protocol family: IP6, ICMP6, UDP, TCP.
*/
+FEATURE(inet6, "Internet Protocol version 6");
extern struct domain inet6domain;
static struct pr_usrreqs nousrreqs;
diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S
index 64e4ac1..7156edb 100644
--- a/sys/powerpc/aim/trap_subr64.S
+++ b/sys/powerpc/aim/trap_subr64.S
@@ -519,6 +519,7 @@ CNAME(trapexit):
mfmsr %r3
andi. %r3,%r3,~PSL_EE@l
mtmsr %r3
+ isync
/* Test AST pending: */
ld %r5,FRAME_SRR1+48(%r1)
mtcr %r5
diff --git a/sys/powerpc/ps3/ps3bus.c b/sys/powerpc/ps3/ps3bus.c
index 11dbba5..6a5120a 100644
--- a/sys/powerpc/ps3/ps3bus.c
+++ b/sys/powerpc/ps3/ps3bus.c
@@ -31,6 +31,7 @@
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/bus.h>
+#include <sys/clock.h>
#include <sys/cpu.h>
#include <sys/resource.h>
#include <sys/rman.h>
@@ -46,6 +47,7 @@
#include "ps3bus.h"
#include "ps3-hvcall.h"
#include "iommu_if.h"
+#include "clock_if.h"
static void ps3bus_identify(driver_t *, device_t);
static int ps3bus_probe(device_t);
@@ -63,6 +65,8 @@ static int ps3_iommu_map(device_t dev, bus_dma_segment_t *segs, int *nsegs,
bus_size_t boundary, void *cookie);
static int ps3_iommu_unmap(device_t dev, bus_dma_segment_t *segs,
int nsegs, void *cookie);
+static int ps3_gettime(device_t dev, struct timespec *ts);
+static int ps3_settime(device_t dev, struct timespec *ts);
struct ps3bus_devinfo {
int bus;
@@ -106,6 +110,10 @@ static device_method_t ps3bus_methods[] = {
DEVMETHOD(iommu_map, ps3_iommu_map),
DEVMETHOD(iommu_unmap, ps3_iommu_unmap),
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, ps3_gettime),
+ DEVMETHOD(clock_settime, ps3_settime),
+
{ 0, 0 }
};
@@ -312,6 +320,8 @@ ps3bus_attach(device_t self)
device_set_ivars(cdev, dinfo);
}
}
+
+ clock_register(self, 1000);
return (bus_generic_attach(self));
}
@@ -551,7 +561,6 @@ ps3_iommu_map(device_t dev, bus_dma_segment_t *segs, int *nsegs,
return (0);
}
-
static int
ps3_iommu_unmap(device_t dev, bus_dma_segment_t *segs, int nsegs, void *cookie)
{
@@ -559,3 +568,26 @@ ps3_iommu_unmap(device_t dev, bus_dma_segment_t *segs, int nsegs, void *cookie)
return (0);
}
+#define Y2K 946684800
+
+static int
+ps3_gettime(device_t dev, struct timespec *ts)
+{
+ uint64_t rtc, tb;
+ int result;
+
+ result = lv1_get_rtc(&rtc, &tb);
+ if (result)
+ return (result);
+
+ ts->tv_sec = rtc + Y2K;
+ ts->tv_nsec = 0;
+ return (0);
+}
+
+static int
+ps3_settime(device_t dev, struct timespec *ts)
+{
+ return (-1);
+}
+
diff --git a/tools/build/make_check/Makefile b/tools/build/make_check/Makefile
index e57e70c..cc8ca6b 100644
--- a/tools/build/make_check/Makefile
+++ b/tools/build/make_check/Makefile
@@ -1,5 +1,7 @@
# $FreeBSD$
+.MAKE.MODE= normal
+
# Test for broken LHS expansion.
# This *must* cause make(1) to detect a recursive variable, and fail as such.
.if make(lhs_expn)
@@ -152,24 +154,19 @@ pass_cmd_vars:
@${SMAKE} CMD1=cmd1 CMD2=cmd2 pass_cmd_vars_4
.endif
-.if make(pass_cmd_vars_1)
+#
# Check that the variable definition arrived from the calling make
+#
+.if make(pass_cmd_vars_1)
+# These values should get overridden by the commandline
+CMD1=oops1
+CMD2=oops2
pass_cmd_vars_1:
@:
.if ${CMD1} != cmd1 || ${CMD2} != cmd2
.error variables not passed through MAKEFLAGS
.endif
-
-# Check that the variable definition is in MAKEFLAGS
-.if ${.MAKEFLAGS:MCMD1=*} != "CMD1=cmd1" || ${.MAKEFLAGS:MCMD2=*} != "CMD2=cmd2"
-.error variable assignment not found in $${MAKEFLAGS}
-.endif
-
-# Check that the variable definition is not in MFLAGS
-.if ${MFLAGS:MCMD1=*} != "" || ${MFLAGS:MCMD2=*} != ""
-.error variable assignment found in $${MFLAGS}
-.endif
.endif
.if make(pass_cmd_vars_2)
@@ -228,7 +225,7 @@ pass_cmd_vars_4_1:
#
.if make(plus_flag)
OUT != ${SMAKE} -n plus_flag_1
-.if ${OUT} != "/tmp"
+.if ${OUT:M/tmp} != "/tmp"
.error make doesn't handle + flag
.endif
plus_flag:
diff --git a/tools/build/options/WITH_BSD_GREP b/tools/build/options/WITH_BSD_GREP
index 702ca25..e664117 100644
--- a/tools/build/options/WITH_BSD_GREP
+++ b/tools/build/options/WITH_BSD_GREP
@@ -1,2 +1,2 @@
.\" $FreeBSD$
-Build BSD-licensed grep instead of GNU grep.
+Install BSD-licensed grep as '[ef]grep' instead of GNU grep.
diff --git a/tools/tools/ether_reflect/ether_reflect.1 b/tools/tools/ether_reflect/ether_reflect.1
index c8388f0..139dcc2 100644
--- a/tools/tools/ether_reflect/ether_reflect.1
+++ b/tools/tools/ether_reflect/ether_reflect.1
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd December 23, 2008
-.Dt ether_reflect 1
+.Dt ETHER_REFLECT 1
.Os
.Sh NAME
.Nm ether_reflect
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 85a9180..f258347 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -57,7 +57,7 @@ SUBDIR= alias \
getconf \
getent \
getopt \
- ${_grep} \
+ grep \
gzip \
head \
hexdump \
@@ -227,10 +227,6 @@ SUBDIR+= bluetooth
SUBDIR+= cpio
.endif
-.if ${MK_BSD_GREP} != "no"
-_grep= grep
-.endif
-
.if ${MK_CALENDAR} != "no"
SUBDIR+= calendar
.endif
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index 83f3151..a04476a 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -266,6 +266,7 @@
09/12 Weongyo Jeong <weongyo@FreeBSD.org> born in Haman, Korea, 1980
09/12 Benedict Christopher Reuschling <bcr@FreeBSD.org> born in Darmstadt, Germany, 1981
09/12 William C. Fumerola II <billf@FreeBSD.org> born in Detroit, Michigan, United States, 1981
+09/15 Aleksandr Rybalko <ray@FreeBSD.org> born in Odessa, Ukraine, 1977
09/15 Dima Panov <fluffy@FreeBSD.org> born in Khabarovsk, Russian Federation, 1978
09/17 Maxim Bolotin <mb@FreeBSD.org> born in Rostov-on-Don, Russian Federation, 1976
09/18 Matthew Fleming <mdf@FreeBSD.org> born in Cleveland, Ohio, United States, 1975
diff --git a/usr.bin/grep/Makefile b/usr.bin/grep/Makefile
index 98fceeb..8cd490d 100644
--- a/usr.bin/grep/Makefile
+++ b/usr.bin/grep/Makefile
@@ -2,9 +2,16 @@
# $FreeBSD$
# $OpenBSD: Makefile,v 1.6 2003/06/25 15:00:04 millert Exp $
+.include <bsd.own.mk>
+
+.if ${MK_BSD_GREP} == "yes"
PROG= grep
+.else
+PROG= bsdgrep
+.endif
SRCS= fastgrep.c file.c grep.c queue.c util.c
+.if ${MK_BSD_GREP} == "yes"
LINKS= ${BINDIR}/grep ${BINDIR}/egrep \
${BINDIR}/grep ${BINDIR}/fgrep \
${BINDIR}/grep ${BINDIR}/zgrep \
@@ -16,6 +23,10 @@ MLINKS= grep.1 egrep.1 \
grep.1 zgrep.1 \
grep.1 zegrep.1 \
grep.1 zfgrep.1
+.endif
+
+bsdgrep.1: grep.1
+ cp ${.ALLSRC} ${.TARGET}
WARNS?= 6
diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
index 927493e..217660e 100644
--- a/usr.bin/gzip/gzip.c
+++ b/usr.bin/gzip/gzip.c
@@ -1782,7 +1782,8 @@ handle_pathname(char *path)
}
retry:
- if (stat(path, &sb) != 0 || (fflag == 0 && lstat(path, &sb) != 0)) {
+ if (stat(path, &sb) != 0 || (fflag == 0 && cflag == 0 &&
+ lstat(path, &sb) != 0)) {
/* lets try <path>.gz if we're decompressing */
if (dflag && s == NULL && errno == ENOENT) {
len = strlen(path);
diff --git a/usr.bin/mkcsmapper/mkcsmapper.1 b/usr.bin/mkcsmapper/mkcsmapper.1
index a2666b4..650df50 100644
--- a/usr.bin/mkcsmapper/mkcsmapper.1
+++ b/usr.bin/mkcsmapper/mkcsmapper.1
@@ -35,7 +35,7 @@
.\" $FreeBSD$
.\"
.Dd Sep 6, 2009
-.Dt mkcsmapper 1
+.Dt MKCSMAPPER 1
.Os
.Sh NAME
.Nm mkcsmapper
diff --git a/usr.bin/mkesdb/mkesdb.1 b/usr.bin/mkesdb/mkesdb.1
index 2e06371..66eb390 100644
--- a/usr.bin/mkesdb/mkesdb.1
+++ b/usr.bin/mkesdb/mkesdb.1
@@ -35,7 +35,7 @@
.\" $FreeBSD$
.\"
.Dd November 1, 2009
-.Dt mkesdb 1
+.Dt MKESDB 1
.Os
.Sh NAME
.Nm mkesdb
diff --git a/usr.bin/netstat/netisr.c b/usr.bin/netstat/netisr.c
index 25f341c..cc05c38 100644
--- a/usr.bin/netstat/netisr.c
+++ b/usr.bin/netstat/netisr.c
@@ -60,8 +60,7 @@ static u_int numthreads;
static u_int defaultqlimit;
static u_int maxqlimit;
-static u_int direct;
-static u_int direct_force;
+static char dispatch_policy[20];
static struct sysctl_netisr_proto *proto_array;
static u_int proto_array_len;
@@ -77,6 +76,32 @@ static u_int *nws_array;
static u_int maxprot;
static void
+netisr_dispatch_policy_to_string(u_int dispatch_policy, char *buf,
+ size_t buflen)
+{
+ const char *str;
+
+ switch (dispatch_policy) {
+ case NETISR_DISPATCH_DEFAULT:
+ str = "default";
+ break;
+ case NETISR_DISPATCH_DEFERRED:
+ str = "deferred";
+ break;
+ case NETISR_DISPATCH_HYBRID:
+ str = "hybrid";
+ break;
+ case NETISR_DISPATCH_DIRECT:
+ str = "direct";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+ snprintf(buf, buflen, "%s", str);
+}
+
+static void
netisr_load_kvm_uint(kvm_t *kd, char *name, u_int *p)
{
struct nlist nl[] = {
@@ -144,6 +169,7 @@ netisr_protoispresent(u_int proto)
static void
netisr_load_kvm_config(kvm_t *kd)
{
+ u_int tmp;
netisr_load_kvm_uint(kd, "_netisr_bindthreads", &bindthreads);
netisr_load_kvm_uint(kd, "_netisr_maxthreads", &maxthreads);
@@ -152,8 +178,9 @@ netisr_load_kvm_config(kvm_t *kd)
netisr_load_kvm_uint(kd, "_netisr_defaultqlimit", &defaultqlimit);
netisr_load_kvm_uint(kd, "_netisr_maxqlimit", &maxqlimit);
- netisr_load_kvm_uint(kd, "_netisr_direct", &direct);
- netisr_load_kvm_uint(kd, "_netisr_direct_force", &direct_force);
+ netisr_load_kvm_uint(kd, "_netisr_dispatch_policy", &tmp);
+ netisr_dispatch_policy_to_string(tmp, dispatch_policy,
+ sizeof(dispatch_policy));
}
static void
@@ -169,6 +196,17 @@ netisr_load_sysctl_uint(const char *name, u_int *p)
}
static void
+netisr_load_sysctl_string(const char *name, char *p, size_t len)
+{
+ size_t retlen;
+
+ retlen = len;
+ if (sysctlbyname(name, p, &retlen, NULL, 0) < 0)
+ err(-1, "%s", name);
+ p[len - 1] = '\0';
+}
+
+static void
netisr_load_sysctl_config(void)
{
@@ -179,8 +217,8 @@ netisr_load_sysctl_config(void)
netisr_load_sysctl_uint("net.isr.defaultqlimit", &defaultqlimit);
netisr_load_sysctl_uint("net.isr.maxqlimit", &maxqlimit);
- netisr_load_sysctl_uint("net.isr.direct", &direct);
- netisr_load_sysctl_uint("net.isr.direct_force", &direct_force);
+ netisr_load_sysctl_string("net.isr.dispatch", dispatch_policy,
+ sizeof(dispatch_policy));
}
static void
@@ -244,6 +282,7 @@ netisr_load_kvm_proto(kvm_t *kd)
snpp->snp_proto = i;
snpp->snp_qlimit = npp->np_qlimit;
snpp->snp_policy = npp->np_policy;
+ snpp->snp_dispatch = npp->np_dispatch;
if (npp->np_m2flow != NULL)
snpp->snp_flags |= NETISR_SNP_FLAGS_M2FLOW;
if (npp->np_m2cpuid != NULL)
@@ -418,6 +457,7 @@ netisr_load_sysctl_work(void)
static void
netisr_print_proto(struct sysctl_netisr_proto *snpp)
{
+ char tmp[20];
printf("%-6s", snpp->snp_name);
printf(" %5u", snpp->snp_proto);
@@ -426,6 +466,9 @@ netisr_print_proto(struct sysctl_netisr_proto *snpp)
(snpp->snp_policy == NETISR_POLICY_SOURCE) ? "source" :
(snpp->snp_policy == NETISR_POLICY_FLOW) ? "flow" :
(snpp->snp_policy == NETISR_POLICY_CPU) ? "cpu" : "-");
+ netisr_dispatch_policy_to_string(snpp->snp_dispatch, tmp,
+ sizeof(tmp));
+ printf(" %8s", tmp);
printf(" %s%s%s\n",
(snpp->snp_flags & NETISR_SNP_FLAGS_M2CPUID) ? "C" : "-",
(snpp->snp_flags & NETISR_SNP_FLAGS_DRAINEDCPU) ? "D" : "-",
@@ -483,17 +526,15 @@ netisr_stats(void *kvmd)
printf("%-25s %12u %12u\n", "Thread count", numthreads, maxthreads);
printf("%-25s %12u %12u\n", "Default queue limit", defaultqlimit,
maxqlimit);
- printf("%-25s %12s %12s\n", "Direct dispatch",
- direct ? "enabled" : "disabled", "n/a");
- printf("%-25s %12s %12s\n", "Forced direct dispatch",
- direct_force ? "enabled" : "disabled", "n/a");
+ printf("%-25s %12s %12s\n", "Dispatch policy", dispatch_policy,
+ "n/a");
printf("%-25s %12s %12s\n", "Threads bound to CPUs",
bindthreads ? "enabled" : "disabled", "n/a");
printf("\n");
printf("Protocols:\n");
- printf("%-6s %5s %6s %-6s %-5s\n", "Name", "Proto", "QLimit",
- "Policy", "Flags");
+ printf("%-6s %5s %6s %-6s %-8s %-5s\n", "Name", "Proto", "QLimit",
+ "Policy", "Dispatch", "Flags");
for (i = 0; i < proto_array_len; i++) {
snpp = &proto_array[i];
netisr_print_proto(snpp);
diff --git a/usr.bin/showmount/showmount.c b/usr.bin/showmount/showmount.c
index f4372b5..2635250 100644
--- a/usr.bin/showmount/showmount.c
+++ b/usr.bin/showmount/showmount.c
@@ -185,7 +185,7 @@ main(int argc, char **argv)
printf("Exports list on %s:\n", host);
exp = exportslist;
while (exp) {
- printf("%-35s", exp->ex_dirp);
+ printf("%-34s ", exp->ex_dirp);
grp = exp->ex_groups;
if (grp == NULL) {
printf("Everyone\n");
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
index ebcf286..b77b5f7 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
@@ -26,7 +26,7 @@
.\" $FreeBSD$
.\"
.Dd August 6, 2007
-.Dt snmp_bridge 3
+.Dt SNMP_BRIDGE 3
.Os
.Sh NAME
.Nm snmp_bridge
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 b/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3
index 403d605..774c027 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3
@@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd January 3, 2006
-.Dt snmp_hostres 3
+.Dt SNMP_HOSTRES 3
.Os
.Sh NAME
.Nm snmp_hostres
diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
index 9f366f1..20256f0 100644
--- a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
+++ b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
@@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd June 28, 2010
-.Dt snmp_wlan 3
+.Dt SNMP_WLAN 3
.Os
.Sh NAME
.Nm snmp_wlan
diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8
index ca14bec..4ceecf6 100644
--- a/usr.sbin/gpioctl/gpioctl.8
+++ b/usr.sbin/gpioctl/gpioctl.8
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 27, 2010
+.Dd May 25, 2011
.Dt GPIOCTL 1
.Os
.Sh NAME
@@ -93,17 +93,17 @@ be verbose: for each listed pin print current configuration
.Sh EXAMPLES
.Bl -bullet
.It
-List pins available on GPIO controller defined by device /dev/gpioctl0
+List pins available on GPIO controller defined by device /dev/gpioc0
.Pp
-gpioctl -f /dev/gpioctl0 -l
+gpioctl -f /dev/gpioc0 -l
.It
Set the value of pin 12 to 1
.Pp
-gpioctl -f /dev/gpioctl0 12 1
+gpioctl -f /dev/gpioc0 12 1
.It
Configure pin 12 to be input pin
.Pp
-gpioctl -f /dev/gpioctl0 -c 12 IN
+gpioctl -f /dev/gpioc0 -c 12 IN
.El
.Sh HISTORY
The
diff --git a/usr.sbin/usbdump/usbdump.8 b/usr.sbin/usbdump/usbdump.8
index f2b00e4..a02f34e 100644
--- a/usr.sbin/usbdump/usbdump.8
+++ b/usr.sbin/usbdump/usbdump.8
@@ -26,7 +26,7 @@
.\" $FreeBSD$
.\"
.Dd December 4, 2010
-.Dt usbdump 8
+.Dt USBDUMP 8
.Os
.Sh NAME
.Nm usbdump
OpenPOWER on IntegriCloud