summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-26 17:38:00 +0000
committerattilio <attilio@FreeBSD.org>2011-05-26 17:38:00 +0000
commit867c6223e7e4f6682389d40926782fd537ffc3ad (patch)
tree87423ad4498424494102d7b58615c0df44019d32 /sys/dev
parentc0038ec50d088a2152d05e1da7d5b4cec45e8d27 (diff)
parentd7214daa609442aa65fdbb054db56a3ffc1ee75a (diff)
downloadFreeBSD-src-867c6223e7e4f6682389d40926782fd537ffc3ad.zip
FreeBSD-src-867c6223e7e4f6682389d40926782fd537ffc3ad.tar.gz
MFC
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ahci/ahci.c101
-rw-r--r--sys/dev/ath/ath_hal/ah.c2
-rw-r--r--sys/dev/ath/ath_hal/ah.h35
-rw-r--r--sys/dev/ath/ath_hal/ah_devid.h2
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom.h4
-rw-r--r--sys/dev/ath/ath_hal/ah_eeprom_9287.c42
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h12
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.h3
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_attach.c3
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_misc.c20
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_ani.c17
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c7
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.c4
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_reset.c54
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c43
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416desc.h23
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416phy.h2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416reg.h60
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9160_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9280_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_phy.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.c392
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.h62
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287.ini783
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_attach.c468
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_cal.c73
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_cal.h33
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_olc.c171
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_olc.h31
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.c570
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_reset.h27
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287an.h49
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287phy.h26
-rw-r--r--sys/dev/ath/if_athvar.h6
-rw-r--r--sys/dev/msk/if_msk.c33
-rw-r--r--sys/dev/mvs/mvs.c44
-rw-r--r--sys/dev/siis/siis.c25
-rw-r--r--sys/dev/sound/pci/hda/hdac.c26
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c8
40 files changed, 3104 insertions, 165 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 2a06492..136011c 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -119,6 +119,7 @@ static struct {
#define AHCI_Q_NOBSYRES 256
#define AHCI_Q_NOAA 512
#define AHCI_Q_NOCOUNT 1024
+#define AHCI_Q_ALTSIG 2048
} ahci_ids[] = {
{0x43801002, 0x00, "ATI IXP600", 0},
{0x43901002, 0x00, "ATI IXP700", 0},
@@ -192,8 +193,9 @@ static struct {
{0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE | AHCI_Q_4CH |
AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
{0x91201b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_NOBSYRES},
- {0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES},
+ {0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES|AHCI_Q_ALTSIG},
{0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES},
+ {0x91721b4b, 0x00, "Marvell 88SE9172", AHCI_Q_NOBSYRES},
{0x91821b4b, 0x00, "Marvell 88SE9182", AHCI_Q_NOBSYRES},
{0x06201103, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
{0x06201b4b, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
@@ -398,6 +400,13 @@ ahci_attach(device_t dev)
if (ctlr->caps & AHCI_CAP_EMS)
ctlr->capsem = ATA_INL(ctlr->r_mem, AHCI_EM_CTL);
ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI);
+
+ /* Identify and set separate quirks for HBA and RAID f/w Marvells. */
+ if ((ctlr->quirks & AHCI_Q_NOBSYRES) &&
+ (ctlr->quirks & AHCI_Q_ALTSIG) &&
+ (ctlr->caps & AHCI_CAP_SPM) == 0)
+ ctlr->quirks &= ~AHCI_Q_NOBSYRES;
+
if (ctlr->quirks & AHCI_Q_1CH) {
ctlr->caps &= ~AHCI_CAP_NPMASK;
ctlr->ichannels &= 0x01;
@@ -1764,7 +1773,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
struct ahci_cmd_list *clp;
union ccb *ccb = slot->ccb;
int port = ccb->ccb_h.target_id & 0x0f;
- int fis_size, i;
+ int fis_size, i, softreset;
uint8_t *fis = ch->dma.rfis + 0x40;
uint8_t val;
@@ -1791,17 +1800,20 @@ ahci_execute_transaction(struct ahci_slot *slot)
if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
(ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
if (ccb->ataio.cmd.control & ATA_A_RESET) {
+ softreset = 1;
/* Kick controller into sane state */
ahci_stop(dev);
ahci_clo(dev);
ahci_start(dev, 0);
clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY;
} else {
+ softreset = 2;
/* Prepare FIS receive area for check. */
for (i = 0; i < 20; i++)
fis[i] = 0xff;
}
- }
+ } else
+ softreset = 0;
clp->bytecount = 0;
clp->cmd_table_phys = htole64(ch->dma.work_bus + AHCI_CT_OFFSET +
(AHCI_CT_SIZE * slot->slot));
@@ -1825,8 +1837,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
ATA_OUTL(ch->r_mem, AHCI_P_CI, (1 << slot->slot));
/* Device reset commands doesn't interrupt. Poll them. */
if (ccb->ccb_h.func_code == XPT_ATA_IO &&
- (ccb->ataio.cmd.command == ATA_DEVICE_RESET ||
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL))) {
+ (ccb->ataio.cmd.command == ATA_DEVICE_RESET || softreset)) {
int count, timeout = ccb->ccb_h.timeout * 100;
enum ahci_err_type et = AHCI_ERR_NONE;
@@ -1834,10 +1845,13 @@ ahci_execute_transaction(struct ahci_slot *slot)
DELAY(10);
if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot)))
break;
- if (ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) {
+ if ((ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) &&
+ softreset != 1) {
+#if 0
device_printf(ch->dev,
"Poll error on slot %d, TFD: %04x\n",
slot->slot, ATA_INL(ch->r_mem, AHCI_P_TFD));
+#endif
et = AHCI_ERR_TFE;
break;
}
@@ -1849,9 +1863,20 @@ ahci_execute_transaction(struct ahci_slot *slot)
break;
}
}
+
+ /* Marvell controllers do not wait for readyness. */
+ if ((ch->quirks & AHCI_Q_NOBSYRES) && softreset == 2 &&
+ et == AHCI_ERR_NONE) {
+ while ((val = fis[2]) & ATA_S_BUSY) {
+ DELAY(10);
+ if (count++ >= timeout)
+ break;
+ }
+ }
+
if (timeout && (count >= timeout)) {
- device_printf(ch->dev,
- "Poll timeout on slot %d\n", slot->slot);
+ device_printf(dev, "Poll timeout on slot %d port %d\n",
+ slot->slot, port);
device_printf(dev, "is %08x cs %08x ss %08x "
"rs %08x tfd %02x serr %08x\n",
ATA_INL(ch->r_mem, AHCI_P_IS),
@@ -1861,30 +1886,11 @@ ahci_execute_transaction(struct ahci_slot *slot)
ATA_INL(ch->r_mem, AHCI_P_SERR));
et = AHCI_ERR_TIMEOUT;
}
- /* Marvell controllers do not wait for readyness. */
- if ((ch->quirks & AHCI_Q_NOBSYRES) &&
- (ccb->ccb_h.func_code == XPT_ATA_IO) &&
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
- (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
- while ((val = fis[2]) & (ATA_S_BUSY | ATA_S_DRQ)) {
- DELAY(10);
- if (count++ >= timeout) {
- device_printf(dev, "device is not "
- "ready after soft-reset: "
- "tfd = %08x\n", val);
- et = AHCI_ERR_TIMEOUT;
- break;
- }
- }
- }
- ahci_end_transaction(slot, et);
+
/* Kick controller into sane state and enable FBS. */
- if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
- (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
- (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
- ahci_stop(ch->dev);
- ahci_start(ch->dev, 1);
- }
+ if (softreset == 2)
+ ch->eslots |= (1 << slot->slot);
+ ahci_end_transaction(slot, et);
return;
}
/* Start command execution timeout */
@@ -1962,7 +1968,8 @@ ahci_timeout(struct ahci_slot *slot)
return;
}
- device_printf(dev, "Timeout on slot %d\n", slot->slot);
+ device_printf(dev, "Timeout on slot %d port %d\n",
+ slot->slot, slot->ccb->ccb_h.target_id & 0x0f);
device_printf(dev, "is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
ATA_INL(ch->r_mem, AHCI_P_IS), ATA_INL(ch->r_mem, AHCI_P_CI),
ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots,
@@ -2013,6 +2020,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
union ccb *ccb = slot->ccb;
struct ahci_cmd_list *clp;
int lastto;
+ uint32_t sig;
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -2050,6 +2058,20 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
res->lba_high_exp = fis[10];
res->sector_count = fis[12];
res->sector_count_exp = fis[13];
+
+ /*
+ * Some weird controllers do not return signature in
+ * FIS receive area. Read it from PxSIG register.
+ */
+ if ((ch->quirks & AHCI_Q_ALTSIG) &&
+ (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
+ (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
+ sig = ATA_INL(ch->r_mem, AHCI_P_SIG);
+ res->lba_high = sig >> 24;
+ res->lba_mid = sig >> 16;
+ res->lba_low = sig >> 8;
+ res->sector_count = sig;
+ }
} else
bzero(res, sizeof(*res));
if ((ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) == 0 &&
@@ -2169,13 +2191,6 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- ahci_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there was fatal error - reset port. */
@@ -2185,6 +2200,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
/* if we have slots in error, we can reinit port. */
if (ch->eslots != 0) {
ahci_stop(dev);
+ ahci_clo(dev);
ahci_start(dev, 1);
}
/* if there commands on hold, we can do READ LOG. */
@@ -2195,6 +2211,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != AHCI_ERR_TIMEOUT)
ahci_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ ahci_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
/* Start PM timer. */
if (ch->numrslots == 0 && ch->pm_level > 3 &&
(ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 13a59f1..e84f9b3 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -117,6 +117,8 @@ ath_hal_mac_name(struct ath_hal *ah)
return "9280";
case AR_XSREV_VERSION_KITE:
return "9285";
+ case AR_XSREV_VERSION_KIWI:
+ return "9287";
}
return "????";
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index 85790e1..7bf2843 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -669,6 +669,41 @@ typedef struct {
} HAL_CHANNEL_SURVEY;
/*
+ * ANI commands.
+ *
+ * These are used both internally and externally via the diagnostic
+ * API.
+ *
+ * Note that this is NOT the ANI commands being used via the INTMIT
+ * capability - that has a different mapping for some reason.
+ */
+typedef enum {
+ HAL_ANI_PRESENT = 0, /* is ANI support present */
+ HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level */
+ HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 2, /* enable/disable */
+ HAL_ANI_CCK_WEAK_SIGNAL_THR = 3, /* enable/disable */
+ HAL_ANI_FIRSTEP_LEVEL = 4, /* set level */
+ HAL_ANI_SPUR_IMMUNITY_LEVEL = 5, /* set level */
+ HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */
+ HAL_ANI_PHYERR_RESET = 7, /* reset phy error stats */
+} HAL_ANI_CMD;
+
+/*
+ * This is the layout of the ANI INTMIT capability.
+ *
+ * Notice that the command values differ to HAL_ANI_CMD.
+ */
+typedef enum {
+ HAL_CAP_INTMIT_PRESENT = 0,
+ HAL_CAP_INTMIT_ENABLE = 1,
+ HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL = 2,
+ HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL = 3,
+ HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR = 4,
+ HAL_CAP_INTMIT_FIRSTEP_LEVEL = 5,
+ HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL = 6
+} HAL_CAP_INTMIT_CMD;
+
+/*
* Hardware Access Layer (HAL) API.
*
* Clients of the HAL call ath_hal_attach to obtain a reference to an
diff --git a/sys/dev/ath/ath_hal/ah_devid.h b/sys/dev/ath/ath_hal/ah_devid.h
index 64033f3..c7a98dd 100644
--- a/sys/dev/ath/ath_hal/ah_devid.h
+++ b/sys/dev/ath/ath_hal/ah_devid.h
@@ -80,6 +80,8 @@
#define AR9280_DEVID_PCIE 0x002a /* AR9280 PCI-E Merlin */
#define AR9285_DEVID_PCIE 0x002b /* AR9285 PCI-E Kite */
#define AR2427_DEVID_PCIE 0x002c /* AR2427 PCI-E w/ 802.11n bonded out */
+#define AR9287_DEVID_PCI 0x002d /* AR9227 PCI Kiwi */
+#define AR9287_DEVID_PCIE 0x002e /* AR9287 PCI-E Kiwi */
#define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */
#define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */
diff --git a/sys/dev/ath/ath_hal/ah_eeprom.h b/sys/dev/ath/ath_hal/ah_eeprom.h
index c7fe385..2ca0589 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom.h
+++ b/sys/dev/ath/ath_hal/ah_eeprom.h
@@ -101,7 +101,9 @@ enum {
AR_EEP_ANTGAINMAX_2, /* int8_t* */
AR_EEP_WRITEPROTECT, /* use ath_hal_eepromGetFlag */
AR_EEP_PWR_TABLE_OFFSET,/* int8_t* */
- AR_EEP_PWDCLKIND /* uint8_t* */
+ AR_EEP_PWDCLKIND, /* uint8_t* */
+ AR_EEP_TEMPSENSE_SLOPE, /* int8_t* */
+ AR_EEP_TEMPSENSE_SLOPE_PAL_ON, /* int8_t* */
};
typedef struct {
diff --git a/sys/dev/ath/ath_hal/ah_eeprom_9287.c b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
index e8c5e54..4055093 100644
--- a/sys/dev/ath/ath_hal/ah_eeprom_9287.c
+++ b/sys/dev/ath/ath_hal/ah_eeprom_9287.c
@@ -63,28 +63,10 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val)
return pBase->opCapFlags;
case AR_EEP_RFSILENT:
return pBase->rfSilent;
-#if 0
- case AR_EEP_OB_5:
- return pModal[CHAN_A_IDX].ob;
- case AR_EEP_DB_5:
- return pModal[CHAN_A_IDX].db;
- case AR_EEP_OB_2:
- return pModal[CHAN_B_IDX].ob;
- case AR_EEP_DB_2:
- return pModal[CHAN_B_IDX].db;
-#endif
case AR_EEP_TXMASK:
return pBase->txMask;
case AR_EEP_RXMASK:
return pBase->rxMask;
-#if 0
- case AR_EEP_RXGAIN_TYPE:
- return IS_VERS(>=, AR5416_EEP_MINOR_VER_17) ?
- pBase->rxGainType : AR5416_EEP_RXGAIN_ORIG;
- case AR_EEP_TXGAIN_TYPE:
- return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ?
- pBase->txGainType : AR5416_EEP_TXGAIN_ORIG;
-#endif
case AR_EEP_OL_PWRCTRL:
HALASSERT(val == AH_NULL);
return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO;
@@ -117,6 +99,18 @@ v9287EepromGet(struct ath_hal *ah, int param, void *val)
case AR_EEP_PWR_TABLE_OFFSET:
*(int8_t *) val = pBase->pwrTableOffset;
return HAL_OK;
+ case AR_EEP_TEMPSENSE_SLOPE:
+ if (IS_VERS(>=, AR9287_EEP_MINOR_VER_2))
+ *(int8_t *)val = pBase->tempSensSlope;
+ else
+ *(int8_t *)val = 0;
+ return HAL_OK;
+ case AR_EEP_TEMPSENSE_SLOPE_PAL_ON:
+ if (IS_VERS(>=, AR9287_EEP_MINOR_VER_3))
+ *(int8_t *)val = pBase->tempSensSlopePalOn;
+ else
+ *(int8_t *)val = 0;
+ return HAL_OK;
default:
HALASSERT(0);
return HAL_EINVAL;
@@ -132,14 +126,12 @@ v9287EepromSet(struct ath_hal *ah, int param, int v)
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (param) {
- case AR_EEP_ANTGAINMAX_2:
- ee->ee_antennaGainMax[1] = (int8_t) v;
- return HAL_OK;
- case AR_EEP_ANTGAINMAX_5:
- ee->ee_antennaGainMax[0] = (int8_t) v;
- return HAL_OK;
+ case AR_EEP_ANTGAINMAX_2:
+ ee->ee_antennaGainMax[1] = (int8_t) v;
+ return HAL_OK;
+ default:
+ return HAL_EINVAL;
}
- return HAL_EINVAL;
}
static HAL_BOOL
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index b4cc817..b994eab 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -418,18 +418,6 @@ extern HAL_BOOL ath_hal_setTxQProps(struct ath_hal *ah,
extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah,
HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi);
-typedef enum {
- HAL_ANI_PRESENT = 0x1, /* is ANI support present */
- HAL_ANI_NOISE_IMMUNITY_LEVEL = 0x2, /* set level */
- HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, /* enable/disable */
- HAL_ANI_CCK_WEAK_SIGNAL_THR = 0x8, /* enable/disable */
- HAL_ANI_FIRSTEP_LEVEL = 0x10, /* set level */
- HAL_ANI_SPUR_IMMUNITY_LEVEL = 0x20, /* set level */
- HAL_ANI_MODE = 0x40, /* 0 => manual, 1 => auto (XXX do not change) */
- HAL_ANI_PHYERR_RESET =0x80, /* reset phy error stats */
- HAL_ANI_ALL = 0xff
-} HAL_ANI_CMD;
-
#define HAL_SPUR_VAL_MASK 0x3FFF
#define HAL_SPUR_CHAN_WIDTH 87
#define HAL_BIN_WIDTH_BASE_100HZ 3125
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
index e226816..5bdfcb4 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
@@ -320,6 +320,9 @@ struct ath_hal_5212 {
struct ar5212AniState *ah_curani; /* cached last reference */
struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */
+ /* AR5416 uses some of the AR5212 ANI code; these are the ANI methods */
+ HAL_BOOL (*ah_aniControl) (struct ath_hal *, HAL_ANI_CMD cmd, int param);
+
/*
* Transmit power state. Note these are maintained
* here so they can be retrieved by diagnostic tools.
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
index 4b0fcbe..5f85522 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
@@ -203,6 +203,9 @@ ar5212AniSetup(struct ath_hal *ah)
ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE);
} else
ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
+
+ /* Set overridable ANI methods */
+ AH5212(ah)->ah_aniControl = ar5212AniControl;
}
/*
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
index 0d6adc1..518d079 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
@@ -880,16 +880,16 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
return HAL_OK;
case HAL_CAP_INTMIT: /* interference mitigation */
switch (capability) {
- case 0: /* hardware capability */
+ case HAL_CAP_INTMIT_PRESENT: /* hardware capability */
return HAL_OK;
- case 1:
+ case HAL_CAP_INTMIT_ENABLE:
return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
HAL_OK : HAL_ENXIO;
- case 2: /* HAL_ANI_NOISE_IMMUNITY_LEVEL */
- case 3: /* HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION */
- case 4: /* HAL_ANI_CCK_WEAK_SIGNAL_THR */
- case 5: /* HAL_ANI_FIRSTEP_LEVEL */
- case 6: /* HAL_ANI_SPUR_IMMUNITY_LEVEL */
+ case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL:
+ case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL:
+ case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR:
+ case HAL_CAP_INTMIT_FIRSTEP_LEVEL:
+ case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL:
ani = ar5212AniGetCurrentState(ah);
if (ani == AH_NULL)
return HAL_ENXIO;
@@ -980,6 +980,8 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
return AH_TRUE;
case HAL_CAP_INTMIT: { /* interference mitigation */
+ /* This maps the public ANI commands to the internal ANI commands */
+ /* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */
static const HAL_ANI_CMD cmds[] = {
HAL_ANI_PRESENT,
HAL_ANI_MODE,
@@ -990,7 +992,7 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
HAL_ANI_SPUR_IMMUNITY_LEVEL,
};
return capability < N(cmds) ?
- ar5212AniControl(ah, cmds[capability], setting) :
+ AH5212(ah)->ah_aniControl(ah, cmds[capability], setting) :
AH_FALSE;
}
case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
@@ -1053,7 +1055,7 @@ ar5212GetDiagState(struct ath_hal *ah, int request,
case HAL_DIAG_ANI_CMD:
if (argsize != 2*sizeof(uint32_t))
return AH_FALSE;
- ar5212AniControl(ah, ((const uint32_t *)args)[0],
+ AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0],
((const uint32_t *)args)[1]);
return AH_TRUE;
case HAL_DIAG_ANI_PARAMS:
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
index 3a8f785..e2c8592 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c
@@ -175,9 +175,17 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params = aniState->params;
+ /* Check whether the particular function is enabled */
+ if (((1 << cmd) & AH5416(ah)->ah_ani_function) == 0) {
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: command %d disabled\n",
+ __func__, cmd);
+ HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd %d; mask %x\n", __func__, cmd, AH5416(ah)->ah_ani_function);
+ return AH_FALSE;
+ }
+
OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd);
- switch (cmd & AH5416(ah)->ah_ani_function) {
+ switch (cmd) {
case HAL_ANI_NOISE_IMMUNITY_LEVEL: {
u_int level = param;
@@ -356,14 +364,14 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah)
aniState = ahp->ah_curani;
params = aniState->params;
/* First, raise noise immunity level, up to max */
- if ((AH5416(ah)->ah_ani_function & HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL)) &&
(aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1);
return;
}
/* then, raise spur immunity level, up to max */
- if ((AH5416(ah)->ah_ani_function & HAL_ANI_SPUR_IMMUNITY_LEVEL) &&
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL)) &&
(aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
aniState->spurImmunityLevel + 1);
@@ -443,7 +451,8 @@ ar5416AniCckErrTrigger(struct ath_hal *ah)
/* first, raise noise immunity level, up to max */
aniState = ahp->ah_curani;
params = aniState->params;
- if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
+ if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
+ aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1);
return;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index 6779bf9..dc1a5ff 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -58,7 +58,7 @@ ar5416AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
@@ -199,7 +199,10 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
/* Enable all ANI functions to begin with */
- AH5416(ah)->ah_ani_function = HAL_ANI_ALL;
+ AH5416(ah)->ah_ani_function = 0xffffffff;
+
+ /* Set overridable ANI methods */
+ AH5212(ah)->ah_aniControl = ar5416AniControl;
}
uint32_t
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
index ee61c30..1356c7d 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
@@ -594,8 +594,8 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
if (AR_SREV_KITE(ah)) {
/* Kite has only one chain */
chainmask = 0x9;
- } else if (AR_SREV_MERLIN(ah)) {
- /* Merlin has only two chains */
+ } else if (AR_SREV_MERLIN(ah) || AR_SREV_KIWI(ah)) {
+ /* Merlin/Kiwi has only two chains */
chainmask = 0x1B;
} else {
chainmask = 0x3F;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
index d2ae351..1da686a 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
@@ -167,6 +167,17 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AH5416(ah)->ah_writeIni(ah, chan);
+ if(AR_SREV_KIWI_13_OR_LATER(ah) ) {
+ /* Enable ASYNC FIFO */
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+ OS_REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+ OS_REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ }
+
/* Override ini values (that can be overriden in this fashion) */
ar5416OverrideIni(ah, chan);
@@ -258,6 +269,12 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) |
saveLedState);
+ /* Start TSF2 for generic timer 8-15 */
+#ifdef NOTYET
+ if (AR_SREV_KIWI(ah))
+ ar5416StartTsf2(ah);
+#endif
+
/* Restore previous antenna */
OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
@@ -292,6 +309,41 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* This may override the AR_DIAG_SW register */
ar5416InitUserSettings(ah);
+ if (AR_SREV_KIWI_13_OR_LATER(ah)) {
+ /*
+ * Enable ASYNC FIFO
+ *
+ * If Async FIFO is enabled, the following counters change
+ * as MAC now runs at 117 Mhz instead of 88/44MHz when
+ * async FIFO is disabled.
+ *
+ * Overwrite the delay/timeouts initialized in ProcessIni()
+ * above.
+ */
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+ AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+ AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+ AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+ OS_REG_WRITE(ah, AR_TIME_OUT,
+ AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+ OS_REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+ OS_REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+ AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+ OS_REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+ AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+ }
+
+ if (AR_SREV_KIWI_13_OR_LATER(ah)) {
+ /* Enable AGGWEP to accelerate encryption engine */
+ OS_REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+ }
+
+
/*
* disable seq number generation in hw
*/
@@ -2576,7 +2628,7 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
if (!AR_SREV_9271(ah))
val &= ~AR_PCU_MISC_MODE2_HWWAR1;
- if (AR_SREV_9287_11_OR_LATER(ah))
+ if (AR_SREV_KIWI_11_OR_LATER(ah))
val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
index 3cf7da9..48956c5 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
@@ -208,10 +208,11 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(ahp->ah_tx_chainmask, AR_ChainSel2)
| SM(ahp->ah_tx_chainmask, AR_ChainSel3)
;
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = (txPower << 24); /* XXX? */
- ads->ds_ctl10 = (txPower << 24); /* XXX? */
- ads->ds_ctl11 = (txPower << 24); /* XXX? */
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
+
if (keyIx != HAL_TXKEYIX_INVALID) {
/* XXX validate key index */
ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
@@ -232,11 +233,16 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
}
+ /*
+ * Set the TX antenna to 0 for Kite
+ * To preserve existing behaviour, also set the TPC bits to 0;
+ * when TPC is enabled these should be filled in appropriately.
+ */
if (AR_SREV_KITE(ah)) {
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = 0;
- ads->ds_ctl10 = 0;
- ads->ds_ctl11 = 0;
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
return AH_TRUE;
#undef RTSCTS
@@ -410,10 +416,10 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
/* NB: no V1 WAR */
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = (txPower << 24);
- ads->ds_ctl10 = (txPower << 24);
- ads->ds_ctl11 = (txPower << 24);
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
ads->ds_ctl6 &= ~(0xffff);
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
@@ -424,11 +430,16 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
}
+ /*
+ * Set the TX antenna to 0 for Kite
+ * To preserve existing behaviour, also set the TPC bits to 0;
+ * when TPC is enabled these should be filled in appropriately.
+ */
if (AR_SREV_KITE(ah)) {
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = 0;
- ads->ds_ctl10 = 0;
- ads->ds_ctl11 = 0;
+ ads->ds_ctl8 = SM(0, AR_AntCtl0);
+ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
+ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
+ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
return AH_TRUE;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
index 76f5080..105c5d6 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h
@@ -205,6 +205,29 @@ struct ar5416_desc {
#define AR_STBC2 0x40000000
#define AR_STBC3 0x80000000
+/* ds_ctl8 */
+#define AR_AntCtl0 0x00ffffff
+#define AR_AntCtl0_S 0
+/* Xmit 0 TPC is AR_XmitPower in ctl0 */
+
+/* ds_ctl9 */
+#define AR_AntCtl1 0x00ffffff
+#define AR_AntCtl1_S 0
+#define AR_XmitPower1 0xff000000
+#define AR_XmitPower1_S 24
+
+/* ds_ctl10 */
+#define AR_AntCtl2 0x00ffffff
+#define AR_AntCtl2_S 0
+#define AR_XmitPower2 0xff000000
+#define AR_XmitPower2_S 24
+
+/* ds_ctl11 */
+#define AR_AntCtl3 0x00ffffff
+#define AR_AntCtl3_S 0
+#define AR_XmitPower3 0xff000000
+#define AR_XmitPower3_S 24
+
/*************
* TX Status *
*************/
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
index 86643f0..2c419d7 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
@@ -301,4 +301,6 @@
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+#define AR_PHY_MODE_ASYNCFIFO 0x80 /* Enable async fifo */
+
#endif /* _DEV_ATH_AR5416PHY_H_ */
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
index 9921366..561c5b4 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
@@ -219,6 +219,10 @@
#define AR_AHB_PAGE_SIZE_1K 0x00000000 /* set page-size as 1k */
#define AR_AHB_PAGE_SIZE_2K 0x00000008 /* set page-size as 2k */
#define AR_AHB_PAGE_SIZE_4K 0x00000010 /* set page-size as 4k */
+/* Kiwi */
+#define AR_AHB_CUSTOM_BURST_EN 0x000000C0 /* set Custom Burst Mode */
+#define AR_AHB_CUSTOM_BURST_EN_S 6 /* set Custom Burst Mode */
+#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3 /* set both bits in Async FIFO mode */
/* MAC PCU Registers */
#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 /* Don't replace seq num */
@@ -451,9 +455,23 @@
* For Merlin and above only.
*/
#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040
+#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000 /* Kiwi or later? */
#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000
#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
+/* For Kiwi */
+#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
+
+/* TSF2. For Kiwi only */
+#define AR_TSF2_L32 0x8390
+#define AR_TSF2_U32 0x8394
+
+/* MAC Direct Connect Control. For Kiwi only */
+#define AR_DIRECT_CONNECT 0x83A0
+#define AR_DC_AP_STA_EN 0x00000001
+
/* GPIO Interrupt */
#define AR_INTR_GPIO 0x3FF00000 /* gpio interrupted */
#define AR_INTR_GPIO_S 20
@@ -488,6 +506,17 @@
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
+/* IFS, SIFS, slot, etc for Async FIFO mode (Kiwi) */
+#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
+#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56
+#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074
+#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420
+#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB
+
+/* Used by Kiwi Async FIFO */
+#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264
+#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000
+
/* Eeprom defines */
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0
@@ -566,6 +595,11 @@
#define AR_XSREV_REVISION_KITE_10 0 /* Kite 1.0 */
#define AR_XSREV_REVISION_KITE_11 1 /* Kite 1.1 */
#define AR_XSREV_REVISION_KITE_12 2 /* Kite 1.2 */
+#define AR_XSREV_VERSION_KIWI 0x180 /* Kiwi (AR9287) */
+#define AR_XSREV_REVISION_KIWI_10 0
+#define AR_XSREV_REVISION_KIWI_11 1
+#define AR_XSREV_REVISION_KIWI_12 2
+#define AR_XSREV_REVISION_KIWI_13 3
/* Owl (AR5416) */
#define AR_SREV_OWL(_ah) \
@@ -648,9 +682,31 @@
(AR_SREV_KITE_12_OR_LATER(_ah) && \
((OS_REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
+#define AR_SREV_KIWI(_ah) \
+ (AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KIWI)
+
+#define AR_SREV_KIWI_11_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_11)
+
+#define AR_SREV_KIWI_11(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_11)
+
+#define AR_SREV_KIWI_12(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_12)
+
+#define AR_SREV_KIWI_12_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_12)
+
+#define AR_SREV_KIWI_13_OR_LATER(_ah) \
+ (AR_SREV_KIWI(_ah) && \
+ AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_13)
+
+
/* Not yet implemented chips */
#define AR_SREV_9271(_ah) 0
-#define AR_SREV_9287_11_OR_LATER(_ah) 0
-#define AR_SREV_KIWI_10_OR_LATER(_ah) 0
#endif /* _DEV_ATH_AR5416REG_H */
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
index 0b6472b..0d950d2 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
@@ -82,7 +82,7 @@ ar9160AniSetup(struct ath_hal *ah)
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
index 3351edb..77b9f58 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
@@ -93,7 +93,7 @@ ar9280AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
/* NB: ANI is not enabled yet */
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
index b7ed27d..111bea2 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
@@ -98,7 +98,7 @@ ar9285AniSetup(struct ath_hal *ah)
.period = 100,
};
/* NB: disable ANI noise immmunity for reliable RIFS rx */
- AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
index e4e73d4..b28b97f 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_phy.c
@@ -87,8 +87,10 @@ ar9285_check_div_comb(struct ath_hal *ah)
HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader;
+#if 0
/* For now, simply disable this until it's better debugged. -adrian */
return AH_FALSE;
+#endif
if (! AR_SREV_KITE(ah))
return AH_FALSE;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.c b/sys/dev/ath/ath_hal/ar9002/ar9287.c
new file mode 100644
index 0000000..92501ca
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+/*
+ * NB: Merlin and later have a simpler RF backend.
+ */
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v14.h"
+
+#include "ar9002/ar9287.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+struct ar9287State {
+ RF_HAL_FUNCS base; /* public state, must be first */
+ uint16_t pcdacTable[1]; /* XXX */
+};
+#define AR9280(ah) ((struct ar9287State *) AH5212(ah)->ah_rfHal)
+
+static HAL_BOOL ar9287GetChannelMaxMinPower(struct ath_hal *,
+ const struct ieee80211_channel *, int16_t *maxPow,int16_t *minPow);
+int16_t ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c);
+
+static void
+ar9287WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
+ int writes)
+{
+ (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain,
+ freqIndex, writes);
+}
+
+/*
+ * Take the MHz channel value and set the Channel value
+ *
+ * ASSUMES: Writes enabled to analog bus
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ *
+ * For 5GHz channels which are 5MHz spaced,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ */
+static HAL_BOOL
+ar9287SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ uint16_t bMode, fracMode, aModeRefSel = 0;
+ uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+ CHAN_CENTERS centers;
+ uint32_t refDivA = 24;
+
+ OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq);
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+ freq = centers.synth_center;
+
+ reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+ reg32 &= 0xc0000000;
+
+ if (freq < 4800) { /* 2 GHz, fractional mode */
+ uint32_t txctl;
+ int regWrites = 0;
+
+ bMode = 1;
+ fracMode = 1;
+ aModeRefSel = 0;
+ channelSel = (freq * 0x10000)/15;
+
+ if (AR_SREV_KIWI_11_OR_LATER(ah)) {
+ if (freq == 2484) {
+ ath_hal_ini_write(ah,
+ &AH9287(ah)->ah_ini_cckFirJapan2484, 1,
+ regWrites);
+ } else {
+ ath_hal_ini_write(ah,
+ &AH9287(ah)->ah_ini_cckFirNormal, 1,
+ regWrites);
+ }
+ }
+
+ txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+ if (freq == 2484) {
+ /* Enable channel spreading for channel 14 */
+ OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+ txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+ } else {
+ OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+ txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
+ }
+ } else {
+ bMode = 0;
+ fracMode = 0;
+
+ if ((freq % 20) == 0) {
+ aModeRefSel = 3;
+ } else if ((freq % 10) == 0) {
+ aModeRefSel = 2;
+ } else {
+ aModeRefSel = 0;
+ /*
+ * Enable 2G (fractional) mode for channels which
+ * are 5MHz spaced
+ */
+ fracMode = 1;
+ refDivA = 1;
+ channelSel = (freq * 0x8000)/15;
+
+ /* RefDivA setting */
+ OS_A_REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+ AR_AN_SYNTH9_REFDIVA, refDivA);
+ }
+ if (!fracMode) {
+ ndiv = (freq * (refDivA >> aModeRefSel))/60;
+ channelSel = ndiv & 0x1ff;
+ channelFrac = (ndiv & 0xfffffe00) * 2;
+ channelSel = (channelSel << 17) | channelFrac;
+ }
+ }
+
+ reg32 = reg32 | (bMode << 29) | (fracMode << 28) |
+ (aModeRefSel << 26) | (channelSel);
+
+ OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+ AH_PRIVATE(ah)->ah_curchan = chan;
+
+ return AH_TRUE;
+}
+
+/*
+ * Return a reference to the requested RF Bank.
+ */
+static uint32_t *
+ar9287GetRfBank(struct ath_hal *ah, int bank)
+{
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n",
+ __func__, bank);
+ return AH_NULL;
+}
+
+/*
+ * Reads EEPROM header info from device structure and programs
+ * all rf registers
+ */
+static HAL_BOOL
+ar9287SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ uint16_t modesIndex, uint16_t *rfXpdGain)
+{
+ return AH_TRUE; /* nothing to do */
+}
+
+/*
+ * Read the transmit power levels from the structures taken from EEPROM
+ * Interpolate read transmit power values for this channel
+ * Organize the transmit power values into a table for writing into the hardware
+ */
+
+static HAL_BOOL
+ar9287SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
+{
+ return AH_TRUE;
+}
+
+#if 0
+static int16_t
+ar9287GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data)
+{
+ int i, minIndex;
+ int16_t minGain,minPwr,minPcdac,retVal;
+
+ /* Assume NUM_POINTS_XPD0 > 0 */
+ minGain = data->pDataPerXPD[0].xpd_gain;
+ for (minIndex=0,i=1; i<NUM_XPD_PER_CHANNEL; i++) {
+ if (data->pDataPerXPD[i].xpd_gain < minGain) {
+ minIndex = i;
+ minGain = data->pDataPerXPD[i].xpd_gain;
+ }
+ }
+ minPwr = data->pDataPerXPD[minIndex].pwr_t4[0];
+ minPcdac = data->pDataPerXPD[minIndex].pcdac[0];
+ for (i=1; i<NUM_POINTS_XPD0; i++) {
+ if (data->pDataPerXPD[minIndex].pwr_t4[i] < minPwr) {
+ minPwr = data->pDataPerXPD[minIndex].pwr_t4[i];
+ minPcdac = data->pDataPerXPD[minIndex].pcdac[i];
+ }
+ }
+ retVal = minPwr - (minPcdac*2);
+ return(retVal);
+}
+#endif
+
+static HAL_BOOL
+ar9287GetChannelMaxMinPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ int16_t *maxPow, int16_t *minPow)
+{
+#if 0
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ int numChannels=0,i,last;
+ int totalD, totalF,totalMin;
+ EXPN_DATA_PER_CHANNEL_5112 *data=AH_NULL;
+ EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL;
+
+ *maxPow = 0;
+ if (IS_CHAN_A(chan)) {
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11A].pDataPerChannel;
+ numChannels = powerArray[headerInfo11A].numChannels;
+ } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) {
+ /* XXX - is this correct? Should we also use the same power for turbo G? */
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11G].pDataPerChannel;
+ numChannels = powerArray[headerInfo11G].numChannels;
+ } else if (IS_CHAN_B(chan)) {
+ powerArray = ahp->ah_modePowerArray5112;
+ data = powerArray[headerInfo11B].pDataPerChannel;
+ numChannels = powerArray[headerInfo11B].numChannels;
+ } else {
+ return (AH_TRUE);
+ }
+ /* Make sure the channel is in the range of the TP values
+ * (freq piers)
+ */
+ if ((numChannels < 1) ||
+ (chan->channel < data[0].channelValue) ||
+ (chan->channel > data[numChannels-1].channelValue))
+ return(AH_FALSE);
+
+ /* Linearly interpolate the power value now */
+ for (last=0,i=0;
+ (i<numChannels) && (chan->channel > data[i].channelValue);
+ last=i++);
+ totalD = data[i].channelValue - data[last].channelValue;
+ if (totalD > 0) {
+ totalF = data[i].maxPower_t4 - data[last].maxPower_t4;
+ *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
+
+ totalMin = ar9287GetMinPower(ah,&data[i]) - ar9287GetMinPower(ah, &data[last]);
+ *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar9287GetMinPower(ah, &data[last])*totalD)/totalD);
+ return (AH_TRUE);
+ } else {
+ if (chan->channel == data[i].channelValue) {
+ *maxPow = data[i].maxPower_t4;
+ *minPow = ar9287GetMinPower(ah, &data[i]);
+ return(AH_TRUE);
+ } else
+ return(AH_FALSE);
+ }
+#else
+ *maxPow = *minPow = 0;
+ return AH_FALSE;
+#endif
+}
+
+/*
+ * The ordering of nfarray is thus:
+ *
+ * nfarray[0]: Chain 0 ctl
+ * nfarray[1]: Chain 1 ctl
+ * nfarray[2]: Chain 2 ctl
+ * nfarray[3]: Chain 0 ext
+ * nfarray[4]: Chain 1 ext
+ * nfarray[5]: Chain 2 ext
+ */
+static void
+ar9287GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
+{
+ int16_t nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ctl] [chain 0] is %d\n", nf);
+ nfarray[0] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ctl] [chain 1] is %d\n", nf);
+ nfarray[1] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ext] [chain 0] is %d\n", nf);
+ nfarray[3] = nf;
+
+ nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ HALDEBUG(ah, HAL_DEBUG_NFCAL,
+ "NF calibrated [ext] [chain 1] is %d\n", nf);
+ nfarray[4] = nf;
+
+ /* Chain 2 - invalid */
+ nfarray[2] = 0;
+ nfarray[5] = 0;
+
+}
+
+/*
+ * Adjust NF based on statistical values for 5GHz frequencies.
+ * Stubbed:Not used by Fowl
+ */
+int16_t
+ar9287GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
+{
+ return 0;
+}
+
+/*
+ * Free memory for analog bank scratch buffers
+ */
+static void
+ar9287RfDetach(struct ath_hal *ah)
+{
+ struct ath_hal_5212 *ahp = AH5212(ah);
+
+ HALASSERT(ahp->ah_rfHal != AH_NULL);
+ ath_hal_free(ahp->ah_rfHal);
+ ahp->ah_rfHal = AH_NULL;
+}
+
+HAL_BOOL
+ar9287RfAttach(struct ath_hal *ah, HAL_STATUS *status)
+{
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ struct ar9287State *priv;
+
+ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: attach AR9280 radio\n", __func__);
+
+ HALASSERT(ahp->ah_rfHal == AH_NULL);
+ priv = ath_hal_malloc(sizeof(struct ar9287State));
+ if (priv == AH_NULL) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: cannot allocate private state\n", __func__);
+ *status = HAL_ENOMEM; /* XXX */
+ return AH_FALSE;
+ }
+ priv->base.rfDetach = ar9287RfDetach;
+ priv->base.writeRegs = ar9287WriteRegs;
+ priv->base.getRfBank = ar9287GetRfBank;
+ priv->base.setChannel = ar9287SetChannel;
+ priv->base.setRfRegs = ar9287SetRfRegs;
+ priv->base.setPowerTable = ar9287SetPowerTable;
+ priv->base.getChannelMaxMinPower = ar9287GetChannelMaxMinPower;
+ priv->base.getNfAdjust = ar9287GetNfAdjust;
+
+ ahp->ah_pcdacTable = priv->pcdacTable;
+ ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable);
+ ahp->ah_rfHal = &priv->base;
+ /*
+ * Set noise floor adjust method; we arrange a
+ * direct call instead of thunking.
+ */
+ AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust;
+ AH_PRIVATE(ah)->ah_getNoiseFloor = ar9287GetNoiseFloor;
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.h b/sys/dev/ath/ath_hal/ar9002/ar9287.h
new file mode 100644
index 0000000..90d25ed
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ATH_AR9287_H_
+#define _ATH_AR9287_H_
+
+#include "ar5416/ar5416.h"
+
+/*
+ * This is a chip thing, but it's used here as part of the
+ * ath_hal_9287 struct; so it's convienent to locate the
+ * define here.
+ */
+#define AR9287_TX_GAIN_TABLE_SIZE 22
+
+struct ath_hal_9287 {
+ struct ath_hal_5416 ah_5416;
+
+ HAL_INI_ARRAY ah_ini_xmodes;
+ HAL_INI_ARRAY ah_ini_rxgain;
+ HAL_INI_ARRAY ah_ini_txgain;
+
+ HAL_INI_ARRAY ah_ini_cckFirNormal;
+ HAL_INI_ARRAY ah_ini_cckFirJapan2484;
+
+ int PDADCdelta;
+
+ uint32_t originalGain[AR9287_TX_GAIN_TABLE_SIZE];
+};
+#define AH9287(_ah) ((struct ath_hal_9287 *)(_ah))
+
+#define AR9287_DEFAULT_RXCHAINMASK 3
+#define AR9285_DEFAULT_RXCHAINMASK 1
+#define AR9287_DEFAULT_TXCHAINMASK 3
+#define AR9285_DEFAULT_TXCHAINMASK 1
+
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -112
+#define AR_PHY_CCA_NOM_VAL_9287_5GHZ -112
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ -122
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -97
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ -102
+
+extern HAL_BOOL ar9287RfAttach(struct ath_hal *, HAL_STATUS *);
+extern HAL_BOOL ar9287SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
+
+#endif /* _ATH_AR9287_H_ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287.ini b/sys/dev/ath/ath_hal/ar9002/ar9287.ini
new file mode 100644
index 0000000..7f4ca05
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287.ini
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+static const uint32_t ar9287Modes_9287_1_1[][6] = {
+ {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0},
+ {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0},
+ {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180},
+ {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008},
+ {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0},
+ {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f},
+ {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
+ {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a},
+ {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880},
+ {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303},
+ {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200},
+ {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+ {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001},
+ {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+ {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007},
+ {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e},
+ {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0},
+ {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2},
+ {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
+ {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e},
+ {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18},
+ {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
+ {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881},
+ {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0},
+ {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016},
+ {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
+ {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010},
+ {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+ {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010},
+ {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210},
+ {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce},
+ {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c},
+ {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00},
+ {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444},
+ {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a},
+ {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
+ {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000},
+ {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
+ {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const uint32_t ar9287Common_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000000c, 0x00000000},
+ {0x00000030, 0x00020015},
+ {0x00000034, 0x00000005},
+ {0x00000040, 0x00000000},
+ {0x00000044, 0x00000008},
+ {0x00000048, 0x00000008},
+ {0x0000004c, 0x00000010},
+ {0x00000050, 0x00000000},
+ {0x00000054, 0x0000001f},
+ {0x00000800, 0x00000000},
+ {0x00000804, 0x00000000},
+ {0x00000808, 0x00000000},
+ {0x0000080c, 0x00000000},
+ {0x00000810, 0x00000000},
+ {0x00000814, 0x00000000},
+ {0x00000818, 0x00000000},
+ {0x0000081c, 0x00000000},
+ {0x00000820, 0x00000000},
+ {0x00000824, 0x00000000},
+ {0x00001040, 0x002ffc0f},
+ {0x00001044, 0x002ffc0f},
+ {0x00001048, 0x002ffc0f},
+ {0x0000104c, 0x002ffc0f},
+ {0x00001050, 0x002ffc0f},
+ {0x00001054, 0x002ffc0f},
+ {0x00001058, 0x002ffc0f},
+ {0x0000105c, 0x002ffc0f},
+ {0x00001060, 0x002ffc0f},
+ {0x00001064, 0x002ffc0f},
+ {0x00001230, 0x00000000},
+ {0x00001270, 0x00000000},
+ {0x00001038, 0x00000000},
+ {0x00001078, 0x00000000},
+ {0x000010b8, 0x00000000},
+ {0x000010f8, 0x00000000},
+ {0x00001138, 0x00000000},
+ {0x00001178, 0x00000000},
+ {0x000011b8, 0x00000000},
+ {0x000011f8, 0x00000000},
+ {0x00001238, 0x00000000},
+ {0x00001278, 0x00000000},
+ {0x000012b8, 0x00000000},
+ {0x000012f8, 0x00000000},
+ {0x00001338, 0x00000000},
+ {0x00001378, 0x00000000},
+ {0x000013b8, 0x00000000},
+ {0x000013f8, 0x00000000},
+ {0x00001438, 0x00000000},
+ {0x00001478, 0x00000000},
+ {0x000014b8, 0x00000000},
+ {0x000014f8, 0x00000000},
+ {0x00001538, 0x00000000},
+ {0x00001578, 0x00000000},
+ {0x000015b8, 0x00000000},
+ {0x000015f8, 0x00000000},
+ {0x00001638, 0x00000000},
+ {0x00001678, 0x00000000},
+ {0x000016b8, 0x00000000},
+ {0x000016f8, 0x00000000},
+ {0x00001738, 0x00000000},
+ {0x00001778, 0x00000000},
+ {0x000017b8, 0x00000000},
+ {0x000017f8, 0x00000000},
+ {0x0000103c, 0x00000000},
+ {0x0000107c, 0x00000000},
+ {0x000010bc, 0x00000000},
+ {0x000010fc, 0x00000000},
+ {0x0000113c, 0x00000000},
+ {0x0000117c, 0x00000000},
+ {0x000011bc, 0x00000000},
+ {0x000011fc, 0x00000000},
+ {0x0000123c, 0x00000000},
+ {0x0000127c, 0x00000000},
+ {0x000012bc, 0x00000000},
+ {0x000012fc, 0x00000000},
+ {0x0000133c, 0x00000000},
+ {0x0000137c, 0x00000000},
+ {0x000013bc, 0x00000000},
+ {0x000013fc, 0x00000000},
+ {0x0000143c, 0x00000000},
+ {0x0000147c, 0x00000000},
+ {0x00004030, 0x00000002},
+ {0x0000403c, 0x00000002},
+ {0x00004024, 0x0000001f},
+ {0x00004060, 0x00000000},
+ {0x00004064, 0x00000000},
+ {0x00007010, 0x00000033},
+ {0x00007020, 0x00000000},
+ {0x00007034, 0x00000002},
+ {0x00007038, 0x000004c2},
+ {0x00008004, 0x00000000},
+ {0x00008008, 0x00000000},
+ {0x0000800c, 0x00000000},
+ {0x00008018, 0x00000700},
+ {0x00008020, 0x00000000},
+ {0x00008038, 0x00000000},
+ {0x0000803c, 0x00000000},
+ {0x00008048, 0x40000000},
+ {0x00008054, 0x00000000},
+ {0x00008058, 0x00000000},
+ {0x0000805c, 0x000fc78f},
+ {0x00008060, 0x0000000f},
+ {0x00008064, 0x00000000},
+ {0x00008070, 0x00000000},
+ {0x000080c0, 0x2a80001a},
+ {0x000080c4, 0x05dc01e0},
+ {0x000080c8, 0x1f402710},
+ {0x000080cc, 0x01f40000},
+ {0x000080d0, 0x00001e00},
+ {0x000080d4, 0x00000000},
+ {0x000080d8, 0x00400000},
+ {0x000080e0, 0xffffffff},
+ {0x000080e4, 0x0000ffff},
+ {0x000080e8, 0x003f3f3f},
+ {0x000080ec, 0x00000000},
+ {0x000080f0, 0x00000000},
+ {0x000080f4, 0x00000000},
+ {0x000080f8, 0x00000000},
+ {0x000080fc, 0x00020000},
+ {0x00008100, 0x00020000},
+ {0x00008104, 0x00000001},
+ {0x00008108, 0x00000052},
+ {0x0000810c, 0x00000000},
+ {0x00008110, 0x00000168},
+ {0x00008118, 0x000100aa},
+ {0x0000811c, 0x00003210},
+ {0x00008124, 0x00000000},
+ {0x00008128, 0x00000000},
+ {0x0000812c, 0x00000000},
+ {0x00008130, 0x00000000},
+ {0x00008134, 0x00000000},
+ {0x00008138, 0x00000000},
+ {0x0000813c, 0x00000000},
+ {0x00008144, 0xffffffff},
+ {0x00008168, 0x00000000},
+ {0x0000816c, 0x00000000},
+ {0x00008170, 0x18487320},
+ {0x00008174, 0xfaa4fa50},
+ {0x00008178, 0x00000100},
+ {0x0000817c, 0x00000000},
+ {0x000081c0, 0x00000000},
+ {0x000081c4, 0x00000000},
+ {0x000081d4, 0x00000000},
+ {0x000081ec, 0x00000000},
+ {0x000081f0, 0x00000000},
+ {0x000081f4, 0x00000000},
+ {0x000081f8, 0x00000000},
+ {0x000081fc, 0x00000000},
+ {0x00008200, 0x00000000},
+ {0x00008204, 0x00000000},
+ {0x00008208, 0x00000000},
+ {0x0000820c, 0x00000000},
+ {0x00008210, 0x00000000},
+ {0x00008214, 0x00000000},
+ {0x00008218, 0x00000000},
+ {0x0000821c, 0x00000000},
+ {0x00008220, 0x00000000},
+ {0x00008224, 0x00000000},
+ {0x00008228, 0x00000000},
+ {0x0000822c, 0x00000000},
+ {0x00008230, 0x00000000},
+ {0x00008234, 0x00000000},
+ {0x00008238, 0x00000000},
+ {0x0000823c, 0x00000000},
+ {0x00008240, 0x00100000},
+ {0x00008244, 0x0010f400},
+ {0x00008248, 0x00000100},
+ {0x0000824c, 0x0001e800},
+ {0x00008250, 0x00000000},
+ {0x00008254, 0x00000000},
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x400000ff},
+ {0x00008260, 0x00080922},
+ {0x00008264, 0x88a00010},
+ {0x00008270, 0x00000000},
+ {0x00008274, 0x40000000},
+ {0x00008278, 0x003e4180},
+ {0x0000827c, 0x00000000},
+ {0x00008284, 0x0000002c},
+ {0x00008288, 0x0000002c},
+ {0x0000828c, 0x000000ff},
+ {0x00008294, 0x00000000},
+ {0x00008298, 0x00000000},
+ {0x0000829c, 0x00000000},
+ {0x00008300, 0x00000040},
+ {0x00008314, 0x00000000},
+ {0x00008328, 0x00000000},
+ {0x0000832c, 0x00000007},
+ {0x00008330, 0x00000302},
+ {0x00008334, 0x00000e00},
+ {0x00008338, 0x00ff0000},
+ {0x0000833c, 0x00000000},
+ {0x00008340, 0x000107ff},
+ {0x00008344, 0x01c81043},
+ {0x00008360, 0xffffffff},
+ {0x00008364, 0xffffffff},
+ {0x00008368, 0x00000000},
+ {0x00008370, 0x00000000},
+ {0x00008374, 0x000000ff},
+ {0x00008378, 0x00000000},
+ {0x0000837c, 0x00000000},
+ {0x00008380, 0xffffffff},
+ {0x00008384, 0xffffffff},
+ {0x00008390, 0x0fffffff},
+ {0x00008394, 0x0fffffff},
+ {0x00008398, 0x00000000},
+ {0x0000839c, 0x00000000},
+ {0x000083a0, 0x00000000},
+ {0x00009808, 0x00000000},
+ {0x0000980c, 0xafe68e30},
+ {0x00009810, 0xfd14e000},
+ {0x00009814, 0x9c0a9f6b},
+ {0x0000981c, 0x00000000},
+ {0x0000982c, 0x0000a000},
+ {0x00009830, 0x00000000},
+ {0x0000983c, 0x00200400},
+ {0x0000984c, 0x0040233c},
+ {0x0000a84c, 0x0040233c},
+ {0x00009854, 0x00000044},
+ {0x00009900, 0x00000000},
+ {0x00009904, 0x00000000},
+ {0x00009908, 0x00000000},
+ {0x0000990c, 0x00000000},
+ {0x00009910, 0x10002310},
+ {0x0000991c, 0x10000fff},
+ {0x00009920, 0x04900000},
+ {0x0000a920, 0x04900000},
+ {0x00009928, 0x00000001},
+ {0x0000992c, 0x00000004},
+ {0x00009930, 0x00000000},
+ {0x0000a930, 0x00000000},
+ {0x00009934, 0x1e1f2022},
+ {0x00009938, 0x0a0b0c0d},
+ {0x0000993c, 0x00000000},
+ {0x00009948, 0x9280c00a},
+ {0x0000994c, 0x00020028},
+ {0x00009954, 0x5f3ca3de},
+ {0x00009958, 0x0108ecff},
+ {0x00009940, 0x14750604},
+ {0x0000c95c, 0x004b6a8e},
+ {0x00009970, 0x990bb514},
+ {0x00009974, 0x00000000},
+ {0x00009978, 0x00000001},
+ {0x0000997c, 0x00000000},
+ {0x000099a0, 0x00000000},
+ {0x000099a4, 0x00000001},
+ {0x000099a8, 0x201fff00},
+ {0x000099ac, 0x0c6f0000},
+ {0x000099b0, 0x03051000},
+ {0x000099b4, 0x00000820},
+ {0x000099c4, 0x06336f77},
+ {0x000099c8, 0x6af6532f},
+ {0x000099cc, 0x08f186c8},
+ {0x000099d0, 0x00046384},
+ {0x000099dc, 0x00000000},
+ {0x000099e0, 0x00000000},
+ {0x000099e4, 0xaaaaaaaa},
+ {0x000099e8, 0x3c466478},
+ {0x000099ec, 0x0cc80caa},
+ {0x000099f0, 0x00000000},
+ {0x000099fc, 0x00001042},
+ {0x0000a208, 0x803e4788},
+ {0x0000a210, 0x4080a333},
+ {0x0000a214, 0x40206c10},
+ {0x0000a218, 0x009c4060},
+ {0x0000a220, 0x01834061},
+ {0x0000a224, 0x00000400},
+ {0x0000a228, 0x000003b5},
+ {0x0000a22c, 0x233f7180},
+ {0x0000a234, 0x20202020},
+ {0x0000a238, 0x20202020},
+ {0x0000a23c, 0x13c889af},
+ {0x0000a240, 0x38490a20},
+ {0x0000a244, 0x00000000},
+ {0x0000a248, 0xfffffffc},
+ {0x0000a24c, 0x00000000},
+ {0x0000a254, 0x00000000},
+ {0x0000a258, 0x0cdbd380},
+ {0x0000a25c, 0x0f0f0f01},
+ {0x0000a260, 0xdfa91f01},
+ {0x0000a264, 0x00418a11},
+ {0x0000b264, 0x00418a11},
+ {0x0000a268, 0x00000000},
+ {0x0000a26c, 0x0e79e5c6},
+ {0x0000b26c, 0x0e79e5c6},
+ {0x0000d270, 0x00820820},
+ {0x0000a278, 0x1ce739ce},
+ {0x0000a27c, 0x050701ce},
+ {0x0000d35c, 0x07ffffef},
+ {0x0000d360, 0x0fffffe7},
+ {0x0000d364, 0x17ffffe5},
+ {0x0000d368, 0x1fffffe4},
+ {0x0000d36c, 0x37ffffe3},
+ {0x0000d370, 0x3fffffe3},
+ {0x0000d374, 0x57ffffe3},
+ {0x0000d378, 0x5fffffe2},
+ {0x0000d37c, 0x7fffffe2},
+ {0x0000d380, 0x7f3c7bba},
+ {0x0000d384, 0xf3307ff0},
+ {0x0000a388, 0x0c000000},
+ {0x0000a38c, 0x20202020},
+ {0x0000a390, 0x20202020},
+ {0x0000a394, 0x1ce739ce},
+ {0x0000a398, 0x000001ce},
+ {0x0000b398, 0x000001ce},
+ {0x0000a39c, 0x00000001},
+ {0x0000a3c8, 0x00000246},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3dc, 0x1ce739ce},
+ {0x0000a3e0, 0x000001ce},
+ {0x0000a3e4, 0x00000000},
+ {0x0000a3e8, 0x18c43433},
+ {0x0000a3ec, 0x00f70081},
+ {0x0000a3f0, 0x01036a1e},
+ {0x0000a3f4, 0x00000000},
+ {0x0000b3f4, 0x00000000},
+ {0x0000a7d8, 0x000003f1},
+ {0x00007800, 0x00000800},
+ {0x00007804, 0x6c35ffd2},
+ {0x00007808, 0x6db6c000},
+ {0x0000780c, 0x6db6cb30},
+ {0x00007810, 0x6db6cb6c},
+ {0x00007814, 0x0501e200},
+ {0x00007818, 0x0094128d},
+ {0x0000781c, 0x976ee392},
+ {0x00007820, 0xf75ff6fc},
+ {0x00007824, 0x00040000},
+ {0x00007828, 0xdb003012},
+ {0x0000782c, 0x04924914},
+ {0x00007830, 0x21084210},
+ {0x00007834, 0x00140000},
+ {0x00007838, 0x0e4548d8},
+ {0x0000783c, 0x54214514},
+ {0x00007840, 0x02025830},
+ {0x00007844, 0x71c0d388},
+ {0x00007848, 0x934934a8},
+ {0x00007850, 0x00000000},
+ {0x00007854, 0x00000800},
+ {0x00007858, 0x6c35ffd2},
+ {0x0000785c, 0x6db6c000},
+ {0x00007860, 0x6db6cb30},
+ {0x00007864, 0x6db6cb6c},
+ {0x00007868, 0x0501e200},
+ {0x0000786c, 0x0094128d},
+ {0x00007870, 0x976ee392},
+ {0x00007874, 0xf75ff6fc},
+ {0x00007878, 0x00040000},
+ {0x0000787c, 0xdb003012},
+ {0x00007880, 0x04924914},
+ {0x00007884, 0x21084210},
+ {0x00007888, 0x001b6db0},
+ {0x0000788c, 0x00376b63},
+ {0x00007890, 0x06db6db6},
+ {0x00007894, 0x006d8000},
+ {0x00007898, 0x48100000},
+ {0x0000789c, 0x00000000},
+ {0x000078a0, 0x08000000},
+ {0x000078a4, 0x0007ffd8},
+ {0x000078a8, 0x0007ffd8},
+ {0x000078ac, 0x001c0020},
+ {0x000078b0, 0x00060aeb},
+ {0x000078b4, 0x40008080},
+ {0x000078b8, 0x2a850160},
+};
+
+static const uint32_t ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000a1f4, 0x00fffeff},
+ {0x0000a1f8, 0x00f5f9ff},
+ {0x0000a1fc, 0xb79f6427},
+};
+
+static const uint32_t ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x0000a1f4, 0x00000000},
+ {0x0000a1f8, 0xefff0301},
+ {0x0000a1fc, 0xca9228ee},
+};
+
+static const uint32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
+ {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002},
+ {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004},
+ {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a},
+ {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c},
+ {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b},
+ {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a},
+ {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a},
+ {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a},
+ {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a},
+ {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a},
+ {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a},
+ {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a},
+ {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a},
+ {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c},
+ {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc},
+ {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4},
+ {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc},
+ {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede},
+ {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e},
+ {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e},
+ {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e},
+ {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062},
+ {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064},
+ {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4},
+ {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa},
+ {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac},
+ {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4},
+ {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4},
+ {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134},
+ {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174},
+ {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c},
+ {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e},
+ {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be},
+ {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe},
+ {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000},
+};
+
+static const uint32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
+ {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+ {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+ {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+ {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+ {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+ {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+ {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+ {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+ {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+ {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+ {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+ {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+ {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+ {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+ {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+ {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+ {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+ {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+ {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+ {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+ {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+ {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+ {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+ {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+ {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+ {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+ {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+ {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+ {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+ {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+ {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+ {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+ {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+ {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+ {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+ {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+ {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+ {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+ {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+ {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+ {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+ {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+ {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+ {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+ {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+ {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+ {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+ {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+ {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+ {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+ {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+ {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+ {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+ {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+ {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+ {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+ {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+ {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+ {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+ {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+ {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+ {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+ {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+ {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+ {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+ {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+ {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+ {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+ {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+ {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+ {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+ {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+ {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+ {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+ {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+ {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+ {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+ {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+ {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+ {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+ {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+ {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+ {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+ {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+ {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+ {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+ {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+ {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+ {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+ {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+ {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+ {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+ {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+ {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+ {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+ {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+ {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+ {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+ {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+ {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+ {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+ {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+ {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+ {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
+ {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
+ {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
+ {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c},
+ {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130},
+ {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194},
+ {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198},
+ {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c},
+ {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210},
+ {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284},
+ {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288},
+ {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c},
+ {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290},
+ {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294},
+ {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0},
+ {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4},
+ {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8},
+ {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac},
+ {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0},
+ {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4},
+ {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8},
+ {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4},
+ {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708},
+ {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c},
+ {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710},
+ {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04},
+ {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08},
+ {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c},
+ {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10},
+ {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14},
+ {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18},
+ {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c},
+ {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90},
+ {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94},
+ {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98},
+ {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4},
+ {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8},
+ {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04},
+ {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08},
+ {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c},
+ {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10},
+ {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14},
+ {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18},
+ {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c},
+ {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90},
+ {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18},
+ {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24},
+ {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28},
+ {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314},
+ {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318},
+ {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c},
+ {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390},
+ {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394},
+ {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398},
+ {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4},
+ {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8},
+ {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac},
+ {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0},
+ {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380},
+ {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384},
+ {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388},
+ {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710},
+ {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714},
+ {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718},
+ {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10},
+ {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14},
+ {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18},
+ {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c},
+ {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90},
+ {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94},
+ {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c},
+ {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90},
+ {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94},
+ {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0},
+ {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4},
+ {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8},
+ {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac},
+ {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0},
+ {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4},
+ {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1},
+ {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5},
+ {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9},
+ {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad},
+ {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1},
+ {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5},
+ {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9},
+ {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5},
+ {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9},
+ {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd},
+ {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1},
+ {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5},
+ {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2},
+ {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6},
+ {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca},
+ {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce},
+ {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2},
+ {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6},
+ {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda},
+ {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7},
+ {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb},
+ {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf},
+ {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3},
+ {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7},
+ {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb},
+ {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+ {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
+};
+
+static const uint32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x00004040, 0x9248fd00},
+ {0x00004040, 0x24924924},
+ {0x00004040, 0xa8000019},
+ {0x00004040, 0x13160820},
+ {0x00004040, 0xe5980560},
+ {0x00004040, 0xc01dcffd},
+ {0x00004040, 0x1aaabe41},
+ {0x00004040, 0xbe105554},
+ {0x00004040, 0x00043007},
+ {0x00004044, 0x00000000},
+};
+
+static const uint32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+ /* Addr allmodes */
+ {0x00004040, 0x9248fd00},
+ {0x00004040, 0x24924924},
+ {0x00004040, 0xa8000019},
+ {0x00004040, 0x13160820},
+ {0x00004040, 0xe5980560},
+ {0x00004040, 0xc01dcffc},
+ {0x00004040, 0x1aaabe41},
+ {0x00004040, 0xbe105554},
+ {0x00004040, 0x00043007},
+ {0x00004044, 0x00000000},
+};
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
new file mode 100644
index 0000000..daee414
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+
+#include "ah_eeprom_v14.h" /* XXX for tx/rx gain */
+#include "ah_eeprom_9287.h"
+
+#include "ar9002/ar9280.h"
+#include "ar9002/ar9287.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "ar9002/ar9287_cal.h"
+#include "ar9002/ar9287_reset.h"
+#include "ar9002/ar9287_olc.h"
+
+#include "ar9002/ar9287.ini"
+
+static const HAL_PERCAL_DATA ar9287_iq_cal = { /* single sample */
+ .calName = "IQ", .calType = IQ_MISMATCH_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MAX_LOG_COUNT,
+ .calCollect = ar5416IQCalCollect,
+ .calPostProc = ar5416IQCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_gain_cal = { /* single sample */
+ .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MIN_LOG_COUNT,
+ .calCollect = ar5416AdcGainCalCollect,
+ .calPostProc = ar5416AdcGainCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_dc_cal = { /* single sample */
+ .calName = "ADC DC", .calType = ADC_DC_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = PER_MIN_LOG_COUNT,
+ .calCollect = ar5416AdcDcCalCollect,
+ .calPostProc = ar5416AdcDcCalibration
+};
+static const HAL_PERCAL_DATA ar9287_adc_init_dc_cal = {
+ .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
+ .calNumSamples = MIN_CAL_SAMPLES,
+ .calCountMax = INIT_LOG_COUNT,
+ .calCollect = ar5416AdcDcCalCollect,
+ .calPostProc = ar5416AdcDcCalibration
+};
+
+static void ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
+static HAL_BOOL ar9287FillCapabilityInfo(struct ath_hal *ah);
+static void ar9287WriteIni(struct ath_hal *ah,
+ const struct ieee80211_channel *chan);
+
+static void
+ar9287AniSetup(struct ath_hal *ah)
+{
+ /*
+ * These are the parameters from the AR5416 ANI code;
+ * they likely need quite a bit of adjustment for the
+ * AR9280.
+ */
+ static const struct ar5212AniParams aniparams = {
+ .maxNoiseImmunityLevel = 4, /* levels 0..4 */
+ .totalSizeDesired = { -55, -55, -55, -55, -62 },
+ .coarseHigh = { -14, -14, -14, -14, -12 },
+ .coarseLow = { -64, -64, -64, -64, -70 },
+ .firpwr = { -78, -78, -78, -78, -80 },
+ .maxSpurImmunityLevel = 2,
+ .cycPwrThr1 = { 2, 4, 6 },
+ .maxFirstepLevel = 2, /* levels 0..2 */
+ .firstep = { 0, 4, 8 },
+ .ofdmTrigHigh = 500,
+ .ofdmTrigLow = 200,
+ .cckTrigHigh = 200,
+ .cckTrigLow = 100,
+ .rssiThrHigh = 40,
+ .rssiThrLow = 7,
+ .period = 100,
+ };
+ /* NB: disable ANI noise immmunity for reliable RIFS rx */
+ AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
+
+ /* NB: ANI is not enabled yet */
+ ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
+}
+
+/*
+ * Attach for an AR9287 part.
+ */
+static struct ath_hal *
+ar9287Attach(uint16_t devid, HAL_SOFTC sc,
+ HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_STATUS *status)
+{
+ struct ath_hal_9287 *ahp9287;
+ struct ath_hal_5212 *ahp;
+ struct ath_hal *ah;
+ uint32_t val;
+ HAL_STATUS ecode;
+ HAL_BOOL rfStatus;
+ int8_t pwr_table_offset;
+
+ HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
+ __func__, sc, (void*) st, (void*) sh);
+
+ /* NB: memory is returned zero'd */
+ ahp9287 = ath_hal_malloc(sizeof (struct ath_hal_9287));
+ if (ahp9287 == AH_NULL) {
+ HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
+ "%s: cannot allocate memory for state block\n", __func__);
+ *status = HAL_ENOMEM;
+ return AH_NULL;
+ }
+ ahp = AH5212(ahp9287);
+ ah = &ahp->ah_priv.h;
+
+ ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
+
+ /* XXX override with 9280 specific state */
+ /* override 5416 methods for our needs */
+ ah->ah_setAntennaSwitch = ar9287SetAntennaSwitch;
+ ah->ah_configPCIE = ar9287ConfigPCIE;
+
+ AH5416(ah)->ah_cal.iqCalData.calData = &ar9287_iq_cal;
+ AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9287_adc_gain_cal;
+ AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9287_adc_dc_cal;
+ AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9287_adc_init_dc_cal;
+ /* Better performance without ADC Gain Calibration */
+ AH5416(ah)->ah_cal.suppCals = ADC_DC_CAL | IQ_MISMATCH_CAL;
+
+ AH5416(ah)->ah_spurMitigate = ar9280SpurMitigate;
+ AH5416(ah)->ah_writeIni = ar9287WriteIni;
+
+ ah->ah_setTxPower = ar9287SetTransmitPower;
+ ah->ah_setBoardValues = ar9287SetBoardValues;
+
+ AH5416(ah)->ah_olcInit = ar9287olcInit;
+ AH5416(ah)->ah_olcTempCompensation = ar9287olcTemperatureCompensation;
+ //AH5416(ah)->ah_setPowerCalTable = ar9287SetPowerCalTable;
+ AH5416(ah)->ah_cal_initcal = ar9287InitCalHardware;
+ AH5416(ah)->ah_cal_pacal = ar9287PACal;
+
+ /* XXX NF calibration */
+ /* XXX Ini override? (IFS vars - since the kiwi mac clock is faster?) */
+ /* XXX what else is kiwi-specific in the radio/calibration pathway? */
+
+ AH5416(ah)->ah_rx_chainmask = AR9287_DEFAULT_RXCHAINMASK;
+ AH5416(ah)->ah_tx_chainmask = AR9287_DEFAULT_TXCHAINMASK;
+
+ if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
+ /* reset chip */
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
+ __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
+ __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+ /* Read Revisions from Chips before taking out of reset */
+ val = OS_REG_READ(ah, AR_SREV);
+ HALDEBUG(ah, HAL_DEBUG_ATTACH,
+ "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
+ __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
+ MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
+ /* NB: include chip type to differentiate from pre-Sowl versions */
+ AH_PRIVATE(ah)->ah_macVersion =
+ (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
+ AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
+ AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
+
+ /* Don't support Kiwi < 1.2; those are pre-release chips */
+ if (! AR_SREV_KIWI_12_OR_LATER(ah)) {
+ ath_hal_printf(ah, "[ath]: Kiwi < 1.2 is not supported\n");
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ /* setup common ini data; rf backends handle remainder */
+ HAL_INI_INIT(&ahp->ah_ini_modes, ar9287Modes_9287_1_1, 6);
+ HAL_INI_INIT(&ahp->ah_ini_common, ar9287Common_9287_1_1, 2);
+
+ /* If pcie_clock_req */
+ HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
+ ar9287PciePhy_clkreq_always_on_L1_9287_1_1, 2);
+
+ /* XXX WoW ini values */
+
+ /* Else */
+#if 0
+ HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
+ ar9287PciePhy_clkreq_off_L1_9287_1_1, 2);
+#endif
+
+ /* Initialise Japan arrays */
+ HAL_INI_INIT(&ahp9287->ah_ini_cckFirNormal,
+ ar9287Common_normal_cck_fir_coeff_9287_1_1, 2);
+ HAL_INI_INIT(&ahp9287->ah_ini_cckFirJapan2484,
+ ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, 2);
+
+ ar5416AttachPCIE(ah);
+
+ ecode = ath_hal_9287EepromAttach(ah);
+ if (ecode != HAL_OK)
+ goto bad;
+
+ if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
+ ecode = HAL_EIO;
+ goto bad;
+ }
+
+ AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
+
+ if (!ar5212ChipTest(ah)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
+ __func__);
+ ecode = HAL_ESELFTEST;
+ goto bad;
+ }
+
+ /*
+ * Set correct Baseband to analog shift
+ * setting to access analog chips.
+ */
+ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+ /* Read Radio Chip Rev Extract */
+ AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
+ switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
+ case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */
+ case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */
+ break;
+ default:
+ if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
+ AH_PRIVATE(ah)->ah_analog5GhzRev =
+ AR_RAD5133_SREV_MAJOR;
+ break;
+ }
+#ifdef AH_DEBUG
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: 5G Radio Chip Rev 0x%02X is not supported by "
+ "this driver\n", __func__,
+ AH_PRIVATE(ah)->ah_analog5GhzRev);
+ ecode = HAL_ENOTSUPP;
+ goto bad;
+#endif
+ }
+ rfStatus = ar9287RfAttach(ah, &ecode);
+ if (!rfStatus) {
+ HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
+ __func__, ecode);
+ goto bad;
+ }
+
+ /*
+ * We only implement open-loop TX power control
+ * for the AR9287 in this codebase.
+ */
+ if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
+ ath_hal_printf(ah, "[ath] AR9287 w/ closed-loop TX power control"
+ " isn't supported.\n");
+ ecode = HAL_ENOTSUPP;
+ goto bad;
+ }
+
+ /*
+ * Check whether the power table offset isn't the default.
+ * This can occur with eeprom minor V21 or greater on Merlin.
+ */
+ (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
+ if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB)
+ ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n",
+ AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset);
+
+ /* setup rxgain table */
+ HAL_INI_INIT(&ahp9287->ah_ini_rxgain, ar9287Modes_rx_gain_9287_1_1, 6);
+
+ /* setup txgain table */
+ HAL_INI_INIT(&ahp9287->ah_ini_txgain, ar9287Modes_tx_gain_9287_1_1, 6);
+
+ /*
+ * Got everything we need now to setup the capabilities.
+ */
+ if (!ar9287FillCapabilityInfo(ah)) {
+ ecode = HAL_EEREAD;
+ goto bad;
+ }
+
+ ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
+ if (ecode != HAL_OK) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: error getting mac address from EEPROM\n", __func__);
+ goto bad;
+ }
+ /* XXX How about the serial number ? */
+ /* Read Reg Domain */
+ AH_PRIVATE(ah)->ah_currentRD =
+ ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
+
+ /*
+ * ah_miscMode is populated by ar5416FillCapabilityInfo()
+ * starting from griffin. Set here to make sure that
+ * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
+ * placed into hardware.
+ */
+ if (ahp->ah_miscMode != 0)
+ OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
+
+ ar9287AniSetup(ah); /* Anti Noise Immunity */
+
+ /* Setup noise floor min/max/nominal values */
+ AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
+ AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
+ AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
+ AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ;
+ AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ;
+ AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9287_5GHZ;
+
+ ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
+
+ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
+
+ return ah;
+bad:
+ if (ah != AH_NULL)
+ ah->ah_detach(ah);
+ if (status)
+ *status = ecode;
+ return AH_NULL;
+}
+
+static void
+ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
+{
+ if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
+ ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
+ OS_DELAY(1000);
+ OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+ OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); /* Yes, Kiwi uses the Kite PCIe PHY WA */
+ }
+}
+
+static void
+ar9287WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ u_int modesIndex, freqIndex;
+ int regWrites = 0;
+
+ /* Setup the indices for the next set of register array writes */
+ /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
+ freqIndex = 2;
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ modesIndex = 3;
+ else if (IEEE80211_IS_CHAN_108G(chan))
+ modesIndex = 5;
+ else
+ modesIndex = 4;
+ } else {
+ freqIndex = 1;
+ if (IEEE80211_IS_CHAN_HT40(chan) ||
+ IEEE80211_IS_CHAN_TURBO(chan))
+ modesIndex = 2;
+ else
+ modesIndex = 1;
+ }
+
+ /* Set correct Baseband to analog shift setting to access analog chips. */
+ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
+ OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_rxgain, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_txgain, modesIndex, regWrites);
+ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites);
+}
+
+#define AR_BASE_FREQ_2GHZ 2300
+#define AR_BASE_FREQ_5GHZ 4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+
+
+
+/*
+ * Fill all software cached or static hardware state information.
+ * Return failure if capabilities are to come from EEPROM and
+ * cannot be read.
+ */
+static HAL_BOOL
+ar9287FillCapabilityInfo(struct ath_hal *ah)
+{
+ HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
+
+ if (!ar5416FillCapabilityInfo(ah))
+ return AH_FALSE;
+ pCap->halNumGpioPins = 10;
+ pCap->halWowSupport = AH_TRUE;
+ pCap->halWowMatchPatternExact = AH_TRUE;
+#if 0
+ pCap->halWowMatchPatternDword = AH_TRUE;
+#endif
+
+ pCap->halCSTSupport = AH_TRUE;
+ pCap->halRifsRxSupport = AH_TRUE;
+ pCap->halRifsTxSupport = AH_TRUE;
+ pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */
+ pCap->halExtChanDfsSupport = AH_TRUE;
+#if 0
+ /* XXX bluetooth */
+ pCap->halBtCoexSupport = AH_TRUE;
+#endif
+ pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */
+ pCap->hal4kbSplitTransSupport = AH_FALSE;
+ /* Disable this so Block-ACK works correctly */
+ pCap->halHasRxSelfLinkedTail = AH_FALSE;
+ pCap->halPSPollBroken = AH_FALSE;
+ pCap->halRxStbcSupport = 1;
+ pCap->halTxStbcSupport = 1;
+
+ return AH_TRUE;
+}
+
+/*
+ * This has been disabled - having the HAL flip chainmasks on/off
+ * when attempting to implement 11n disrupts things. For now, just
+ * leave this flipped off and worry about implementing TX diversity
+ * for legacy and MCS0-7 when 11n is fully functioning.
+ */
+HAL_BOOL
+ar9287SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
+{
+ return AH_TRUE;
+}
+
+static const char*
+ar9287Probe(uint16_t vendorid, uint16_t devid)
+{
+ if (vendorid == ATHEROS_VENDOR_ID &&
+ (devid == AR9287_DEVID_PCI || devid == AR9287_DEVID_PCIE))
+ return "Atheros 9287";
+ return AH_NULL;
+}
+AH_CHIP(AR9287, ar9287Probe, ar9287Attach);
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
new file mode 100644
index 0000000..d5024b0
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v4k.h"
+
+#include "ar9002/ar9285.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+#include "ar9002/ar9002phy.h"
+//#include "ar9002/ar9287phy.h"
+
+#include "ar9002/ar9287_cal.h"
+
+
+void
+ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset)
+{
+ /* XXX not required */
+}
+
+/*
+ * This is like Merlin but without ADC disable
+ */
+HAL_BOOL
+ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ /* Calibrate the AGC */
+ OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+ OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
+
+ /* Poll for offset calibration complete */
+ if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0)) {
+ HALDEBUG(ah, HAL_DEBUG_RESET,
+ "%s: offset calibration failed to complete in 1ms; "
+ "noisy environment?\n", __func__);
+ return AH_FALSE;
+ }
+
+ OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h
new file mode 100644
index 0000000..1a7cda2
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_cal.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef __AR9287_CAL_H__
+#define __AR9287_CAL_H__
+
+extern void ar9287PACal(struct ath_hal *ah, HAL_BOOL is_reset);
+extern HAL_BOOL ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan);
+
+#endif /* __AR9287_CAL_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c
new file mode 100644
index 0000000..cbbe017
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "ah_eeprom_v14.h"
+#include "ah_eeprom_9287.h"
+
+#include "ar9002/ar9280.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+#include "ar9002/ar9002phy.h"
+
+#include "ar9002/ar9287phy.h"
+#include "ar9002/ar9287an.h"
+#include "ar9002/ar9287_olc.h"
+
+void
+ar9287olcInit(struct ath_hal *ah)
+{
+ OS_REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
+ AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
+ OS_A_REG_RMW_FIELD(ah, AR9287_AN_TXPC0,
+ AR9287_AN_TXPC0_TXPCMODE,
+ AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
+ OS_DELAY(100);
+}
+
+/*
+ * Run temperature compensation calibration.
+ *
+ * The TX gain table is adjusted depending upon the difference
+ * between the initial PDADC value and the currently read
+ * average TX power sample value. This value is only valid if
+ * frames have been transmitted, so currPDADC will be 0 if
+ * no frames have yet been transmitted.
+ */
+void
+ar9287olcTemperatureCompensation(struct ath_hal *ah)
+{
+ uint32_t rddata;
+ int32_t delta, currPDADC, slope;
+
+ rddata = OS_REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+ currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+ HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: initPDADC=%d, currPDADC=%d\n",
+ __func__, AH5416(ah)->initPDADC, currPDADC);
+
+ if (AH5416(ah)->initPDADC == 0 || currPDADC == 0) {
+ /*
+ * Zero value indicates that no frames have been transmitted
+ * yet, can't do temperature compensation until frames are
+ * transmitted.
+ */
+ return;
+ } else {
+ int8_t val;
+ (void) (ath_hal_eepromGet(ah, AR_EEP_TEMPSENSE_SLOPE, &val));
+ slope = val;
+
+ if (slope == 0) { /* to avoid divide by zero case */
+ delta = 0;
+ } else {
+ delta = ((currPDADC - AH5416(ah)->initPDADC)*4) / slope;
+ }
+ OS_REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+ AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+ OS_REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+ AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+
+ HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: delta=%d\n", __func__, delta);
+ }
+}
+
+void
+ar9287olcGetTxGainIndex(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+ uint8_t *pCalChans, uint16_t availPiers, int8_t *pPwr)
+{
+ uint16_t idxL = 0, idxR = 0, numPiers;
+ HAL_BOOL match;
+ CHAN_CENTERS centers;
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
+
+ match = ath_ee_getLowerUpperIndex(
+ (uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
+ pCalChans, numPiers, &idxL, &idxR);
+
+ if (match) {
+ *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
+ } else {
+ *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
+ (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+ }
+}
+
+void
+ar9287olcSetPDADCs(struct ath_hal *ah, int32_t txPower,
+ uint16_t chain)
+{
+ uint32_t tmpVal;
+ uint32_t a;
+
+ /* Enable OLPC for chain 0 */
+
+ tmpVal = OS_REG_READ(ah, 0xa270);
+ tmpVal = tmpVal & 0xFCFFFFFF;
+ tmpVal = tmpVal | (0x3 << 24);
+ OS_REG_WRITE(ah, 0xa270, tmpVal);
+
+ /* Enable OLPC for chain 1 */
+
+ tmpVal = OS_REG_READ(ah, 0xb270);
+ tmpVal = tmpVal & 0xFCFFFFFF;
+ tmpVal = tmpVal | (0x3 << 24);
+ OS_REG_WRITE(ah, 0xb270, tmpVal);
+
+ /* Write the OLPC ref power for chain 0 */
+
+ if (chain == 0) {
+ tmpVal = OS_REG_READ(ah, 0xa398);
+ tmpVal = tmpVal & 0xff00ffff;
+ a = (txPower)&0xff;
+ tmpVal = tmpVal | (a << 16);
+ OS_REG_WRITE(ah, 0xa398, tmpVal);
+ }
+
+ /* Write the OLPC ref power for chain 1 */
+
+ if (chain == 1) {
+ tmpVal = OS_REG_READ(ah, 0xb398);
+ tmpVal = tmpVal & 0xff00ffff;
+ a = (txPower)&0xff;
+ tmpVal = tmpVal | (a << 16);
+ OS_REG_WRITE(ah, 0xb398, tmpVal);
+ }
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h
new file mode 100644
index 0000000..ff21ce6
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_olc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287_OLC_H__
+#define __AR9287_OLC_H__
+
+extern void ar9287olcInit(struct ath_hal *ah);
+extern void ar9287olcTemperatureCompensation(struct ath_hal *ah);
+extern void ar9287olcGetTxGainIndex(struct ath_hal *ah,
+ const struct ieee80211_channel *chan,
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+ uint8_t *pCalChans, uint16_t availPiers, int8_t *pPwr);
+extern void ar9287olcSetPDADCs(struct ath_hal *ah,
+ int32_t txPower, uint16_t chain);
+
+#endif /* __AR9287_OLC_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
new file mode 100644
index 0000000..34a723a
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+
+#include "ah_eeprom_v14.h"
+#include "ah_eeprom_9287.h"
+
+#include "ar5416/ar5416.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "ar9002/ar9287phy.h"
+#include "ar9002/ar9287an.h"
+
+#include "ar9002/ar9287_olc.h"
+#include "ar9002/ar9287_reset.h"
+
+/*
+ * Set the TX power calibration table per-chain.
+ *
+ * This only supports open-loop TX power control for the AR9287.
+ */
+static void
+ar9287SetPowerCalTable(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
+{
+ struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
+ uint8_t *pCalBChans = NULL;
+ uint16_t pdGainOverlap_t2;
+ uint16_t numPiers = 0, i;
+ uint16_t numXpdGain, xpdMask;
+ uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
+ uint32_t regChainOffset;
+ HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ struct ar9287_eeprom *pEepData = &ee->ee_base;
+
+ xpdMask = pEepData->modalHeader.xpdGain;
+
+ if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+ AR9287_EEP_MINOR_VER_2)
+ pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
+ else
+ pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+
+ /* Note: Kiwi should only be 2ghz.. */
+ if (IEEE80211_IS_CHAN_2GHZ(chan)) {
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR9287_NUM_2G_CAL_PIERS;
+ pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0];
+ AH5416(ah)->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
+ }
+ numXpdGain = 0;
+
+ /* Calculate the value of xpdgains from the xpdGain Mask */
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (uint16_t)(AR5416_PD_GAINS_IN_MASK-i);
+ numXpdGain++;
+ }
+ }
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ regChainOffset = i * 0x1000;
+
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ int8_t txPower;
+ pRawDatasetOpenLoop =
+ (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i];
+ ar9287olcGetTxGainIndex(ah, chan,
+ pRawDatasetOpenLoop,
+ pCalBChans, numPiers,
+ &txPower);
+ ar9287olcSetPDADCs(ah, txPower, i);
+ }
+ }
+
+ *pTxPowerIndexOffset = 0;
+}
+
+
+/* XXX hard-coded values? */
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
+
+/*
+ * ar9287SetPowerPerRateTable
+ *
+ * Sets the transmit power in the baseband for the given
+ * operating channel and mode.
+ *
+ * This is like the v14 EEPROM table except the 5GHz code.
+ */
+static HAL_BOOL
+ar9287SetPowerPerRateTable(struct ath_hal *ah,
+ struct ar9287_eeprom *pEepData,
+ const struct ieee80211_channel *chan,
+ int16_t *ratesArray, uint16_t cfgCtl,
+ uint16_t AntennaReduction,
+ uint16_t twiceMaxRegulatoryPower,
+ uint16_t powerLimit)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+/* Local defines to distinguish between extension and control CTL's */
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+ uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ int i;
+ int16_t twiceLargestAntenna;
+ struct cal_ctl_data_ar9287 *rep;
+ CAL_TARGET_POWER_LEG targetPowerOfdm;
+ CAL_TARGET_POWER_LEG targetPowerCck = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_LEG targetPowerCckExt = {0, {0, 0, 0, 0}};
+ CAL_TARGET_POWER_HT targetPowerHt20;
+ CAL_TARGET_POWER_HT targetPowerHt40 = {0, {0, 0, 0, 0}};
+ int16_t scaledPower, minCtlPower;
+
+#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
+ static const uint16_t ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ const uint16_t *pCtlMode;
+ uint16_t numCtlModes, ctlMode, freq;
+ CHAN_CENTERS centers;
+
+ ar5416GetChannelCenters(ah, chan, &centers);
+
+ /* Compute TxPower reduction due to Antenna Gain */
+
+ twiceLargestAntenna = AH_MAX(
+ pEepData->modalHeader.antennaGainCh[0],
+ pEepData->modalHeader.antennaGainCh[1]);
+
+ twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
+
+ /* XXX setup for 5212 use (really used?) */
+ ath_hal_eepromSet(ah, AR_EEP_ANTGAINMAX_2, twiceLargestAntenna);
+
+ /*
+ * scaledPower is the minimum of the user input power level and
+ * the regulatory allowed power level
+ */
+ scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna);
+
+ /* Reduce scaled Power by number of chains active to get to per chain tx power level */
+ /* TODO: better value than these? */
+ switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) {
+ case 1:
+ break;
+ case 2:
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ default:
+ return AH_FALSE; /* Unsupported number of chains */
+ }
+
+ scaledPower = AH_MAX(0, scaledPower);
+
+ /* Get target powers from EEPROM - our baseline for TX Power */
+ /* XXX assume channel is 2ghz */
+ if (1) {
+ /* Setup for CTL modes */
+ numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
+ pCtlMode = ctlModesFor11g;
+
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck,
+ AR9287_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE);
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
+ ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
+
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
+ numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */
+
+ ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40,
+ AR9287_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
+ /* Get target powers for extension channels */
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck,
+ AR9287_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE);
+ ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G,
+ AR9287_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
+ }
+ }
+
+ /*
+ * For MIMO, need to apply regulatory caps individually across dynamically
+ * running modes: CCK, OFDM, HT20, HT40
+ *
+ * The outer loop walks through each possible applicable runtime mode.
+ * The inner loop walks through each ctlIndex entry in EEPROM.
+ * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
+ *
+ */
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode) {
+ freq = centers.ctl_center;
+ } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
+ freq = centers.ext_center;
+ } else {
+ freq = centers.ctl_center;
+ }
+
+ /* walk through each CTL index stored in EEPROM */
+ for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+ uint16_t twiceMinEdgePower;
+
+ /* compare test group from regulatory channel list with test mode from pCtlMode list */
+ if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+ rep = &(pEepData->ctlData[i]);
+ twiceMinEdgePower = ar5416GetMaxEdgePower(freq,
+ rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1],
+ IEEE80211_IS_CHAN_2GHZ(chan));
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+ /* Find the minimum of all CTL edge powers that apply to this channel */
+ twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
+ } else {
+ /* specific */
+ twiceMaxEdgePower = twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+ minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower);
+ /* Apply ctl mode to correct target power set */
+ switch(pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = 0; i < N(targetPowerCck.tPow2x); i++) {
+ targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_11A:
+ case CTL_11G:
+ for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) {
+ targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_5GHT20:
+ case CTL_2GHT20:
+ for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
+ targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower);
+ }
+ break;
+ case CTL_11B_EXT:
+ targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower);
+ break;
+ case CTL_11A_EXT:
+ case CTL_11G_EXT:
+ targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower);
+ break;
+ case CTL_5GHT40:
+ case CTL_2GHT40:
+ for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
+ targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower);
+ }
+ break;
+ default:
+ return AH_FALSE;
+ break;
+ }
+ } /* end ctl mode checking */
+
+ /* Set rates Array from collected data */
+ ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray,
+ &targetPowerCck,
+ &targetPowerCckExt,
+ &targetPowerOfdm,
+ &targetPowerOfdmExt,
+ &targetPowerHt20,
+ &targetPowerHt40);
+ return AH_TRUE;
+#undef EXT_ADDITIVE
+#undef CTL_11A_EXT
+#undef CTL_11G_EXT
+#undef CTL_11B_EXT
+#undef SUB_NUM_CTL_MODES_AT_5G_40
+#undef SUB_NUM_CTL_MODES_AT_2G_40
+#undef N
+}
+
+#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
+
+/*
+ * This is based off of the AR5416/AR9285 code and likely could
+ * be unified in the future.
+ */
+HAL_BOOL
+ar9287SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
+{
+#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
+#define N(a) (sizeof (a) / sizeof (a[0]))
+
+ const struct modal_eep_ar9287_header *pModal;
+ struct ath_hal_5212 *ahp = AH5212(ah);
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ uint8_t ht40PowerIncForPdadc = 2;
+ int i;
+
+ uint16_t cfgCtl;
+ uint16_t powerLimit;
+ uint16_t twiceAntennaReduction;
+ uint16_t twiceMaxRegulatoryPower;
+ int16_t maxPower;
+ HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ struct ar9287_eeprom *pEepData = &ee->ee_base;
+
+ /* Setup info for the actual eeprom */
+ OS_MEMZERO(ratesArray, sizeof(ratesArray));
+ cfgCtl = ath_hal_getctl(ah, chan);
+ powerLimit = chan->ic_maxregpower * 2;
+ twiceAntennaReduction = chan->ic_maxantgain;
+ twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
+ pModal = &pEepData->modalHeader;
+ HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
+ __func__,chan->ic_freq, cfgCtl );
+
+ /* XXX Assume Minor is v2 or later */
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+
+ /* Fetch per-rate power table for the given channel */
+ if (! ar9287SetPowerPerRateTable(ah, pEepData, chan,
+ &ratesArray[0],cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower, powerLimit)) {
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: unable to set tx power per rate table\n", __func__);
+ return AH_FALSE;
+ }
+
+ /* Set TX power control calibration curves for each TX chain */
+ ar9287SetPowerCalTable(ah, chan, &txPowerIndexOffset);
+
+ /* Calculate maximum power level */
+ maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
+ maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
+
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
+
+ ahp->ah_tx6PowerInHalfDbm = maxPower;
+ AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower;
+ ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
+
+ /*
+ * txPowerIndexOffset is set by the SetPowerTable() call -
+ * adjust the rate table (0 offset if rates EEPROM not loaded)
+ */
+ /* XXX what about the pwrTableOffset? */
+ for (i = 0; i < N(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ /* -5 dBm offset for Merlin and later; this includes Kiwi */
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
+ if (ratesArray[i] < 0)
+ ratesArray[i] = 0;
+ }
+
+#ifdef AH_EEPROM_DUMP
+ ar5416PrintPowerPerRate(ah, ratesArray);
+#endif
+
+ /*
+ * Adjust the HT40 power to meet the correct target TX power
+ * for 40MHz mode, based on TX power curves that are established
+ * for 20MHz mode.
+ *
+ * XXX handle overflow/too high power level?
+ */
+ if (IEEE80211_IS_CHAN_HT40(chan)) {
+ ratesArray[rateHt40_0] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_1] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_2] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_3] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_4] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_5] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_6] += ht40PowerIncForPdadc;
+ ratesArray[rateHt40_7] += ht40PowerIncForPdadc;
+ }
+
+ /* Write the TX power rate registers */
+ ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray);
+
+ return AH_TRUE;
+#undef POW_SM
+#undef N
+}
+
+/*
+ * Read EEPROM header info and program the device for correct operation
+ * given the channel value.
+ */
+HAL_BOOL
+ar9287SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
+{
+ const HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
+ const struct ar9287_eeprom *eep = &ee->ee_base;
+ const struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+ uint16_t antWrites[AR9287_ANT_16S];
+ uint32_t regChainOffset, regval;
+ uint8_t txRxAttenLocal;
+ int i, j, offset_num;
+
+ pModal = &eep->modalHeader;
+
+ antWrites[0] = (uint16_t)((pModal->antCtrlCommon >> 28) & 0xF);
+ antWrites[1] = (uint16_t)((pModal->antCtrlCommon >> 24) & 0xF);
+ antWrites[2] = (uint16_t)((pModal->antCtrlCommon >> 20) & 0xF);
+ antWrites[3] = (uint16_t)((pModal->antCtrlCommon >> 16) & 0xF);
+ antWrites[4] = (uint16_t)((pModal->antCtrlCommon >> 12) & 0xF);
+ antWrites[5] = (uint16_t)((pModal->antCtrlCommon >> 8) & 0xF);
+ antWrites[6] = (uint16_t)((pModal->antCtrlCommon >> 4) & 0xF);
+ antWrites[7] = (uint16_t)(pModal->antCtrlCommon & 0xF);
+
+ offset_num = 8;
+
+ for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 28) & 0xf);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 10) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 8) & 0x3);
+ antWrites[j++] = 0;
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 6) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 4) & 0x3);
+ antWrites[j++] = (uint16_t)((pModal->antCtrlChain[i] >> 2) & 0x3);
+ antWrites[j++] = (uint16_t)(pModal->antCtrlChain[i] & 0x3);
+ }
+
+ OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ regChainOffset = i * 0x1000;
+
+ OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+ pModal->antCtrlChain[i]);
+
+ OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset,
+ (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0) + regChainOffset)
+ & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+ SM(pModal->iqCalICh[i],
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+ SM(pModal->iqCalQCh[i],
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+ txRxAttenLocal = pModal->txRxAttenCh[i];
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ pModal->bswMargin[i]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ pModal->bswAtten[i]);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN,
+ txRxAttenLocal);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN,
+ pModal->rxTxMarginCh[i]);
+ }
+
+
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
+ else
+ OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+ AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
+
+ OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+ | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+ | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+ | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
+ AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_CCA,
+ AR9280_PHY_CCA_THRESH62, pModal->thresh62);
+ OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+ AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
+
+ regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH0);
+ regval &= ~(AR9287_AN_RF2G3_DB1 |
+ AR9287_AN_RF2G3_DB2 |
+ AR9287_AN_RF2G3_OB_CCK |
+ AR9287_AN_RF2G3_OB_PSK |
+ AR9287_AN_RF2G3_OB_QAM |
+ AR9287_AN_RF2G3_OB_PAL_OFF);
+ regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+ SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+ SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+ SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+ SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+ SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+ OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH0, regval);
+ OS_DELAY(100); /* analog write */
+
+ regval = OS_REG_READ(ah, AR9287_AN_RF2G3_CH1);
+ regval &= ~(AR9287_AN_RF2G3_DB1 |
+ AR9287_AN_RF2G3_DB2 |
+ AR9287_AN_RF2G3_OB_CCK |
+ AR9287_AN_RF2G3_OB_PSK |
+ AR9287_AN_RF2G3_OB_QAM |
+ AR9287_AN_RF2G3_OB_PAL_OFF);
+ regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
+ SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
+ SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
+ SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
+ SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
+ SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
+
+ OS_REG_WRITE(ah, AR9287_AN_RF2G3_CH1, regval);
+ OS_DELAY(100); /* analog write */
+
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+ AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart);
+ OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+ AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn);
+
+ OS_A_REG_RMW_FIELD(ah, AR9287_AN_TOP2,
+ AR9287_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl);
+
+ return AH_TRUE;
+}
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h
new file mode 100644
index 0000000..679fb8c
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_reset.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287_RESET_H__
+#define __AR9287_RESET_H__
+
+extern HAL_BOOL ar9287SetTransmitPower(struct ath_hal *ah,
+ const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
+extern HAL_BOOL ar9287SetBoardValues(struct ath_hal *ah,
+ const struct ieee80211_channel *chan);
+
+#endif /* __AR9287_RESET_H__ */
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287an.h b/sys/dev/ath/ath_hal/ar9002/ar9287an.h
new file mode 100644
index 0000000..ba7a92c
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287an.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287AN_H__
+#define __AR9287AN_H__
+
+#define AR9287_AN_RF2G3_CH0 0x7808
+#define AR9287_AN_RF2G3_CH1 0x785c
+#define AR9287_AN_RF2G3_DB1 0xE0000000
+#define AR9287_AN_RF2G3_DB1_S 29
+#define AR9287_AN_RF2G3_DB2 0x1C000000
+#define AR9287_AN_RF2G3_DB2_S 26
+#define AR9287_AN_RF2G3_OB_CCK 0x03800000
+#define AR9287_AN_RF2G3_OB_CCK_S 23
+#define AR9287_AN_RF2G3_OB_PSK 0x00700000
+#define AR9287_AN_RF2G3_OB_PSK_S 20
+#define AR9287_AN_RF2G3_OB_QAM 0x000E0000
+#define AR9287_AN_RF2G3_OB_QAM_S 17
+#define AR9287_AN_RF2G3_OB_PAL_OFF 0x0001C000
+#define AR9287_AN_RF2G3_OB_PAL_OFF_S 14
+
+#define AR9287_AN_TXPC0 0x7898
+#define AR9287_AN_TXPC0_TXPCMODE 0x0000C000
+#define AR9287_AN_TXPC0_TXPCMODE_S 14
+#define AR9287_AN_TXPC0_TXPCMODE_NORMAL 0
+#define AR9287_AN_TXPC0_TXPCMODE_TEST 1
+#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
+#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST 3
+
+#define AR9287_AN_TOP2 0x78b4
+#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000
+#define AR9287_AN_TOP2_XPABIAS_LVL_S 30
+
+#endif
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287phy.h b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h
new file mode 100644
index 0000000..8f28194
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287phy.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __AR9287PHY_H__
+#define __AR9287PHY_H__
+
+/* AR_PHY_CH0_TX_PWRCTRL11, AR_PHY_CH1_TX_PWRCTRL11 */
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#endif
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 26a50bc..6353847 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -634,11 +634,11 @@ void ath_intr(void *);
#define ath_hal_settpcts(_ah, _tpcts) \
ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL)
#define ath_hal_hasintmit(_ah) \
- (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 0, NULL) == HAL_OK)
+ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_PRESENT, NULL) == HAL_OK)
#define ath_hal_getintmit(_ah) \
- (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK)
+ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, NULL) == HAL_OK)
#define ath_hal_setintmit(_ah, _v) \
- ath_hal_setcapability(_ah, HAL_CAP_INTMIT, 1, _v, NULL)
+ ath_hal_setcapability(_ah, HAL_CAP_INTMIT, HAL_CAP_INTMIT_ENABLE, _v, NULL)
#define ath_hal_getchannoise(_ah, _c) \
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
#define ath_hal_getrxchainmask(_ah, _prxchainmask) \
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 2adbf1c..23538f7 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -1018,7 +1018,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN)
error = EINVAL;
else if (ifp->if_mtu != ifr->ifr_mtu) {
- if (ifr->ifr_mtu > ETHERMTU) {
+ if (ifr->ifr_mtu > ETHERMTU) {
if ((sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) {
error = EINVAL;
MSK_IF_UNLOCK(sc_if);
@@ -1636,7 +1636,7 @@ msk_attach(device_t dev)
* this workaround does not work so disable checksum offload
* for VLAN interface.
*/
- ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
/*
* Enable Rx checksum offloading for VLAN tagged frames
* if controller support new descriptor format.
@@ -1921,7 +1921,8 @@ mskc_attach(device_t dev)
error = ENXIO;
goto fail;
}
- mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO);
+ mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK |
+ M_ZERO);
if (mmd == NULL) {
device_printf(dev, "failed to allocate memory for "
"ivars of PORT_B\n");
@@ -1930,9 +1931,9 @@ mskc_attach(device_t dev)
}
mmd->port = MSK_PORT_B;
mmd->pmd = sc->msk_pmd;
- if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
+ if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
mmd->mii_flags |= MIIF_HAVEFIBER;
- if (sc->msk_pmd == 'P')
+ if (sc->msk_pmd == 'P')
mmd->mii_flags |= MIIF_HAVEFIBER | MIIF_MACPRIV0;
device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd);
}
@@ -3741,10 +3742,10 @@ msk_init_locked(struct msk_if_softc *sc_if)
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
}
- /* GMAC Control reset. */
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
+ /* GMAC Control reset. */
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
@@ -3854,13 +3855,13 @@ msk_init_locked(struct msk_if_softc *sc_if)
msk_set_tx_stfwd(sc_if);
}
- if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
- sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
- /* Disable dynamic watermark - from Linux. */
- reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
- reg &= ~0x03;
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
- }
+ if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
+ sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
+ /* Disable dynamic watermark - from Linux. */
+ reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
+ reg &= ~0x03;
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
+ }
/*
* Disable Force Sync bit and Alloc bit in Tx RAM interface
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 5dbe30c..54808c5 100644
--- a/sys/dev/mvs/mvs.c
+++ b/sys/dev/mvs/mvs.c
@@ -1738,13 +1738,6 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- mvs_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there was fatal error - reset port. */
@@ -1764,6 +1757,13 @@ mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != MVS_ERR_TIMEOUT)
mvs_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ mvs_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
/* Start PM timer. */
if (ch->numrslots == 0 && ch->pm_level > 3 &&
(ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
@@ -2080,7 +2080,8 @@ mvs_softreset(device_t dev, union ccb *ccb)
{
struct mvs_channel *ch = device_get_softc(dev);
int port = ccb->ccb_h.target_id & 0x0f;
- int i;
+ int i, stuck;
+ uint8_t status;
mvs_set_edma_mode(dev, MVS_EDMA_OFF);
ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT);
@@ -2089,12 +2090,35 @@ mvs_softreset(device_t dev, union ccb *ccb)
ATA_OUTB(ch->r_mem, ATA_CONTROL, 0);
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
/* Wait for clearing busy status. */
- if ((i = mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout)) < 0) {
+ if ((i = mvs_wait(dev, 0, ATA_S_BUSY, ccb->ccb_h.timeout)) < 0) {
ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
+ stuck = 1;
} else {
- ccb->ccb_h.status |= CAM_REQ_CMP;
+ status = mvs_getstatus(dev, 0);
+ if (status & ATA_S_ERROR)
+ ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
+ else
+ ccb->ccb_h.status |= CAM_REQ_CMP;
+ if (status & ATA_S_DRQ)
+ stuck = 1;
+ else
+ stuck = 0;
}
mvs_tfd_read(dev, ccb);
+
+ /*
+ * XXX: If some device on PMP failed to soft-reset,
+ * try to recover by sending dummy soft-reset to PMP.
+ */
+ if (stuck && ch->pm_present && port != 15) {
+ ATA_OUTB(ch->r_mem, SATA_SATAICTL,
+ 15 << SATA_SATAICTL_PMPTX_SHIFT);
+ ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET);
+ DELAY(10000);
+ ATA_OUTB(ch->r_mem, ATA_CONTROL, 0);
+ mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout);
+ }
+
xpt_done(ccb);
}
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 01edae3..a7b018a 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1178,11 +1178,22 @@ siis_timeout(struct siis_slot *slot)
{
device_t dev = slot->dev;
struct siis_channel *ch = device_get_softc(dev);
+ union ccb *ccb = slot->ccb;
mtx_assert(&ch->mtx, MA_OWNED);
/* Check for stale timeout. */
if (slot->state < SIIS_SLOT_RUNNING)
return;
+
+ /* Handle soft-reset timeouts without doing hard-reset. */
+ if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
+ (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
+ (ccb->ataio.cmd.control & ATA_A_RESET)) {
+ xpt_freeze_simq(ch->sim, ch->numrslots);
+ siis_end_transaction(slot, SIIS_ERR_TFE);
+ return;
+ }
+
device_printf(dev, "Timeout on slot %d\n", slot->slot);
device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n",
__func__, ATA_INL(ch->r_mem, SIIS_P_IS),
@@ -1331,13 +1342,6 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
ch->numhslots++;
} else
xpt_done(ccb);
- /* Unfreeze frozen command. */
- if (ch->frozen && !siis_check_collision(dev, ch->frozen)) {
- union ccb *fccb = ch->frozen;
- ch->frozen = NULL;
- siis_begin_transaction(dev, fccb);
- xpt_release_simq(ch->sim, TRUE);
- }
/* If we have no other active commands, ... */
if (ch->rslots == 0) {
/* if there were timeouts or fatal error - reset port. */
@@ -1355,6 +1359,13 @@ siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
} else if ((ch->rslots & ~ch->toslots) == 0 &&
et != SIIS_ERR_TIMEOUT)
siis_rearm_timeout(dev);
+ /* Unfreeze frozen command. */
+ if (ch->frozen && !siis_check_collision(dev, ch->frozen)) {
+ union ccb *fccb = ch->frozen;
+ ch->frozen = NULL;
+ siis_begin_transaction(dev, fccb);
+ xpt_release_simq(ch->sim, TRUE);
+ }
}
static void
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 7af5303..5bec624 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -826,12 +826,13 @@ static const struct {
#define HDA_CODEC_NVIDIAXXXX HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff)
/* INTEL */
-#define HDA_CODEC_INTELG45_1 HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
-#define HDA_CODEC_INTELG45_2 HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
-#define HDA_CODEC_INTELG45_3 HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
-#define HDA_CODEC_INTELG45_4 HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
-#define HDA_CODEC_INTELG45_5 HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
-#define HDA_CODEC_INTELQ57 HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
+#define HDA_CODEC_INTELIP HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
+#define HDA_CODEC_INTELBL HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
+#define HDA_CODEC_INTELCA HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
+#define HDA_CODEC_INTELEL HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
+#define HDA_CODEC_INTELIP2 HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
+#define HDA_CODEC_INTELCPT HDA_CODEC_CONSTRUCT(INTEL, 0x2805)
+#define HDA_CODEC_INTELCL HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
#define HDA_CODEC_INTELXXXX HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
/* Codecs */
@@ -998,12 +999,13 @@ static const struct {
{ HDA_CODEC_NVIDIAGT21X, "NVidia GT21x HDMI" },
{ HDA_CODEC_NVIDIAMCP89, "NVidia MCP89 HDMI" },
{ HDA_CODEC_NVIDIAGT240, "NVidia GT240 HDMI" },
- { HDA_CODEC_INTELG45_1, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_2, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_3, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_4, "Intel G45 HDMI" },
- { HDA_CODEC_INTELG45_5, "Intel G45 HDMI" },
- { HDA_CODEC_INTELQ57, "Intel Q57 HDMI" },
+ { HDA_CODEC_INTELIP, "Intel Ibex Peak HDMI" },
+ { HDA_CODEC_INTELBL, "Intel Bearlake HDMI" },
+ { HDA_CODEC_INTELCA, "Intel Cantiga HDMI" },
+ { HDA_CODEC_INTELEL, "Intel Eaglelake HDMI" },
+ { HDA_CODEC_INTELIP2, "Intel Ibex Peak HDMI" },
+ { HDA_CODEC_INTELCPT, "Intel Cougar Point HDMI" },
+ { HDA_CODEC_INTELCL, "Intel Crestline HDMI" },
{ HDA_CODEC_SII1390, "Silicon Image SiI1390 HDMI" },
{ HDA_CODEC_SII1392, "Silicon Image SiI1392 HDMI" },
/* Unknown codec */
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 3cdd5ad..489be29 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -242,8 +242,14 @@ ns8250_probe(struct uart_bas *bas)
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
+ /*
+ * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699
+ * chip, but otherwise doesn't seem to have a function. In
+ * other words, uart(4) works regardless. Ignore that bit so
+ * the probe succeeds.
+ */
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
OpenPOWER on IntegriCloud