This commit is contained in:
Attilio Rao 2011-05-26 17:38:00 +00:00
commit 7fcdc9a26f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/largeSMP/; revision=222318
102 changed files with 3760 additions and 389 deletions

View File

@ -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;
}

View File

@ -223,6 +223,7 @@ fsshare_main(const char *file, const char *mountpoint, const char *shareopts,
error = errno;
unlink(tmpfile);
} else {
fflush(newfd);
/*
* Send SIGHUP to mountd, but unlock exports file later.
*/

View File

@ -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

View File

@ -27,9 +27,7 @@ _groff= groff
.endif
.endif
.if ${MK_BSD_GREP} != "yes"
_grep= grep
.endif
.if ${MK_CVS} != "no"
_cvs= cvs

View File

@ -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

View File

@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd January 8, 2008
.Dt feature_present 3
.Dt FEATURE_PRESENT 3
.Os
.Sh NAME
.Nm feature_present

View File

@ -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)

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 17, 2010
.Dt atrtc 4
.Dt ATRTC 4
.Os
.Sh NAME
.Nm atrtc

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 14, 2010
.Dt attimer 4
.Dt ATTIMER 4
.Os
.Sh NAME
.Nm attimer

View File

@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
.Dt cc 4
.Dt CC 4
.Os
.Sh NAME
.Nm cc

View File

@ -30,7 +30,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
.Dt h_ertt 9
.Dt H_ERTT 9
.Os
.Sh NAME
.Nm h_ertt

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd April 3, 2011
.Dt nvram2env 4
.Dt NVRAM2ENV 4
.Os
.Sh NAME
.Nm nvram2env

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 15, 2010
.Dt eventtimers 4
.Dt EVENTTIMERS 4
.Os
.Sh NAME
.Nm eventtimers

View File

@ -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.

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd September 8, 2008
.Dt DEVFS_CDEVPRIV
.Dt DEVFS_CDEVPRIV 9
.Os
.Sh NAME
.Nm devfs_set_cdevpriv ,

View File

@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
.Dt hhook 9
.Dt HHOOK 9
.Os
.Sh NAME
.Nm hhook ,

View File

@ -31,7 +31,7 @@
.\" $FreeBSD$
.\"
.Dd February 15, 2011
.Dt khelp 9
.Dt KHELP 9
.Os
.Sh NAME
.Nm khelp ,

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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
};

View File

@ -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);
}
/*

View File

@ -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],

View File

@ -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

View File

@ -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)) {

View File

@ -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 "????";
}

View File

@ -668,6 +668,41 @@ typedef struct {
uint32_t cur_seq; /* current sequence number */
} 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.
*

View File

@ -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 */

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
}
/*

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 *
*************/

View File

@ -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_ */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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},
};

View File

@ -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);

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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);
}
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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

View File

@ -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) \

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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 *,

View File

@ -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 @@ nfsrpc_readrpc(vnode_t vp, struct uio *uiop, struct ucred *cred,
* 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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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"));

View File

@ -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);
@ -336,6 +340,34 @@ smp_rendezvous_action(void)
local_teardown_func = smp_rv_teardown_func;
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
@ -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

View File

@ -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 *);
@ -610,9 +614,26 @@ epair_qflush(struct ifnet *ifp)
sc->if_qflush(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);

View File

@ -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
@ -275,6 +287,106 @@ netisr_default_flow2cpu(u_int flowid)
return (nws_array[flowid % nws_count]);
}
/*
* 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
@ -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));
@ -540,16 +659,33 @@ netisr_unregister(const struct netisr_handler *nhp)
NETISR_WUNLOCK();
}
/*
* 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);
case NETISR_POLICY_FLOW:
/*
* 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;
}
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)

View File

@ -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
@ -70,6 +70,15 @@
#define NETISR_POLICY_FLOW 2 /* Maintain flow ordering. */
#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).
*
@ -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. */
};

View File

@ -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. */

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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. */

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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:

View File

@ -1,2 +1,2 @@
.\" $FreeBSD$
Build BSD-licensed grep instead of GNU grep.
Install BSD-licensed grep as '[ef]grep' instead of GNU grep.

View File

@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd December 23, 2008
.Dt ether_reflect 1
.Dt ETHER_REFLECT 1
.Os
.Sh NAME
.Nm ether_reflect

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -35,7 +35,7 @@
.\" $FreeBSD$
.\"
.Dd Sep 6, 2009
.Dt mkcsmapper 1
.Dt MKCSMAPPER 1
.Os
.Sh NAME
.Nm mkcsmapper

View File

@ -35,7 +35,7 @@
.\" $FreeBSD$
.\"
.Dd November 1, 2009
.Dt mkesdb 1
.Dt MKESDB 1
.Os
.Sh NAME
.Nm mkesdb

View File

@ -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;
@ -76,6 +75,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)
{
@ -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
@ -168,6 +195,17 @@ netisr_load_sysctl_uint(const char *name, u_int *p)
errx(-1, "%s: invalid len %ju", name, (uintmax_t)retlen);
}
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);

View File

@ -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");

View File

@ -26,7 +26,7 @@
.\" $FreeBSD$
.\"
.Dd August 6, 2007
.Dt snmp_bridge 3
.Dt SNMP_BRIDGE 3
.Os
.Sh NAME
.Nm snmp_bridge

View File

@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd January 3, 2006
.Dt snmp_hostres 3
.Dt SNMP_HOSTRES 3
.Os
.Sh NAME
.Nm snmp_hostres

View File

@ -29,7 +29,7 @@
.\" $FreeBSD$
.\"
.Dd June 28, 2010
.Dt snmp_wlan 3
.Dt SNMP_WLAN 3
.Os
.Sh NAME
.Nm snmp_wlan

Some files were not shown because too many files have changed in this diff Show More