From 5c59afe04ba636c536071fdab3a388b21158415c Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 24 May 2011 02:19:45 +0000 Subject: [PATCH 01/63] Add RTC support for the LV1 clock on the PS3. The hypervisor won't let us set it, but it's better than nothing. --- sys/powerpc/ps3/ps3bus.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/ps3/ps3bus.c b/sys/powerpc/ps3/ps3bus.c index 11dbba5a67d..6a5120a5743 100644 --- a/sys/powerpc/ps3/ps3bus.c +++ b/sys/powerpc/ps3/ps3bus.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -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); +} + From e808ca44541f072491ea74ae1cd19a683f4213c6 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Tue, 24 May 2011 05:34:45 +0000 Subject: [PATCH 02/63] Add in descriptions for TX descriptor fields ctl8-11 - these fields control the antenna control bits for the four TX series and the TPC settings for TX series 1, 2, 3. The specifics: * The TPC setting for TX series 0 is handled in ctl0. * TPC is currently disabled, so the per-packet TX power is set via the global per-rate TX power register, not per packet. * The antenna control bits don't matter for AR5416 and later so they should stay 0 (which they currently do); they may be set for Kite but as there's no TX diversity supported at the moment (it requires the NIC to be built with an external antenna switch, matching how antenna diversity is done on legacy NICs), so again keep them 0. This is in preparation for supporting per-rate TPC on the AR5416 and later. The Kite (and soon to come Kiwi) code sets ctl8-11 to 0x0, which doesn't have any effect at the moment. When TPC is enabled it would result in the second, third and fourth TX series attmpts to be done with a TX power of 0. This commit doesn't change that; it'll be followed up with some commits to properly set the TPC registers appropriately. --- sys/dev/ath/ath_hal/ar5416/ar5416desc.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h index 76f508025e6..105c5d6080d 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h @@ -205,6 +205,29 @@ struct ar5416_desc { #define AR_STBC2 0x40000000 #define AR_STBC3 0x80000000 +/* ds_ctl8 */ +#define AR_AntCtl0 0x00ffffff +#define AR_AntCtl0_S 0 +/* Xmit 0 TPC is AR_XmitPower in ctl0 */ + +/* ds_ctl9 */ +#define AR_AntCtl1 0x00ffffff +#define AR_AntCtl1_S 0 +#define AR_XmitPower1 0xff000000 +#define AR_XmitPower1_S 24 + +/* ds_ctl10 */ +#define AR_AntCtl2 0x00ffffff +#define AR_AntCtl2_S 0 +#define AR_XmitPower2 0xff000000 +#define AR_XmitPower2_S 24 + +/* ds_ctl11 */ +#define AR_AntCtl3 0x00ffffff +#define AR_AntCtl3_S 0 +#define AR_XmitPower3 0xff000000 +#define AR_XmitPower3_S 24 + /************* * TX Status * *************/ From 634be0a971b5e3ed97db34edb7142ec5cda380fd Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Tue, 24 May 2011 05:49:02 +0000 Subject: [PATCH 03/63] Use the new per-series antenna and TPC definitions when setting ctl8->11. This should hopefully make it clearer to developers what is going on and when TPC is being hacked on, make it obvious why it isn't working for series 1, 2, 3. I won't flip on setting TX power for TX series 1, 2, 3 until I've done some further testing with Kite to ensure it doesn't break anything. (Before people ask - yes, TPC is only needed for 5ghz regdomains and yes, Kite is a 2.4ghz only chip, but there are potential use cases for 2ghz TPC. I just need to sit down and ensure it's supported and functional.) --- sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c | 43 +++++++++++++++--------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c index 3cf7da92938..48956c51cb8 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c @@ -208,10 +208,11 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, | SM(ahp->ah_tx_chainmask, AR_ChainSel2) | SM(ahp->ah_tx_chainmask, AR_ChainSel3) ; - ads->ds_ctl8 = 0; - ads->ds_ctl9 = (txPower << 24); /* XXX? */ - ads->ds_ctl10 = (txPower << 24); /* XXX? */ - ads->ds_ctl11 = (txPower << 24); /* XXX? */ + ads->ds_ctl8 = SM(0, AR_AntCtl0); + ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1); + ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2); + ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3); + if (keyIx != HAL_TXKEYIX_INVALID) { /* XXX validate key index */ ads->ds_ctl1 |= SM(keyIx, AR_DestIdx); @@ -232,11 +233,16 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S); } + /* + * Set the TX antenna to 0 for Kite + * To preserve existing behaviour, also set the TPC bits to 0; + * when TPC is enabled these should be filled in appropriately. + */ if (AR_SREV_KITE(ah)) { - ads->ds_ctl8 = 0; - ads->ds_ctl9 = 0; - ads->ds_ctl10 = 0; - ads->ds_ctl11 = 0; + ads->ds_ctl8 = SM(0, AR_AntCtl0); + ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1); + ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2); + ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3); } return AH_TRUE; #undef RTSCTS @@ -410,10 +416,10 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds, | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3); /* NB: no V1 WAR */ - ads->ds_ctl8 = 0; - ads->ds_ctl9 = (txPower << 24); - ads->ds_ctl10 = (txPower << 24); - ads->ds_ctl11 = (txPower << 24); + ads->ds_ctl8 = SM(0, AR_AntCtl0); + ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1); + ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2); + ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3); ads->ds_ctl6 &= ~(0xffff); ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); @@ -424,11 +430,16 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds, | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0); } + /* + * Set the TX antenna to 0 for Kite + * To preserve existing behaviour, also set the TPC bits to 0; + * when TPC is enabled these should be filled in appropriately. + */ if (AR_SREV_KITE(ah)) { - ads->ds_ctl8 = 0; - ads->ds_ctl9 = 0; - ads->ds_ctl10 = 0; - ads->ds_ctl11 = 0; + ads->ds_ctl8 = SM(0, AR_AntCtl0); + ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1); + ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2); + ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3); } return AH_TRUE; From e47136127949e311ee53472b7d1620c09bc5170a Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 24 May 2011 06:44:16 +0000 Subject: [PATCH 04/63] Remove unused variable. MFC after: 1 week --- sys/geom/part/g_part_mbr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c index 4fa829a3c91..63dcac4c3a9 100644 --- a/sys/geom/part/g_part_mbr.c +++ b/sys/geom/part/g_part_mbr.c @@ -251,14 +251,11 @@ 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); From 49d12fd5be6154208a780e9a916ec6bed37c02e0 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 24 May 2011 06:46:07 +0000 Subject: [PATCH 05/63] Remove unused variable. MFC after: 1 week --- sys/geom/part/g_part_pc98.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c index 693fad881c3..0bdc0a6042c 100644 --- a/sys/geom/part/g_part_pc98.c +++ b/sys/geom/part/g_part_pc98.c @@ -246,14 +246,11 @@ 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) From 71737f5a06afd4967cf7549ddb1dcf0a5695ac12 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 24 May 2011 06:56:40 +0000 Subject: [PATCH 06/63] Ensure there is a whitespace after a mount point. PR: 157286 Submitted by: Marcus Reid MFC after: 3 days --- usr.bin/showmount/showmount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/showmount/showmount.c b/usr.bin/showmount/showmount.c index f4372b52bd1..26352506680 100644 --- a/usr.bin/showmount/showmount.c +++ b/usr.bin/showmount/showmount.c @@ -185,7 +185,7 @@ main(int argc, char **argv) printf("Exports list on %s:\n", host); exp = exportslist; while (exp) { - printf("%-35s", exp->ex_dirp); + printf("%-34s ", exp->ex_dirp); grp = exp->ex_groups; if (grp == NULL) { printf("Everyone\n"); From 2dccdd45623bd043d930790a02e33da5b6305d28 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Tue, 24 May 2011 07:57:28 +0000 Subject: [PATCH 07/63] Let epair(4) virtual interfaces report fake link / media status, by borrowing the skeleton of if_media manipulation and reporting code from if_lagg(4). The main motivation behind this change is to allow for epair(4) interfaces to participate in STP if_bridge(4) configurations. Reviewed by: bz MFC after: 3 days --- sys/net/if_epair.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index 8775e6f7337..a8d47113e52 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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; @@ -829,6 +856,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 +930,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); From 9f8cab7fc21d921c4ac0dccc2b4401a9813ef0a4 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Tue, 24 May 2011 08:02:55 +0000 Subject: [PATCH 08/63] Allow for vlan(4) interfaces with MTU of 1500 bytes to be configured on top of epair(4) virtual interfaces, since there's no physical hardware associated with epair interfaces which would imply any constraints on MTU sizes. MFC after: 3 days --- sys/net/if_epair.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index a8d47113e52..dff9efcf86f 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -810,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; @@ -834,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; From 12dd58a3198ece862d1c341218ca2814fbf94b34 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Tue, 24 May 2011 09:01:56 +0000 Subject: [PATCH 09/63] Remove an outdated comment as requested by Bruce Evans in a private email to Alexander Best (arundel@). For clang, -fdiagnostics-show-option is enabled by default, but for gcc it isn't. This option will report which -W* flag was responsible for triggering a certain warning. This will bring gcc warnings closer to the ones clang emits and might also help developers track down tinderbox failures a bit quicker. Submitted by: arundel --- sys/conf/kern.mk | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 58ab6eebf01..a0a595f5064 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -1,15 +1,12 @@ # $FreeBSD$ # -# Warning flags for compiling the kernel and components of the kernel. +# Warning flags for compiling the kernel and components of the kernel: # -# Note that the newly added -Wcast-qual is responsible for generating -# most of the remaining warnings. Warnings introduced with -Wall will -# also pop up, but are easier to fix. CWARNFLAGS?= -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes \ -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual \ -Wundef -Wno-pointer-sign -fformat-extensions \ - -Wmissing-include-dirs + -Wmissing-include-dirs -fdiagnostics-show-option # # The following flags are next up for working on: # -Wextra From f2d2d69438edd673aa8917cdbb782267551fbedc Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 24 May 2011 12:34:19 +0000 Subject: [PATCH 10/63] Rework netisr policy mechanism so that per-protocol dispatch policies can be represented: - A single policy namespace is defined, consisting of four possible policies: "default" to use the global default, "deferred" to force deferred dispatch, "direct" to employ direct dispatch where possible, and "hybrid" which makes a dynamic decision based on CPU affinity, ordering, etc. Routines are implemented to convert between strings and an integer namespace. - A new global variable, netisr_dispatch_policy, subsumes existing global variables for direct dispatch, forced direct dispatch, etc, and is used for explicit policy interpretation and composition. Old variables remain so that they can be exported by legacy sysctls for use by old netstat(1) binaries. A new sysctl and tunable, netisr.dispatch.policy, accepts the above strings for specifying a global policy default. - The protocol registration structure, netisr_handler, grows an nh_dispatch field, which accepts a per-policy policy override. The default value is '0', which corresponds to "default", meaning that protocols will accept the global default policy unless otherwise specified. - Policies are now interpreted and composed explicitly at various points in packet dispatch; protocol policies override global policies. - Protocols grow the ability to express a non-opinion about affinity even when implenting m2cpuid by returning NETISR_CPUID_NONE. In that case, the framework falls back on source ordering, rather than simply using the current CPU. These changes are in support of allowing link layer re-dispatch based on RSS or similar hashes provided by NICs, especially in the case where the number of hardware receive queues matches hardware core count, rather than hardware thread count, requiring further software redistributeon. (i.e., on RMI XLR). MFC after: 3 weeks Reviewed by: bz Sponsored by: Juniper Networks, Inc. --- sys/net/netisr.c | 282 +++++++++++++++++++++++++++++++------- sys/net/netisr.h | 19 ++- sys/net/netisr_internal.h | 3 +- 3 files changed, 247 insertions(+), 57 deletions(-) diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 952b463e115..67ec16014c3 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007-2009 Robert N. M. Watson - * Copyright (c) 2010 Juniper Networks, Inc. + * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * This software was developed by Robert N. M. Watson under contract @@ -127,32 +127,44 @@ static struct rmlock netisr_rmlock; SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr"); /*- - * Three direct dispatch policies are supported: + * Three global direct dispatch policies are supported: * - * - Always defer: all work is scheduled for a netisr, regardless of context. - * (!direct) + * NETISR_DISPATCH_QUEUED: All work is deferred for a netisr, regardless of + * context (may be overriden by protocols). * - * - Hybrid: if the executing context allows direct dispatch, and we're - * running on the CPU the work would be done on, then direct dispatch if it - * wouldn't violate ordering constraints on the workstream. - * (direct && !direct_force) + * NETISR_DISPATCH_HYBRID: If the executing context allows direct dispatch, + * and we're running on the CPU the work would be performed on, then direct + * dispatch it if it wouldn't violate ordering constraints on the workstream. * - * - Always direct: if the executing context allows direct dispatch, always - * direct dispatch. (direct && direct_force) + * NETISR_DISPATCH_DIRECT: If the executing context allows direct dispatch, + * always direct dispatch. (The default.) * * Notice that changing the global policy could lead to short periods of * misordered processing, but this is considered acceptable as compared to - * the complexity of enforcing ordering during policy changes. + * the complexity of enforcing ordering during policy changes. Protocols can + * override the global policy (when they're not doing that, they select + * NETISR_DISPATCH_DEFAULT). */ -static int netisr_direct_force = 1; /* Always direct dispatch. */ -TUNABLE_INT("net.isr.direct_force", &netisr_direct_force); -SYSCTL_INT(_net_isr, OID_AUTO, direct_force, CTLFLAG_RW, - &netisr_direct_force, 0, "Force direct dispatch"); +#define NETISR_DISPATCH_POLICY_DEFAULT NETISR_DISPATCH_DIRECT +#define NETISR_DISPATCH_POLICY_MAXSTR 20 /* Used for temporary buffers. */ +static u_int netisr_dispatch_policy = NETISR_DISPATCH_POLICY_DEFAULT; +static int sysctl_netisr_dispatch_policy(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_net_isr, OID_AUTO, dispatch, CTLTYPE_STRING | CTLFLAG_RW | + CTLFLAG_TUN, 0, 0, sysctl_netisr_dispatch_policy, "A", + "netisr dispatch policy"); -static int netisr_direct = 1; /* Enable direct dispatch. */ -TUNABLE_INT("net.isr.direct", &netisr_direct); -SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RW, - &netisr_direct, 0, "Enable direct dispatch"); +/* + * These sysctls were used in previous versions to control and export + * dispatch policy state. Now, we provide read-only export via them so that + * older netstat binaries work. At some point they can be garbage collected. + */ +static int netisr_direct_force; +SYSCTL_INT(_net_isr, OID_AUTO, direct_force, CTLFLAG_RD, + &netisr_direct_force, 0, "compat: force direct dispatch"); + +static int netisr_direct; +SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RD, &netisr_direct, 0, + "compat: enable direct dispatch"); /* * Allow the administrator to limit the number of threads (CPUs) to use for @@ -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) diff --git a/sys/net/netisr.h b/sys/net/netisr.h index cd692f6d601..83bf9ce5d4d 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007-2009 Robert N. M. Watson - * Copyright (c) 2010 Juniper Networks, Inc. + * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * This software was developed by Robert N. M. Watson under contract @@ -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. */ }; diff --git a/sys/net/netisr_internal.h b/sys/net/netisr_internal.h index 40afaf16d83..ac3ed0f292f 100644 --- a/sys/net/netisr_internal.h +++ b/sys/net/netisr_internal.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007-2009 Robert N. M. Watson - * Copyright (c) 2010 Juniper Networks, Inc. + * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * This software was developed by Robert N. M. Watson under contract @@ -64,6 +64,7 @@ struct netisr_proto { netisr_drainedcpu_t *np_drainedcpu; /* Callback when drained a queue. */ u_int np_qlimit; /* Maximum per-CPU queue depth. */ u_int np_policy; /* Work placement policy. */ + u_int np_dispatch; /* Work dispatch policy. */ }; #define NETISR_MAXPROT 16 /* Compile-time limit. */ From 8f092df025ce5a08d98085c4390ab0224170273d Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 24 May 2011 12:38:00 +0000 Subject: [PATCH 11/63] Teach netstat(1) about the new global netisr policy sysctl, net.isr.dispatch, and about per-protocol dispatch policies. MFC after: 3 weeks Reviewed by: bz Sponsored by: Juniper Networks, Inc. --- usr.bin/netstat/netisr.c | 65 ++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/usr.bin/netstat/netisr.c b/usr.bin/netstat/netisr.c index 25f341cc5dd..cc05c38b76e 100644 --- a/usr.bin/netstat/netisr.c +++ b/usr.bin/netstat/netisr.c @@ -60,8 +60,7 @@ static u_int numthreads; static u_int defaultqlimit; static u_int maxqlimit; -static u_int direct; -static u_int direct_force; +static char dispatch_policy[20]; static struct sysctl_netisr_proto *proto_array; static u_int proto_array_len; @@ -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); From 61401ec2dee8eeb5480f6becfc82658cf52ee447 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 24 May 2011 13:08:59 +0000 Subject: [PATCH 12/63] An inpcb lock is no longer required in in_pcbref() since the move to refcount(9). MFC after: 3 weeks Sponsored by: Juniper Networks, Inc. --- sys/netinet/in_pcb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 9bde3c82124..85e31dc0ca1 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1054,8 +1054,6 @@ void in_pcbref(struct inpcb *inp) { - INP_WLOCK_ASSERT(inp); - KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__)); refcount_acquire(&inp->inp_refcount); From 211d4a2c42f4a070f0339d4cc641c456c6607e21 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 24 May 2011 13:17:08 +0000 Subject: [PATCH 13/63] Simplify a stale assertion. We have not called mi_switch() from a nested critical section during a preemption for several years. MFC after: 1 week --- sys/kern/kern_synch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index d3aef7648d5..05fb4a119a3 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -400,9 +400,7 @@ mi_switch(int flags, struct thread *newtd) if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td)) mtx_assert(&Giant, MA_NOTOWNED); #endif - KASSERT(td->td_critnest == 1 || (td->td_critnest == 2 && - (td->td_owepreempt) && (flags & SW_INVOL) != 0 && - newtd == NULL) || panicstr, + KASSERT(td->td_critnest == 1 || panicstr, ("mi_switch: switch in a critical section")); KASSERT((flags & (SW_INVOL | SW_VOL)) != 0, ("mi_switch: switch must be voluntary or involuntary")); From af21235ac46d08fb107b79f18b0d48cbcaa34407 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 24 May 2011 13:22:40 +0000 Subject: [PATCH 14/63] Update comments for DEVICE_PROBE() to reflect that BUS_PROBE_DEFAULT is now the preferred typical return value from a probe routine. Discourage the use of 0 (BUS_PROBE_SPECIFIC) as it should be used very rarely. Point the reader to the DEVICE_PROBE(9) manpage for more detailed notes on possible probe return values. Submitted by: Philip Soeberg philip-dev of soeberg net --- sys/kern/device_if.m | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m index 2931c0a5cd2..eb720eb69dc 100644 --- a/sys/kern/device_if.m +++ b/sys/kern/device_if.m @@ -89,28 +89,29 @@ CODE { * the probe before returning. The return value of DEVICE_PROBE() * is used to elect which driver is used - the driver which returns * the largest non-error value wins the election and attaches to - * the device. + * the device. Common non-error values are described in the + * DEVICE_PROBE(9) manual page. * * If a driver matches the hardware, it should set the device * description string using device_set_desc() or - * device_set_desc_copy(). This string is - * used to generate an informative message when DEVICE_ATTACH() - * is called. + * device_set_desc_copy(). This string is used to generate an + * informative message when DEVICE_ATTACH() is called. * * As a special case, if a driver returns zero, the driver election * is cut short and that driver will attach to the device - * immediately. + * immediately. This should rarely be used. * - * For example, a probe method for a pci device driver might look + * For example, a probe method for a PCI device driver might look * like this: * * @code - * int foo_probe(device_t dev) + * int + * foo_probe(device_t dev) * { * if (pci_get_vendor(dev) == FOOVENDOR && * pci_get_device(dev) == FOODEVICE) { * device_set_desc(dev, "Foo device"); - * return (0); + * return (BUS_PROBE_DEFAULT); * } * return (ENXIO); * } @@ -125,7 +126,8 @@ CODE { * * @param dev the device to probe * - * @retval 0 if the driver strongly matches this device + * @retval 0 if this is the only possible driver for this + * device * @retval negative if the driver can match this device - the * least negative value is used to select the * driver From 47ad691f8763115eda126f6c2c021d88bfc22ea3 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 24 May 2011 13:36:41 +0000 Subject: [PATCH 15/63] Fix an issue with critical sections and SMP rendezvous handlers. Specifically, a critical_exit() call that drops the nesting level to zero has a brief window where the pending preemption flag is set and the nesting level is set to zero. This is done purposefully to avoid races where a preemption scheduled by an interrupt could be lost otherwise (see revision 144777). However, this does mean that if an interrupt fires during this window and enters and exits a critical section, it may preempt from the interrupt context. This is generally fine as the interrupt code is careful to arrange critical sections so that they are not exited until it is safe to preempt (e.g. interrupts EOI'd and masked if necessary). However, the SMP rendezvous IPI handler does not quite follow this rule, and in general a rendezvous can never be preempted. Rendezvous handlers are also not permitted to schedule threads to execute, so they will not typically trigger preemptions. SMP rendezvous handlers may use spinlocks (carefully) such as the rm_cleanIPI() handler used in rmlocks, but using a spinlock also enters and exits a critical section. If the interrupted top-half code is in the brief window of critical_exit() where the nesting level is zero but a preemption is pending, then releasing the spinlock can trigger a preemption. Because we know that SMP rendezvous handlers can never schedule a thread, we know that a critical_exit() in an SMP rendezvous handler will only preempt in this edge case. We also know that the top-half thread will happily handle the deferred preemption once the SMP rendezvous has completed, so the preemption will not be lost. This makes it safe to employ a workaround where we use a nested critical section in the SMP rendezvous code itself around rendezvous action routines to prevent any preemptions during an SMP rendezvous. The workaround intentionally avoids checking for a deferred preemption when leaving the critical section on the assumption that if there is a pending preemption it will be handled by the interrupted top-half code. Submitted by: mlaier (variation specific to rm_cleanIPI()) Obtained from: Isilon MFC after: 1 week --- sys/kern/subr_smp.c | 50 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 0c2c286f1d0..67774d812c7 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -311,11 +311,15 @@ restart_cpus(cpumask_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); @@ -329,6 +333,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 acknowleged via an EOI). Instead, we + * intentionally ignore td_owepreempt when leaving the + * critical setion. 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 @@ -362,14 +394,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 From 7d5ddd30cd6c46f5202ba541653aef5263d77f4c Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Tue, 24 May 2011 14:10:33 +0000 Subject: [PATCH 16/63] Provide fake link status information in an attempt to let ng_eiface(4) virtual ifnets more realistically mimic physical ethernet interfaces. The main motivation behind this change is to allow for ng_eiface(4) interfaces to participate in STP if_bridge(4) configurations. When announcing link status changes, switch to the vnet to which the ifnet belongs, since it is possible for ng_eiface ifnets to be assigned to a vnet different from the one in which its netgraph node resides. MFC after: 3 days --- sys/netgraph/ng_eiface.c | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c index cbae38fafd1..d761a6cbac7 100644 --- a/sys/netgraph/ng_eiface.c +++ b/sys/netgraph/ng_eiface.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -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); } From 2956ec9bc7c5e948714f7e8ec9ed8c512ed890d8 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Tue, 24 May 2011 14:36:32 +0000 Subject: [PATCH 17/63] Assume the link to be dead if bit error rate (BER) parameter is set to 1. When a transition from link alive to link dead configuration or vice versa occurs, notify any upstream and / or downstream peers using NGM_FLOW messagges. Link state notification using NGM_FLOW messages is modelled around around already existing code in ng_ether.c. MFC after: 3 days --- sys/netgraph/ng_pipe.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c index b5bab3cd2e2..11ea8149ba6 100644 --- a/sys/netgraph/ng_pipe.c +++ b/sys/netgraph/ng_pipe.c @@ -298,11 +298,12 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook) { const priv_p priv = NG_NODE_PRIVATE(node); struct ng_mesg *resp = NULL; - struct ng_mesg *msg; + struct ng_mesg *msg, *flow_msg; struct ng_pipe_stats *stats; struct ng_pipe_run *run; struct ng_pipe_cfg *cfg; int error = 0; + int prev_down, now_down, cmd; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { @@ -403,10 +404,38 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook) cfg->header_offset < 64) priv->header_offset = cfg->header_offset; + prev_down = priv->upper.cfg.ber == 1 || + priv->lower.cfg.ber == 1; parse_cfg(&priv->upper.cfg, &cfg->downstream, &priv->upper, priv); parse_cfg(&priv->lower.cfg, &cfg->upstream, &priv->lower, priv); + now_down = priv->upper.cfg.ber == 1 || + priv->lower.cfg.ber == 1; + + if (prev_down != now_down) { + if (now_down) + cmd = NGM_LINK_IS_DOWN; + else + cmd = NGM_LINK_IS_UP; + + if (priv->lower.hook != NULL) { + NG_MKMESSAGE(flow_msg, NGM_FLOW_COOKIE, + cmd, 0, M_NOWAIT); + if (flow_msg != NULL) + NG_SEND_MSG_HOOK(error, node, + flow_msg, priv->lower.hook, + 0); + } + if (priv->upper.hook != NULL) { + NG_MKMESSAGE(flow_msg, NGM_FLOW_COOKIE, + cmd, 0, M_NOWAIT); + if (flow_msg != NULL) + NG_SEND_MSG_HOOK(error, node, + flow_msg, priv->upper.hook, + 0); + } + } break; default: error = EINVAL; From 72b066244cffde6ca929384d480bd87e66b73b61 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 24 May 2011 16:49:34 +0000 Subject: [PATCH 18/63] Fix calculation of alignment for odd values. Also do not change value when it is already aligned. --- sbin/geom/class/part/geom_part.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 19d1502fbe7..e11edd5ecb8 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -295,8 +295,8 @@ fmtattrib(struct gprovider *pp) return (buf); } -#define ALIGNDOWN(d, a) (-(a) & (d)) -#define ALIGNUP(d, a) (-(-(a) & -(d))) +#define ALIGNDOWN(d, a) ((d) % (a) ? (d) - (d) % (a): (d)) +#define ALIGNUP(d, a) ((d) % (a) ? (d) - (d) % (a) + (a): (d)) static int gpart_autofill_resize(struct gctl_req *req) From 53fb12dbef9ba18df62ee71757c14836b44b6f01 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 24 May 2011 17:03:46 +0000 Subject: [PATCH 19/63] Simplify ALIGNDOWN macro. --- sbin/geom/class/part/geom_part.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index e11edd5ecb8..278030d71a2 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -295,7 +295,7 @@ fmtattrib(struct gprovider *pp) return (buf); } -#define ALIGNDOWN(d, a) ((d) % (a) ? (d) - (d) % (a): (d)) +#define ALIGNDOWN(d, a) ((d) - (d) % (a)) #define ALIGNUP(d, a) ((d) % (a) ? (d) - (d) % (a) + (a): (d)) static int From 9f4563363b33dadf9e3eab914f650b1e2a898c14 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Tue, 24 May 2011 18:25:40 +0000 Subject: [PATCH 20/63] The ANI control for the AR5416 and later chips was calling ar5212AniControl(), which did AR5212 specific initialisation. This would cause some slight silliness when enabling/disabling ANI. Just to be completely correct - and to ensure the phy error mask/RX filter register isn't incorrectly played with - make the ANI control function a method, have it set appropriately for AR5212/AR5416, and call that from the ANI control interface. --- sys/dev/ath/ath_hal/ar5212/ar5212.h | 3 +++ sys/dev/ath/ath_hal/ar5212/ar5212_attach.c | 3 +++ sys/dev/ath/ath_hal/ar5212/ar5212_misc.c | 4 ++-- sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h index e22681614e1..5bdfcb43206 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212.h +++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h @@ -320,6 +320,9 @@ struct ath_hal_5212 { struct ar5212AniState *ah_curani; /* cached last reference */ struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */ + /* AR5416 uses some of the AR5212 ANI code; these are the ANI methods */ + HAL_BOOL (*ah_aniControl) (struct ath_hal *, HAL_ANI_CMD cmd, int param); + /* * Transmit power state. Note these are maintained * here so they can be retrieved by diagnostic tools. diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c index 4b0fcbe95ce..5f85522dd5f 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c @@ -203,6 +203,9 @@ ar5212AniSetup(struct ath_hal *ah) ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE); } else ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE); + + /* Set overridable ANI methods */ + AH5212(ah)->ah_aniControl = ar5212AniControl; } /* diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c index 0d6adc13e98..d5b96a59149 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c @@ -990,7 +990,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 +1053,7 @@ ar5212GetDiagState(struct ath_hal *ah, int request, case HAL_DIAG_ANI_CMD: if (argsize != 2*sizeof(uint32_t)) return AH_FALSE; - ar5212AniControl(ah, ((const uint32_t *)args)[0], + AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0], ((const uint32_t *)args)[1]); return AH_TRUE; case HAL_DIAG_ANI_PARAMS: diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 6779bf9f846..fd4a905ed2b 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -200,6 +200,9 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc, /* Enable all ANI functions to begin with */ AH5416(ah)->ah_ani_function = HAL_ANI_ALL; + + /* Set overridable ANI methods */ + AH5212(ah)->ah_aniControl = ar5416AniControl; } uint32_t From 5b41f90fd15425ee6558bdb9107d0b48feb9c664 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 24 May 2011 19:55:57 +0000 Subject: [PATCH 21/63] Silly spelling typos. Submitted by: "b. f." --- sys/kern/subr_smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 67774d812c7..351f09677fa 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -348,11 +348,11 @@ smp_rendezvous_action(void) * 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 acknowleged via an EOI). Instead, we + * has been acknowledged via an EOI). Instead, we * intentionally ignore td_owepreempt when leaving the - * critical setion. 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 + * 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; From 541c60d98823968a403cdf23764b46f0d7f8943f Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Tue, 24 May 2011 20:07:15 +0000 Subject: [PATCH 22/63] Don't access task structure once we call task function. The task structure might be no longer available. This also allows to eliminates the need for two tasks in the zio structure. Submitted by: anonymous MFC after: 2 weeks --- .../compat/opensolaris/kern/opensolaris_taskq.c | 5 ----- sys/cddl/compat/opensolaris/sys/taskq.h | 1 - .../opensolaris/uts/common/fs/zfs/sys/zio.h | 3 +-- .../contrib/opensolaris/uts/common/fs/zfs/zio.c | 14 ++------------ 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c index 5a204884b09..a74f795c88f 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c @@ -147,9 +147,7 @@ taskq_run_safe(void *arg, int pending __unused) { struct ostask *task = arg; - ASSERT(task->ost_magic == TASKQ_MAGIC); task->ost_func(task->ost_arg); - task->ost_magic = 0; } taskqid_t @@ -158,15 +156,12 @@ taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg, u_int flags, { int prio; - ASSERT(task->ost_magic != TASKQ_MAGIC); - /* * If TQ_FRONT is given, we want higher priority for this task, so it * can go at the front of the queue. */ prio = !!(flags & TQ_FRONT); - task->ost_magic = TASKQ_MAGIC; task->ost_func = func; task->ost_arg = arg; diff --git a/sys/cddl/compat/opensolaris/sys/taskq.h b/sys/cddl/compat/opensolaris/sys/taskq.h index eedc4da3ff4..ffe70ca9e29 100644 --- a/sys/cddl/compat/opensolaris/sys/taskq.h +++ b/sys/cddl/compat/opensolaris/sys/taskq.h @@ -35,7 +35,6 @@ struct ostask { struct task ost_task; task_func_t *ost_func; void *ost_arg; - int ost_magic; }; taskqid_t taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index 355f560f0fc..e8372f71196 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -421,8 +421,7 @@ struct zio { #ifdef _KERNEL /* FreeBSD only. */ - struct ostask io_task_issue; - struct ostask io_task_interrupt; + struct ostask io_task; #endif }; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 5e968b5c29b..9a043449c8a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -1068,19 +1068,9 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline) spa_t *spa = zio->io_spa; zio_type_t t = zio->io_type; int flags = TQ_SLEEP | (cutinline ? TQ_FRONT : 0); -#ifdef _KERNEL - struct ostask *task; -#endif ASSERT(q == ZIO_TASKQ_ISSUE || q == ZIO_TASKQ_INTERRUPT); -#ifdef _KERNEL - if (q == ZIO_TASKQ_ISSUE) - task = &zio->io_task_issue; - else /* if (q == ZIO_TASKQ_INTERRUPT) */ - task = &zio->io_task_interrupt; -#endif - /* * If we're a config writer or a probe, the normal issue and * interrupt threads may all be blocked waiting for the config lock. @@ -1105,7 +1095,7 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline) ASSERT3U(q, <, ZIO_TASKQ_TYPES); #ifdef _KERNEL (void) taskq_dispatch_safe(spa->spa_zio_taskq[t][q], - (task_func_t *)zio_execute, zio, flags, task); + (task_func_t *)zio_execute, zio, flags, &zio->io_task); #else (void) taskq_dispatch(spa->spa_zio_taskq[t][q], (task_func_t *)zio_execute, zio, flags); @@ -2904,7 +2894,7 @@ zio_done(zio_t *zio) (void) taskq_dispatch_safe( spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE], (task_func_t *)zio_reexecute, zio, TQ_SLEEP, - &zio->io_task_issue); + &zio->io_task); #else (void) taskq_dispatch( spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE], From b5a060dd8b146bea6361167b1d372db785724db7 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Tue, 24 May 2011 20:10:12 +0000 Subject: [PATCH 23/63] Don't pass pointer to name buffer which is on the stack to another thread, because the stack might be paged out once the other thread tries to use the data. Instead, just allocate memory. MFC after: 2 weeks --- .../opensolaris/uts/common/fs/zfs/zfs_dir.c | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c index bae9071c3c3..6ff93395f7c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c @@ -239,15 +239,20 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, return (ENOENT); } if (dl == NULL) { + size_t namesize; + /* * Allocate a new dirlock and add it to the list. */ - dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP); + namesize = strlen(name) + 1; + dl = kmem_alloc(sizeof (zfs_dirlock_t) + namesize, + KM_SLEEP); cv_init(&dl->dl_cv, NULL, CV_DEFAULT, NULL); - dl->dl_name = name; + dl->dl_name = (char *)(dl + 1); + bcopy(name, dl->dl_name, namesize); dl->dl_sharecnt = 0; dl->dl_namelock = 0; - dl->dl_namesize = 0; + dl->dl_namesize = namesize; dl->dl_dzp = dzp; dl->dl_next = dzp->z_dirlocks; dzp->z_dirlocks = dl; @@ -264,20 +269,8 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, if (flag & ZHAVELOCK) dl->dl_namelock = 1; - if ((flag & ZSHARED) && ++dl->dl_sharecnt > 1 && dl->dl_namesize == 0) { - /* - * We're the second shared reference to dl. Make a copy of - * dl_name in case the first thread goes away before we do. - * Note that we initialize the new name before storing its - * pointer into dl_name, because the first thread may load - * dl->dl_name at any time. He'll either see the old value, - * which is his, or the new shared copy; either is OK. - */ - dl->dl_namesize = strlen(dl->dl_name) + 1; - name = kmem_alloc(dl->dl_namesize, KM_SLEEP); - bcopy(dl->dl_name, name, dl->dl_namesize); - dl->dl_name = name; - } + if (flag & ZSHARED) + dl->dl_sharecnt++; mutex_exit(&dzp->z_lock); @@ -361,10 +354,8 @@ zfs_dirent_unlock(zfs_dirlock_t *dl) cv_broadcast(&dl->dl_cv); mutex_exit(&dzp->z_lock); - if (dl->dl_namesize != 0) - kmem_free(dl->dl_name, dl->dl_namesize); cv_destroy(&dl->dl_cv); - kmem_free(dl, sizeof (*dl)); + kmem_free(dl, sizeof (*dl) + dl->dl_namesize); } /* From 81e2a01a7797c74008a133de513968a422535d95 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Tue, 24 May 2011 20:39:07 +0000 Subject: [PATCH 24/63] style(9) --- sys/dev/msk/if_msk.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 2adbf1cb2c7..23538f700bf 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1018,7 +1018,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN) error = EINVAL; else if (ifp->if_mtu != ifr->ifr_mtu) { - if (ifr->ifr_mtu > ETHERMTU) { + if (ifr->ifr_mtu > ETHERMTU) { if ((sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) { error = EINVAL; MSK_IF_UNLOCK(sc_if); @@ -1636,7 +1636,7 @@ msk_attach(device_t dev) * this workaround does not work so disable checksum offload * for VLAN interface. */ - ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO; + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO; /* * Enable Rx checksum offloading for VLAN tagged frames * if controller support new descriptor format. @@ -1921,7 +1921,8 @@ mskc_attach(device_t dev) error = ENXIO; goto fail; } - mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO); + mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | + M_ZERO); if (mmd == NULL) { device_printf(dev, "failed to allocate memory for " "ivars of PORT_B\n"); @@ -1930,9 +1931,9 @@ mskc_attach(device_t dev) } mmd->port = MSK_PORT_B; mmd->pmd = sc->msk_pmd; - if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S') + if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S') mmd->mii_flags |= MIIF_HAVEFIBER; - if (sc->msk_pmd == 'P') + if (sc->msk_pmd == 'P') mmd->mii_flags |= MIIF_HAVEFIBER | MIIF_MACPRIV0; device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd); } @@ -3741,10 +3742,10 @@ msk_init_locked(struct msk_if_softc *sc_if) ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM); } - /* GMAC Control reset. */ - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET); - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR); - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF); + /* GMAC Control reset. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF); if (sc->msk_hw_id == CHIP_ID_YUKON_EX || sc->msk_hw_id == CHIP_ID_YUKON_SUPR) CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), @@ -3854,13 +3855,13 @@ msk_init_locked(struct msk_if_softc *sc_if) msk_set_tx_stfwd(sc_if); } - if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P && - sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { - /* Disable dynamic watermark - from Linux. */ - reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA)); - reg &= ~0x03; - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg); - } + if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P && + sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { + /* Disable dynamic watermark - from Linux. */ + reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA)); + reg &= ~0x03; + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg); + } /* * Disable Force Sync bit and Alloc bit in Tx RAM interface From 8d5a3ca77bc357a21ed5eed52084ac6eceeb6429 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 25 May 2011 00:34:25 +0000 Subject: [PATCH 25/63] Add FEATURE() definitions for IPv4 and IPv6 so that we can use feature_present(3) to dynamically decide whether to use one or the other family. Reviewed by: gnn Sponsored by: The FreeBSD Foundation Sponsored by: iXsystems MFC after: 10 days --- sys/netinet/in_proto.c | 2 ++ sys/netinet6/in6_proto.c | 1 + 2 files changed, 3 insertions(+) diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 2827c221e6e..d2a772f46c7 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -106,6 +106,8 @@ static struct pr_usrreqs nousrreqs; #include #endif +FEATURE(inet, "Internet Protocol version 4"); + extern struct domain inetdomain; /* Spacer for loadable protocols. */ diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index acd156950fe..ab54755f02c 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -133,6 +133,7 @@ __FBSDID("$FreeBSD$"); /* * TCP/IP protocol family: IP6, ICMP6, UDP, TCP. */ +FEATURE(inet6, "Internet Protocol version 6"); extern struct domain inet6domain; static struct pr_usrreqs nousrreqs; From a23d1c70b3ec60cd41eb0e063e88f171c7f81084 Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Wed, 25 May 2011 01:04:12 +0000 Subject: [PATCH 26/63] Build and install a BSD licensed grep. If WITH_BSD_GREP is not set, it will be 'bsdgrep' and GNUgrep will be '[ef]grep'. Otherwise, BSD-grep will be the grep family, and GNUgrep will be 'gnugrep'. Discussed with: brooks --- gnu/usr.bin/Makefile | 2 -- gnu/usr.bin/grep/Makefile | 15 +++++++++++++++ tools/build/options/WITH_BSD_GREP | 2 +- usr.bin/Makefile | 6 +----- usr.bin/grep/Makefile | 11 +++++++++++ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile index 0ee257f9867..95eeeb8acd1 100644 --- a/gnu/usr.bin/Makefile +++ b/gnu/usr.bin/Makefile @@ -27,9 +27,7 @@ _groff= groff .endif .endif -.if ${MK_BSD_GREP} != "yes" _grep= grep -.endif .if ${MK_CVS} != "no" _cvs= cvs diff --git a/gnu/usr.bin/grep/Makefile b/gnu/usr.bin/grep/Makefile index b0c3988552b..7d3b60769b8 100644 --- a/gnu/usr.bin/grep/Makefile +++ b/gnu/usr.bin/grep/Makefile @@ -1,35 +1,50 @@ # $FreeBSD$ +.include + GREP_LIBZ=YES +.if ${MK_BSD_GREP} != "yes" PROG= grep +.else +PROG= gnugrep +.endif SRCS= closeout.c dfa.c error.c exclude.c grep.c grepmat.c hard-locale.c \ isdir.c kwset.c obstack.c quotearg.c savedir.c search.c xmalloc.c \ xstrtoumax.c CFLAGS+=-I${.CURDIR} -I${DESTDIR}/usr/include/gnu -DHAVE_CONFIG_H +.if ${MK_BSD_GREP} != "yes" LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \ ${BINDIR}/grep ${BINDIR}/fgrep MLINKS= grep.1 egrep.1 grep.1 fgrep.1 +.endif DPADD= ${LIBGNUREGEX} ${LIBBZ2} LDADD= -lgnuregex -lbz2 +.if ${MK_BSD_GREP} != "yes" LINKS+= ${BINDIR}/grep ${BINDIR}/bzgrep \ ${BINDIR}/grep ${BINDIR}/bzegrep \ ${BINDIR}/grep ${BINDIR}/bzfgrep MLINKS+=grep.1 bzgrep.1 grep.1 bzegrep.1 grep.1 bzfgrep.1 +.endif .if defined(GREP_LIBZ) && !empty(GREP_LIBZ) LDADD+= -lz DPADD+= ${LIBZ} CFLAGS+=-DHAVE_LIBZ=1 +.if ${MK_BSD_GREP} != "yes" LINKS+= ${BINDIR}/grep ${BINDIR}/zgrep \ ${BINDIR}/grep ${BINDIR}/zegrep \ ${BINDIR}/grep ${BINDIR}/zfgrep MLINKS+=grep.1 zgrep.1 grep.1 zegrep.1 grep.1 zfgrep.1 .endif +.endif + +gnugrep.1: grep.1 + cp ${.ALLSRC} ${.TARGET} SUBDIR+=doc diff --git a/tools/build/options/WITH_BSD_GREP b/tools/build/options/WITH_BSD_GREP index 702ca25f612..e6641173e2d 100644 --- a/tools/build/options/WITH_BSD_GREP +++ b/tools/build/options/WITH_BSD_GREP @@ -1,2 +1,2 @@ .\" $FreeBSD$ -Build BSD-licensed grep instead of GNU grep. +Install BSD-licensed grep as '[ef]grep' instead of GNU grep. diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 85a9180f9d8..f258347ef7d 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -57,7 +57,7 @@ SUBDIR= alias \ getconf \ getent \ getopt \ - ${_grep} \ + grep \ gzip \ head \ hexdump \ @@ -227,10 +227,6 @@ SUBDIR+= bluetooth SUBDIR+= cpio .endif -.if ${MK_BSD_GREP} != "no" -_grep= grep -.endif - .if ${MK_CALENDAR} != "no" SUBDIR+= calendar .endif diff --git a/usr.bin/grep/Makefile b/usr.bin/grep/Makefile index 98fceebf5c3..8cd490d9b39 100644 --- a/usr.bin/grep/Makefile +++ b/usr.bin/grep/Makefile @@ -2,9 +2,16 @@ # $FreeBSD$ # $OpenBSD: Makefile,v 1.6 2003/06/25 15:00:04 millert Exp $ +.include + +.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 From 6d5ee6cd7f8187cf54b74acd511b64ac568968c2 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Wed, 25 May 2011 04:46:48 +0000 Subject: [PATCH 27/63] run(4) needs firmware loaded to work --- sys/amd64/conf/GENERIC | 1 + sys/i386/conf/GENERIC | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index c43cd3365ff..ce71dd81713 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -324,6 +324,7 @@ device udav # Davicom DM9601E USB # USB Wireless device rum # Ralink Technology RT2501USB wireless NICs device run # Ralink Technology RT2700/RT2800/RT3000 NICs. +device runfw # Ralink Technology RT2700/RT2800/RT3000 NICs firmware device uath # Atheros AR5523 wireless NICs device upgt # Conexant/Intersil PrismGT wireless NICs. device ural # Ralink Technology RT2500USB wireless NICs diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index ec5b113fb18..44d2f18a5fa 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -337,6 +337,7 @@ device udav # Davicom DM9601E USB # USB Wireless device rum # Ralink Technology RT2501USB wireless NICs device run # Ralink Technology RT2700/RT2800/RT3000 NICs. +device runfw # Ralink Technology RT2700/RT2800/RT3000 NICs firmware device uath # Atheros AR5523 wireless NICs device upgt # Conexant/Intersil PrismGT wireless NICs. device ural # Ralink Technology RT2500USB wireless NICs From 241d9a3400d7266edd5afb3d46d885a3f508df18 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 25 May 2011 07:19:19 +0000 Subject: [PATCH 28/63] Tidy up the ANI API in preparation for looking to expose some more of the ANI statistics and committing some tools which use these. * Change HAL_ANI_* commands _back_ to be numerical, rather than a bitmap; * modify access to the ANI control bitmap to convert a command to a bitmap; * Fix the ANI noise immunity fiddling for CCK errors - it wasn't checking whether noise immunity was disabled or not. --- sys/dev/ath/ath_hal/ah_internal.h | 23 +++++++++++++--------- sys/dev/ath/ath_hal/ar5416/ar5416_ani.c | 17 ++++++++++++---- sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9001/ar9160_attach.c | 2 +- sys/dev/ath/ath_hal/ar9002/ar9280_attach.c | 2 +- sys/dev/ath/ath_hal/ar9002/ar9285_attach.c | 2 +- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index b4cc8172454..b9dce2567e1 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -418,16 +418,21 @@ 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); +/* + * Internal HAL ANI commands. + * + * These values represent the ANI commands passed to the ANI Control method + * for AR5212, AR5416 and later chipsets. + */ 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_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; #define HAL_SPUR_VAL_MASK 0x3FFF diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c index 3a8f7859b43..e2c8592a13b 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c @@ -175,9 +175,17 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) struct ar5212AniState *aniState = ahp->ah_curani; const struct ar5212AniParams *params = aniState->params; + /* Check whether the particular function is enabled */ + if (((1 << cmd) & AH5416(ah)->ah_ani_function) == 0) { + HALDEBUG(ah, HAL_DEBUG_ANI, "%s: command %d disabled\n", + __func__, cmd); + HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd %d; mask %x\n", __func__, cmd, AH5416(ah)->ah_ani_function); + return AH_FALSE; + } + OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd); - switch (cmd & AH5416(ah)->ah_ani_function) { + switch (cmd) { case HAL_ANI_NOISE_IMMUNITY_LEVEL: { u_int level = param; @@ -356,14 +364,14 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah) aniState = ahp->ah_curani; params = aniState->params; /* First, raise noise immunity level, up to max */ - if ((AH5416(ah)->ah_ani_function & HAL_ANI_NOISE_IMMUNITY_LEVEL) && + if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL)) && (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) { ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); return; } /* then, raise spur immunity level, up to max */ - if ((AH5416(ah)->ah_ani_function & HAL_ANI_SPUR_IMMUNITY_LEVEL) && + if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL)) && (aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel)) { ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel + 1); @@ -443,7 +451,8 @@ ar5416AniCckErrTrigger(struct ath_hal *ah) /* first, raise noise immunity level, up to max */ aniState = ahp->ah_curani; params = aniState->params; - if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) { + if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL) && + aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) { ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); return; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index fd4a905ed2b..dc1a5ffac74 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -58,7 +58,7 @@ ar5416AniSetup(struct ath_hal *ah) .period = 100, }; /* NB: disable ANI noise immmunity for reliable RIFS rx */ - AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL; + AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); } @@ -199,7 +199,7 @@ 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; diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c index 0b6472b7331..0d950d26fbd 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c @@ -82,7 +82,7 @@ ar9160AniSetup(struct ath_hal *ah) }; /* NB: disable ANI noise immmunity for reliable RIFS rx */ - AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL; + AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); } diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c index 3351edbc6d1..77b9f58c3b5 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c @@ -93,7 +93,7 @@ ar9280AniSetup(struct ath_hal *ah) .period = 100, }; /* NB: disable ANI noise immmunity for reliable RIFS rx */ - AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL; + AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); /* NB: ANI is not enabled yet */ ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c index b7ed27d2132..111bea229b5 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c @@ -98,7 +98,7 @@ ar9285AniSetup(struct ath_hal *ah) .period = 100, }; /* NB: disable ANI noise immmunity for reliable RIFS rx */ - AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL; + AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); } From 727edca45b1d08da27865e9f315810829868083e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 25 May 2011 07:34:49 +0000 Subject: [PATCH 29/63] The current ANI capability information uses a different set of values for the commands, compared to the internal command values (HAL_ANI_CMD.) My eventual aim is to make the HAL_ANI_CMD internal enum match the public API and then remove all this messiness. This now allows HAL_CAP_INTMIT users to use a public HAL_CAP_INTMIT_ enum rather than magic constants. The only magic constants currently used by if_ath are "enable" and "present". Some local tools of mine allow for direct, manual fiddling of the ANI variables and I'll convert these to use the public enum API before I commit them. --- sys/dev/ath/ath_hal/ah.h | 35 ++++++++++++++++++++++++ sys/dev/ath/ath_hal/ah_internal.h | 17 ------------ sys/dev/ath/ath_hal/ar5212/ar5212_misc.c | 16 ++++++----- sys/dev/ath/if_athvar.h | 6 ++-- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index 85790e12101..7bf284399d1 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -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. * diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index b9dce2567e1..b994eab268e 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -418,23 +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); -/* - * Internal HAL ANI commands. - * - * These values represent the ANI commands passed to the ANI Control method - * for AR5212, AR5416 and later chipsets. - */ -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; - #define HAL_SPUR_VAL_MASK 0x3FFF #define HAL_SPUR_CHAN_WIDTH 87 #define HAL_BIN_WIDTH_BASE_100HZ 3125 diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c index d5b96a59149..518d0791a31 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c @@ -880,16 +880,16 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, return HAL_OK; case HAL_CAP_INTMIT: /* interference mitigation */ switch (capability) { - case 0: /* hardware capability */ + case HAL_CAP_INTMIT_PRESENT: /* hardware capability */ return HAL_OK; - case 1: + case HAL_CAP_INTMIT_ENABLE: return (ahp->ah_procPhyErr & HAL_ANI_ENA) ? HAL_OK : HAL_ENXIO; - case 2: /* HAL_ANI_NOISE_IMMUNITY_LEVEL */ - case 3: /* HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION */ - case 4: /* HAL_ANI_CCK_WEAK_SIGNAL_THR */ - case 5: /* HAL_ANI_FIRSTEP_LEVEL */ - case 6: /* HAL_ANI_SPUR_IMMUNITY_LEVEL */ + case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL: + case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL: + case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR: + case HAL_CAP_INTMIT_FIRSTEP_LEVEL: + case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL: ani = ar5212AniGetCurrentState(ah); if (ani == AH_NULL) return HAL_ENXIO; @@ -980,6 +980,8 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC); return AH_TRUE; case HAL_CAP_INTMIT: { /* interference mitigation */ + /* This maps the public ANI commands to the internal ANI commands */ + /* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */ static const HAL_ANI_CMD cmds[] = { HAL_ANI_PRESENT, HAL_ANI_MODE, diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 26a50bc5d65..6353847a72f 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -634,11 +634,11 @@ void ath_intr(void *); #define ath_hal_settpcts(_ah, _tpcts) \ ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL) #define ath_hal_hasintmit(_ah) \ - (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 0, NULL) == HAL_OK) + (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_PRESENT, NULL) == HAL_OK) #define ath_hal_getintmit(_ah) \ - (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK) + (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, NULL) == HAL_OK) #define ath_hal_setintmit(_ah, _v) \ - ath_hal_setcapability(_ah, HAL_CAP_INTMIT, 1, _v, NULL) + ath_hal_setcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, _v, NULL) #define ath_hal_getchannoise(_ah, _c) \ ((*(_ah)->ah_getChanNoise)((_ah), (_c))) #define ath_hal_getrxchainmask(_ah, _prxchainmask) \ From 67900914ffcb0abe7708c5c9a699869589556be5 Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Wed, 25 May 2011 08:42:01 +0000 Subject: [PATCH 30/63] Add a description to the checksum target about not only being able to verify, but also having the ability to fetch distfiles that are missing or failed the checksum calculation PR: docs/138887 Submitted by: Radim Kolar (hsn at sendmail dot cz) MFC after: 5 days --- share/man/man7/ports.7 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/share/man/man7/ports.7 b/share/man/man7/ports.7 index 54afe0aa07b..2344a4dc85c 100644 --- a/share/man/man7/ports.7 +++ b/share/man/man7/ports.7 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 14, 2009 +.Dd May 25, 2011 .Dt PORTS 7 .Os .Sh NAME @@ -124,6 +124,8 @@ and .It Cm checksum Verify that the fetched distfile's checksum matches the one the port was tested against. +If the distfile's checksum does not match, it also fetches the distfiles +which are missing or failed the checksum calculation. Defining .Va NO_CHECKSUM will skip this step. From db48d4a92ec3ce601d3d68fb1dd593dc06de2f5e Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 25 May 2011 09:32:19 +0000 Subject: [PATCH 31/63] Do not truncate available disk space to the closest track boundary. --- sys/geom/part/g_part_mbr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c index 63dcac4c3a9..0b40366efc1 100644 --- a/sys/geom/part/g_part_mbr.c +++ b/sys/geom/part/g_part_mbr.c @@ -253,15 +253,14 @@ g_part_mbr_create(struct g_part_table *basetable, struct g_part_parms *gpp) { struct g_provider *pp; struct g_part_mbr_table *table; - uint32_t msize; pp = gpp->gpp_provider; 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); @@ -470,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); From 23a349003461210f84d8af7585bb55048896c9ba Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 25 May 2011 09:38:12 +0000 Subject: [PATCH 32/63] Do not truncate available disk space to the closest track boundary. --- sys/geom/part/g_part_ebr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/geom/part/g_part_ebr.c b/sys/geom/part/g_part_ebr.c index f6278cc8d9c..8ea9b47c5dc 100644 --- a/sys/geom/part/g_part_ebr.c +++ b/sys/geom/part/g_part_ebr.c @@ -289,7 +289,6 @@ g_part_ebr_create(struct g_part_table *basetable, struct g_part_parms *gpp) return (ENXIO); msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); - msize -= msize % basetable->gpt_sectors; basetable->gpt_first = 0; basetable->gpt_last = msize - 1; basetable->gpt_entries = msize / basetable->gpt_sectors; @@ -523,7 +522,7 @@ g_part_ebr_read(struct g_part_table *basetable, struct g_consumer *cp) basetable->gpt_entries = msize / basetable->gpt_sectors; basetable->gpt_first = 0; - basetable->gpt_last = msize - (msize % basetable->gpt_sectors) - 1; + basetable->gpt_last = msize - 1; return (0); } From 6fd1e2e013077900f411b7c7158bef3923751fd3 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 25 May 2011 09:45:13 +0000 Subject: [PATCH 33/63] Do not truncate available disk space to the closest track boundary. --- sys/geom/part/g_part_pc98.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c index 0bdc0a6042c..0d81a0e0c84 100644 --- a/sys/geom/part/g_part_pc98.c +++ b/sys/geom/part/g_part_pc98.c @@ -248,7 +248,6 @@ g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp) { struct g_provider *pp; struct g_part_pc98_table *table; - uint32_t cyl, msize; pp = gpp->gpp_provider; if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE) @@ -256,11 +255,8 @@ g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp) 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); @@ -488,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); From a92e80be3f2cd022f0bf1a69403d7dd1f179b856 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Wed, 25 May 2011 10:04:13 +0000 Subject: [PATCH 34/63] Bring back r222275. runfw(4) will statically link in rt2870.fw.uu to the kernel, though I have MODULES_OVERRIDE="" in GENERIC. Spotted by: thompsa --- sys/amd64/conf/GENERIC | 1 - sys/i386/conf/GENERIC | 1 - 2 files changed, 2 deletions(-) diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index ce71dd81713..c43cd3365ff 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -324,7 +324,6 @@ device udav # Davicom DM9601E USB # USB Wireless device rum # Ralink Technology RT2501USB wireless NICs device run # Ralink Technology RT2700/RT2800/RT3000 NICs. -device runfw # Ralink Technology RT2700/RT2800/RT3000 NICs firmware device uath # Atheros AR5523 wireless NICs device upgt # Conexant/Intersil PrismGT wireless NICs. device ural # Ralink Technology RT2500USB wireless NICs diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 44d2f18a5fa..ec5b113fb18 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -337,7 +337,6 @@ device udav # Davicom DM9601E USB # USB Wireless device rum # Ralink Technology RT2501USB wireless NICs device run # Ralink Technology RT2700/RT2800/RT3000 NICs. -device runfw # Ralink Technology RT2700/RT2800/RT3000 NICs firmware device uath # Atheros AR5523 wireless NICs device upgt # Conexant/Intersil PrismGT wireless NICs. device ural # Ralink Technology RT2500USB wireless NICs From ceef8f2477ce6f0e311c60ca7ecd30fb31f3e3f3 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 25 May 2011 11:14:26 +0000 Subject: [PATCH 35/63] Prevent non-aligned reading from provider while tasting. Reject providers with unsupported sectorsize. Reported by: Joerg Wunsch MFC after: 1 week --- sys/geom/vinum/geom_vinum_drive.c | 4 ++++ sys/geom/vinum/geom_vinum_events.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/sys/geom/vinum/geom_vinum_drive.c b/sys/geom/vinum/geom_vinum_drive.c index 5ab68f39dd7..f782fd0c721 100644 --- a/sys/geom/vinum/geom_vinum_drive.c +++ b/sys/geom/vinum/geom_vinum_drive.c @@ -126,6 +126,10 @@ gv_read_header(struct g_consumer *cp, struct gv_hdr *m_hdr) pp = cp->provider; KASSERT(pp != NULL, ("gv_read_header: null pp")); + if ((GV_HDR_OFFSET % pp->sectorsize) != 0 || + (GV_HDR_LEN % pp->sectorsize) != 0) + return (ENODEV); + d_hdr = g_read_data(cp, GV_HDR_OFFSET, pp->sectorsize, NULL); if (d_hdr == NULL) return (-1); diff --git a/sys/geom/vinum/geom_vinum_events.c b/sys/geom/vinum/geom_vinum_events.c index fcd45f10f84..db4e5434b58 100644 --- a/sys/geom/vinum/geom_vinum_events.c +++ b/sys/geom/vinum/geom_vinum_events.c @@ -109,6 +109,12 @@ gv_drive_tasted(struct gv_softc *sc, struct g_provider *pp) buf = NULL; G_VINUM_DEBUG(2, "tasted drive on '%s'", pp->name); + if ((GV_CFG_OFFSET % pp->sectorsize) != 0 || + (GV_CFG_LEN % pp->sectorsize) != 0) { + G_VINUM_DEBUG(0, "provider %s has unsupported sectorsize.", + pp->name); + return; + } gp = sc->geom; g_topology_lock(); From 08c8fde0079c7b19d7e13ad65744faf56454e193 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 25 May 2011 13:55:49 +0000 Subject: [PATCH 36/63] According to SATA specification, when Serial ATA Enclosure Management Bridge (SEMB) is unable to communicate to Storage Enclosure Processor (SEP), in response to hard and soft resets it should among other things return value 0x7F in Status register. The weird side is that it means DRQ bit set, which tells that reset request is not completed. It would be fine if SEMB was the only device on port. But if SEMB connected to PMP or built into it, it may block access to other devices sharing same SATA port. Make some tunings/fixes to soft-reset handling to workaround the issue: - ahci(4): request CLO on the port after soft reset to ignore DRQ bit; - siis(4): gracefully reinitialize port after soft reset timeout (hardware doesn't detect reset request completion in this case); - mvs(4): if PMP is used, send dummy soft-reset to the PMP port to make it clear DRQ bit for us. For now this makes quirks in ata_pmp.c, hiding SEMB ports of SiI3726/SiI4726 PMPs, less important. Further, if hardware permit, I hope to implement real SEMB support. --- sys/dev/ahci/ahci.c | 25 +++++++++++++------------ sys/dev/mvs/mvs.c | 44 ++++++++++++++++++++++++++++++++++---------- sys/dev/siis/siis.c | 25 ++++++++++++++++++------- 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 2a064923cf3..5db3a04a36e 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1835,9 +1835,11 @@ ahci_execute_transaction(struct ahci_slot *slot) 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 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; } @@ -1877,14 +1879,12 @@ ahci_execute_transaction(struct ahci_slot *slot) } } } - 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); - } + (ccb->ataio.cmd.control & ATA_A_RESET) == 0) + ch->eslots |= (1 << slot->slot); + ahci_end_transaction(slot, et); return; } /* Start command execution timeout */ @@ -2169,13 +2169,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 +2178,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 +2189,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) } else if ((ch->rslots & ~ch->toslots) == 0 && et != AHCI_ERR_TIMEOUT) ahci_rearm_timeout(dev); + /* Unfreeze frozen command. */ + if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + ahci_begin_transaction(dev, fccb); + xpt_release_simq(ch->sim, TRUE); + } /* Start PM timer. */ if (ch->numrslots == 0 && ch->pm_level > 3 && (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c index 5dbe30cd1a7..54808c51b58 100644 --- a/sys/dev/mvs/mvs.c +++ b/sys/dev/mvs/mvs.c @@ -1738,13 +1738,6 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et) ch->numhslots++; } else xpt_done(ccb); - /* Unfreeze frozen command. */ - if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) { - union ccb *fccb = ch->frozen; - ch->frozen = NULL; - mvs_begin_transaction(dev, fccb); - xpt_release_simq(ch->sim, TRUE); - } /* If we have no other active commands, ... */ if (ch->rslots == 0) { /* if there was fatal error - reset port. */ @@ -1764,6 +1757,13 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et) } else if ((ch->rslots & ~ch->toslots) == 0 && et != MVS_ERR_TIMEOUT) mvs_rearm_timeout(dev); + /* Unfreeze frozen command. */ + if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + mvs_begin_transaction(dev, fccb); + xpt_release_simq(ch->sim, TRUE); + } /* Start PM timer. */ if (ch->numrslots == 0 && ch->pm_level > 3 && (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { @@ -2080,7 +2080,8 @@ mvs_softreset(device_t dev, union ccb *ccb) { struct mvs_channel *ch = device_get_softc(dev); int port = ccb->ccb_h.target_id & 0x0f; - int i; + int i, stuck; + uint8_t status; mvs_set_edma_mode(dev, MVS_EDMA_OFF); ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT); @@ -2089,12 +2090,35 @@ mvs_softreset(device_t dev, union ccb *ccb) ATA_OUTB(ch->r_mem, ATA_CONTROL, 0); ccb->ccb_h.status &= ~CAM_STATUS_MASK; /* Wait for clearing busy status. */ - if ((i = mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout)) < 0) { + if ((i = mvs_wait(dev, 0, ATA_S_BUSY, ccb->ccb_h.timeout)) < 0) { ccb->ccb_h.status |= CAM_CMD_TIMEOUT; + stuck = 1; } else { - ccb->ccb_h.status |= CAM_REQ_CMP; + status = mvs_getstatus(dev, 0); + if (status & ATA_S_ERROR) + ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; + else + ccb->ccb_h.status |= CAM_REQ_CMP; + if (status & ATA_S_DRQ) + stuck = 1; + else + stuck = 0; } mvs_tfd_read(dev, ccb); + + /* + * XXX: If some device on PMP failed to soft-reset, + * try to recover by sending dummy soft-reset to PMP. + */ + if (stuck && ch->pm_present && port != 15) { + ATA_OUTB(ch->r_mem, SATA_SATAICTL, + 15 << SATA_SATAICTL_PMPTX_SHIFT); + ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET); + DELAY(10000); + ATA_OUTB(ch->r_mem, ATA_CONTROL, 0); + mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout); + } + xpt_done(ccb); } diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 01edae368a5..a7b018a4321 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -1178,11 +1178,22 @@ siis_timeout(struct siis_slot *slot) { device_t dev = slot->dev; struct siis_channel *ch = device_get_softc(dev); + union ccb *ccb = slot->ccb; mtx_assert(&ch->mtx, MA_OWNED); /* Check for stale timeout. */ if (slot->state < SIIS_SLOT_RUNNING) return; + + /* Handle soft-reset timeouts without doing hard-reset. */ + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && + (ccb->ataio.cmd.control & ATA_A_RESET)) { + xpt_freeze_simq(ch->sim, ch->numrslots); + siis_end_transaction(slot, SIIS_ERR_TFE); + return; + } + device_printf(dev, "Timeout on slot %d\n", slot->slot); device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n", __func__, ATA_INL(ch->r_mem, SIIS_P_IS), @@ -1331,13 +1342,6 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) ch->numhslots++; } else xpt_done(ccb); - /* Unfreeze frozen command. */ - if (ch->frozen && !siis_check_collision(dev, ch->frozen)) { - union ccb *fccb = ch->frozen; - ch->frozen = NULL; - siis_begin_transaction(dev, fccb); - xpt_release_simq(ch->sim, TRUE); - } /* If we have no other active commands, ... */ if (ch->rslots == 0) { /* if there were timeouts or fatal error - reset port. */ @@ -1355,6 +1359,13 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) } else if ((ch->rslots & ~ch->toslots) == 0 && et != SIIS_ERR_TIMEOUT) siis_rearm_timeout(dev); + /* Unfreeze frozen command. */ + if (ch->frozen && !siis_check_collision(dev, ch->frozen)) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + siis_begin_transaction(dev, fccb); + xpt_release_simq(ch->sim, TRUE); + } } static void From a6d11f7139f1379415d6ac544c8ff778059622e6 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Wed, 25 May 2011 14:13:53 +0000 Subject: [PATCH 37/63] [mdoc] Fixed .Dt call. --- contrib/openbsm/libbsm/audit_submit.3 | 2 +- lib/libc/gen/feature_present.3 | 2 +- share/man/man4/atrtc.4 | 2 +- share/man/man4/attimer.4 | 2 +- share/man/man4/cc.4 | 2 +- share/man/man4/h_ertt.4 | 2 +- share/man/man4/nvram2env.4 | 2 +- share/man/man7/eventtimers.7 | 2 +- share/man/man9/devfs_set_cdevpriv.9 | 2 +- share/man/man9/hhook.9 | 2 +- share/man/man9/khelp.9 | 2 +- tools/tools/ether_reflect/ether_reflect.1 | 2 +- usr.bin/mkcsmapper/mkcsmapper.1 | 2 +- usr.bin/mkesdb/mkesdb.1 | 2 +- usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 | 2 +- usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 | 2 +- usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 | 2 +- usr.sbin/usbdump/usbdump.8 | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/contrib/openbsm/libbsm/audit_submit.3 b/contrib/openbsm/libbsm/audit_submit.3 index b6c28a7142a..c77e1d4f43c 100644 --- a/contrib/openbsm/libbsm/audit_submit.3 +++ b/contrib/openbsm/libbsm/audit_submit.3 @@ -30,7 +30,7 @@ .\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#17 $ .\" .Dd January 18, 2008 -.Dt audit_submit 3 +.Dt AUDIT_SUBMIT 3 .Os .Sh NAME .Nm audit_submit diff --git a/lib/libc/gen/feature_present.3 b/lib/libc/gen/feature_present.3 index 9a4269e9c9a..3a702d441df 100644 --- a/lib/libc/gen/feature_present.3 +++ b/lib/libc/gen/feature_present.3 @@ -29,7 +29,7 @@ .\" $FreeBSD$ .\" .Dd January 8, 2008 -.Dt feature_present 3 +.Dt FEATURE_PRESENT 3 .Os .Sh NAME .Nm feature_present diff --git a/share/man/man4/atrtc.4 b/share/man/man4/atrtc.4 index 35e770dd221..51d6f05ee3a 100644 --- a/share/man/man4/atrtc.4 +++ b/share/man/man4/atrtc.4 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd September 17, 2010 -.Dt atrtc 4 +.Dt ATRTC 4 .Os .Sh NAME .Nm atrtc diff --git a/share/man/man4/attimer.4 b/share/man/man4/attimer.4 index d5bfaf9aff0..67d001e3a5a 100644 --- a/share/man/man4/attimer.4 +++ b/share/man/man4/attimer.4 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd September 14, 2010 -.Dt attimer 4 +.Dt ATTIMER 4 .Os .Sh NAME .Nm attimer diff --git a/share/man/man4/cc.4 b/share/man/man4/cc.4 index 32da7417993..c518f456452 100644 --- a/share/man/man4/cc.4 +++ b/share/man/man4/cc.4 @@ -31,7 +31,7 @@ .\" $FreeBSD$ .\" .Dd February 15, 2011 -.Dt cc 4 +.Dt CC 4 .Os .Sh NAME .Nm cc diff --git a/share/man/man4/h_ertt.4 b/share/man/man4/h_ertt.4 index ed7461ef92e..b04efaa2a9f 100644 --- a/share/man/man4/h_ertt.4 +++ b/share/man/man4/h_ertt.4 @@ -30,7 +30,7 @@ .\" $FreeBSD$ .\" .Dd February 15, 2011 -.Dt h_ertt 9 +.Dt H_ERTT 9 .Os .Sh NAME .Nm h_ertt diff --git a/share/man/man4/nvram2env.4 b/share/man/man4/nvram2env.4 index c0ee0cf5e8f..51760979b66 100644 --- a/share/man/man4/nvram2env.4 +++ b/share/man/man4/nvram2env.4 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd April 3, 2011 -.Dt nvram2env 4 +.Dt NVRAM2ENV 4 .Os .Sh NAME .Nm nvram2env diff --git a/share/man/man7/eventtimers.7 b/share/man/man7/eventtimers.7 index 6c9552aed2f..37d5fc838b7 100644 --- a/share/man/man7/eventtimers.7 +++ b/share/man/man7/eventtimers.7 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd September 15, 2010 -.Dt eventtimers 4 +.Dt EVENTTIMERS 4 .Os .Sh NAME .Nm eventtimers diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9 index fcdc5c4fd41..a2b027903d8 100644 --- a/share/man/man9/devfs_set_cdevpriv.9 +++ b/share/man/man9/devfs_set_cdevpriv.9 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd September 8, 2008 -.Dt DEVFS_CDEVPRIV +.Dt DEVFS_CDEVPRIV 9 .Os .Sh NAME .Nm devfs_set_cdevpriv , diff --git a/share/man/man9/hhook.9 b/share/man/man9/hhook.9 index 1dd391f2dd2..df74543f5cc 100644 --- a/share/man/man9/hhook.9 +++ b/share/man/man9/hhook.9 @@ -31,7 +31,7 @@ .\" $FreeBSD$ .\" .Dd February 15, 2011 -.Dt hhook 9 +.Dt HHOOK 9 .Os .Sh NAME .Nm hhook , diff --git a/share/man/man9/khelp.9 b/share/man/man9/khelp.9 index 25125c0e91f..2f3f0e1284d 100644 --- a/share/man/man9/khelp.9 +++ b/share/man/man9/khelp.9 @@ -31,7 +31,7 @@ .\" $FreeBSD$ .\" .Dd February 15, 2011 -.Dt khelp 9 +.Dt KHELP 9 .Os .Sh NAME .Nm khelp , diff --git a/tools/tools/ether_reflect/ether_reflect.1 b/tools/tools/ether_reflect/ether_reflect.1 index c8388f01b56..139dcc26bbb 100644 --- a/tools/tools/ether_reflect/ether_reflect.1 +++ b/tools/tools/ether_reflect/ether_reflect.1 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd December 23, 2008 -.Dt ether_reflect 1 +.Dt ETHER_REFLECT 1 .Os .Sh NAME .Nm ether_reflect diff --git a/usr.bin/mkcsmapper/mkcsmapper.1 b/usr.bin/mkcsmapper/mkcsmapper.1 index a2666b45bab..650df500b77 100644 --- a/usr.bin/mkcsmapper/mkcsmapper.1 +++ b/usr.bin/mkcsmapper/mkcsmapper.1 @@ -35,7 +35,7 @@ .\" $FreeBSD$ .\" .Dd Sep 6, 2009 -.Dt mkcsmapper 1 +.Dt MKCSMAPPER 1 .Os .Sh NAME .Nm mkcsmapper diff --git a/usr.bin/mkesdb/mkesdb.1 b/usr.bin/mkesdb/mkesdb.1 index 2e063716a0a..66eb3908804 100644 --- a/usr.bin/mkesdb/mkesdb.1 +++ b/usr.bin/mkesdb/mkesdb.1 @@ -35,7 +35,7 @@ .\" $FreeBSD$ .\" .Dd November 1, 2009 -.Dt mkesdb 1 +.Dt MKESDB 1 .Os .Sh NAME .Nm mkesdb diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 index ebcf286ed49..b77b5f7ed6f 100644 --- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 +++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 @@ -26,7 +26,7 @@ .\" $FreeBSD$ .\" .Dd August 6, 2007 -.Dt snmp_bridge 3 +.Dt SNMP_BRIDGE 3 .Os .Sh NAME .Nm snmp_bridge diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 b/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 index 403d605ddd3..774c027dafc 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/snmp_hostres.3 @@ -29,7 +29,7 @@ .\" $FreeBSD$ .\" .Dd January 3, 2006 -.Dt snmp_hostres 3 +.Dt SNMP_HOSTRES 3 .Os .Sh NAME .Nm snmp_hostres diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 index 9f366f1c79d..20256f01378 100644 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 +++ b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 @@ -29,7 +29,7 @@ .\" $FreeBSD$ .\" .Dd June 28, 2010 -.Dt snmp_wlan 3 +.Dt SNMP_WLAN 3 .Os .Sh NAME .Nm snmp_wlan diff --git a/usr.sbin/usbdump/usbdump.8 b/usr.sbin/usbdump/usbdump.8 index f2b00e45742..a02f34ebfd1 100644 --- a/usr.sbin/usbdump/usbdump.8 +++ b/usr.sbin/usbdump/usbdump.8 @@ -26,7 +26,7 @@ .\" $FreeBSD$ .\" .Dd December 4, 2010 -.Dt usbdump 8 +.Dt USBDUMP 8 .Os .Sh NAME .Nm usbdump From 5106ce89d050932c7ed3d5bf6a9d5fbff722ba47 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 25 May 2011 18:04:11 +0000 Subject: [PATCH 38/63] Fix a regression introduced with previous changeset: if output is stdout, do not check for symbolic link. --- usr.bin/gzip/gzip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c index 927493eced7..217660ea239 100644 --- a/usr.bin/gzip/gzip.c +++ b/usr.bin/gzip/gzip.c @@ -1782,7 +1782,8 @@ handle_pathname(char *path) } retry: - if (stat(path, &sb) != 0 || (fflag == 0 && lstat(path, &sb) != 0)) { + if (stat(path, &sb) != 0 || (fflag == 0 && cflag == 0 && + lstat(path, &sb) != 0)) { /* lets try .gz if we're decompressing */ if (dflag && s == NULL && errno == ENOENT) { len = strlen(path); From e74fe876b59a6b4e80c7649655d1fb87efed513c Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Wed, 25 May 2011 20:25:13 +0000 Subject: [PATCH 39/63] Document the device name change from gpioctl to gpioc in the man page. PR: docs/157075 Submitted by: brix Reviewed by: gonzo --- usr.sbin/gpioctl/gpioctl.8 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8 index ca14beca25c..a277cda0398 100644 --- a/usr.sbin/gpioctl/gpioctl.8 +++ b/usr.sbin/gpioctl/gpioctl.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 27, 2010 +.Dd May 15, 2011 .Dt GPIOCTL 1 .Os .Sh NAME @@ -93,17 +93,17 @@ be verbose: for each listed pin print current configuration .Sh EXAMPLES .Bl -bullet .It -List pins available on GPIO controller defined by device /dev/gpioctl0 +List pins available on GPIO controller defined by device /dev/gpioc0 .Pp -gpioctl -f /dev/gpioctl0 -l +gpioctl -f /dev/gpioc0 -l .It Set the value of pin 12 to 1 .Pp -gpioctl -f /dev/gpioctl0 12 1 +gpioctl -f /dev/gpioc0 12 1 .It Configure pin 12 to be input pin .Pp -gpioctl -f /dev/gpioctl0 -c 12 IN +gpioctl -f /dev/gpioc0 -c 12 IN .El .Sh HISTORY The From 147206ae68b62cf3b80905c8fb365c004a13842f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 25 May 2011 20:53:08 +0000 Subject: [PATCH 40/63] Fix the new NFS client so that it correctly sets the "must_commit" argument for a write RPC when it succeeds for the first one and fails for a subsequent RPC within the same call to the function. This makes it compatible with the old NFS client for this case. MFC after: 2 weeks --- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfsclient/nfs_clrpcops.c | 15 +++++++++------ sys/fs/nfsclient/nfs_clvnops.c | 12 +----------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 6182ee869e5..d83d52392e4 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -370,7 +370,7 @@ int nfsrpc_readlink(vnode_t, struct uio *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); int nfsrpc_read(vnode_t, struct uio *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); -int nfsrpc_write(vnode_t, struct uio *, int *, u_char *, +int nfsrpc_write(vnode_t, struct uio *, int *, int *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *, int); int nfsrpc_mknod(vnode_t, char *, int, struct vattr *, u_int32_t, enum vtype, struct ucred *, NFSPROC_T *, struct nfsvattr *, diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 7af0852301e..0fc9bfd1da9 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -68,7 +68,7 @@ static int nfsrpc_setattrrpc(vnode_t , struct vattr *, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); static int nfsrpc_readrpc(vnode_t , struct uio *, struct ucred *, nfsv4stateid_t *, NFSPROC_T *, struct nfsvattr *, int *, void *); -static int nfsrpc_writerpc(vnode_t , struct uio *, int *, u_char *, +static int nfsrpc_writerpc(vnode_t , struct uio *, int *, int *, struct ucred *, nfsv4stateid_t *, NFSPROC_T *, struct nfsvattr *, int *, void *); static int nfsrpc_createv23(vnode_t , char *, int, struct vattr *, @@ -1369,7 +1369,7 @@ nfsmout: * will then deadlock. */ APPLESTATIC int -nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp, +nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp, void *stuff, int called_from_strategy) { @@ -1382,6 +1382,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp, nfsv4stateid_t stateid; void *lckp; + *must_commit = 0; if (nmp->nm_clp != NULL) clidrev = nmp->nm_clp->nfsc_clientidrev; newcred = cred; @@ -1412,7 +1413,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp, if (nostateid) error = 0; else - error = nfsrpc_writerpc(vp, uiop, iomode, verfp, + error = nfsrpc_writerpc(vp, uiop, iomode, must_commit, newcred, &stateid, p, nap, attrflagp, stuff); if (error == NFSERR_STALESTATEID) nfscl_initiate_recovery(nmp->nm_clp); @@ -1447,7 +1448,7 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, u_char *verfp, */ static int nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode, - u_char *verfp, struct ucred *cred, nfsv4stateid_t *stateidp, + int *must_commit, struct ucred *cred, nfsv4stateid_t *stateidp, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp, void *stuff) { u_int32_t *tl; @@ -1585,14 +1586,16 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode, else if (committed == NFSWRITE_DATASYNC && commit == NFSWRITE_UNSTABLE) committed = commit; - if (verfp != NULL) - NFSBCOPY((caddr_t)tl, verfp, NFSX_VERF); NFSLOCKMNT(nmp); if (!NFSHASWRITEVERF(nmp)) { NFSBCOPY((caddr_t)tl, (caddr_t)&nmp->nm_verf[0], NFSX_VERF); NFSSETWRITEVERF(nmp); + } else if (NFSBCMP(tl, nmp->nm_verf, + NFSX_VERF)) { + *must_commit = 1; + NFSBCOPY(tl, nmp->nm_verf, NFSX_VERF); } NFSUNLOCKMNT(nmp); } diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 1b085821976..355e168a454 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1332,19 +1332,9 @@ ncl_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, { struct nfsvattr nfsva; int error = 0, attrflag, ret; - u_char verf[NFSX_VERF]; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - *must_commit = 0; - error = nfsrpc_write(vp, uiop, iomode, verf, cred, + error = nfsrpc_write(vp, uiop, iomode, must_commit, cred, uiop->uio_td, &nfsva, &attrflag, NULL, called_from_strategy); - NFSLOCKMNT(nmp); - if (!error && NFSHASWRITEVERF(nmp) && - NFSBCMP(verf, nmp->nm_verf, NFSX_VERF)) { - *must_commit = 1; - NFSBCOPY(verf, nmp->nm_verf, NFSX_VERF); - } - NFSUNLOCKMNT(nmp); if (attrflag) { if (VTONFS(vp)->n_flag & ND_NFSV4) ret = nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 1, From bef655932c4ad575ecb46f5974455123c761ddd5 Mon Sep 17 00:00:00 2001 From: Benedict Reuschling Date: Wed, 25 May 2011 21:04:11 +0000 Subject: [PATCH 41/63] Bump the date of the man page to the date of the actual commit. Noticed by: brix --- usr.sbin/gpioctl/gpioctl.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8 index a277cda0398..4ceecf6f4a1 100644 --- a/usr.sbin/gpioctl/gpioctl.8 +++ b/usr.sbin/gpioctl/gpioctl.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 15, 2011 +.Dd May 25, 2011 .Dt GPIOCTL 1 .Os .Sh NAME From 81ddb192e87610a2bfbd44fac10bdb095b52aa16 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 25 May 2011 21:17:53 +0000 Subject: [PATCH 42/63] Add some missing mutex locking to the new NFS client. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clvnops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 355e168a454..3ec12ca37a2 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -2470,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); From 168b9dd182e299e9c35140b32ed18aaf60e607f9 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Wed, 25 May 2011 21:38:16 +0000 Subject: [PATCH 43/63] sh: Show errno messages in cd. --- bin/sh/cd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 776bdbaf905..2cd9dafa5d5 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -86,6 +86,7 @@ cdcmd(int argc, char **argv) struct stat statb; int ch, phys, print = 0, getcwderr = 0; int rc; + int errno1 = ENOENT; optreset = 1; optind = 1; opterr = 0; /* initialize getopt */ phys = Pflag; @@ -138,9 +139,11 @@ cdcmd(int argc, char **argv) rc = docd(p, print, phys); if (rc >= 0) return getcwderr ? rc : 0; + if (errno != ENOENT) + errno1 = errno; } } - error("can't cd to %s", dest); + error("%s: %s", dest, strerror(errno1)); /*NOTREACHED*/ return 0; } From 3c24f8e827c0caf10c792bc3328c2f5a09913310 Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Wed, 25 May 2011 23:33:49 +0000 Subject: [PATCH 44/63] + Tighten up (and simplify) the pass_cmd_vars_1 "variable definition arrived from the calling make" test. + Be more tolerant of newlines in the plus_flag "supports the '+' flag" test. --- tools/build/make_check/Makefile | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tools/build/make_check/Makefile b/tools/build/make_check/Makefile index e57e70c32db..cc8ca6b918c 100644 --- a/tools/build/make_check/Makefile +++ b/tools/build/make_check/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.MAKE.MODE= normal + # Test for broken LHS expansion. # This *must* cause make(1) to detect a recursive variable, and fail as such. .if make(lhs_expn) @@ -152,24 +154,19 @@ pass_cmd_vars: @${SMAKE} CMD1=cmd1 CMD2=cmd2 pass_cmd_vars_4 .endif -.if make(pass_cmd_vars_1) +# # Check that the variable definition arrived from the calling make +# +.if make(pass_cmd_vars_1) +# These values should get overridden by the commandline +CMD1=oops1 +CMD2=oops2 pass_cmd_vars_1: @: .if ${CMD1} != cmd1 || ${CMD2} != cmd2 .error variables not passed through MAKEFLAGS .endif - -# Check that the variable definition is in MAKEFLAGS -.if ${.MAKEFLAGS:MCMD1=*} != "CMD1=cmd1" || ${.MAKEFLAGS:MCMD2=*} != "CMD2=cmd2" -.error variable assignment not found in $${MAKEFLAGS} -.endif - -# Check that the variable definition is not in MFLAGS -.if ${MFLAGS:MCMD1=*} != "" || ${MFLAGS:MCMD2=*} != "" -.error variable assignment found in $${MFLAGS} -.endif .endif .if make(pass_cmd_vars_2) @@ -228,7 +225,7 @@ pass_cmd_vars_4_1: # .if make(plus_flag) OUT != ${SMAKE} -n plus_flag_1 -.if ${OUT} != "/tmp" +.if ${OUT:M/tmp} != "/tmp" .error make doesn't handle + flag .endif plus_flag: From 0591ab9c302e7d9cf95e4a6028e51d3287b348ef Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 26 May 2011 06:43:10 +0000 Subject: [PATCH 45/63] Add better names for the Intel HDMI audio codecs. --- sys/dev/sound/pci/hda/hdac.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 7af53034a0c..5bec624431e 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -826,12 +826,13 @@ static const struct { #define HDA_CODEC_NVIDIAXXXX HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff) /* INTEL */ -#define HDA_CODEC_INTELG45_1 HDA_CODEC_CONSTRUCT(INTEL, 0x2801) -#define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802) -#define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803) -#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x2804) -#define HDA_CODEC_INTELG45_5 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb) -#define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054) +#define HDA_CODEC_INTELIP HDA_CODEC_CONSTRUCT(INTEL, 0x0054) +#define HDA_CODEC_INTELBL HDA_CODEC_CONSTRUCT(INTEL, 0x2801) +#define HDA_CODEC_INTELCA HDA_CODEC_CONSTRUCT(INTEL, 0x2802) +#define HDA_CODEC_INTELEL HDA_CODEC_CONSTRUCT(INTEL, 0x2803) +#define HDA_CODEC_INTELIP2 HDA_CODEC_CONSTRUCT(INTEL, 0x2804) +#define HDA_CODEC_INTELCPT HDA_CODEC_CONSTRUCT(INTEL, 0x2805) +#define HDA_CODEC_INTELCL HDA_CODEC_CONSTRUCT(INTEL, 0x29fb) #define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff) /* Codecs */ @@ -998,12 +999,13 @@ static const struct { { HDA_CODEC_NVIDIAGT21X, "NVidia GT21x HDMI" }, { HDA_CODEC_NVIDIAMCP89, "NVidia MCP89 HDMI" }, { HDA_CODEC_NVIDIAGT240, "NVidia GT240 HDMI" }, - { HDA_CODEC_INTELG45_1, "Intel G45 HDMI" }, - { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" }, - { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" }, - { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" }, - { HDA_CODEC_INTELG45_5, "Intel G45 HDMI" }, - { HDA_CODEC_INTELQ57, "Intel Q57 HDMI" }, + { HDA_CODEC_INTELIP, "Intel Ibex Peak HDMI" }, + { HDA_CODEC_INTELBL, "Intel Bearlake HDMI" }, + { HDA_CODEC_INTELCA, "Intel Cantiga HDMI" }, + { HDA_CODEC_INTELEL, "Intel Eaglelake HDMI" }, + { HDA_CODEC_INTELIP2, "Intel Ibex Peak HDMI" }, + { HDA_CODEC_INTELCPT, "Intel Cougar Point HDMI" }, + { HDA_CODEC_INTELCL, "Intel Crestline HDMI" }, { HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" }, { HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" }, /* Unknown codec */ From a1cf3a877adc353dcdacb80b051f3af9abf20429 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 08:20:14 +0000 Subject: [PATCH 46/63] Add temp sense to the EEPROM variable list; Export the temperature sense variables to ah_eeprom_9287.c --- sys/dev/ath/ath_hal/ah_eeprom.h | 4 +++- sys/dev/ath/ath_hal/ah_eeprom_9287.c | 34 ++++++++++------------------ 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_eeprom.h b/sys/dev/ath/ath_hal/ah_eeprom.h index c7fe3856622..2ca058982f3 100644 --- a/sys/dev/ath/ath_hal/ah_eeprom.h +++ b/sys/dev/ath/ath_hal/ah_eeprom.h @@ -101,7 +101,9 @@ enum { AR_EEP_ANTGAINMAX_2, /* int8_t* */ AR_EEP_WRITEPROTECT, /* use ath_hal_eepromGetFlag */ AR_EEP_PWR_TABLE_OFFSET,/* int8_t* */ - AR_EEP_PWDCLKIND /* uint8_t* */ + AR_EEP_PWDCLKIND, /* uint8_t* */ + AR_EEP_TEMPSENSE_SLOPE, /* int8_t* */ + AR_EEP_TEMPSENSE_SLOPE_PAL_ON, /* int8_t* */ }; typedef struct { diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.c b/sys/dev/ath/ath_hal/ah_eeprom_9287.c index e8c5e54f1b9..f6de55b0236 100644 --- a/sys/dev/ath/ath_hal/ah_eeprom_9287.c +++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.c @@ -63,28 +63,10 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val) return pBase->opCapFlags; case AR_EEP_RFSILENT: return pBase->rfSilent; -#if 0 - case AR_EEP_OB_5: - return pModal[CHAN_A_IDX].ob; - case AR_EEP_DB_5: - return pModal[CHAN_A_IDX].db; - case AR_EEP_OB_2: - return pModal[CHAN_B_IDX].ob; - case AR_EEP_DB_2: - return pModal[CHAN_B_IDX].db; -#endif case AR_EEP_TXMASK: return pBase->txMask; case AR_EEP_RXMASK: return pBase->rxMask; -#if 0 - case AR_EEP_RXGAIN_TYPE: - return IS_VERS(>=, AR5416_EEP_MINOR_VER_17) ? - pBase->rxGainType : AR5416_EEP_RXGAIN_ORIG; - case AR_EEP_TXGAIN_TYPE: - return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ? - pBase->txGainType : AR5416_EEP_TXGAIN_ORIG; -#endif case AR_EEP_OL_PWRCTRL: HALASSERT(val == AH_NULL); return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO; @@ -117,6 +99,18 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val) case AR_EEP_PWR_TABLE_OFFSET: *(int8_t *) val = pBase->pwrTableOffset; return HAL_OK; + case AR_EEP_TEMPSENSE_SLOPE: + if (IS_VERS(>=, AR9287_EEP_MINOR_VER_2)) + *(int8_t *)val = pBase->tempSensSlope; + else + *(int8_t *)val = 0; + return HAL_OK; + case AR_EEP_TEMPSENSE_SLOPE_PAL_ON: + if (IS_VERS(>=, AR9287_EEP_MINOR_VER_3)) + *(int8_t *)val = pBase->tempSensSlopePalOn; + else + *(int8_t *)val = 0; + return HAL_OK; default: HALASSERT(0); return HAL_EINVAL; @@ -135,10 +129,6 @@ v9287EepromSet(struct ath_hal *ah, int param, int v) 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; - } return HAL_EINVAL; } From b3096aee0b402ed94908cad3ccadf91beaa4f17c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 08:35:47 +0000 Subject: [PATCH 47/63] AR9287 prep work: * Add PCI/PCIE devids * Add AR9287/Kiwi version check macros * AR_SREV_9287 -> AR_SREV_KIWI Obtained from: Atheros, ath9k --- sys/dev/ath/ath_hal/ah_devid.h | 2 ++ sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 2 +- sys/dev/ath/ath_hal/ar5416/ar5416reg.h | 31 +++++++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_devid.h b/sys/dev/ath/ath_hal/ah_devid.h index 64033f3ced1..348dcf38109 100644 --- a/sys/dev/ath/ath_hal/ah_devid.h +++ b/sys/dev/ath/ath_hal/ah_devid.h @@ -80,6 +80,8 @@ #define AR9280_DEVID_PCIE 0x002a /* AR9280 PCI-E Merlin */ #define AR9285_DEVID_PCIE 0x002b /* AR9285 PCI-E Kite */ #define AR2427_DEVID_PCIE 0x002c /* AR2427 PCI-E w/ 802.11n bonded out */ +#define AR9287_DEVID_PCI 0x002d /* AR9227 PCI Merlin */ +#define AR9287_DEVID_PCIE 0x002e /* AR9287 PCI-E Merlin */ #define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */ #define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index d2ae351f730..10e85a00183 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -2576,7 +2576,7 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) if (!AR_SREV_9271(ah)) val &= ~AR_PCU_MISC_MODE2_HWWAR1; - if (AR_SREV_9287_11_OR_LATER(ah)) + if (AR_SREV_KIWI_11_OR_LATER(ah)) val = val & (~AR_PCU_MISC_MODE2_HWWAR2); OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val); diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index 99213669c40..f59100a7a81 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -566,6 +566,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 /* Kite Version */ +#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 +653,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 */ From d8daa2e3f6ec316ee6c94f37dadffe75a8b8d4fd Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 09:15:33 +0000 Subject: [PATCH 48/63] Bring over my AR9287 work in progress. It isn't linked into the build because it's missing the TX power and PDADC programming code. This code is mostly based on the ath9k codebase, compared against the Atheros codebase as appropriate. What's implemented: * probe/attach * EEPROM board value programming * RX initial calibration * radio channel programming * general MAC / baseband setup * async fifo setup * open-loop tx power calibration What's missing before it can be enabled by default: * TX power / calibration setting code * closed-loop tx power calibration routines * TSF2 handling * generic timer support from ath9k Obtained from: Atheros, ath9k --- sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 52 ++ sys/dev/ath/ath_hal/ar5416/ar5416phy.h | 2 + sys/dev/ath/ath_hal/ar5416/ar5416reg.h | 31 +- sys/dev/ath/ath_hal/ar9002/ar9285_phy.c | 2 + sys/dev/ath/ath_hal/ar9002/ar9287.c | 392 +++++++++++ sys/dev/ath/ath_hal/ar9002/ar9287.h | 62 ++ sys/dev/ath/ath_hal/ar9002/ar9287.ini | 783 +++++++++++++++++++++ sys/dev/ath/ath_hal/ar9002/ar9287_attach.c | 457 ++++++++++++ sys/dev/ath/ath_hal/ar9002/ar9287_cal.c | 73 ++ sys/dev/ath/ath_hal/ar9002/ar9287_cal.h | 33 + sys/dev/ath/ath_hal/ar9002/ar9287_olc.c | 94 +++ sys/dev/ath/ath_hal/ar9002/ar9287_olc.h | 25 + sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 186 +++++ sys/dev/ath/ath_hal/ar9002/ar9287_reset.h | 27 + sys/dev/ath/ath_hal/ar9002/ar9287an.h | 49 ++ sys/dev/ath/ath_hal/ar9002/ar9287phy.h | 26 + 16 files changed, 2293 insertions(+), 1 deletion(-) create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287.c create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287.h create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287.ini create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_attach.c create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_cal.c create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_cal.h create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_olc.c create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_olc.h create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_reset.c create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287_reset.h create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287an.h create mode 100644 sys/dev/ath/ath_hal/ar9002/ar9287phy.h diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index 10e85a00183..1da686a3df0 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -167,6 +167,17 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, AH5416(ah)->ah_writeIni(ah, chan); + if(AR_SREV_KIWI_13_OR_LATER(ah) ) { + /* Enable ASYNC FIFO */ + OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); + OS_REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); + OS_REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); + OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); + } + /* Override ini values (that can be overriden in this fashion) */ ar5416OverrideIni(ah, chan); @@ -258,6 +269,12 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); + /* Start TSF2 for generic timer 8-15 */ +#ifdef NOTYET + if (AR_SREV_KIWI(ah)) + ar5416StartTsf2(ah); +#endif + /* Restore previous antenna */ OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); @@ -292,6 +309,41 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, /* This may override the AR_DIAG_SW register */ ar5416InitUserSettings(ah); + if (AR_SREV_KIWI_13_OR_LATER(ah)) { + /* + * Enable ASYNC FIFO + * + * If Async FIFO is enabled, the following counters change + * as MAC now runs at 117 Mhz instead of 88/44MHz when + * async FIFO is disabled. + * + * Overwrite the delay/timeouts initialized in ProcessIni() + * above. + */ + OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, + AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); + OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, + AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR); + OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, + AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR); + + OS_REG_WRITE(ah, AR_TIME_OUT, + AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR); + OS_REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR); + + OS_REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, + AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); + OS_REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, + AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); + } + + if (AR_SREV_KIWI_13_OR_LATER(ah)) { + /* Enable AGGWEP to accelerate encryption engine */ + OS_REG_SET_BIT(ah, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_ENABLE_AGGWEP); + } + + /* * disable seq number generation in hw */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h index 86643f06f80..2c419d74018 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h @@ -301,4 +301,6 @@ #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 +#define AR_PHY_MODE_ASYNCFIFO 0x80 /* Enable async fifo */ + #endif /* _DEV_ATH_AR5416PHY_H_ */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index f59100a7a81..561c5b41b38 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -219,6 +219,10 @@ #define AR_AHB_PAGE_SIZE_1K 0x00000000 /* set page-size as 1k */ #define AR_AHB_PAGE_SIZE_2K 0x00000008 /* set page-size as 2k */ #define AR_AHB_PAGE_SIZE_4K 0x00000010 /* set page-size as 4k */ +/* Kiwi */ +#define AR_AHB_CUSTOM_BURST_EN 0x000000C0 /* set Custom Burst Mode */ +#define AR_AHB_CUSTOM_BURST_EN_S 6 /* set Custom Burst Mode */ +#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3 /* set both bits in Async FIFO mode */ /* MAC PCU Registers */ #define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 /* Don't replace seq num */ @@ -451,9 +455,23 @@ * For Merlin and above only. */ #define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040 +#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000 /* Kiwi or later? */ #define AR_PCU_MISC_MODE2_HWWAR1 0x00100000 #define AR_PCU_MISC_MODE2_HWWAR2 0x02000000 +/* For Kiwi */ +#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 +#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 +#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 + +/* TSF2. For Kiwi only */ +#define AR_TSF2_L32 0x8390 +#define AR_TSF2_U32 0x8394 + +/* MAC Direct Connect Control. For Kiwi only */ +#define AR_DIRECT_CONNECT 0x83A0 +#define AR_DC_AP_STA_EN 0x00000001 + /* GPIO Interrupt */ #define AR_INTR_GPIO 0x3FF00000 /* gpio interrupted */ #define AR_INTR_GPIO_S 20 @@ -488,6 +506,17 @@ #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 +/* IFS, SIFS, slot, etc for Async FIFO mode (Kiwi) */ +#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB +#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56 +#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074 +#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420 +#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB + +/* Used by Kiwi Async FIFO */ +#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264 +#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000 + /* Eeprom defines */ #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff #define AR_EEPROM_STATUS_DATA_VAL_S 0 @@ -566,7 +595,7 @@ #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 /* Kite Version */ +#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 diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c index e4e73d47f08..b28b97fb9d8 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c @@ -87,8 +87,10 @@ ar9285_check_div_comb(struct ath_hal *ah) HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader; +#if 0 /* For now, simply disable this until it's better debugged. -adrian */ return AH_FALSE; +#endif if (! AR_SREV_KITE(ah)) return AH_FALSE; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.c b/sys/dev/ath/ath_hal/ar9002/ar9287.c new file mode 100644 index 00000000000..92501cac8e7 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting + * Copyright (c) 2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#include "opt_ah.h" + +/* + * NB: Merlin and later have a simpler RF backend. + */ +#include "ah.h" +#include "ah_internal.h" + +#include "ah_eeprom_v14.h" + +#include "ar9002/ar9287.h" +#include "ar5416/ar5416reg.h" +#include "ar5416/ar5416phy.h" + +#define N(a) (sizeof(a)/sizeof(a[0])) + +struct ar9287State { + RF_HAL_FUNCS base; /* public state, must be first */ + uint16_t pcdacTable[1]; /* XXX */ +}; +#define AR9280(ah) ((struct ar9287State *) AH5212(ah)->ah_rfHal) + +static HAL_BOOL ar9287GetChannelMaxMinPower(struct ath_hal *, + const struct ieee80211_channel *, int16_t *maxPow,int16_t *minPow); +int16_t ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c); + +static void +ar9287WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, + int writes) +{ + (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain, + freqIndex, writes); +} + +/* + * Take the MHz channel value and set the Channel value + * + * ASSUMES: Writes enabled to analog bus + * + * Actual Expression, + * + * For 2GHz channel, + * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) + * (freq_ref = 40MHz) + * + * For 5GHz channel, + * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) + * (freq_ref = 40MHz/(24>>amodeRefSel)) + * + * For 5GHz channels which are 5MHz spaced, + * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) + * (freq_ref = 40MHz) + */ +static HAL_BOOL +ar9287SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) +{ + uint16_t bMode, fracMode, aModeRefSel = 0; + uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; + CHAN_CENTERS centers; + uint32_t refDivA = 24; + + OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq); + + ar5416GetChannelCenters(ah, chan, ¢ers); + 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; ipDataPerXPD[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; ipDataPerXPD[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; + (ichannel > data[i].channelValue); + last=i++); + totalD = data[i].channelValue - data[last].channelValue; + if (totalD > 0) { + totalF = data[i].maxPower_t4 - data[last].maxPower_t4; + *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD); + + totalMin = ar9287GetMinPower(ah,&data[i]) - ar9287GetMinPower(ah, &data[last]); + *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar9287GetMinPower(ah, &data[last])*totalD)/totalD); + return (AH_TRUE); + } else { + if (chan->channel == data[i].channelValue) { + *maxPow = data[i].maxPower_t4; + *minPow = ar9287GetMinPower(ah, &data[i]); + return(AH_TRUE); + } else + return(AH_FALSE); + } +#else + *maxPow = *minPow = 0; + return AH_FALSE; +#endif +} + +/* + * The ordering of nfarray is thus: + * + * nfarray[0]: Chain 0 ctl + * nfarray[1]: Chain 1 ctl + * nfarray[2]: Chain 2 ctl + * nfarray[3]: Chain 0 ext + * nfarray[4]: Chain 1 ext + * nfarray[5]: Chain 2 ext + */ +static void +ar9287GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) +{ + int16_t nf; + + nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); + if (nf & 0x100) + nf = 0 - ((nf ^ 0x1ff) + 1); + HALDEBUG(ah, HAL_DEBUG_NFCAL, + "NF calibrated [ctl] [chain 0] is %d\n", nf); + nfarray[0] = nf; + + nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); + if (nf & 0x100) + nf = 0 - ((nf ^ 0x1ff) + 1); + HALDEBUG(ah, HAL_DEBUG_NFCAL, + "NF calibrated [ctl] [chain 1] is %d\n", nf); + nfarray[1] = nf; + + nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); + if (nf & 0x100) + nf = 0 - ((nf ^ 0x1ff) + 1); + HALDEBUG(ah, HAL_DEBUG_NFCAL, + "NF calibrated [ext] [chain 0] is %d\n", nf); + nfarray[3] = nf; + + nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); + if (nf & 0x100) + nf = 0 - ((nf ^ 0x1ff) + 1); + HALDEBUG(ah, HAL_DEBUG_NFCAL, + "NF calibrated [ext] [chain 1] is %d\n", nf); + nfarray[4] = nf; + + /* Chain 2 - invalid */ + nfarray[2] = 0; + nfarray[5] = 0; + +} + +/* + * Adjust NF based on statistical values for 5GHz frequencies. + * Stubbed:Not used by Fowl + */ +int16_t +ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) +{ + return 0; +} + +/* + * Free memory for analog bank scratch buffers + */ +static void +ar9287RfDetach(struct ath_hal *ah) +{ + struct ath_hal_5212 *ahp = AH5212(ah); + + HALASSERT(ahp->ah_rfHal != AH_NULL); + ath_hal_free(ahp->ah_rfHal); + ahp->ah_rfHal = AH_NULL; +} + +HAL_BOOL +ar9287RfAttach(struct ath_hal *ah, HAL_STATUS *status) +{ + struct ath_hal_5212 *ahp = AH5212(ah); + struct ar9287State *priv; + + HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: attach AR9280 radio\n", __func__); + + HALASSERT(ahp->ah_rfHal == AH_NULL); + priv = ath_hal_malloc(sizeof(struct ar9287State)); + if (priv == AH_NULL) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s: cannot allocate private state\n", __func__); + *status = HAL_ENOMEM; /* XXX */ + return AH_FALSE; + } + priv->base.rfDetach = ar9287RfDetach; + priv->base.writeRegs = ar9287WriteRegs; + priv->base.getRfBank = ar9287GetRfBank; + priv->base.setChannel = ar9287SetChannel; + priv->base.setRfRegs = ar9287SetRfRegs; + priv->base.setPowerTable = ar9287SetPowerTable; + priv->base.getChannelMaxMinPower = ar9287GetChannelMaxMinPower; + priv->base.getNfAdjust = ar9287GetNfAdjust; + + ahp->ah_pcdacTable = priv->pcdacTable; + ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable); + ahp->ah_rfHal = &priv->base; + /* + * Set noise floor adjust method; we arrange a + * direct call instead of thunking. + */ + AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust; + AH_PRIVATE(ah)->ah_getNoiseFloor = ar9287GetNoiseFloor; + + return AH_TRUE; +} diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.h b/sys/dev/ath/ath_hal/ar9002/ar9287.h new file mode 100644 index 00000000000..90d25ed28fc --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef _ATH_AR9287_H_ +#define _ATH_AR9287_H_ + +#include "ar5416/ar5416.h" + +/* + * This is a chip thing, but it's used here as part of the + * ath_hal_9287 struct; so it's convienent to locate the + * define here. + */ +#define AR9287_TX_GAIN_TABLE_SIZE 22 + +struct ath_hal_9287 { + struct ath_hal_5416 ah_5416; + + HAL_INI_ARRAY ah_ini_xmodes; + HAL_INI_ARRAY ah_ini_rxgain; + HAL_INI_ARRAY ah_ini_txgain; + + HAL_INI_ARRAY ah_ini_cckFirNormal; + HAL_INI_ARRAY ah_ini_cckFirJapan2484; + + int PDADCdelta; + + uint32_t originalGain[AR9287_TX_GAIN_TABLE_SIZE]; +}; +#define AH9287(_ah) ((struct ath_hal_9287 *)(_ah)) + +#define AR9287_DEFAULT_RXCHAINMASK 3 +#define AR9285_DEFAULT_RXCHAINMASK 1 +#define AR9287_DEFAULT_TXCHAINMASK 3 +#define AR9285_DEFAULT_TXCHAINMASK 1 + +#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -112 +#define AR_PHY_CCA_NOM_VAL_9287_5GHZ -112 +#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127 +#define AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ -122 +#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -97 +#define AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ -102 + +extern HAL_BOOL ar9287RfAttach(struct ath_hal *, HAL_STATUS *); +extern HAL_BOOL ar9287SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); + +#endif /* _ATH_AR9287_H_ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.ini b/sys/dev/ath/ath_hal/ar9002/ar9287.ini new file mode 100644 index 00000000000..7f4ca05190c --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287.ini @@ -0,0 +1,783 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +static const uint32_t ar9287Modes_9287_1_1[][6] = { + {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001}, + {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, + {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18}, + {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const uint32_t ar9287Common_9287_1_1[][2] = { + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000033}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18487320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0x01c81043}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0x0fffffff}, + {0x00008394, 0x0fffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x0000a84c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x10002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x0000a920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009930, 0x00000000}, + {0x0000a930, 0x00000000}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x0108ecff}, + {0x00009940, 0x14750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x990bb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x0c6f0000}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099c4, 0x06336f77}, + {0x000099c8, 0x6af6532f}, + {0x000099cc, 0x08f186c8}, + {0x000099d0, 0x00046384}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x000099fc, 0x00001042}, + {0x0000a208, 0x803e4788}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x40206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x233f7180}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cdbd380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a264, 0x00418a11}, + {0x0000b264, 0x00418a11}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000b398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x0000a3f0, 0x01036a1e}, + {0x0000a3f4, 0x00000000}, + {0x0000b3f4, 0x00000000}, + {0x0000a7d8, 0x000003f1}, + {0x00007800, 0x00000800}, + {0x00007804, 0x6c35ffd2}, + {0x00007808, 0x6db6c000}, + {0x0000780c, 0x6db6cb30}, + {0x00007810, 0x6db6cb6c}, + {0x00007814, 0x0501e200}, + {0x00007818, 0x0094128d}, + {0x0000781c, 0x976ee392}, + {0x00007820, 0xf75ff6fc}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb003012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x00140000}, + {0x00007838, 0x0e4548d8}, + {0x0000783c, 0x54214514}, + {0x00007840, 0x02025830}, + {0x00007844, 0x71c0d388}, + {0x00007848, 0x934934a8}, + {0x00007850, 0x00000000}, + {0x00007854, 0x00000800}, + {0x00007858, 0x6c35ffd2}, + {0x0000785c, 0x6db6c000}, + {0x00007860, 0x6db6cb30}, + {0x00007864, 0x6db6cb6c}, + {0x00007868, 0x0501e200}, + {0x0000786c, 0x0094128d}, + {0x00007870, 0x976ee392}, + {0x00007874, 0xf75ff6fc}, + {0x00007878, 0x00040000}, + {0x0000787c, 0xdb003012}, + {0x00007880, 0x04924914}, + {0x00007884, 0x21084210}, + {0x00007888, 0x001b6db0}, + {0x0000788c, 0x00376b63}, + {0x00007890, 0x06db6db6}, + {0x00007894, 0x006d8000}, + {0x00007898, 0x48100000}, + {0x0000789c, 0x00000000}, + {0x000078a0, 0x08000000}, + {0x000078a4, 0x0007ffd8}, + {0x000078a8, 0x0007ffd8}, + {0x000078ac, 0x001c0020}, + {0x000078b0, 0x00060aeb}, + {0x000078b4, 0x40008080}, + {0x000078b8, 0x2a850160}, +}; + +static const uint32_t ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = { + /* Addr allmodes */ + {0x0000a1f4, 0x00fffeff}, + {0x0000a1f8, 0x00f5f9ff}, + {0x0000a1fc, 0xb79f6427}, +}; + +static const uint32_t ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = { + /* Addr allmodes */ + {0x0000a1f4, 0x00000000}, + {0x0000a1f8, 0xefff0301}, + {0x0000a1fc, 0xca9228ee}, +}; + +static const uint32_t ar9287Modes_tx_gain_9287_1_1[][6] = { + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b}, + {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, + {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a}, + {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a}, + {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c}, + {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc}, + {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4}, + {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc}, + {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede}, + {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, + {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e}, + {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e}, + {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062}, + {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064}, + {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4}, + {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa}, + {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac}, + {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4}, + {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4}, + {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134}, + {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174}, + {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c}, + {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e}, + {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be}, + {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000}, +}; + +static const uint32_t ar9287Modes_rx_gain_9287_1_1[][6] = { + {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, + {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, +}; + +static const uint32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; + +static const uint32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c new file mode 100644 index 00000000000..08105606281 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c @@ -0,0 +1,457 @@ +/* + * 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; + } + + /* + * Check whether the power table offset isn't the default. + * This can occur with eeprom minor V21 or greater on Merlin. + */ + (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset); + if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB) + ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n", + AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset); + + /* setup rxgain table */ + HAL_INI_INIT(&ahp9287->ah_ini_rxgain, ar9287Modes_rx_gain_9287_1_1, 6); + + /* setup txgain table */ + HAL_INI_INIT(&ahp9287->ah_ini_txgain, ar9287Modes_tx_gain_9287_1_1, 6); + + /* + * Got everything we need now to setup the capabilities. + */ + if (!ar9287FillCapabilityInfo(ah)) { + ecode = HAL_EEREAD; + goto bad; + } + + ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); + if (ecode != HAL_OK) { + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s: error getting mac address from EEPROM\n", __func__); + goto bad; + } + /* XXX How about the serial number ? */ + /* Read Reg Domain */ + AH_PRIVATE(ah)->ah_currentRD = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + + /* + * ah_miscMode is populated by ar5416FillCapabilityInfo() + * starting from griffin. Set here to make sure that + * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is + * placed into hardware. + */ + if (ahp->ah_miscMode != 0) + OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); + + ar9287AniSetup(ah); /* Anti Noise Immunity */ + + /* Setup noise floor min/max/nominal values */ + AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ; + AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ; + AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ; + AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ; + AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ; + AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9287_5GHZ; + + ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); + + HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); + + return ah; +bad: + if (ah != AH_NULL) + ah->ah_detach(ah); + if (status) + *status = ecode; + return AH_NULL; +} + +static void +ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) +{ + if (AH_PRIVATE(ah)->ah_ispcie && !restore) { + ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0); + OS_DELAY(1000); + OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); + OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); /* Yes, Kiwi uses the Kite PCIe PHY WA */ + } +} + +static void +ar9287WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) +{ + u_int modesIndex, freqIndex; + int regWrites = 0; + + /* Setup the indices for the next set of register array writes */ + /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ + if (IEEE80211_IS_CHAN_2GHZ(chan)) { + freqIndex = 2; + if (IEEE80211_IS_CHAN_HT40(chan)) + modesIndex = 3; + else if (IEEE80211_IS_CHAN_108G(chan)) + modesIndex = 5; + else + modesIndex = 4; + } else { + freqIndex = 1; + if (IEEE80211_IS_CHAN_HT40(chan) || + IEEE80211_IS_CHAN_TURBO(chan)) + modesIndex = 2; + else + modesIndex = 1; + } + + /* Set correct Baseband to analog shift setting to access analog chips. */ + OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); + OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); + + regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites); + regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_rxgain, modesIndex, regWrites); + regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_txgain, modesIndex, regWrites); + regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites); +} + +#define AR_BASE_FREQ_2GHZ 2300 +#define AR_BASE_FREQ_5GHZ 4900 +#define AR_SPUR_FEEQ_BOUND_HT40 19 +#define AR_SPUR_FEEQ_BOUND_HT20 10 + + + +/* + * Fill all software cached or static hardware state information. + * Return failure if capabilities are to come from EEPROM and + * cannot be read. + */ +static HAL_BOOL +ar9287FillCapabilityInfo(struct ath_hal *ah) +{ + HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; + + if (!ar5416FillCapabilityInfo(ah)) + return AH_FALSE; + pCap->halNumGpioPins = 10; + pCap->halWowSupport = AH_TRUE; + pCap->halWowMatchPatternExact = AH_TRUE; +#if 0 + pCap->halWowMatchPatternDword = AH_TRUE; +#endif + + pCap->halCSTSupport = AH_TRUE; + pCap->halRifsRxSupport = AH_TRUE; + pCap->halRifsTxSupport = AH_TRUE; + pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ + pCap->halExtChanDfsSupport = AH_TRUE; +#if 0 + /* XXX bluetooth */ + pCap->halBtCoexSupport = AH_TRUE; +#endif + pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ + pCap->hal4kbSplitTransSupport = AH_FALSE; + /* Disable this so Block-ACK works correctly */ + pCap->halHasRxSelfLinkedTail = AH_FALSE; + pCap->halPSPollBroken = AH_FALSE; + pCap->halRxStbcSupport = 1; + pCap->halTxStbcSupport = 1; + + return AH_TRUE; +} + +/* + * This has been disabled - having the HAL flip chainmasks on/off + * when attempting to implement 11n disrupts things. For now, just + * leave this flipped off and worry about implementing TX diversity + * for legacy and MCS0-7 when 11n is fully functioning. + */ +HAL_BOOL +ar9287SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) +{ + return AH_TRUE; +} + +static const char* +ar9287Probe(uint16_t vendorid, uint16_t devid) +{ + if (vendorid == ATHEROS_VENDOR_ID && + (devid == AR9287_DEVID_PCI || devid == AR9287_DEVID_PCIE)) + return "Atheros 9287"; + return AH_NULL; +} +AH_CHIP(AR9287, ar9287Probe, ar9287Attach); diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c new file mode 100644 index 00000000000..d5024b06239 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2008-2010 Atheros Communications Inc. + * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include "opt_ah.h" +#include "ah.h" +#include "ah_internal.h" + +#include "ah_eeprom_v4k.h" + +#include "ar9002/ar9285.h" +#include "ar5416/ar5416reg.h" +#include "ar5416/ar5416phy.h" +#include "ar9002/ar9002phy.h" +//#include "ar9002/ar9287phy.h" + +#include "ar9002/ar9287_cal.h" + + +void +ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset) +{ + /* XXX not required */ +} + +/* + * This is like Merlin but without ADC disable + */ +HAL_BOOL +ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan) +{ + OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + + /* Calibrate the AGC */ + OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, + OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); + + /* Poll for offset calibration complete */ + if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, + AR_PHY_AGC_CONTROL_CAL, 0)) { + HALDEBUG(ah, HAL_DEBUG_RESET, + "%s: offset calibration failed to complete in 1ms; " + "noisy environment?\n", __func__); + return AH_FALSE; + } + + OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + + return AH_TRUE; +} diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h new file mode 100644 index 00000000000..1a7cda25597 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2010 Atheros Communications Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#ifndef __AR9287_CAL_H__ +#define __AR9287_CAL_H__ + +extern void ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset); +extern HAL_BOOL ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan); + +#endif /* __AR9287_CAL_H__ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c new file mode 100644 index 00000000000..938ce635302 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c @@ -0,0 +1,94 @@ +/* + * 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 "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); + + 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); + } +} diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h new file mode 100644 index 00000000000..882f6fe6f01 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h @@ -0,0 +1,25 @@ +/* + * 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); + +#endif /* __AR9287_OLC_H__ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c new file mode 100644 index 00000000000..6e0e104fb09 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -0,0 +1,186 @@ +/* + * 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_reset.h" + +HAL_BOOL +ar9287SetTransmitPower(struct ath_hal *ah, + const struct ieee80211_channel *chan, uint16_t *rfXpdGain) +{ + /* XXX TODO */ + return AH_TRUE; +} + +/* + * Read EEPROM header info and program the device for correct operation + * given the channel value. + */ +HAL_BOOL +ar9287SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) +{ + const HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom; + const struct ar9287_eeprom *eep = &ee->ee_base; + const struct modal_eep_ar9287_header *pModal = &eep->modalHeader; + uint16_t antWrites[AR9287_ANT_16S]; + uint32_t regChainOffset, regval; + uint8_t txRxAttenLocal; + int i, j, offset_num; + + pModal = &eep->modalHeader; + + antWrites[0] = (uint16_t)((pModal->antCtrlCommon >> 28) & 0xF); + antWrites[1] = (uint16_t)((pModal->antCtrlCommon >> 24) & 0xF); + antWrites[2] = (uint16_t)((pModal->antCtrlCommon >> 20) & 0xF); + antWrites[3] = (uint16_t)((pModal->antCtrlCommon >> 16) & 0xF); + antWrites[4] = (uint16_t)((pModal->antCtrlCommon >> 12) & 0xF); + antWrites[5] = (uint16_t)((pModal->antCtrlCommon >> 8) & 0xF); + antWrites[6] = (uint16_t)((pModal->antCtrlCommon >> 4) & 0xF); + antWrites[7] = (uint16_t)(pModal->antCtrlCommon & 0xF); + + offset_num = 8; + + for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 28) & 0xf); + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 10) & 0x3); + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 8) & 0x3); + antWrites[j++] = 0; + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 6) & 0x3); + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 4) & 0x3); + antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 2) & 0x3); + antWrites[j++] = (uint16_t)(pModal->antCtrlChain[i] & 0x3); + } + + OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); + + for (i = 0; i < AR9287_MAX_CHAINS; i++) { + regChainOffset = i * 0x1000; + + OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, + pModal->antCtrlChain[i]); + + OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset, + (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset) + & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | + AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | + SM(pModal->iqCalICh[i], + AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | + SM(pModal->iqCalQCh[i], + AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); + + txRxAttenLocal = pModal->txRxAttenCh[i]; + + OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, + AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, + pModal->bswMargin[i]); + OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, + AR_PHY_GAIN_2GHZ_XATTEN1_DB, + pModal->bswAtten[i]); + OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, + AR9280_PHY_RXGAIN_TXRX_ATTEN, + txRxAttenLocal); + OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, + AR9280_PHY_RXGAIN_TXRX_MARGIN, + pModal->rxTxMarginCh[i]); + } + + + if (IEEE80211_IS_CHAN_HT40(chan)) + OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, + AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); + else + OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, + AR_PHY_SETTLING_SWITCH, pModal->switchSettling); + + OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, + AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); + + OS_REG_WRITE(ah, AR_PHY_RF_CTL4, + SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) + | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) + | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) + | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); + + OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, + AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); + + OS_REG_RMW_FIELD(ah, AR_PHY_CCA, + AR9280_PHY_CCA_THRESH62, pModal->thresh62); + OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, + AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); + + regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH0); + regval &= ~(AR9287_AN_RF2G3_DB1 | + AR9287_AN_RF2G3_DB2 | + AR9287_AN_RF2G3_OB_CCK | + AR9287_AN_RF2G3_OB_PSK | + AR9287_AN_RF2G3_OB_QAM | + AR9287_AN_RF2G3_OB_PAL_OFF); + regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | + SM(pModal->db2, AR9287_AN_RF2G3_DB2) | + SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | + SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | + SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | + SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); + + OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH0, regval); + OS_DELAY(100); /* analog write */ + + regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH1); + regval &= ~(AR9287_AN_RF2G3_DB1 | + AR9287_AN_RF2G3_DB2 | + AR9287_AN_RF2G3_OB_CCK | + AR9287_AN_RF2G3_OB_PSK | + AR9287_AN_RF2G3_OB_QAM | + AR9287_AN_RF2G3_OB_PAL_OFF); + regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | + SM(pModal->db2, AR9287_AN_RF2G3_DB2) | + SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | + SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | + SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | + SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); + + OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH1, regval); + OS_DELAY(100); /* analog write */ + + OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, + AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); + OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, + AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); + + OS_A_REG_RMW_FIELD(ah, AR9287_AN_TOP2, + AR9287_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl); + + return AH_TRUE; +} diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h new file mode 100644 index 00000000000..679fb8cfc81 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2010 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef __AR9287_RESET_H__ +#define __AR9287_RESET_H__ + +extern HAL_BOOL ar9287SetTransmitPower(struct ath_hal *ah, + const struct ieee80211_channel *chan, uint16_t *rfXpdGain); +extern HAL_BOOL ar9287SetBoardValues(struct ath_hal *ah, + const struct ieee80211_channel *chan); + +#endif /* __AR9287_RESET_H__ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287an.h b/sys/dev/ath/ath_hal/ar9002/ar9287an.h new file mode 100644 index 00000000000..ba7a92cbaa6 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287an.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef __AR9287AN_H__ +#define __AR9287AN_H__ + +#define AR9287_AN_RF2G3_CH0 0x7808 +#define AR9287_AN_RF2G3_CH1 0x785c +#define AR9287_AN_RF2G3_DB1 0xE0000000 +#define AR9287_AN_RF2G3_DB1_S 29 +#define AR9287_AN_RF2G3_DB2 0x1C000000 +#define AR9287_AN_RF2G3_DB2_S 26 +#define AR9287_AN_RF2G3_OB_CCK 0x03800000 +#define AR9287_AN_RF2G3_OB_CCK_S 23 +#define AR9287_AN_RF2G3_OB_PSK 0x00700000 +#define AR9287_AN_RF2G3_OB_PSK_S 20 +#define AR9287_AN_RF2G3_OB_QAM 0x000E0000 +#define AR9287_AN_RF2G3_OB_QAM_S 17 +#define AR9287_AN_RF2G3_OB_PAL_OFF 0x0001C000 +#define AR9287_AN_RF2G3_OB_PAL_OFF_S 14 + +#define AR9287_AN_TXPC0 0x7898 +#define AR9287_AN_TXPC0_TXPCMODE 0x0000C000 +#define AR9287_AN_TXPC0_TXPCMODE_S 14 +#define AR9287_AN_TXPC0_TXPCMODE_NORMAL 0 +#define AR9287_AN_TXPC0_TXPCMODE_TEST 1 +#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2 +#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST 3 + +#define AR9287_AN_TOP2 0x78b4 +#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000 +#define AR9287_AN_TOP2_XPABIAS_LVL_S 30 + +#endif diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287phy.h b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h new file mode 100644 index 00000000000..8f28194e44b --- /dev/null +++ b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#ifndef __AR9287PHY_H__ +#define __AR9287PHY_H__ + +/* AR_PHY_CH0_TX_PWRCTRL11, AR_PHY_CH1_TX_PWRCTRL11 */ +#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 +#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 + +#endif From 029377489832a1b863e30af49b334805f47e254f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 09:16:09 +0000 Subject: [PATCH 49/63] Merlin -> Kiwi --- sys/dev/ath/ath_hal/ah_devid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_devid.h b/sys/dev/ath/ath_hal/ah_devid.h index 348dcf38109..c7a98dda4f8 100644 --- a/sys/dev/ath/ath_hal/ah_devid.h +++ b/sys/dev/ath/ath_hal/ah_devid.h @@ -80,8 +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 Merlin */ -#define AR9287_DEVID_PCIE 0x002e /* AR9287 PCI-E Merlin */ +#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 */ From 8143e16401f20486ebba863c17f9ec4dd4f83fd9 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 09:22:59 +0000 Subject: [PATCH 50/63] Fix a bad merge from a previous commit. --- sys/dev/ath/ath_hal/ah_eeprom_9287.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.c b/sys/dev/ath/ath_hal/ah_eeprom_9287.c index f6de55b0236..40550939bb6 100644 --- a/sys/dev/ath/ath_hal/ah_eeprom_9287.c +++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.c @@ -126,10 +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; - return HAL_EINVAL; + case AR_EEP_ANTGAINMAX_2: + ee->ee_antennaGainMax[1] = (int8_t) v; + return HAL_OK; + default: + return HAL_EINVAL; + } } static HAL_BOOL From 232a9d55fb4cd306149ebf38009257e1453d5f30 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 26 May 2011 09:23:01 +0000 Subject: [PATCH 51/63] Marvell 88SE91xx controllers are known to report soft-reset completion without waiting for device readiness (or at least not updating FIS receive area in time). To workaround that, special quirk was added earlier to wait for the FIS receive area update. But it was found that under same PCI ID 0x91231b4b and revision 0x11 there are two completely different chip versions (firmware?): HBA and RAID. The problem is that RAID version in some cases, such as hot-plug, does not update FIS receive area at all! To workaround that, differentiate the chip versions by their capabilities, and, if RAID version found, skip FIS receive area update waiting and read device signature from the PxSIG register instead. This method doesn't work for HBA version when PMP attached, so keep using previous workaround there. --- sys/dev/ahci/ahci.c | 77 ++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 5db3a04a36e..befe6577908 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -119,6 +119,7 @@ static struct { #define AHCI_Q_NOBSYRES 256 #define AHCI_Q_NOAA 512 #define AHCI_Q_NOCOUNT 1024 +#define AHCI_Q_ALTSIG 2048 } ahci_ids[] = { {0x43801002, 0x00, "ATI IXP600", 0}, {0x43901002, 0x00, "ATI IXP700", 0}, @@ -192,7 +193,7 @@ 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}, {0x91821b4b, 0x00, "Marvell 88SE9182", AHCI_Q_NOBSYRES}, {0x06201103, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES}, @@ -398,6 +399,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 +1772,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 +1799,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 +1836,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,7 +1844,8 @@ 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", @@ -1851,9 +1862,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), @@ -1863,26 +1885,9 @@ 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; - } - } - } + /* 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) + if (softreset == 2) ch->eslots |= (1 << slot->slot); ahci_end_transaction(slot, et); return; @@ -1962,7 +1967,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 +2019,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 +2057,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 && From 90759dbed6057002d1c94e42c448e5b158707c23 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 09:27:58 +0000 Subject: [PATCH 52/63] Add the AR9287 chip identification string. --- sys/dev/ath/ath_hal/ah.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c index 13a59f1e92e..e84f9b393ef 100644 --- a/sys/dev/ath/ath_hal/ah.c +++ b/sys/dev/ath/ath_hal/ah.c @@ -117,6 +117,8 @@ ath_hal_mac_name(struct ath_hal *ah) return "9280"; case AR_XSREV_VERSION_KITE: return "9285"; + case AR_XSREV_VERSION_KIWI: + return "9287"; } return "????"; } From 1d4ce50afe533898caf706d233f8a4c7101c1ae7 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 26 May 2011 10:10:10 +0000 Subject: [PATCH 53/63] Add Marvell 88SE9172 chip PCI ID. --- sys/dev/ahci/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index befe6577908..136011cc03b 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -195,6 +195,7 @@ static struct { {0x91201b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|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}, From 141fa00b5f0b753003939b5c7f8d696ac7b08034 Mon Sep 17 00:00:00 2001 From: Aleksandr Rybalko Date: Thu, 26 May 2011 13:54:07 +0000 Subject: [PATCH 54/63] Added myself as src committer. Approved by: adrian (mentor) --- share/misc/committers-src.dot | 3 +++ usr.bin/calendar/calendars/calendar.freebsd | 1 + 2 files changed, 4 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index d450c8a2d67..2fce08f0e6b 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -206,6 +206,7 @@ ps [label="Paul Saab\nps@FreeBSD.org\n2000/02/23"] qingli [label="Qing Li\nqingli@FreeBSD.org\n2005/04/13"] rafan [label="Rong-En Fan\nrafan@FreeBSD.org\n2007/01/31"] randi [label="Randi Harper\nrandi@FreeBSD.org\n2010/04/20"] +ray [label="Aleksandr Rybalko\nray@FreeBSD.org\n2011/05/25"] rdivacky [label="Roman Divacky\nrdivacky@FreeBSD.org\n2008/03/13"] remko [label="Remko Lodder\nremko@FreeBSD.org\n2007/02/23"] rik [label="Roman Kurakin\nrik@FreeBSD.org\n2003/12/18"] @@ -268,6 +269,8 @@ day1 -> rgrimes day1 -> alm day1 -> dg +adrian -> ray + andre -> qingli anholt -> jkim diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 83f3151609b..a04476a1218 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -266,6 +266,7 @@ 09/12 Weongyo Jeong born in Haman, Korea, 1980 09/12 Benedict Christopher Reuschling born in Darmstadt, Germany, 1981 09/12 William C. Fumerola II born in Detroit, Michigan, United States, 1981 +09/15 Aleksandr Rybalko born in Odessa, Ukraine, 1977 09/15 Dima Panov born in Khabarovsk, Russian Federation, 1978 09/17 Maxim Bolotin born in Rostov-on-Don, Russian Federation, 1976 09/18 Matthew Fleming born in Cleveland, Ohio, United States, 1975 From 4551052dbe5257c519183e9ff78da9668a8773bd Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 14:29:05 +0000 Subject: [PATCH 55/63] Flesh out the TX power calibration for the AR9287. I'm assuming for now that the AR9287 is only open-loop TX power control (as mine is) so I've hard-coded the attach path to fail if the NIC is not open-loop. This greatly simplifies the TX calibration path and the amount of code which needs to be ported over. This still isn't complete - the rate calculation code still needs to be ported and it all needs to be glued together. Obtained from: Linux ath9k --- sys/dev/ath/ath_hal/ar9002/ar9287_attach.c | 11 +++ sys/dev/ath/ath_hal/ar9002/ar9287_olc.c | 72 +++++++++++++++++ sys/dev/ath/ath_hal/ar9002/ar9287_olc.h | 6 ++ sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 90 ++++++++++++++++++++++ 4 files changed, 179 insertions(+) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c index 08105606281..daee4148c49 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c @@ -276,6 +276,17 @@ ar9287Attach(uint16_t devid, HAL_SOFTC sc, 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. diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c index 938ce635302..9d65bbde903 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c @@ -30,6 +30,7 @@ #include "ah_internal.h" #include "ah_eeprom_v14.h" +#include "ah_eeprom_9287.h" #include "ar9002/ar9280.h" #include "ar5416/ar5416reg.h" @@ -92,3 +93,74 @@ ar9287olcTemperatureCompensation(struct ath_hal *ah) AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, 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, ¢ers); + + for (numPiers = 0; numPiers < availPiers; numPiers++) { + if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED) + break; + } + + match = ath_ee_getLowerUpperIndex( + (uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)), + pCalChans, numPiers, &idxL, &idxR); + + if (match) { + *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; + } else { + *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + + (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; + } +} + +void +ar9287olcSetPDADCs(struct ath_hal *ah, int32_t txPower, + uint16_t chain) +{ + uint32_t tmpVal; + uint32_t a; + + /* Enable OLPC for chain 0 */ + + tmpVal = OS_REG_READ(ah, 0xa270); + tmpVal = tmpVal & 0xFCFFFFFF; + tmpVal = tmpVal | (0x3 << 24); + OS_REG_WRITE(ah, 0xa270, tmpVal); + + /* Enable OLPC for chain 1 */ + + tmpVal = OS_REG_READ(ah, 0xb270); + tmpVal = tmpVal & 0xFCFFFFFF; + tmpVal = tmpVal | (0x3 << 24); + OS_REG_WRITE(ah, 0xb270, tmpVal); + + /* Write the OLPC ref power for chain 0 */ + + if (chain == 0) { + tmpVal = OS_REG_READ(ah, 0xa398); + tmpVal = tmpVal & 0xff00ffff; + a = (txPower)&0xff; + tmpVal = tmpVal | (a << 16); + OS_REG_WRITE(ah, 0xa398, tmpVal); + } + + /* Write the OLPC ref power for chain 1 */ + + if (chain == 1) { + tmpVal = OS_REG_READ(ah, 0xb398); + tmpVal = tmpVal & 0xff00ffff; + a = (txPower)&0xff; + tmpVal = tmpVal | (a << 16); + OS_REG_WRITE(ah, 0xb398, tmpVal); + } +} diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h index 882f6fe6f01..ff21ce6da5f 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h @@ -21,5 +21,11 @@ extern void ar9287olcInit(struct ath_hal *ah); extern void ar9287olcTemperatureCompensation(struct ath_hal *ah); +extern void ar9287olcGetTxGainIndex(struct ath_hal *ah, + const struct ieee80211_channel *chan, + struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, + uint8_t *pCalChans, uint16_t availPiers, int8_t *pPwr); +extern void ar9287olcSetPDADCs(struct ath_hal *ah, + int32_t txPower, uint16_t chain); #endif /* __AR9287_OLC_H__ */ diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c index 6e0e104fb09..26fb0780806 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -33,13 +33,103 @@ #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; +} + HAL_BOOL ar9287SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan, uint16_t *rfXpdGain) { + int16_t txPowerIndexOffset = 0; + /* XXX TODO */ + + /* Fetch per-rate power table for the given channel */ + + /* Set open-loop TX power control calibration */ + ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset); + + /* Calculate regulatory maximum power level */ + + /* Kiwi TX power starts at -5 dBm */ + + /* Write TX power registers */ + return AH_TRUE; } From 2ec6a5984c44d49b1e4063bccef47b2a1b33ddd1 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 26 May 2011 14:34:22 +0000 Subject: [PATCH 56/63] Add a missing isync. --- sys/powerpc/aim/trap_subr64.S | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 64e4ac1d208..7156edb45f8 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -519,6 +519,7 @@ CNAME(trapexit): mfmsr %r3 andi. %r3,%r3,~PSL_EE@l mtmsr %r3 + isync /* Test AST pending: */ ld %r5,FRAME_SRR1+48(%r1) mtcr %r5 From ea18ed263e747911ce72b418ace82722d020bbe0 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 15:01:37 +0000 Subject: [PATCH 57/63] Flesh out ar9287SetTransmitPower() based on the AR9285 routine. Hard-code the per-rate TX power at 5dBm for now so testing can be done. This passes initial TX testing in 11g mode (but, obviously, at 5dBm.) --- sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 122 ++++++++++++++++++++-- 1 file changed, 116 insertions(+), 6 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c index 26fb0780806..e477a05c4fe 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -111,26 +111,136 @@ ar9287SetPowerCalTable(struct ath_hal *ah, *pTxPowerIndexOffset = 0; } +/* + * Fetch the maximum TX power per rate. + * + * For now, this is hard-coded at 5dBm until this code has been ported + * from Atheros/ath9k and tested. + */ +static HAL_BOOL +ar9285SetPowerPerRateTable(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) +{ + int i; + + /* For now, set all tx power rates to 5 dBm */ + for (i = 0; i < Ar5416RateSize; i++) + ratesArray[i] = 10; + + return AH_TRUE; +} + +/* + * 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) { - int16_t txPowerIndexOffset = 0; +#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) +#define N(a) (sizeof (a) / sizeof (a[0])) - /* XXX TODO */ + 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 (!ar9285SetPowerPerRateTable(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 open-loop TX power control calibration */ + /* Set TX power control calibration curves for each TX chain */ ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset); - /* Calculate regulatory maximum power level */ + /* Calculate maximum power level */ + maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); + maxPower = AH_MAX(maxPower, ratesArray[rate1l]); - /* Kiwi TX power starts at -5 dBm */ + if (IEEE80211_IS_CHAN_HT40(chan)) + maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); - /* Write TX power registers */ + 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 } /* From f1285519e2ce6d66efc93317afe922e81fa9d5c2 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 15:55:27 +0000 Subject: [PATCH 58/63] Bring over the AR5416 per-rate TX power code, modified to use the AR9287 EEPROM layout. The AR9287 only supports 2ghz, so I've removed the 5ghz code (but left the 5ghz edge flags in there for now) and hard-coded the 2ghz-only path. Whilst I'm there, fix a typo (ar9285->ar9287.) This meets basic TX throughput testing - iperf TX tests == 27-28mbit in 11g, matching the rest of my 11g kit. --- sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 208 +++++++++++++++++++++- 1 file changed, 199 insertions(+), 9 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c index e477a05c4fe..b152c2d60c4 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -111,30 +111,220 @@ ar9287SetPowerCalTable(struct ath_hal *ah, *pTxPowerIndexOffset = 0; } + +/* XXX hard-coded values? */ +#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 +#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 + /* - * Fetch the maximum TX power per rate. + * ar9287SetPowerPerRateTable * - * For now, this is hard-coded at 5dBm until this code has been ported - * from Atheros/ath9k and tested. + * 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 -ar9285SetPowerPerRateTable(struct ath_hal *ah, +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 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; - /* For now, set all tx power rates to 5 dBm */ - for (i = 0; i < Ar5416RateSize; i++) - ratesArray[i] = 10; +#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, ¢ers); + + /* 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; + break; + case 3: + scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + break; + 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 +#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN + /* * This is based off of the AR5416/AR9285 code and likely could * be unified in the future. @@ -175,7 +365,7 @@ ar9287SetTransmitPower(struct ath_hal *ah, ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; /* Fetch per-rate power table for the given channel */ - if (!ar9285SetPowerPerRateTable(ah, pEepData, chan, + if (! ar9287SetPowerPerRateTable(ah, pEepData, chan, &ratesArray[0],cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit)) { From a194c9f7090b59b6fd137d25fe5d6a5bf3461042 Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Thu, 26 May 2011 16:27:00 +0000 Subject: [PATCH 59/63] Close a race between libzfs and mountd when updating NFS exports. - Flush the file descriptor for the new ZFS exports file before sending a SIGHUP to mountd. Reviewed by: pjd Approved by: ken MFC after: 3 days --- cddl/compat/opensolaris/misc/fsshare.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cddl/compat/opensolaris/misc/fsshare.c b/cddl/compat/opensolaris/misc/fsshare.c index e8faa928d6f..c3247f91fec 100644 --- a/cddl/compat/opensolaris/misc/fsshare.c +++ b/cddl/compat/opensolaris/misc/fsshare.c @@ -223,6 +223,7 @@ out: error = errno; unlink(tmpfile); } else { + fflush(newfd); /* * Send SIGHUP to mountd, but unlock exports file later. */ From fe5237edef926aaabc3ccc2aa6fac9390f2f9de4 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 16:52:37 +0000 Subject: [PATCH 60/63] Add some open-loop TX power debugging for AR9287. --- sys/dev/ath/ath_hal/ar9002/ar9287_olc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c index 9d65bbde903..cbbe017667e 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c @@ -70,6 +70,9 @@ ar9287olcTemperatureCompensation(struct ath_hal *ah) 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 @@ -91,6 +94,8 @@ ar9287olcTemperatureCompensation(struct ath_hal *ah) 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); } } From 1ecf8ddf5abd58bfe7d3be9fb6f9c99511245ead Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 16:55:44 +0000 Subject: [PATCH 61/63] Make sure only two chains are calibrated for the AR9287. --- sys/dev/ath/ath_hal/ar5416/ar5416_cal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c index ee61c3013cd..1356c7d1081 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c @@ -594,8 +594,8 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan) if (AR_SREV_KITE(ah)) { /* Kite has only one chain */ chainmask = 0x9; - } else if (AR_SREV_MERLIN(ah)) { - /* Merlin has only two chains */ + } else if (AR_SREV_MERLIN(ah) || AR_SREV_KIWI(ah)) { + /* Merlin/Kiwi has only two chains */ chainmask = 0x1B; } else { chainmask = 0x3F; From 0c50156f918ad36ec85373ea1909c2a554b35db2 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 26 May 2011 16:59:42 +0000 Subject: [PATCH 62/63] Remove the three-chain scaled power check for the AR9287 - it isn't needed. --- sys/dev/ath/ath_hal/ar9002/ar9287_reset.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c index b152c2d60c4..34a723aa80e 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c @@ -114,7 +114,6 @@ ar9287SetPowerCalTable(struct ath_hal *ah, /* XXX hard-coded values? */ #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 -#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* * ar9287SetPowerPerRateTable @@ -186,10 +185,6 @@ ar9287SetPowerPerRateTable(struct ath_hal *ah, break; case 2: scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; - break; - case 3: - scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; - break; default: return AH_FALSE; /* Unsupported number of chains */ } @@ -323,7 +318,6 @@ ar9287SetPowerPerRateTable(struct ath_hal *ah, } #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN -#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN /* * This is based off of the AR5416/AR9285 code and likely could From 5bdddc29c26ade6abd6a0a7970b9fae5b8776f56 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 26 May 2011 17:02:56 +0000 Subject: [PATCH 63/63] Ignore MCR[6] during the probe to fix a false negative. Bit 6 of the MCR register on the Sunix Sun1699 chip tends to be set but doesn't seem to have a function. That is, FreeBSD just works (provided the correct RCLK is used) regardless. PR: kern/129663 Diagnostics: Eygene Ryabinkin MFC after: 3 days --- sys/dev/uart/uart_dev_ns8250.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index 3cdd5ad3c48..489be29a70a 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -242,8 +242,14 @@ ns8250_probe(struct uart_bas *bas) val = uart_getreg(bas, REG_IIR); if (val & 0x30) return (ENXIO); + /* + * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699 + * chip, but otherwise doesn't seem to have a function. In + * other words, uart(4) works regardless. Ignore that bit so + * the probe succeeds. + */ val = uart_getreg(bas, REG_MCR); - if (val & 0xe0) + if (val & 0xa0) return (ENXIO); return (0);